Sample - WASAPI loopback capture (record what you hear)
This blog post has moved to https://matthewvaneerde.wordpress.com/2008/12/16/sample-wasapi-loopback-capture-record-what-you-hear/
Comments
Anonymous
December 24, 2008
Hello Matt! Excellent blog! Would you happen to know whether it's possible to record audio from a specific application using the loopback technique? Thanks, JayAnonymous
January 05, 2009
Not directly... loopback capture is the aggregate of all shared-mode streams to the device in question, post-mix. This also won't work for applications that play in exclusive mode.Anonymous
February 10, 2009
I have been looking for something similar to what Jay mentions as well. I would like to capture the audio stream for a single application to a file stream. So if loopback capture isn't the right answer, is there one?Anonymous
February 12, 2009
I will provide your feedback to the audio team.Anonymous
March 02, 2009
Thanks very much for the post.. I was desperately looking for this idea for my pet project. Thanks again.Anonymous
March 25, 2009
Thanks for this. One of my systems (a Dell e521) is a model that has no ability to record stereo mix. Why I think stereo mix should've been included, and am at a loss as to why Dell or MS would remove it, this is a decent workaround.Anonymous
April 16, 2009
First of all, thanks for an interesting post! I'm trying to port the code to C# but have run into some trouble. Everything is up and running except the inner capturing loop. When I call iAudioCaptureClient.GetNextPacketSize it throws an AUDCLNT_E_OUT_OF_ORDER at me. If I skip that and call iAudioCaptureClient.GetBuffer it actually returns a couple of frames (around 400) and that data seems good. But when I call ReleaseBuffer I get an AccessViolationException and the next call to GetBuffer will now also return an AUDCLNT_E_OUT_OF_ORDER error. Any idea what I could be doing wrong?Anonymous
April 17, 2009
It sounds like your C# iAudioCaptureClient methods aren't mapping to the IAudioCaptureClient methods correctly.; that is, the method you think you're calling is not the method you're actually calling. AUDCLNT_E_OUT_OF_ORDER is expected if you call ReleaseBuffer() without calling GetBuffer() first, or if you call GetBuffer() twice in a row without a ReleaseBuffer() in between. The Access Violation is harder to explain. Can you post (or email me) the DllImport code you're using to define the iAudioCaptureClient methods?Anonymous
May 20, 2009
I have looked into the attachments and had the loopback-capture.exe file. How should i use the exe file to record what i hear from my system speakers? can any one help me please? Thnks Baskaran BAnonymous
June 01, 2009
What have you tried, and what happened when you tried it? Note that depending on your audio hardware and drivers there are likely other ways to record what comes from your speakers: e.g., using the analog mixer.Anonymous
June 10, 2009
Thank you very much, Matthew! It's awesome! I really want to on like this. Again thank you! BongShin.Anonymous
July 10, 2009
How we can make it the loop back capture usefull for AEC, in the sense I need to record what are the samples rendering to play back device as well as the sound capturing from microphone. If it is possible in vista could i do it in XP also?. Plz reply me.......Anonymous
July 23, 2009
The comment has been removedAnonymous
September 11, 2009
Thanks for sharing -- this is great. Will the AUDCLNT_STREAMFLAGS_EVENTCALLBACK and "data is ready" event be support for LOOPBACK in Win7? i.e., was this a bug that will be fixed in Win7? Thanks again, DanAnonymous
September 11, 2009
No, this is a design decision. I'm lobbying for IAudioClient::Initialize(... _EVENTCALLBACK | _LOOPBACK, ...) to return an error code, but that won't happen for Win7 either.Anonymous
November 12, 2009
Maurits, Would you be willing to port this code to C# (or even create a DLL which I could include in a C# project)? I am willing to pay you for your time. CDAnonymous
November 12, 2009
The comment has been removedAnonymous
November 22, 2009
Are there any plans to make this compatible with Windows 7?Anonymous
November 23, 2009
The comment has been removedAnonymous
November 24, 2009
Oh my gosh, thanks so much! This is going to be invaluable, I really appreciate it!Anonymous
November 26, 2009
Hi, I can't make it work as I lack AVRT.dll. Is this supposed to work only on Vista? What should I install to get the Dll? Weird thing the MSVC came with AVRT.lib, but not the dll...Anonymous
November 26, 2009
Yes, this requires Windows Vista or later.Anonymous
December 28, 2009
is there a way to capture at rates other than 16 bits, 44.1 Khz? can i capture at 24 bit, 96 Khz? thanksAnonymous
December 28, 2009
hi matthew, is there a way to stop the glitch behavior? i want to record all audio on my computer without a break, from various applications/devices, non-stop. i'm a teacher, and i need this to document my audio classes. can you provide a version with the glitch-stop feature? this would be supremely helpful. thanksAnonymous
December 29, 2009
to clarify, on my pc, your app closes when i open or close an audio-producing software. on my friend's pc, your app does NOT close when i open or close an audio-producing software. so different pc's may or may not create "glitches". my need is to open and close audio software repeatedly, without causing your recording to stop. thanksAnonymous
June 07, 2010
Hi Maurits, Thanks for providing this good example. :) There is a question would like to consult with you. loopback-capture will capture audio with default sample rate. (my default setting is 16bit, 44100Hz) Is it possible to capture audio with different sample rate (such as 16bit, 48000Hz)? Thanks you very much. :) EdwardAnonymous
June 08, 2010
Loopback capture uses the render endpoint's "mix" format (or trivial conversions thereof, such as float-to-int.) Converting sample rate from 44100 to 48000 is a non-trivial operation so loopback capture won't perform it. If the render endpoint supports 48000 you could change the "mix" format. To do so using the Sound control panel, double-click on the default playback device, go to the Advanced tab, and see if there's a suitable 48 kHz format listed in the "default format" section.- Anonymous
November 25, 2018
Hi Maurits, Thanks for providing this good example. :)There is a question would like to consult with you.loopback-capture will capture audio with default sample rate. (my default setting is 16bit, 44100Hz)Is it possible to capture audio with different sample rate (such as 16bit, 16000Hz), I want to do Voice recognition So it must be in th sample rate(16bit, one channel, 16000hz)>Could you privider me a way to do this conversion?Thanks you very much. :)Edward
- Anonymous
Anonymous
June 15, 2010
nAudio has a good C# example. I had the exact same issue with the OUT_OF_ORDER exception on GetNextPacketSize() and it turned out that I had the wrong order of methods in my IAudioCaptureClient interface. I definitely did not know that it mattered...Anonymous
July 30, 2010
Thanks for the code! For me, for whatever reason, silence yields (within a few seconds) >silence Press Enter to quit... Got "feed me" event but IAudioClient::GetCurrentPadding reports buffer is full - glitch? The thread terminated early - something bad happened Thread HRESULT is 0x8000ffff as also loopback always (even with sound going, after a few seconds): loopback-capture.exe Press Enter to quit... Probably spurious glitch reported on first packet IAudioCaptureClient::GetBuffer set flags to 0x00000001 on pass 102 after 22400 frames The thread terminated early - something bad happened Thread HRESULT is 0x8000ffff perhaps it's not windows 7 friendly yet? Thanks. -rAnonymous
July 30, 2010
> Got "feed me" event but IAudioClient::GetCurrentPadding reports buffer is full - glitch? > IAudioCaptureClient::GetBuffer set flags to 0x00000001 on pass 102 after 22400 frames Both of these point to glitches. Under normal circumstances, glitches shouldn't happen; they point to a problem with the system. Can you follow the instructions in this forum thread social.msdn.microsoft.com/.../1A796E5C-E808-42C0-96CD-84CEBFAF71D5 and send me the .etl file? mateer at microsoft dot comAnonymous
September 07, 2010
Hi, I tried to compile the code, I'm using code block 10.05 and gcc that comes with code block. I got a long list of errors that start with C:Program Files (x86)Microsoft SDKsWindowsv7.0AIncludespecstrings.h|11|error: sal.h: No such file or directory| C:Program Files (x86)Microsoft SDKsWindowsv7.0AIncludewinnt.h|851|error: #error Must define a target architecture.| C:Program Files (x86)Microsoft SDKsWindowsv7.0AIncludewinnt.h|1202|error: pasting "(" and "__drv_nop" does not give a valid preprocessing token| C:Program Files (x86)Microsoft SDKsWindowsv7.0AIncludewinnt.h|12880|error: pasting "(" and "__drv_nop" does not give a valid preprocessing token| C:Program Files (x86)Microsoft SDKsWindowsv7.0AIncludewinnt.h|13305|error: pasting "(" and "__drv_nop" does not give a valid preprocessing token| C:Program Files (x86)Microsoft SDKsWindowsv7.0AIncludewinbase.h|2936|error: pasting "(" and "__drv_nop" does not give a valid preprocessing token| ....................... I was wondering how to fix this? Do I have to use vc compiler ? Thanks. TVAnonymous
September 18, 2010
I have recorded audio from a specific application successfully, I hooked IAudioRenderClinet and copy out audio data from the buffer, it works well with Windows Media Player/Media Center and some other popular media player in China.Anonymous
November 18, 2010
Hi, I'm not very computer-savvy, so all this coding means NOTHING to me ^^; could you explain it so people without much coding experience etc, know how it works?Anonymous
November 19, 2010
The comment has been removedAnonymous
March 23, 2011
Hi, this example is what i'm looking for but it has one bad issue "IAudioCaptureClient::GetBuffer set flags to 0x00000002 on pass 4896 after 730560 frames The thread terminated early - something bad happened Thread HRESULT is 0x8000ffff" and program exit. This happen when I test system sound like ding.wav from control panel. Is this possible to work around this? RegardsAnonymous
March 24, 2011
2 is AUDCLNT_BUFFERFLAGS_SILENT. This is provided as a convenience for IAudioRenderClient apps who want to mark a buffer as silence without actually having to fill the buffer with silence. I'm a little surprised to see it being set on a capture buffer. The audio engine should always fill the buffer with silence. When you hit this, is the last buffer you get actually filled with silence (for the format you're using?)Anonymous
March 24, 2011
Hi, I tested it on 2 OS. Vista 64 Business:
- if after I start loopback-capture.exe first sound is ding.wav i get exception with flags 2
- when loopback-capture is running and i play music I can make ding.wav without error, when i stoped music and then make ding it crashes with flags 2. Windows 7: Difference is i always get "Probably spurious glitch reported on first packet when some sound is played" on start of capturing, i never get this on Vista. Error occurs always when i play music -> stop music -> and play again i get error Probably spurious glitch reported on first packet IAudioCaptureClient::GetBuffer set flags to 0x00000001 on pass 1260 after 35040 frames The thread terminated early - something bad happened Thread HRESULT is 0x8000ffff this is caused by my settings on speaker i have 24 bit and 48000hz. After change it to 16 bit and 44100hz i can play - stop - play without error but ding creates error. After program crash i can't open the wav file with sounds which appear to that time because file is corrupted.
Anonymous
May 17, 2011
Hi,Maurits, I run your source code successfully, but I have a question, I want to capture what I hear, and then send the data to a client such as mobile phone, but there is a latency about 1-2 seconds, how can I solve this problem, is there any way to reduce the buffer size or get the audio data directly? thanks!Anonymous
May 17, 2011
The latency between the playback app and the loopback capture app has a lower bound of the audio engine period, which is queried in the code and is typically 10 ms. You mentioned a latency of 1-2 seconds. How much of this is between the playback app and the loopback capture app, and how much is between the loopback capture app and the phone?Anonymous
May 18, 2011
The audio engine period is 10ms, the latency of the wifi network between mobile phone and loopback app is about 200ms.Anonymous
May 19, 2011
And I guess maybe the latency is from the player of the mobile phone. I used player in Android OS, maybe the player produce the latency.Anonymous
August 17, 2011
For those interested, I've bundled this up into a directshow audio capture device, which works well for me as an alternative to say virtual audio cable. github.com/.../virtual-audio-capture-grabber-device Enjoy, and thanks to Matthew for the initial codebase.Anonymous
August 22, 2011
Hi, This sample only works on Windows vista or later. Can somebody please help me in achieveing the same on Windows 2000 or Windows XP? Thanks in advanceAnonymous
October 16, 2011
Hello. I've searched this kind of solution to capture sound in windows. But I am faced on one thing. It's about "samplepersec". When I use GetMixFormat... it has 48000 for sampling rate. But I want to change it to 44100. I've found one thing about that. It's AUDCLNT_STREAMFLAGS_RATEADJUST. But available on win7 only. Not on VISTA... Do you think there is any other solution for it?Anonymous
October 17, 2011
WASAPI will generally not do sample rate conversions. IAudioClockAdjustment is meant for a scenario where:you're pulling audio from a real-time source
you're handing it off to a real-time sink
the sample rates of the source and sink nominally agree
but they're using slightly different clocks so they're a little bit off For example, if the source is a S/PDIF in, then the clock for the source is driven by the incoming data. So if the source and sink are both nominally 44100, but the source is really more like 44100.4, then IAudioClockAdjustment can adjust for that. To do a macro sample rate conversion, you would need to use a different API like Media Foundation, which has a sample rate conversion transform. msdn.microsoft.com/.../ff819070(v=vs.85).aspx
Anonymous
November 24, 2011
Hi Mauritis, I want to enable "Record what youe hear" on Windows 7 with WASAPI on C++, but I didn't find solution, can you help me? thanks vsibillaAnonymous
December 21, 2011
The sample isn't working again with Windows 8 Developer Preview.Anonymous
December 23, 2011
It worked for me on Windows 7 RTM 32-bit. Now on Windows 7 SP1 x64, I get: IAudioCaptureClient::GetBuffer set flags to 0x00000003 on pass 510 after 0 frame s The thread terminated early - something bad happened Thread HRESULT is 0x8000ffff The moment any sound plays I get this error. Until then, it "captures".Anonymous
December 25, 2011
Thanks for this post. It is very annoying for me that WASAPI doesn't capture continuously even if nothing is playing as I plan to also capture the microphone input at the same time and mix the two streams together. I guess I'll have to play silence as well (is silence.exe a well-known app - I couldn't find it). It would be nice to have a continuous capture flag for loopback. Also, as you say, it would be good to support Event callback. WASAPI unfortunately feels like a half-finished audio API, with the lack of built-in SRC also a major inconvenience.Anonymous
March 19, 2012
For some reason I get an error when I try run it no matter what options I use: Press Enter to quit... IAudioCaptureClient::GetBuffer set flags to 0x00000003 on pass 1 after 0 frames The thread terminated early - something bad happened Thread HRESULT is 0x8000ffff Any ideas?Anonymous
March 19, 2012
@Mike 3 is AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY | AUDCLNT_BUFFERFLAGS_SILENT. What OS are you running on? Is the buffer you're getting actually full of silence? You'll need to modify the code to actually write the buffer to disk, or you can look at the buffer in memory under a debugger if you set a breakpoint at the point of failure. It's fine for WASAPI to set the AUDCLNT_BUFFERFLAGS_SILENT flag, but it should also put actual silence in the buffer.Anonymous
April 27, 2012
Hi Maurits, Am I able to modify output sound by process *pData in pAudioCaptureClient->GetBuffer() I like to port your loopback-capture to a windows sound EQ effect program using WASAPI. If not possible do you have suggestions? Thanks pongleeAnonymous
April 28, 2012
Modifying the samples you get from the loopback capture interface will not affect what goes out of the speakers. If you want to apply an effect to the sound produced by all applications you can write a SysFX Audio Processing Object, which will install with the audio driver.Anonymous
May 09, 2012
Hi Mauritis, I'm trying to capture the audio output with the WASAPI loopback capture mode, without the audio output of my application. Do you know of a way to register an audio stream that will not get captured by WASAPI in loopback mode. Something like the exclusive mode of an audio-client but without blocking all other applications from using the same endpoint device.Anonymous
May 10, 2012
One thing you could do is install a Virtual Audio Cable-like solution. Create a virtual render endpoint and set that as a default. Create a virtual cable going from this endpoint to the physical speakers, so all audio can be heard. Have your application play directly to the physical speakers. Do loopback capture from the virtual endpoint.Anonymous
May 14, 2012
When I am using the WASAPI Loopback, I noticed that it will still record all the audio if I mute my speakers. Is there a way to easily sync up the main volume control with that of my capture client?Anonymous
May 14, 2012
You can call IAudioEndpointVolume::RegisterControlChangeNotify to be notified when the volume or mute status is changed.Anonymous
July 18, 2012
Thank you for providing this example. I've noticed that when I build the code (mvc++ 2010 express, Windows SDK 7.1), my hdd is typically not fast enough to keep up with the audio stream so it cuts out after 30-50 seconds (AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY), yet with your provided binaries, it is more than fast enough. If I comment out the disk write, it never reports glitching. When I've had similar issues in linux, it's been because my read and write have been in the same thread, which I solved first by increasing the audio device buffer which decreased the effect of hd latency by writing bigger blocks, and subsequently by splitting read and write threads and swapping a shared buffer between them. It seems like I should get a similar increased buffer effect by passing a larger number to IAudioClient::Initialize argument #3 hnsBufferDuration, say for example 25000, but that does not seem to have had any effect. I'm wondering if you had any thoughts on the matter.Anonymous
July 18, 2012
The version of this that we use for testing ran into the disk-slows-you-down-too-much problem too. I fixed that by creating a work queue with a single thread, and sending the "write the data to a file" part to that thread instead of blocking the capture thread in mmioWrite.Anonymous
September 20, 2012
The comment has been removedAnonymous
November 28, 2012
Do you know if it's possible to capture audio output from "just a single application" using any sort of loopback capture? I know windows 7's audio mixer can control the volume of single applications, can it possibly also capture audio from single applications?Anonymous
November 28, 2012
The comment has been removedAnonymous
December 09, 2012
Hey Maurits, I started looking into the ability to read the currently playing audio stream because I wanted to get a vue meter of sorts my media currently being played on my machine. Then I thought I could take it a step further. I am going to read the stream and do some quick FFT or some other math to get a frequency graph. Then I can feed that into a game engine real time. The game engine will alter the experience based upon the music being played by ANY source. So if someone wanted to play some preferred music while playing the game the game would add to the experience by altering the visuals to match the music. I think this feature could make for some truly unique gaming experiences for end users. Thanks for the code!Anonymous
March 07, 2013
Hi Maurits, Is there a way to change the buffer size I get? I'd like to get, for example, 1024 or 2048 number of samples once buffer was ready. Can it possible? thank, howardAnonymous
March 08, 2013
Nope.Anonymous
April 22, 2013
I have the same problem as: Fredrik Thu, Apr 16 2009 9:49 PM === ... Everything is up and running except the inner capturing loop. When I call iAudioCaptureClient.GetNextPacketSize it throws an AUDCLNT_E_OUT_OF_ORDER at me. If I skip that and call iAudioCaptureClient.GetBuffer it actually returns a couple of frames (around 400) and that data seems good. But when I call ReleaseBuffer I get an AccessViolationException ... ====== So I can't find Frederik email. May be you can your help me? Thank in advance!Anonymous
April 22, 2013
Your wrapper is wrong. Make sure to declare the members in the interface in the same order that audioclient.idl has them listed, not in the order they're listed on MSDN.Anonymous
April 22, 2013
Many Thanks! You are right, it was error in the Interface declataion.Anonymous
June 27, 2013
I created a win32 app in VC++ 2008, I got this error when building it: 1>------ Build started: Project: winSoundDetect, Configuration: Debug Win32 ------ 1>Compiling... 1>guid.cpp 1>loopback-capture.cpp 1>main.cpp 1>prefs.cpp 1>Generating Code... 1>Linking... 1>loopback-capture.obj : error LNK2019: unresolved external symbol imp__mmioWrite@12 referenced in function "long cdecl LoopbackCapture(struct IMMDevice *,struct HMMIO *,bool,void *,void *,unsigned int *)" (?LoopbackCapture@@YAJPAUIMMDevice@@PAUHMMIO@@_NPAX3PAI@Z) 1>main.obj : error LNK2001: unresolved external symbol _imp__mmioWrite@12 1>loopback-capture.obj : error LNK2019: unresolved external symbol AvRevertMmThreadCharacteristics@4 referenced in function "long cdecl LoopbackCapture(struct IMMDevice *,struct HMMIO *,bool,void *,void *,unsigned int *)" (?LoopbackCapture@@YAJPAUIMMDevice@@PAUHMMIO@@NPAX3PAI@Z) 1>loopback-capture.obj : error LNK2019: unresolved external symbol AvSetMmThreadCharacteristicsW@8 referenced in function "long cdecl LoopbackCapture(struct IMMDevice *,struct HMMIO *,bool,void *,void *,unsigned int *)" (?LoopbackCapture@@YAJPAUIMMDevice@@PAUHMMIO@@_NPAX3PAI@Z) 1>loopback-capture.obj : error LNK2019: unresolved external symbol __imp__mmioAscend@12 referenced in function "long cdecl WriteWaveHeader(struct HMMIO *,struct tWAVEFORMATEX const *,struct MMCKINFO *,struct MMCKINFO *)" (?WriteWaveHeader@@YAJPAUHMMIO@@PBUtWAVEFORMATEX@@PAU_MMCKINFO@@2@Z) 1>main.obj : error LNK2001: unresolved external symbol __imp__mmioAscend@12 1>loopback-capture.obj : error LNK2019: unresolved external symbol __imp__mmioCreateChunk@12 referenced in function "long cdecl WriteWaveHeader(struct HMMIO *,struct tWAVEFORMATEX const *,struct MMCKINFO *,struct MMCKINFO *)" (?WriteWaveHeader@@YAJPAUHMMIO@@PBUtWAVEFORMATEX@@PAU_MMCKINFO@@2@Z) 1>main.obj : error LNK2019: unresolved external symbol __imp__mmioDescend@16 referenced in function "int __cdecl do_everything(int,wchar_t const * * const)" (?do_everything@@YAHHQAPB_W@Z) 1>main.obj : error LNK2019: unresolved external symbol __imp__mmioOpenW@12 referenced in function "int __cdecl do_everything(int,wchar_t const * * const)" (?do_everything@@YAHHQAPB_W@Z) 1>prefs.obj : error LNK2001: unresolved external symbol __imp__mmioOpenW@12 1>main.obj : error LNK2019: unresolved external symbol __imp__mmioClose@8 referenced in function "int __cdecl do_everything(int,wchar_t const * * const)" (?do_everything@@YAHHQAPB_W@Z) 1>prefs.obj : error LNK2001: unresolved external symbol __imp__mmioClose@8Anonymous
June 27, 2013
looks like the 'sources' file is not recognized by VC 2008, can someone kindly give a solution?Anonymous
June 27, 2013
> unresolved external symbol __imp__mmioWrite See the documentation for mmioWrite: msdn.microsoft.com/.../dd757341(v=vs.85).aspx "Library: Winmm.lib" Note that you need to link against winmm.lib; add that to your VC++ project.Anonymous
June 27, 2013
I did try adding libs into the VC project, by folliwng stackoverflow.com/.../how-do-i-add-a-lib-file-to-link-in-visual-c-2010 but still got : 1>------ Build started: Project: winSoundDetector, Configuration: Debug Win32 ------ 1>Linking... 1>prefs.obj : error LNK2019: unresolved external symbol __imp__CoTaskMemFree@4 referenced in function "public: __thiscall CPrefs::~CPrefs(void)" (??1CPrefs@@QAE@XZ) 1>loopback-capture.obj : error LNK2001: unresolved external symbol __imp__CoTaskMemFree@4 ..... I was wondering how did you compile and build? I guess some IDE or tool that will honor 'sources' file instead of manually adding the dependency libraries?Anonymous
June 27, 2013
> unresolved external symbol __imp__CoTaskMemFree Read my previous comment very carefully and see if you can figure out what you need to do to make this error go away :-)Anonymous
June 27, 2013
I tried to add avrt.lib, ole32.lib and winmm.lib into the project's linker input settings as the stackoverflow.com/.../how-do-i-add-a-lib-file-to-link-in-visual-c-2010 instructed, I also did: #pragma comment(lib,"avrt.lib") #pragma comment(lib,"Ole32.lib") #pragma comment(lib,"winmm.lib") still no luck. looks like the libs are still not seen.Anonymous
June 27, 2013
I think now I got a clean build by following:
- looks like I need the lib Not from x64 even tho I am on win7 64bit machine,
- copy all the needed libs into the folder together with the cpp/h, add them in to the project through "add/existing item..."
- stackoverflow.com/.../error-lnk2019-unresolved-external-symbol-winmain16-referenced-in-function Thats a linker problem. Try to change Properties -> Linker -> System -> SubSystem from Windows (/SUBSYSTEM:WINDOWS) to Console (/SUBSYSTEM:CONSOLE) Thanks Maurits for providing this sample and bearing with me! :-)
Anonymous
June 27, 2013
You should be able to add winmm.lib;avrt.lib;ole32.lib in your "Additional Dependencies" field under the linker options in your C++ project file; Visual Studio will then know whether to link x86 or x64. Even though your dev machine is x64, your solution is probably set to target x86; an x86 app will generally run on both x86 and x64 machines. You can change this to explicitly target x64 if you want.Anonymous
August 20, 2013
Hi Maurits, I have had good success with the app until trying it on Windows 8. Currently I get the following output >loopback.exe --file test.wav Press Enter to quit... Probably spurious glitch reported on first packet IAudioCaptureClient::GetBuffer set flags to 0x00000001 on pass 1166 after 279360 frames The thread terminated early - something bad happened Thread HRESULT is 0x8000ffff This error will happen in the following conditions:
- I run app during silence.. and then begin to play audio. The app will immediately crash in this case. (This was reported earlier in comment thread as well)
- If I am already playing sound and then start the app.. I will get about 5 seconds worth of record before.. then the same error occurs. This will leave the audio file in a corrupted and unplayable state.
- If I am already playing sound and then stat the app... i then press enter to close the app (in under 5s) .. I will get a playable audio file as expected. Any guidance on this would be greatly appreciated. Thanks.
Anonymous
August 21, 2013
Update: (Windows 8 workaround) By simply choosing to ignore the AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY flag.. rather then error... everything seems to work fine. Although I am not sure if there will be implications to this on a large enough time domain.Anonymous
September 10, 2013
I have created a directshow filter that generates silence and works with win 7/8 My work can be found here: github.com/.../AudioLoopbackFilterAnonymous
February 09, 2014
Hi, first of all sorry for my english. I'm trying to develop a free software that reconise the sound played by speakers (the software would run in the background, in the "notification area" of windows) and displays the music played on a label closed to the so-called "notification area" (the message should be discrete). My idea is to use loopback-capture derivated background program to record 25 seconds of the sound played, use a background program to convert wav->mp3 and then use lastfmfpclient product (also works in the background) to search for the artist and title of the music played. So first of all, I want to modify loopback-capture sources to capture 25 seconds of what is played without any prompt windows (again, in the background) but I can't compile loopback-capture sources with visual C++ 2012,Anonymous
February 09, 2014
here are the lines of errors :
1>------ Build started: Project: loopback-capture, Configuration: Debug Win32 ------ 1>loopback-capture.obj : error LNK2019: unresolved external symbol imp__mmioWrite@12 referenced in function "long cdecl LoopbackCapture(struct IMMDevice *,struct HMMIO *,bool,void *,void *,unsigned int *)" (?LoopbackCapture@@YAJPAUIMMDevice@@PAUHMMIO@@_NPAX3PAI@Z) 1>main.obj : error LNK2001: unresolved external symbol __imp__mmioWrite@12 1>loopback-capture.obj : error LNK2019: unresolved external symbol __imp__mmioAscend@12 referenced in function "long cdecl FinishWaveFile(struct HMMIO *,struct MMCKINFO *,struct MMCKINFO *)" (?FinishWaveFile@@YAJPAUHMMIO@@PAU_MMCKINFO@@1@Z) 1>main.obj : error LNK2001: unresolved external symbol __imp__mmioAscend@12 1>loopback-capture.obj : error LNK2019: unresolved external symbol _imp__mmioCreateChunk@12 referenced in function "long cdecl WriteWaveHeader(struct HMMIO *,struct tWAVEFORMATEX const *,struct MMCKINFO *,struct MMCKINFO *)" (?WriteWaveHeader@@YAJPAUHMMIO@@PBUtWAVEFORMATEX@@PAU_MMCKINFO@@2@Z) 1>loopback-capture.obj : error LNK2019: unresolved external symbol AvSetMmThreadCharacteristicsW@8 referenced in function "long cdecl LoopbackCapture(struct IMMDevice *,struct HMMIO *,bool,void *,void *,unsigned int *)" (?LoopbackCapture@@YAJPAUIMMDevice@@PAUHMMIO@@NPAX3PAI@Z) 1>loopback-capture.obj : error LNK2019: unresolved external symbol AvRevertMmThreadCharacteristics@4 referenced in function "long cdecl LoopbackCapture(struct IMMDevice *,struct HMMIO *,bool,void *,void *,unsigned int *)" (?LoopbackCapture@@YAJPAUIMMDevice@@PAUHMMIO@@_NPAX3PAI@Z) 1>main.obj : error LNK2019: unresolved external symbol __imp__mmioOpenW@12 referenced in function "int __cdecl do_everything(int,wchar_t const * * const)" (?do_everything@@YAHHQAPB_W@Z) 1>prefs.obj : error LNK2001: unresolved external symbol __imp__mmioOpenW@12 1>main.obj : error LNK2019: unresolved external symbol __imp__mmioClose@8 referenced in function "int __cdecl do_everything(int,wchar_t const * * const)" (?do_everything@@YAHHQAPB_W@Z) 1>prefs.obj : error LNK2001: unresolved external symbol __imp__mmioClose@8 1>main.obj : error LNK2019: unresolved external symbol __imp__mmioDescend@16 referenced in function "int __cdecl do_everything(int,wchar_t const * * const)" (?do_everything@@YAHHQAPB_W@Z) 1>C:UsersAdminGoogle DriveTRAVAUXPROGRAMMINGC++MyMusicRecognitionloopback-capturesourceloopback-captureDebugloopback-capture.exe : fatal error LNK1120: 8 unresolved externals ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
please help me
Anonymous
February 10, 2014
As the documentation for mmioWrite says, you need to link against winmm.lib msdn.microsoft.com/.../dd757341(v=vs.85).aspxAnonymous
February 10, 2014
Thank u for your help (and your source ^^) Now I have only 2 errors, do you know what is related to? : 1>------ Build started: Project: loopback-capture, Configuration: Debug Win32 ------ 1> prefs.cpp 1> main.cpp 1> loopback-capture.cpp 1> guid.cpp 1> Generating Code... 1>loopback-capture.obj : error LNK2019: unresolved external symbol AvSetMmThreadCharacteristicsW@8 referenced in function "long cdecl LoopbackCapture(struct IMMDevice *,struct HMMIO *,bool,void *,void *,unsigned int *)" (?LoopbackCapture@@YAJPAUIMMDevice@@PAUHMMIO_@@NPAX3PAI@Z) 1>loopback-capture.obj : error LNK2019: unresolved external symbol AvRevertMmThreadCharacteristics@4 referenced in function "long cdecl LoopbackCapture(struct IMMDevice *,struct HMMIO *,bool,void *,void *,unsigned int *)" (?LoopbackCapture@@YAJPAUIMMDevice@@PAUHMMIO@@_NPAX3PAI@Z) 1>C:UsersAdminGoogle DriveTRAVAUXPROGRAMMINGC++MyMusicRecognitionloopback-capturesourceloopback-captureDebugloopback-capture.exe : fatal error LNK1120: 2 unresolved externals ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========Anonymous
February 10, 2014
You need to look up the documentation for AvSetMmThreadCharacteristics and AvRevertMmThreadCharacteristics. That documentation will tell you what library you need to link against to get the stub implementations of those functions. msdn.microsoft.com/.../ms681974(v=vs.85).aspxAnonymous
February 10, 2014
Oh yeah thank u^^ Once my project finished, I'll post it here. good jobAnonymous
February 25, 2014
Hello, I'm trying to find a solution that will allow me to run the Audio Loopback portion of the Passmark BurnIn test in a Windows virtual machine with out the need of loop back hardware. I found this blog and it seems like a possible solution. Is WASAPI (and particularly this example) a viable solution to accomplish this? Any guidance on if and how I might go about doing this? Thanks.Anonymous
February 25, 2014
Beats me. What is the "Audio Loopback portion of the Passmark BurnIn test" and what does it entail?Anonymous
February 26, 2014
This is the BurnIn Tests software: www.passmark.com/.../bit.htm The audio loop back portion normally requires a loop back cable connecting the microphone jack to the headphone jack. It will play a specific sound frequency and then listen for any distortion of the sound. I only have a few of those cables. However, most of my machines are newer, and so they have the combination headphone and microphone jack. I'm not sure if I can use a single combination jack for the loop back test, and will be looking into it. In the meantime, I'm curious to find out if it can be done in software. I looked at Virtual Audio Cable, but that is a pure digital loop back and guarantees no audio distortion, which would defeat the purpose of the test. Basically, I need software that can convert from digital to analog and then analog back to digital to simulate the use of headphone and microphone loop back. Thanks, again.Anonymous
February 26, 2014
I see. WASAPI loopback is also a pure digital loopback, which would defeat the purpose of the test in the same way that Virtual Audio Cable would defeat the purpose. There are Y-adapters on the market which convert a 3.5mm TRRS headset jack into a stereo 3.5mm TRS headphone jack plus a mono 3.5mm TS microphone jack. Sometimes you can just use one of these plus a loopback cable. Unfortunately there isn't much in the way of industry standardization around the way jack presence detection works on TRRS headset jacks (there are three states: nothing plugged in; headphone plugged in; headset plugged in) so you might have to play games with resistors to get everything to work.Anonymous
February 26, 2014
I see. Thank you for the information and your time.Anonymous
March 20, 2014
I am running into some very strange issue with loopback capture:
- Open a loopback capture stream on default audio endpoint (headphones)
- Play audio using WMP. This audio gets captured in loopback stream
- Terminate audio playback using ctrl+w shortcut. At this stage, you'll get a buzzing sound from my headphones. This buzzing sound will go away only after I terminate loopback capture. How can loopback capture affect audio going out on the device? Thanks
Anonymous
March 26, 2014
@Ambrish: this sounds like a bug, either in Windows or the driver. What audio driver do you have? If you like you can send me a dxdiag: mateer at microsoft dot comAnonymous
May 05, 2014
The comment has been removedAnonymous
May 05, 2014
@alex: WASAPI is a C++-only API; it cannot be consumed directly from the .NET framework. It's possible that someone has written a P/invoke wrapper, though. WASAPI loopback will give you the mixed audio of all applications which are currently playing. If you want to capture only your own audio, you need to make sure you're the only application playing. Also, WASAPI loopback will include some kinds of audio effects that are added by the audio driver.Anonymous
July 22, 2014
Hey could you please tell me how i could do the same thing in windows 8 c++/xaml?Please i need help in my project and i want to record all the music which is being played in my app.Anonymous
October 20, 2014
Why do you code "CoTaskMemFree(pwfx);" if there is no ALLOC? I'm trying to get it to record MP3, so I need to understand details. Txs.Anonymous
October 20, 2014
@Martin: per the documentation of IAudioClient::GetMixFormat msdn.microsoft.com/.../dd370872(v=vs.85).aspx "The caller is responsible for freeing the storage, when it is no longer needed, by calling the CoTaskMemFree function" - that is, IAudioClient::GetMixFormat's implementation apparently calls CoTaskMemAlloc on the caller's behalf. WASAPI will not do format conversion for you; if you want to record in MP3 format, you're better off using a higher-level API like MediaCapture. You can write a custom source which does WASAPI loopback capture, then rely on the MediaCapture stack to insert format converters for you (like a PCM-to-MP3 encoder.)Anonymous
October 20, 2014
The comment has been removedAnonymous
October 20, 2014
@martin: The format of the IAudioCaptureClient::GetBuffer(...) data should be whatever you passed to IAudioClient::Initialize. Note also that IAudioCaptureClient::GetBuffer and ReleaseBuffer deal in frames rather than bytes; assuming a format of stereo int16, one frame is four bytes.Anonymous
October 21, 2014
The comment has been removedAnonymous
October 22, 2014
Got it all working fine, see your mail (cited above) to see how.Anonymous
December 01, 2014
watAnonymous
January 18, 2015
Maurits Hi. I would like to ask you to view my question about WASAPI loopback here: social.msdn.microsoft.com/.../rendering-audio-using-wasapi-loopback-capturing-the-speakers-volume Thank you for any help you can give on this.Anonymous
January 20, 2015
Maurits Hi. I wonder if you can continue your help in this question: social.msdn.microsoft.com/.../rendering-audio-using-wasapi-loopback-capturing-the-speakers-volume Again, thanks.Anonymous
January 21, 2015
Maurits Hi. Again thank you for your comments in social.msdn.microsoft.com/.../rendering-audio-using-wasapi-loopback-capturing-the-speakers-volume So is there another way (or what is the best way) other than WASAPI loopback in Win7 and above to get what you hear from speakers just like I get from the WASAPI loopback?Anonymous
March 27, 2016
Thank you for your sample.Anonymous
May 24, 2016
thanks!Anonymous
December 26, 2016
Thank you for this article, very helpful!In case somebody wants to use a bit more powerful recorder, take a look at a free and open-source tool - fmedia (http://fmedia.firmdev.com/). It can record audio in WASAPI loopback mode, convert audio sample rate, and compress into FLAC or other popular formats. You can start recording with a simple command: fmedia --record --dev-loopback=0 -o myrec.flacand press "S" or "Ctrl+C" to stop recording. While recording it shows how load your signal is in real time, e.g.: 0:07 [=====.....] -17.93dB / -0.06dBSo, maybe it would be helpful for someone.By the way, it's too bad that Microsoft doesn't want to support event-driven capture in loopback mode (i.e. AUDCLNT_STREAMFLAGS_EVENTCALLBACK), because using a separate timer for this isn't convenient at all.