#include <iostream>
#include <windows.h>
#include <Mmsystem.h>
#pragma comment(lib, "winmm.lib")
static BYTE* file = (BYTE*)malloc(sizeof(BYTE) * 512);
static DWORD hasRecorded = 0;
static BOOL recurr = TRUE;
class USER
{
public:
int a = 0;
char b = 'a';
};
void CALLBACK callback(HWAVEIN hwi, // 設備句柄
UINT uMsg, // 消息
DWORD_PTR dwInstance, // 對象
DWORD_PTR dwParam1, // 參數1
DWORD_PTR dwParam2); // 參數2
int main()
{
HWAVEIN hWaveIn; //輸入設備
HWAVEOUT hWaveOut; //輸出設備
WAVEFORMATEX waveform; //定義音頻流格式
BYTE* pBuffer1, * pBuffer2; //輸入音頻緩衝區(左右聲道)
WAVEHDR whdr_i1, whdr_i2; //輸入音頻頭
WAVEHDR whdr_o; //輸出音頻頭
USER* user = new USER(); //定義用戶
// 設備數量
int count = waveInGetNumDevs();
printf("\n音頻輸入數量:%d\n", count);
// 設備名稱
WAVEINCAPS waveIncaps;
MMRESULT mmResult = waveInGetDevCaps(0, &waveIncaps, sizeof(WAVEINCAPS));//2
std::cout <<"設備名稱:"<< waveIncaps.szPname << std::endl;
// 設置音頻流格式
waveform.nSamplesPerSec = 44100; // 採樣率
waveform.wBitsPerSample = 16; // 採樣精度
waveform.nChannels = 2; // 聲道個數
waveform.cbSize = 0; // 額外空間
waveform.wFormatTag = WAVE_FORMAT_PCM; // 音頻格式
waveform.nBlockAlign = (waveform.wBitsPerSample * waveform.nChannels) / 8; // 塊對齊
waveform.nAvgBytesPerSec = waveform.nBlockAlign * waveform.nSamplesPerSec; // 傳輸速率
//分配內存
pBuffer1 = new BYTE[1024 * 10000];
pBuffer2 = new BYTE[1024 * 10000];
memset(pBuffer1, 0, 1024 * 10000); // 內存置0
memset(pBuffer2, 0, 1024 * 10000); // 內存置0
// 設置音頻頭
whdr_i1.lpData = (LPSTR)pBuffer1; // 指向buffer
whdr_i1.dwBufferLength = 1024 * 10000; // buffer大小
whdr_i1.dwBytesRecorded = 0; // buffer存放大小
whdr_i1.dwUser = 0;
whdr_i1.dwFlags = 0;
whdr_i1.dwLoops = 1;
whdr_i2.lpData = (LPSTR)pBuffer1; // 指向buffer
whdr_i2.dwBufferLength = 1024 * 10000; // buffer大小
whdr_i2.dwBytesRecorded = 0; // buffer存放大小
whdr_i2.dwUser = 0;
whdr_i2.dwFlags = 0;
whdr_i2.dwLoops = 1;
// 開啓錄音
MMRESULT mRet = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD_PTR)callback, (DWORD_PTR)user, CALLBACK_FUNCTION);
waveInPrepareHeader(hWaveIn, &whdr_i1, sizeof(WAVEHDR));//準備buffer
waveInPrepareHeader(hWaveIn, &whdr_i2, sizeof(WAVEHDR));//準備buffer
waveInAddBuffer(hWaveIn, &whdr_i1, sizeof(WAVEHDR)); //添加buffer
waveInAddBuffer(hWaveIn, &whdr_i2, sizeof(WAVEHDR)); //添加buffer
waveInStart(hWaveIn);
getchar();
recurr = FALSE;
//waveInStop(hWaveIn);
waveInReset(hWaveIn);
waveInClose(hWaveIn);
HANDLE wait = CreateEvent(NULL, 0, 0, NULL);
waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveform, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);
// 播放錄音
whdr_o.lpData = (LPSTR)file; // 指向buffer
whdr_o.dwBufferLength = hasRecorded; // buffer大小
whdr_o.dwBytesRecorded = hasRecorded;
whdr_o.dwFlags = 0;
whdr_o.dwLoops = 1;
ResetEvent(wait);
waveOutPrepareHeader(hWaveOut, &whdr_o, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &whdr_o, sizeof(WAVEHDR));
/*Sleep(5000);*/
DWORD dw = WaitForSingleObject(wait, INFINITE);
if (dw == WAIT_OBJECT_0)
{
std::cout << "jieshu" << std::endl;
return 0;
}
}
void CALLBACK callback(HWAVEIN hwi, // 設備句柄
UINT uMsg, // 消息
DWORD_PTR dwInstance, // 對象
DWORD_PTR dwParam1, // 參數1
DWORD_PTR dwParam2) // 參數2
{
// 獲取對象
USER* user2 = (USER*)dwInstance;
// 獲取音頻頭
PWAVEHDR pwhdr = (PWAVEHDR)dwParam1;
// 處理消息
switch (uMsg)
{
case WIM_OPEN: // 打開錄音設備
printf("成功打開設備..\n");
break;
case WIM_DATA: // 緩衝區已滿
{
printf("緩衝池已滿..\n");
printf("a:%d , b:%c \n",user2->a,user2->b);
// 緩衝池信息
DWORD buflen = pwhdr->dwBufferLength;
DWORD bytrecd = pwhdr->dwBytesRecorded;
hasRecorded += bytrecd;
// 緩衝擴增
file = (BYTE*)realloc(file, hasRecorded * sizeof(BYTE));
// 存儲新內容
if (file)
{
memcpy(&file[hasRecorded-bytrecd], pwhdr->lpData, bytrecd);
printf("已存儲:%d byte\n",hasRecorded);
}
// 循環
if (recurr)
{
// 加入緩存
waveInAddBuffer(hwi, pwhdr, sizeof(WAVEHDR));
}
}
break;
case WIM_CLOSE: // 關閉錄音設備
{
printf("停止錄音..\n");
}
break;
default:
break;
}
}