Я записываю свой голос с помощью микрофона. Для этого я использовал функции 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;
}
Технически, если вы выделяете буфер, вы можете назначить вход и выход для одного и того же буфера и запустить поток для воспроизведения и поток для записи. Тем не менее, я ожидаю, что вам понадобится больше, чем это на разумную сумму.
Проблема заключается в том, что содержимое буфера будет загружаться из памяти в аппаратное обеспечение с помощью некоторого механизма, и это «предварительно считывает» данные для воспроизведения небольшими блоками, а также «буферизует» сторону записи. И у драйвера, и у оборудования будет такой механизм «кеширования». Это означает, что воспроизведение будет считывать данные до того, как они будут сохранены в памяти из записи, что, конечно, не будет работать правильно.
Большинство систем обработки аудио работают так, что немного задерживают вывод, поэтому вы вводите немного, обрабатываете, выводите. Это, конечно, вызывает небольшую задержку, которая может быть довольно раздражающей.
Перед вызовом waveInStart вы можете подготовить и добавить несколько буферов в аудиодрайвер. Драйвер поставит их в очередь и упорядочит из буфера в буфер без потери каких-либо данных. Вам нужно будет использовать флаг fdwOpen в waveInOpen, чтобы вы получали уведомление при каждом заполнении буфера.
waveOut обладает такой же способностью ставить в очередь: вы можете вывести буфер во время воспроизведения предыдущего буфера, и он будет плавно чередоваться между буферами.
Таким образом, вместо одного большого 3-секундного буфера вы можете использовать десять 0,3-секундных буферов и писать код, чтобы перетаскивать эти буферы из записи в воспроизведение по мере их заполнения. Результатом будет звук без пауз, но с задержкой 0,3 секунды.