многопоточность — как я могу записывать и воспроизводить свой голос в режиме реального времени, используя c / Stack Overflow

Я записываю свой голос с помощью микрофона. Для этого я использовал функции waveIn () и waveOut (). Когда я начинаю запись с помощью функции waveInStart (), она сначала полностью записывает мой голос в течение указанного времени и сохраняет его в буфере (), а затем воспроизводит мой голос из этого буфера. Во время записи и во время воспроизведения ничего не происходит. Я хочу записывать и играть одновременно.
для этого я хочу получить доступ к буферу во время записи. Как это возможно ? Или любое другое предложение будет полезно.

Here is the code :#include <iostream>
#include <Windows.h>
using namespace std;

#pragma comment(lib, "winmm.lib")

short int waveIn[8000 * 3];

void PlayRecord();
void writedataTofile(LPSTR lpData,DWORD dwBufferLength);

void StartRecord()
{
const int NUMPTS = 8000 * 3;   // 3 seconds
int sampleRate = 8000;
// '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;
MMRESULT result;

WAVEFORMATEX pFormat;
pFormat.wFormatTag=WAVE_FORMAT_PCM;     // simple, uncompressed format
pFormat.nChannels=1;                    //  1=mono, 2=stereo
pFormat.nSamplesPerSec=sampleRate;      // 8.0 kHz, 11.025 kHz, 22.05 kHz, and 44.1 kHz
pFormat.nAvgBytesPerSec=sampleRate*2;   // =  nSamplesPerSec × nBlockAlign
pFormat.nBlockAlign=2;                  // = (nChannels × wBitsPerSample) / 8
pFormat.wBitsPerSample=16;              //  16 for high quality, 8 for telephone-grade
pFormat.cbSize=0;

// Specify recording parameters

result = waveInOpen(&hWaveIn, WAVE_MAPPER,&pFormat,
0L, 0L, WAVE_FORMAT_DIRECT);

WAVEHDR      WaveInHdr;
// Set up and prepare header for input
WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = NUMPTS*2;
WaveInHdr.dwBytesRecorded=0;
WaveInHdr.dwUser = 0L;
WaveInHdr.dwFlags = 0L;
WaveInHdr.dwLoops = 0L;
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

// Insert a wave input buffer
result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));// Commence sampling input
result = waveInStart(hWaveIn);cout << "recording..." << endl;

Sleep(3 * 1000);
// Wait until finished recording

waveInClose(hWaveIn);
PlayRecord();
}

void PlayRecord()
{
const int NUMPTS = 8000 * 3;   // 3 seconds
int sampleRate = 8000;
// '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 pFormat;
pFormat.wFormatTag=WAVE_FORMAT_PCM;     // simple, uncompressed format
pFormat.nChannels=1;                    //  1=mono, 2=stereo
pFormat.nSamplesPerSec=sampleRate;      // 44100
pFormat.nAvgBytesPerSec=sampleRate*2;   // = nSamplesPerSec * n.Channels * wBitsPerSample/8
pFormat.nBlockAlign=2;                  // = n.Channels * wBitsPerSample/8
pFormat.wBitsPerSample=16;              //  16 for high quality, 8 for telephone-grade
pFormat.cbSize=0;

// Specify recording parameters

waveInOpen(&hWaveIn, WAVE_MAPPER,&pFormat, 0L, 0L, WAVE_FORMAT_DIRECT);

WAVEHDR      WaveInHdr;
// Set up and prepare header for input
WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = NUMPTS*2;
WaveInHdr.dwBytesRecorded=0;
WaveInHdr.dwUser = 0L;
WaveInHdr.dwFlags = 0L;
WaveInHdr.dwLoops = 0L;
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

HWAVEOUT hWaveOut;
cout << "playing..." << endl;
waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT);
waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr)); // Playing the data
Sleep(3 * 1000); //Sleep for as long as there was recordedwaveInClose(hWaveIn);
waveOutClose(hWaveOut);
}
int main()
{
StartRecord();
return 0;
}

2

Решение

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

Проблема заключается в том, что содержимое буфера будет загружаться из памяти в аппаратное обеспечение с помощью некоторого механизма, и это «предварительно считывает» данные для воспроизведения небольшими блоками, а также «буферизует» сторону записи. И у драйвера, и у оборудования будет такой механизм «кеширования». Это означает, что воспроизведение будет считывать данные до того, как они будут сохранены в памяти из записи, что, конечно, не будет работать правильно.

Большинство систем обработки аудио работают так, что немного задерживают вывод, поэтому вы вводите немного, обрабатываете, выводите. Это, конечно, вызывает небольшую задержку, которая может быть довольно раздражающей.

0

Другие решения

Перед вызовом waveInStart вы можете подготовить и добавить несколько буферов в аудиодрайвер. Драйвер поставит их в очередь и упорядочит из буфера в буфер без потери каких-либо данных. Вам нужно будет использовать флаг fdwOpen в waveInOpen, чтобы вы получали уведомление при каждом заполнении буфера.

waveOut обладает такой же способностью ставить в очередь: вы можете вывести буфер во время воспроизведения предыдущего буфера, и он будет плавно чередоваться между буферами.

Таким образом, вместо одного большого 3-секундного буфера вы можете использовать десять 0,3-секундных буферов и писать код, чтобы перетаскивать эти буферы из записи в воспроизведение по мере их заполнения. Результатом будет звук без пауз, но с задержкой 0,3 секунды.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector