Click here to Skip to main content
15,039,244 members
Articles / Programming Languages / C++
Article
Posted 12 Apr 2017

Stats

17.7K views
1.7K downloads
8 bookmarked

Audio Capture

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
13 Apr 2017CPOL1 min read
Stereo mix audio capture with peak level display

Introduction

This 64-bit Visual Studio 2017 community project is intended to perform real time audio capture of anything playing on your PC.

While it could be used to record from the microphone, the best quality is achieved when using a multiplex audio card and recording from the "Stereo mix" device.

How to Use AudioCap

  1. Start AudioCap.
  2. Start playing a movie (with a sound track) or a local or internet audio file (streaming).
  3. Press the [Start capture] button, to see the oscilloscope PCM WIMDATA curve.
  4. Check "Capture to Wave" if you want to create the "capture.wav", or check "Monitoring only" if you want to see only the peak level.

Background

The original version was written long ago at the time of XP in PowerBASIC.

Using the Code

Here is the OpenWaveIn function that can be customized to use a specific device.

Search for:

C++
if ((DeviceToUse == MICROPHONE) && (StrStrI(wic.szPname, L"micro"))) { break; } // Microphone
if ((DeviceToUse == STEREO_MIX) && (StrStrI(wic.szPname, L"stereo"))) { break; } // Stereo mix
C++
DWORD OpenWaveIn(IN HWND hParent, IN long UseWaveFormat, IN long DeviceToUse) {
    WAVEINCAPS wic = { 0 };
    WORD zBitsPerSample = 0, zChannels = 0;
    LONG zSamplesPerSec = 0, I = 0;
    DWORD nRet = 0;

    switch (UseWaveFormat) {
    case WAVE_FORMAT_1M08: // Mono   11025 8-bit
         zChannels = 1; zSamplesPerSec = 11025; zBitsPerSample = 8;
         break;
    case WAVE_FORMAT_1S08: // Stereo 11025 8-bit
         zChannels = 2; zSamplesPerSec = 11025; zBitsPerSample = 8;
         break;
    case WAVE_FORMAT_1M16: // Mono   11025 16-bit
         zChannels = 1; zSamplesPerSec = 11025; zBitsPerSample = 16;
         break;
    case WAVE_FORMAT_1S16: // Stereo 11025 16-bit
         zChannels = 2; zSamplesPerSec = 11025; zBitsPerSample = 16;
         break;
    case WAVE_FORMAT_2M08: // Mono   22050 8-bit
         zChannels = 1; zSamplesPerSec = 22050; zBitsPerSample = 8;
         break;
    case WAVE_FORMAT_2S08: // Stereo 22050 8-bit
         zChannels = 2; zSamplesPerSec = 22050; zBitsPerSample = 8;
         break;
    case WAVE_FORMAT_2S16: // Stereo 22050 16-bit
         zChannels = 2; zSamplesPerSec = 22050; zBitsPerSample = 16;
         break;
    case WAVE_FORMAT_4M08: // Mono   44100 8-bit
         zChannels = 1; zSamplesPerSec = 44100; zBitsPerSample = 8;
         break;
    case WAVE_FORMAT_4S08: // Stereo 44100 8-bit
         zChannels = 2; zSamplesPerSec = 44100; zBitsPerSample = 8;
         break;
    case WAVE_FORMAT_4M16: // Mono   44100 16-bit
         zChannels = 1; zSamplesPerSec = 44100; zBitsPerSample = 16;
         break;
    case WAVE_FORMAT_4S16: // Stereo 44100 16-bit
         zChannels = 2; zSamplesPerSec = 44100; zBitsPerSample = 16;
         break;
    default:   //WAVE_FORMAT_2M16 Mono   22050 16-bit
         zChannels = 1; zSamplesPerSec = 22050; zBitsPerSample = 16;
    }
    LONG nDev = (LONG) waveInGetNumDevs();
    for (I = 0; I < nDev; I++) {
         nRet = waveInGetDevCaps(I, &wic, sizeof(wic));
         if (nRet == 0) {
             if (wic.dwFormats & UseWaveFormat) {
                 gCap.wfx.nChannels = zChannels;
                 gCap.wfx.nSamplesPerSec = zSamplesPerSec;
                 gCap.wfx.wFormatTag = WAVE_FORMAT_PCM;
                 gCap.wfx.wBitsPerSample = zBitsPerSample;
                 gCap.wfx.nBlockAlign = gCap.wfx.nChannels * gCap.wfx.wBitsPerSample / 8;
                 gCap.wfx.nAvgBytesPerSec = gCap.wfx.nSamplesPerSec * gCap.wfx.nBlockAlign;
                 gCap.wfx.cbSize = 0;
                 nRet = waveInOpen(&gCap.hWaveIn, I, &gCap.wfx, 
                 (DWORD_PTR) gCap.hAudioWnd, (DWORD_PTR)gCap.hAudioWnd, CALLBACK_WINDOW);
                 if (nRet == 0) {
                     if ((DeviceToUse == MICROPHONE) && 
                     (StrStrI(wic.szPname, L"micro"))) { break; } // Microphone
                     if ((DeviceToUse == STEREO_MIX) && 
                     (StrStrI(wic.szPname, L"stereo"))) { break; } // Stereo mix
                 }
            } else {
                 nRet = 22;   //"Le périphérique 
                 //ne reconnaît pas la commande." alias "No suitable device found"
            }
        }
    }
    return nRet;
}

And here is a link to show you how to setup Windows to enable the hidden "Stereo mix" mode. .

Points of Interest

The code is written in full procedural mode, using only the core flat API SDK, to be easily translated from one language to another. The AudioCap.h section has been designed to also be easily turned into a DLL.

You can find more free contributions on my private forum www.objreader.com, especially if you like graphic, multimedia, OpenGL and 3D wavefront model viewer.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

zapsolution
Software Developer zapsolution
France France
I am a low level SDK programmer, focusing mainly on graphic imaging and multimedia applications.
I am using several languages, including C, C++, PowerBASIC, WinDev.
I wrote also a few demos in C#, but i never used DotNET in real code production.

Comments and Discussions

 
QuestionCannot recompile Pin
avisal17-Apr-17 3:36
professionalavisal17-Apr-17 3:36 
AnswerRe: Cannot recompile Pin
zapsolution18-Apr-17 1:00
Memberzapsolution18-Apr-17 1:00 
GeneralRe: Cannot recompile Pin
Member 1369250313-Mar-18 2:35
MemberMember 1369250313-Mar-18 2:35 
GeneralRe: Cannot recompile Pin
Member 1369250314-Mar-18 0:10
MemberMember 1369250314-Mar-18 0:10 
PraiseGREAT Pin
Geogooos13-Apr-17 7:54
MemberGeogooos13-Apr-17 7:54 
QuestionThe corrupted/missing ZIP file has been fixed Pin
zapsolution13-Apr-17 7:01
Memberzapsolution13-Apr-17 7:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.