Sample - WASAPI exclusive-mode event-driven playback app, including the HD Audio alignment dance
This blog post has moved to https://matthewvaneerde.wordpress.com/2009/04/03/sample-wasapi-exclusive-mode-event-driven-playback-app-including-the-hd-audio-alignment-dance/
Comments
Anonymous
April 05, 2009
Your comment on Raymond's blog is rather odd. http://blogs.msdn.com/oldnewthing/archive/2009/04/03/9529929.aspx#9530732 How do you expect computers to work without virtual memory?Anonymous
April 06, 2009
> How do you expect computers to work without virtual memory? Quickly* or not at all**. *If everything fits in physical memory **If it doesn'tAnonymous
August 29, 2009
I do not get it: You initialize it at 3 ms. It returns a buffer size of 160 bytes. You tear it down and re-initialize it with a time that corresponds to 160 bytes buffer. Woudn't ignoring "AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED" give the same end-result, or did I miss something?Anonymous
August 29, 2009
If you ignore the AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED error, then further calls you make on that IAudioClient object will fail (well, calls other than IAudioClient::GetBufferSize.) In particular, there's no way to get an IAudioRenderClient or an IAudioCaptureClient on a needs-alignment endpoint without doing the dance (or guessing right the first time) because IAudioClient::GetService(...) will fail.Anonymous
August 30, 2009
Thaks for your reply. My current implementation does guess right the first time (as long as the rule is to stick with 128 byte alignment).Anonymous
July 30, 2010
So I assume the purpose of this was just an example demo to show how to us exclusive mode "right" or "well"?Anonymous
March 26, 2011
be careful !!! hnsPeriod = // hns = (REFERENCE_TIME)( 10000.0 * // (hns / ms) * 1000 * // (ms / s) * nFramesInBuffer / // frames / pWfx->nSamplesPerSec // (frames / s) + 0.5 // rounding ); doesn't work as expected. (10000.0 * 1000 / 44100 * 160) = 36281.179138321997 (10000.0 * 1000 / 44100 * 160) + 0.5 = 36281.679138321997 when assigning to hnsPeriod which is supposedly "int" or smth we get hnsPeriod = 36281 then doing reverse calculations of nFramesInBuffer nFramesInBuffer=3628144100/(100010000)=159 Not 160 as expected. another one from MS :(Anonymous
March 27, 2011
The going-back-to-frames code looks like this: // need to know how many frames that is UINT32 nFramesInBuffer = (UINT32)( // frames = 1.0 * hnsPeriod * // hns * pWfx->nSamplesPerSec / // (frames / s) / 1000 / // (ms / s) / 10000 // (hns / s) / + 0.5 // rounding ); Notice the 1.0 to force a conversion to double, and then the +0.5 at the end. 36281*44100/1000/10000 is 159.9992...; adding 0.5 and then converting to int snaps this to the nearest frame, 160.Anonymous
March 29, 2011
where does code snippet coming from? Is it really code that works in the OS or you think it should be like this?Anonymous
March 29, 2011
And what is priority in your calculations duration or number of frames? Why is it so confusing?Anonymous
March 29, 2011
Code snippets come from the attached play-exclusive.zip, play.cpp. This code is not in the OS; this is an example WASAPI client.Anonymous
October 12, 2011
On this forum post: social.msdn.microsoft.com/.../f4ec50d0-01cc-4217-8647-a2d7ec693c6d you mention that capture would look similar. I tried to create a simple exclusive capture program, but the program hangs when I unplug the microphone. Forum post: social.msdn.microsoft.com/.../83f5978d-e809-46ab-95bd-e41502901cdd Have you tried creating an exclusive capture example program? Have you ever run into this problem before? I saw that there's a problem calling Release from a different thread than the one that called GetService(), but that does not appear to be my problem. Thanks! Great post, BTW. BillAnonymous
October 12, 2011
The comment has been removedAnonymous
December 07, 2011
what codes do I need to add in order to play files other than 16bit 44.1KHz format? Sorry, maybe off topic!Anonymous
December 07, 2011
If the audio driver supports the wave format in the .wav file, this will play it. If the audio driver does not support the wave format in the .wav file, then you will need a format converter. WASAPI does not provide a format converter, so you will need to use a higher-level API like Media Foundation to play the content.Anonymous
December 07, 2011
The comment has been removedAnonymous
April 24, 2012
When i compile your code, i obtain this error :s prefs.cpp(366): error C2664: 'mmioOpenA' : cannot convert parameter 1 from 'LPWSTR' to 'LPSTR' 1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style castAnonymous
April 24, 2012
@Cubra: there are two ways a driver can support 24 bit. It can support 24 bit in 24-bit containers, where each sample is three bytes long. Or it can support 24 bit in 32-bit containers. Each sample is a signed four-byte integer, but the least significant byte is considered garbage and should be ignored. Heuristically, HD Audio drivers tend to favor 24-bit-in-32-bit-containers, and USB Audio drivers tend to favor 24-bit-in-24-bit-containers. But the app should query format support for both separately. For 24-in-24, specify wBitsPerSample and wValidBitsPerSample of 24; for 24-in-32, specify wBitsPerSample = 32 and wValidBitsPerSample of 24. If you're playing 24-in-24 audio to a 24-in-32-capable driver you'll need to do some processing in your app to add the extra byte of padding. Similarly, if you're playing 24-in-32 audio to a 24-in-24-capable driver you'll need to remove the padding.Anonymous
April 24, 2012
@Jeyminee: edit your project properties to include these flags to pass to the C++ compiler: -DUNICODE -D_UNICODEAnonymous
September 04, 2014
The comment has been removedAnonymous
September 04, 2014
0x88890008 is AUDCLNT_E_UNSUPPORTED_FORMAT, which is normal if the device does not support the WAVEFORMATEX format in the .wav file. ac3.wav has Dolby Digital audio in it. I would only expect a hardware receiver with the Dolby logo to be able to decode Dolby Digital in hardware, so I am not surprised your HDMI TV and built-in speakers reject it.Anonymous
November 17, 2014
Thanks for the sample code. I was going to ask about this to you; but decided to do a web search first and found my answer :)Anonymous
January 03, 2015
Hi Matthew, I'm trying to get a WASAPI shared client working with capture + rendering, but have artefact problems (render part) when I use a non-buffer-size. It works fine when ONLY rendering, but not when doing both. I know it's hard to have answers from this brief, informationless, description :) But do you have any general pointers to handling events etc. i.e. is it better to WaitForMultipleObjects with the capture/play handles, or WaitForSingleObject on each ? That kind of stuff.. :)Anonymous
January 03, 2015
@Robert a good place to ask your question is here: social.msdn.microsoft.com/.../home If you're capturing and rendering on the same thread you might have to worry about clock skew; you can use IAudioClockAdjustment to compensate.Anonymous
June 06, 2017
As a newbie to WASAPI, this post helped me get up and going which was great. I tried it out using (VS17) and got drop-outs on almost any machine activity on 192kHz. I bumped up priorities which didn't seem to help. Any ideas?- Anonymous
June 07, 2017
Please file a problem report in the Feedback Hub as described here https://blogs.msdn.microsoft.com/matthew_van_eerde/2016/09/26/report-problems-with-logs-and-suggest-features-with-the-feedback-hub/Once filed, use the "Share" widget to grab a direct linkSend me the link- Anonymous
June 07, 2017
Got it. Thanks. - Anonymous
June 07, 2017
Actually. I just tested the executable on a Windows 10 machine and the behavior is much improved over the Windows 7 which was experiencing the dropouts. Does that make sense?- Anonymous
June 07, 2017
Could be a problem triggered by certain hardware.
- Anonymous
- Anonymous
- Anonymous
Anonymous
November 09, 2018
Hi I am beginner in WASAPI programing so when i was searching i found your articleCan i use your help to ask some questions please!