首页产品库评测行情新闻|手机数码笔记本台式机DIY硬件数字家庭数码相机办公外设|软件下载游戏开发|社区

更多

数码相机
MP4
LCD
机箱
音箱

软件资讯设计 工具 系统 开发 安全 办公 陶吧 IT教育 Vista频道 | 下载中心酷我音乐盒 腾讯QQ
天极网 > 开发频道>利用Directsound编程实现实时混音

利用Directsound编程实现实时混音

2005-11-23 09:08作者:李强出处:天极开发责任编辑:方舟

  假设你锁定了30,000字节,偏移位置为20,000字节,也就是开始位置,如果你的缓冲区的大小为40,000字节,此时就会给你返回四个数据:

  1、内存地址的偏移位置20,000,

  2、从偏移位置到buffer的最末端的字节数,也是20,000,你要在第一个地址写入20,000个字节的内容

  3、偏移量为0的地址

  4、从起始点开始的字节数,也就是10,000字节,你要将这个字节数的内容写入第二个地址。

  如果不包含零点,最后两个数值为NULL和0,

  当然,你也有可能锁定buffer的全部内存,建议你在播放的时候不要这么做,通过你只是更新所有buffer中的一部份,例如,你可能在播放广标到达1/2位置前要将第一个1/4内存更新成新的数据,你一定不要更新play光标和Write光标间的内容。

  下面的这个函数演示了如果向streaming buffer中填充音频数据,在调用这个函数之前,你一定要确保你的streaming buffer是空的,但如何知道buffer是空闲没有数据呢?一个更有效的方法采用通知机制,通过IDirectSoundNotify8::SetNotificationPositions方法,你可以设置任何一个小于buffer的位置来触发一个事件,然后响应处理函数中调用下面的函数将音频数据copy到Directsound的Streaming buffer中。

BOOL AppWriteDataToBuffer(
 LPDIRECTSOUNDBUFFER8 lpDsb, // The buffer.
 DWORD dwOffset, // Our own write cursor.
 LPBYTE lpbSoundData, // Start of our data.
 DWORD dwSoundBytes) // Size of block to copy.
{
 LPVOID lpvPtr1;
 DWORD dwBytes1;
 LPVOID lpvPtr2;
 DWORD dwBytes2;
 HRESULT hr;
 // Obtain memory address of write block. This will be in two parts
 // if the block wraps around.
 hr = lpDsb->Lock(dwOffset, dwSoundBytes, &lpvPtr1,&dwBytes1, &lpvPtr2, &dwBytes2, 0);
 // If the buffer was lost, restore and retry lock.
 if (DSERR_BUFFERLOST == hr)
 {
  lpDsb->Restore();
  hr = lpDsb->Lock(dwOffset, dwSoundBytes, &lpvPtr1, &dwBytes1,&lpvPtr2, &dwBytes2, 0);
 }
 if (SUCCEEDED(hr))
 {
  // Write to pointers.
  CopyMemory(lpvPtr1, lpbSoundData, dwBytes1);
  if (NULL != lpvPtr2)
  {
   CopyMemory(lpvPtr2, lpbSoundData+dwBytes1, dwBytes2);
  }
  // Release the data back to DirectSound.
  hr = lpDsb->Unlock(lpvPtr1, dwBytes1, lpvPtr2,dwBytes2);
  if (SUCCEEDED(hr))
  {
   // Success.
   return  TRUE;
  }
 }  
 // Lock, Unlock, or Restore failed.
 return FALSE;
}

  将音频数据复制到Directsound 的辅助缓冲区中,剩下的工作就是play buffer了,play很简单的,只是简单地调用Buffer提供的Play函数就可以了,复杂的工作Directsound会替我们做好的。

void Play(LPDIRECTSOUNDBUFFER lpdsbStatic)
{
 if ( lpdsbStatic == NULL ) return;

 lpdsbStatic->SetCurrentPosition(0);
 lpdsbStatic->Play(0,0,0);
}

  现在混音的主要代码已经完成,你可以用下面的代码来对三段wave文件进行实时混音了。

Void StartMixer()
{
 InitDirectSound();
 g_pDsbuffer[0] = LoadWaveFile("test1.wav");
 g_pDsbuffer[1] = LoadWaveFile("test2.wav");
 g_pDsbuffer[2] = LoadWaveFile("test3.wav");
 Play(g_pDsbuffer[0]);
 Play(g_pDsbuffer[1]);
 Play(g_pDsbuffer[2]);
}

  现在就可以同时听到三段wave音频了,利用Directsound进行混音是不是很简单啊,这里要提醒一下,如果你想将Directsound的混音用到网络视频会议中,你就要做一些额外的工作了,现在的网络视频会议系统一般都是用Directshow技术开发的,因为在Directshow用播放音频的都是通过一个filter来访问声卡的,所以你可以将DirectSound封装成一个filter,然后将这个filter加入到你的Graph图表中。

  好了,关于Directsound的混音我就简单介绍到这里,下一篇文档我会介绍一下,如何用Directsound 生成3D声音。

关注此文的读者还看过:

返回开发频道首页

共3页。 上一页123

软件频道最新更新

热点推荐

IT嘉年华

编辑推荐

软件下载

热门
推荐

网友关注

软件
资料
游戏

装机推荐

文章排行

本周
本月
最新更新
天极服务|关于我们|About us|网站律师|RSS订阅|友情合作|加入我们|天极动态|网站地图|意见反馈|MSN/QQ上看天极
Copyright (C) 1999-2012 Yesky.com, All Rights Reserved 版权所有 天极网络