|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
// 设置音频格式
waveform.wFormatTag = WAVE_FORMAT_PCM;
waveform.nChannels = 1; // 声道数
waveform.nSamplesPerSec = 44100; // 采样频率
waveform.wBitsPerSample = 16; // 位深
waveform.nBlockAlign = waveform.nChannels * (waveform.wBitsPerSample / 8);
waveform.nAvgBytesPerSec = waveform.nSamplesPerSec * waveform.nBlockAlign;
waveform.cbSize = 0;
//创建并准备缓冲区
waveHeader.lpData = (LPSTR)g_samples;
waveHeader.dwBufferLength = NUM_SAMPLES * sizeof(short);
waveHeader.dwBytesRecorded = 0;
waveHeader.dwUser = 0;
waveHeader.dwFlags = 0;
waveHeader.dwLoops = 0;
pWnd = GetDlgItem(IDC_SOUND); //获取picture控件句柄
hWnd = ::GetDlgItem(GetSafeHwnd(), IDC_SOUND);
hdc = ::GetDC(hWnd);
hpen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255));//创建画笔
oldhpen= (HPEN)SelectObject(hdc, hpen);
::GetClientRect(hWnd, &rect);//获取picture控件客户区的坐标
hbr = CreateSolidBrush(RGB(255, 255, 255));
oldhbr =(HBRUSH)SelectObject(hdc, hbr);
FillRect(hdc, &rect, hbr);//绘制并填充矩形
void CMFCyinpinDlg::OnBnClickedBtnStart()
{
MMRESULT mm=waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD)this->m_hWnd, NULL, CALLBACK_WINDOW);//打开录音设备
if (mm != MMSYSERR_NOERROR) {
AfxMessageBox(_T("打开失败"));
return;
}
waveInPrepareHeader(hWaveIn, &waveHeader, sizeof(WAVEHDR));//准备缓冲区
waveInAddBuffer(hWaveIn, &waveHeader, sizeof(WAVEHDR));// 添加缓冲区到音频输入设备
waveInStart(hWaveIn);//启动输入设备
}
void CMFCyinpinDlg::OnBnClickedBtnStop()
{
waveInReset(hWaveIn);//停止录音设备
ReleaseMutex(mutex);//释放线程控制权
}
UINT func1(LPVOID pParam) //线程函数
{
FillRect(hdc, &rect, hbr);//绘制并填充矩形
int t = 1;//第一个点不能画直线
short* g = (short*)pParam;
DWORD d = WaitForSingleObject(mutex, INFINITE);
for (int i = 0; i < zong / sizeof(short); i++) {
if (t == 1) {
//移到起始点
::MoveToEx(hdc, i, *(g + i), NULL);
t = 0;
}
else {
LineTo(hdc, i, *(g + i));//绘制直线
}
}
return 0;
}
afx_msg LRESULT CMFCyinpinDlg::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam)
{
WAVEHDR* pWaveHdr = (WAVEHDR*)lParam;
memcpy(g_samples, pWaveHdr->lpData, pWaveHdr->dwBytesRecorded);//复制音频数据
zong = pWaveHdr->dwBytesRecorded;
CWinThread* pp = AfxBeginThread(func1, (short*)(g_samples), 0, 0, 0, NULL);//创建工作线程
waveInAddBuffer(hWaveIn, pWaveHdr, sizeof(WAVEHDR)); // 继续录制下一段音频数据
return 0;
}
afx_msg LRESULT CMFCyinpinDlg::OnMM_WIM_CLOSE(WPARAM wParam, LPARAM lParam)
{
return 0;
}
我的问题:点击 开始 按钮后,画出麦克风的波形图
可是我按了 停止 按钮后,再按开始按钮 就不画波形图 了,也就是说线程函数没有执行 ??
这个问题可能是由于您停止录音设备后没有重新准备缓冲区导致的。在停止录音设备后,您需要使用 waveInUnprepareHeader函数进行缓冲区的清理工作,然后再次调用 waveInPrepareHeader和 waveInAddBuffer函数来准备新的缓冲区。请按照以下方式修改代码: void CMFCyinpinDlg::OnBnClickedBtnStart() { MMRESULT mm = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD)this->m_hWnd, NULL, CALLBACK_WINDOW); if (mm != MMSYSERR_NOERROR) { AfxMessageBox(_T("打开失败")); return; } waveInPrepareHeader(hWaveIn, &waveHeader, sizeof(WAVEHDR)); waveInAddBuffer(hWaveIn, &waveHeader, sizeof(WAVEHDR)); waveInStart(hWaveIn);}void CMFCyinpinDlg::OnBnClickedBtnStop() { waveInReset(hWaveIn); waveInUnprepareHeader(hWaveIn, &waveHeader, sizeof(WAVEHDR)); ReleaseMutex(mutex);}
另外,您在线程函数 func1中使用了 HDC对象 hdc,但是这个对象在主线程中声明并初始化,无法直接在子线程中访问。您可以将 hdc作为参数传递给线程函数,或者使用其他同步机制来确保在子线程中能够正确访问 hdc。
希望这些修改对您有帮助!如果还有其他问题,请随时提问。
如果回答对你有帮助,请给我一个最佳答案!
|
|