求:各位麻烦帮我看看我的DirectSound录音为什么取缓冲区数据好像有问题,我找了好久也没找到原因

my15y 2006-03-09 11:10:40
下面代码中有一个函数是用directshow枚举设备的。这里不用。流程是这样的。
点击录音调用录音函数 OnBnClickedButton1() 然后函数创建录音缓冲区-->创建通知事件--->创建工作线程--》等待事件触发-->调用处理函数 RecordCapturedData 取走缓冲区数据,并写入wav文件。出问题的地方。可能在通知事件和RecordCapturedData函数。能写文件。但是文件中有费数据,用程序打开文件就提示不是有效的wav文件。文件中也有波形。高手帮忙看看。。。。

HRESULT RecordCapturedData(void)
{
HRESULT hr;
VOID* pbCaptureData = NULL;
DWORD dwCaptureLength;
VOID* pbCaptureData2 = NULL;
DWORD dwCaptureLength2;
VOID* pbPlayData = NULL;
UINT dwDataWrote;
DWORD dwReadPos;
LONG lLockSize;

if (NULL == g_pDSBCapture)
return S_FALSE;
if (NULL == g_pWaveFile)
return S_FALSE;

if (FAILED (hr = g_pDSBCapture->GetCurrentPosition(
NULL, &dwReadPos)))
return hr;

// Lock everything between the private cursor
// and the read cursor, allowing for wraparound.

lLockSize = dwReadPos - g_dwNextCaptureOffset;
if( lLockSize < 0 ) lLockSize += g_dwCaptureBufferSize;

if( lLockSize == 0 ) return S_FALSE;

if (FAILED(hr = g_pDSBCapture->Lock(
g_dwNextCaptureOffset, lLockSize,
&pbCaptureData, &dwCaptureLength,
&pbCaptureData2, &dwCaptureLength2, 0L)))
return hr;

// Write the data. This is done in two steps
// to account for wraparound.

if (FAILED( hr = g_pWaveFile->Write( dwCaptureLength,
(BYTE*)pbCaptureData, &dwDataWrote)))
return hr;

if (pbCaptureData2 != NULL)
{
if (FAILED(hr = g_pWaveFile->Write(
dwCaptureLength2, (BYTE*)pbCaptureData2,
&dwDataWrote)))
return hr;
}

// Unlock the capture buffer.

g_pDSBCapture->Unlock( pbCaptureData, dwCaptureLength,
pbCaptureData2, dwCaptureLength2 );

// Move the capture offset forward.

g_dwNextCaptureOffset += dwCaptureLength;
g_dwNextCaptureOffset %= g_dwCaptureBufferSize;
g_dwNextCaptureOffset += dwCaptureLength2;
g_dwNextCaptureOffset %= g_dwCaptureBufferSize;

return S_OK;
}
//thread worker....
DWORD WINAPI ThreadRecord(LPVOID lpParameter)
{

DWORD dwResult =1;
g_bRecording = TRUE;
while(g_bRecording)
{
dwResult = WaitForMultipleObjects(3, rghEvent,FALSE,INFINITE );
switch(dwResult)
{
case WAIT_OBJECT_0 +0:
ListBox_AddString(hmsg,"收到事件1");
RecordCapturedData();
case WAIT_OBJECT_0 + 1:
ListBox_AddString(hmsg,"收到事件2");
RecordCapturedData();
// case WAIT_OBJECT_0+2:
//m_dlg->MessageBox("调用函数 3");
}
}
m_dlg->MessageBox("线程退出");
return 0;
}
...全文
110 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
my15y 2006-03-09
  • 打赏
  • 举报
回复
创内核事件函数。3个事件 1是缓冲区 1半时。 2 是缓冲区满时 3是停止录音时
HRESULT CrecdemoDlg::InitNotifications(LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB)
{
m_msg.AddString("创建事件");
LPDIRECTSOUNDNOTIFY8 pDSNotify;
WAVEFORMATEX wfx;
DSBPOSITIONNOTIFY rgdsbpn[cEvents];
HRESULT hr;

if (NULL == pDSCB) return E_INVALIDARG;
if (FAILED(hr = pDSCB->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&pDSNotify)))
{
return hr;
}
if (FAILED(hr = pDSCB->GetFormat(&wfx, sizeof(WAVEFORMATEX), NULL)))
{
return hr;
}

// Create events.
for (int i = 0; i < cEvents; ++i)
{
rghEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
if (NULL == rghEvent[i])
{
hr = GetLastError();
return hr;
}
}

// Describe notifications.

rgdsbpn[0].dwOffset = (wfx.nAvgBytesPerSec/2) -1;
rgdsbpn[0].hEventNotify = rghEvent[0];

rgdsbpn[1].dwOffset = wfx.nAvgBytesPerSec - 1;
rgdsbpn[1].hEventNotify = rghEvent[1];

rgdsbpn[2].dwOffset = DSBPN_OFFSETSTOP;
rgdsbpn[2].hEventNotify = rghEvent[2];

// Create notifications.

hr = pDSNotify->SetNotificationPositions(cEvents, rgdsbpn);
pDSNotify->Release();
return hr;

}
my15y 2006-03-09
  • 打赏
  • 举报
回复
创建录音缓冲区函数

HRESULT CrecdemoDlg::CreateCaptureBuffer(LPDIRECTSOUNDCAPTURE8 pDSC, LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCB8)
{
HRESULT hr;
DSCBUFFERDESC dscbd;
LPDIRECTSOUNDCAPTUREBUFFER pDSCB;
WAVEFORMATEX wfx;
wfx.cbSize=0;
wfx.nChannels=1;
wfx.nSamplesPerSec=8000;
wfx.wBitsPerSample=8;
wfx.wFormatTag=WAVE_FORMAT_PCM;
wfx.nBlockAlign=wfx.nChannels*(wfx.wBitsPerSample/8);
wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;

if ((NULL == pDSC) || (NULL == ppDSCB8)) return E_INVALIDARG;
dscbd.dwSize = sizeof(DSCBUFFERDESC);
dscbd.dwFlags = 0;
dscbd.dwBufferBytes = wfx.nAvgBytesPerSec;
dscbd.dwReserved = 0;
dscbd.lpwfxFormat = &wfx;
dscbd.dwFXCount = 0;
dscbd.lpDSCFXDesc = NULL;
if (SUCCEEDED(hr = pDSC->CreateCaptureBuffer(&dscbd, &pDSCB, NULL)))
{
hr = pDSCB->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)ppDSCB8);
pDSCB->Release();
}
g_dwCaptureBufferSize=dscbd.dwBufferBytes;
g_dwNotifySize=g_dwCaptureBufferSize/2;

return hr;
}
my15y 2006-03-09
  • 打赏
  • 举报
回复
按下录音键。函数

void CrecdemoDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码


//初始化com接口
InitCommonControls();
HRESULT hr = CoInitialize(NULL); //初始化com接口
if (FAILED(hr))
{
MessageBox("ERROR - Could not initialize COM library.\n");
return;
}
LPGUID s_devid;
s_devid=(LPGUID)m_syslist.GetItemData(m_syslist.GetCurSel());
//----------------bind设备-------------
if (FAILED(hr = DirectSoundCaptureCreate8(s_devid,&g_pDSCapture,NULL))) {
//MessageBox("bind 设备错误");
if (FAILED(hr =DirectSoundCaptureCreate8(NULL,&g_pDSCapture,NULL))) {
MessageBox("录音设备错误");
return;
}
}
if (FAILED(hr=CreateCaptureBuffer(g_pDSCapture,&g_pDSBCapture))) {
MessageBox("创建录音缓冲失败");
return;
}
if(FAILED(InitNotifications(g_pDSBCapture))) {
MessageBox("通知触发创建失败");
}
ZeroMemory( &wfxInput, sizeof(wfxInput));
wfxInput.cbSize=0;
wfxInput.wFormatTag = WAVE_FORMAT_PCM;
wfxInput.nSamplesPerSec = 8000;
wfxInput.wBitsPerSample = 8;
wfxInput.nChannels = 1;
wfxInput.nBlockAlign =wfxInput.nChannels * (wfxInput.wBitsPerSample / 8);
wfxInput.nAvgBytesPerSec = wfxInput.nBlockAlign * wfxInput.nSamplesPerSec;
g_pWaveFile = new CWaveFile;
if (FAILED(g_pWaveFile->Open("mywave.wav", &wfxInput,WAVEFILE_WRITE)))
{
g_pWaveFile->Close();
MessageBox("创建wav文件失败");
}
CreateThread(NULL,0,ThreadRecord,this,0,NULL);
g_pDSBCapture->Start(DSCBSTART_LOOPING);
}

16,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧