簡體   English   中英

我如何使用c / c ++實時錄制和播放聲音

[英]how can i record and play my voice in real time using c/c++

我正在用麥克風錄制聲音。 為此,我使用了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 recorded


waveInClose(hWaveIn);
waveOutClose(hWaveOut);
}
int main()
{
 StartRecord();
    return 0;
}  

從技術上講,如果您分配緩沖區,則可以將in和output分配給相同的緩沖區,並運行一個線程進行播放和一個線程進行記錄。 但是,我希望您將需要的數量更多。

問題在於,緩沖區內容將通過某種機制從內存加載到硬件中,從而“預讀取”數據以小塊的形式進行播放,以及“緩沖”記錄端。 驅動程序和硬件都將具有這種“緩存”機制。 這意味着回放將在從記錄中將其存儲到內存之前先讀取數據,這當然不能正常工作。

大多數音頻處理系統的工作方式是延遲輸出一點點,因此您輸入一點點,對其進行處理,然后將其輸出。 當然,這會引起很小的延遲,這可能會很煩人。

在調用waveInStart之前,您可以准備幾個緩沖區並將其添加到音頻驅動程序。 驅動程序將它們排隊並在緩沖區之間進行排序,而不會丟失任何數據。 您將必須在waveInOpen中使用fdwOpen標志,以便每次填充緩沖區時都收到通知。

waveOut具有相同的排隊功能:您可以在播放前一個緩沖區時輸出一個緩沖區,它將在緩沖區之間順暢地排序。

因此,您可以使用10個0.3秒的緩沖區來代替一個大的3秒的緩沖區,並編寫代碼以使這些緩沖區在記錄滿時從記錄播放到播放。 結果將是音頻沒有暫停,但有0.3秒的延遲。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM