跪求熟悉DirectSound录音的神人进来帮帮忙。

好好單调 2013-07-02 02:57:35

小弟这几天在写一个录音的小程序,用的是MFC和DirectSound,第一次接触DirectSound,困难重重啊,按照SDK和网上部分资料的介绍,终于完成了DEMO,现在问题是:
1、录出来的wave文件声音全是噪音。
2、录出来的wave文件比实际我录的时间要长很多。

我自己目前在代码中发现的奇怪的地方是IDirectSoundCaptureBuffer8.GetCurrentPosition返回的两个指针值有时候会和上一次的一模一样。求大神指点迷津。
附上部分关键代码,以及整个Demo下载链接http://pan.baidu.com/share/link?shareid=3367745304&uk=587739268,有空的大神帮忙看看,谢谢了。
// 记录捕获数据
HRESULT RecordCapturedData()
{
HRESULT hr = S_FALSE;
do
{
if (NULL == gpoDSCaptureBuffer8 || gpoWaveFile == NULL)
{
hr = E_INVALIDARG;
break;
}

// 获取当前可读到的数据的位置
DWORD dwReadPos;
DWORD dwCapturePos;
hr = gpoDSCaptureBuffer8->GetCurrentPosition(&dwCapturePos, &dwReadPos);
if (S_OK != hr)
break;

// TEST: 会出现这种情况。。。。。所以有问题。。。
if(gdwLastCapPos != dwCapturePos && gdwLastReadPos != dwReadPos)
{
hr = S_FALSE;
break;
}
gdwLastReadPos = dwReadPos;
gdwLastCapPos = dwCapturePos;

// 计算当前要锁定的缓冲大小
LONG lLockSize = dwReadPos - glNextReadOffset;
if( lLockSize < 0 ) lLockSize += gdwCaptureBufferSize;// 出现这种情况,说明缓冲已经至少写完一个环形了
if(lLockSize == 0)
{
hr = S_FALSE;
break;
}

// 锁定缓冲
VOID* pbCaptureData = NULL;
DWORD dwCaptureLength;
VOID* pbCaptureData2 = NULL;
DWORD dwCaptureLength2;
hr = gpoDSCaptureBuffer8->Lock(
glNextReadOffset,lLockSize,&pbCaptureData,&dwCaptureLength,&pbCaptureData2,&dwCaptureLength2,0L);
if (S_OK != hr)
break;

if(lLockSize != (dwCaptureLength + dwCaptureLength2))
break;
// Write the data. This is done in two steps to account for wraparound.
UINT dwDataWrote;
hr = gpoWaveFile->Write( dwCaptureLength, (BYTE*)pbCaptureData, &dwDataWrote);
if (S_OK != hr)
break;

if (pbCaptureData2 != NULL)
{
hr = gpoWaveFile->Write( dwCaptureLength2, (BYTE*)pbCaptureData2, &dwDataWrote);
if (S_OK != hr)
break;
}

// Unlock the capture buffer.
gpoDSCaptureBuffer8->Unlock( pbCaptureData, dwCaptureLength, pbCaptureData2, dwCaptureLength2 );

// Move the capture offset forward.
glNextReadOffset += dwCaptureLength;
glNextReadOffset %= gdwCaptureBufferSize;
glNextReadOffset += dwCaptureLength2;
glNextReadOffset %= gdwCaptureBufferSize;

// TEST:其实最后记住下一次的偏移值应该就是本次readPos指向的位置
if(glNextReadOffset != dwReadPos)
{
hr = S_FALSE;
break;
}
hr = S_OK;

} while (false);

return hr;
}

...全文
334 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
sinat_32690507 2015-11-20
  • 打赏
  • 举报
回复
能不能发一份demo源代码给我看看啊 刚开始学习 网上资料都收费下载 1010862276@qq.com
好好單调 2013-07-23
  • 打赏
  • 举报
回复
引用 6 楼 turingo 的回复:
Ringbuf一般会包含读和写两个部分,也许这里就有两个线程。 [quote=引用 5 楼 a2619308 的回复:] [quote=引用 4 楼 turingo 的回复:] 所以重点查第三点,数据多了也不行,同样会产生噪音。 [quote=引用 3 楼 a2619308 的回复:] [quote=引用 2 楼 turingo 的回复:] 1、首先检查录音设备是否硬件本身就是有噪音的; 2、其次检查录音和播放的时候采样率和bit数是否一致; 3、最后检查录音的时候是否丢失了数据。
第一点我验证过,用windows的录音设备不会,另外我也实现了一套用waveIn录音的,没有问题。 第二点播放的时候难道不是根据你文件里面写的采样率去播放的吗? 第三点我发现录音的文件播放起来比实际录取的时间还长。所以应该是没丢数据的。甚至可能还多了。 谢谢回头。[/quote][/quote] 额。 有没有一种思路能介绍下,我觉得读循环缓冲这点不知道怎么着手去查啊。[/quote][/quote] 问题找到了。 发现是我指明的缓冲区的格式和创建wave文件时所使用的PCM格式不一致造成的。比如采样率和通道啊之类的。 感谢您的帮助啊,谢谢了。
图灵狗 2013-07-07
  • 打赏
  • 举报
回复
所以重点查第三点,数据多了也不行,同样会产生噪音。
引用 3 楼 a2619308 的回复:
[quote=引用 2 楼 turingo 的回复:] 1、首先检查录音设备是否硬件本身就是有噪音的; 2、其次检查录音和播放的时候采样率和bit数是否一致; 3、最后检查录音的时候是否丢失了数据。
第一点我验证过,用windows的录音设备不会,另外我也实现了一套用waveIn录音的,没有问题。 第二点播放的时候难道不是根据你文件里面写的采样率去播放的吗? 第三点我发现录音的文件播放起来比实际录取的时间还长。所以应该是没丢数据的。甚至可能还多了。 谢谢回头。[/quote]
图灵狗 2013-07-07
  • 打赏
  • 举报
回复
Ringbuf一般会包含读和写两个部分,也许这里就有两个线程。
引用 5 楼 a2619308 的回复:
[quote=引用 4 楼 turingo 的回复:] 所以重点查第三点,数据多了也不行,同样会产生噪音。 [quote=引用 3 楼 a2619308 的回复:] [quote=引用 2 楼 turingo 的回复:] 1、首先检查录音设备是否硬件本身就是有噪音的; 2、其次检查录音和播放的时候采样率和bit数是否一致; 3、最后检查录音的时候是否丢失了数据。
第一点我验证过,用windows的录音设备不会,另外我也实现了一套用waveIn录音的,没有问题。 第二点播放的时候难道不是根据你文件里面写的采样率去播放的吗? 第三点我发现录音的文件播放起来比实际录取的时间还长。所以应该是没丢数据的。甚至可能还多了。 谢谢回头。[/quote][/quote] 额。 有没有一种思路能介绍下,我觉得读循环缓冲这点不知道怎么着手去查啊。[/quote]
好好單调 2013-07-07
  • 打赏
  • 举报
回复
引用 4 楼 turingo 的回复:
所以重点查第三点,数据多了也不行,同样会产生噪音。 [quote=引用 3 楼 a2619308 的回复:] [quote=引用 2 楼 turingo 的回复:] 1、首先检查录音设备是否硬件本身就是有噪音的; 2、其次检查录音和播放的时候采样率和bit数是否一致; 3、最后检查录音的时候是否丢失了数据。
第一点我验证过,用windows的录音设备不会,另外我也实现了一套用waveIn录音的,没有问题。 第二点播放的时候难道不是根据你文件里面写的采样率去播放的吗? 第三点我发现录音的文件播放起来比实际录取的时间还长。所以应该是没丢数据的。甚至可能还多了。 谢谢回头。[/quote][/quote] 额。 有没有一种思路能介绍下,我觉得读循环缓冲这点不知道怎么着手去查啊。
图灵狗 2013-07-06
  • 打赏
  • 举报
回复
1、首先检查录音设备是否硬件本身就是有噪音的; 2、其次检查录音和播放的时候采样率和bit数是否一致; 3、最后检查录音的时候是否丢失了数据。
好好單调 2013-07-06
  • 打赏
  • 举报
回复
汗颜。。 都没人回答啊。 我自己顶一个。。
好好單调 2013-07-06
  • 打赏
  • 举报
回复
引用 2 楼 turingo 的回复:
1、首先检查录音设备是否硬件本身就是有噪音的; 2、其次检查录音和播放的时候采样率和bit数是否一致; 3、最后检查录音的时候是否丢失了数据。
第一点我验证过,用windows的录音设备不会,另外我也实现了一套用waveIn录音的,没有问题。 第二点播放的时候难道不是根据你文件里面写的采样率去播放的吗? 第三点我发现录音的文件播放起来比实际录取的时间还长。所以应该是没丢数据的。甚至可能还多了。 谢谢回头。
内容概要:本文针对无刷直流电机驱动的电子机械制动(EMB)执行器,建立了考虑Stribeck摩擦特性的非线性耦合动力学模型,并在Simulink环境中完成了系统级仿真分析。研究综合集成了电机动力学、齿轮传动机构与制动执行机构的动力学特性,构建了高保真的机电一体化系统模型。重点引入Stribeck摩擦模型以精确描述低速工况下执行器内部存在的静摩擦、粘滞摩擦与库仑摩擦之间的过渡行为,有效提升了系统在启停、反向运动等瞬态过程中的动态响应仿真精度。通过多工况仿真验证了模型的有效性,能够准确反映摩擦引起的爬行、滞后与定位误差等非线性现象,为EMB系统的高性能控制算法设计(如摩擦补偿、滑模控制)与结构优化提供了高可信度的仿真平台。; 适合人群:从事汽车电子制动系统、电机驱动控制、机电系统建模与仿真研究的研究生、科研人员及工程技术人员,需具备扎实的机械动力学、自动控制理论基础和MATLAB/Simulink仿真能力。; 使用场景及目标:①用于高精度电子机械制动系统的设计验证与性能预测;②为消除摩擦非线性影响的先进控制策略(如自适应控制、智能控制)提供精确的被控对象模型;③深入探究Stribeck摩擦等非线性因素对系统动态性能(如响应延迟、稳态误差)的作用机理; 阅读建议:读者应结合提供的Simulink模型文件,深入剖析Stribeck摩擦模块的数学实现与参数辨识方法,建议通过改变输入指令(如阶跃、正弦)和负载条件进行对比仿真,以直观理解非线性摩擦对系统动态特性的影响。

33,316

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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