Как уменьшить потребление процессора в программе аудиозаписи (c++)

с помощью интернета я написал программу, которая записывает звук с микрофона все время, когда он работает. Все хорошо, но мне нужно снизить нагрузку на процессор, потому что сейчас около 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);
}

Это целая функция, которая генерирует заряд. Как я могу уменьшить его? А может я не умею? Использовать другой метод захвата, кроме WindowsAPI?

Я попытался уменьшить выборку в секунду, но это не сильно помогло. Я предполагаю, что это что-то о буфере, но нужен совет.

Ваше здоровье


person dylo    schedule 12.07.2018    source источник
comment
Я думаю, что проблема заключается в активном ожидании (выполнение цикла while), вы потребляете бесполезный процессор без какой-либо производительности. Попробуйте изменить свой код, чтобы использовать события в Windows.   -  person JTejedor    schedule 12.07.2018
comment
@JTejdor Спасибо, вы правы. Я удаляю этот цикл и получаю минимальную загрузку процессора. Программа сейчас работает некорректно, но я знаю где искать решение.   -  person dylo    schedule 12.07.2018
comment
Добро пожаловать @dylo. В качестве обходного пути я предлагаю заснуть на несколько микросекунд внутри цикла, пока вы не найдете правильное решение.   -  person JTejedor    schedule 12.07.2018
comment
@JTejedor: микросекунды? У вас есть довольно приличное представление о том, сколько сэмплов вы обрабатываете в одном буфере, и обычно это гораздо больше, чем один. Даже если бы у вас был всего один сэмпл на частоте 44 кГц, вы бы проспали 25 нас. Для реалистичных 1000 сэмплов вы будете спать 25000 микросекунд, а не несколько.   -  person MSalters    schedule 12.07.2018
comment
@MSalters. Микросекунда - это опечатка, вместо этого я хотел сказать миллисекунда. Моя вина :=|.   -  person JTejedor    schedule 12.07.2018
comment
Я добавляю 1 мс сна в цикле, и теперь программа работает как надо, спасибо @JTejedor.   -  person dylo    schedule 12.07.2018
comment
@MSalters что-то не так с нашим решением? Или речь только об единице?   -  person dylo    schedule 12.07.2018
comment
@dylo: Это действительно было связано с устройством, которое сделало сон в 1000 раз короче, вплоть до возможного увеличения загрузки ЦП.   -  person MSalters    schedule 12.07.2018


Ответы (1)


Как мы уже отмечали, потребление процессора связано с активным ожиданием в цикле do-while. Я предложил использовать объект Event в Windows. Но в качестве немедленного решения я предлагаю поспать несколько миллисекунд (выполните соответствующие расчеты, чтобы точно знать, что такое идеальное время, как отмечает @MSalters в своих комментариях).

На основе Как вы делаете засыпать в C++ на Win 32? возможное решение:

#include <windows.h>

//....
do {
   Sleep(X);
} 
while (waveInUnprepareHeader(hWaveIn, &waveHeader, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING);
//....
person JTejedor    schedule 12.07.2018