Search code examples
c++cpucpu-usageaudio-recordingaudio-capture

How to reduce consumption of CPU in audio recording program (c++)


with help of the internet I wrote program that capture audio from microphone all time when it's running. Everything it's ok, but I need to reduce charge of CPU, because now it's about 30-35%.

int SoundCapture()
{
const int NUMPTS = 8000 * 1; // Sample rate * seconds
int sampleRate = 8000;
short int waveIn[NUMPTS];   // 'short int' is a 16-bit type; I request 16-bit samples below
                            // for 8-bit capture, you'd use 'unsigned char' or 'BYTE' 8-bit types
    HWAVEIN hWaveIn;
    WAVEFORMATEX waveform;
    WAVEHDR waveHeader;

waveform.wFormatTag = WAVE_FORMAT_PCM;  // simple, uncompressed format
waveform.nChannels = 1;                 //  1=mono, 2=stereo
waveform.nSamplesPerSec = 8000;
waveform.nAvgBytesPerSec = 8000;        // = nSamplesPerSec * n.Channels * wBitsPerSample/8
waveform.nBlockAlign = 1;               // = n.Channels * wBitsPerSample/8
waveform.wBitsPerSample = 8;            //  16 for high quality, 8 for telephone-grade
waveform.cbSize = 0;
MMRESULT result = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, 0, 0, WAVE_FORMAT_DIRECT);
if (result)
{
    std::cout << "Something wrong with WaveOpen";
    std::cin.ignore(2);
    return 0;
}
// Set up and prepare header for input
waveHeader.lpData = (LPSTR)waveIn; //pointer to waveform buffer
waveHeader.dwBufferLength = NUMPTS;
waveHeader.dwBytesRecorded = 0;
waveHeader.dwUser = 0L;
waveHeader.dwFlags = 0L;
waveHeader.dwLoops = 0L;
waveInPrepareHeader(hWaveIn, &waveHeader, sizeof(WAVEHDR));

// Insert a wave input buffer
result = waveInAddBuffer(hWaveIn, &waveHeader, sizeof(WAVEHDR));
if (result)
{
    std::cout << "Something wrong with waveInAddBuffer";
    std::cin.ignore(2);
    return 0;
}
// Commence sampling input
time_t t = time(0);   // get time now
result = waveInStart(hWaveIn);
if (result)
{
    std::cout << "Something wrong with WaveStart";
    std::cin.ignore(2);
    return 0;
}


// Wait until finished recording
do {} while (waveInUnprepareHeader(hWaveIn, &waveHeader, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING);
SaveWavFile(&waveHeader, t);
waveInClose(hWaveIn);
}

This is entire function that generate charge. How can I reduce it? Or maybe I can't? Use other capture method than WindowsAPI?

I tried to decrease sample per sec, but that didn't help much. I suppose it's something about buffer, but need any tip.

Cheers


Solution

  • As we have commented, the cpu consumption is due the active waiting in do-while loop. I suggested use Event object in windows. But as immediate solution, I suggest sleep a few milliseconds (do the relevant calculations to know exactly what is perfect time as @MSalters remark in his comments).

    Based on How do you make a program sleep in C++ on Win 32? a possible solution would be:

    #include <windows.h>
    
    //....
    do {
       Sleep(X);
    } 
    while (waveInUnprepareHeader(hWaveIn, &waveHeader, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING);
    //....