比如mp3->wma等,提供资源也可以,谢先!
解决方案 »
- MFC实现扫描移动硬盘,遇见问题
- 帮忙解答关于:CConfigParser
- 我用_outp(0x210,4); 直接写出错为什么那?我在WIN2000下运行.
- 如何设置CListCtrl,使得第一列无图像,第2列有图像?
- 紧急求救!!!
- 高手求助,CListCtrl 的本地编辑问题
- 请问各位,进程间如何传数据,在钩子中如何传数据回主程序?
- 初学vc 请问-> 和 . 的区别!
- 有没有谁知道怎么把汉字中的":",转换成英文中的":",注意两个是不一样的。
- 创建线程失败,错误原因是:0x00000008:存贮空间不足,无法执行该操作
- 你好,为什么VC编写的有些程序在没有安装 IE4.0 的系统下运行出错?
- 如何通过按"帮助主题"菜单项来用"记事本"打开一个.txt文件
Filename.mp3=>MPEG-I sream splitter->MPEG Layer-3 Decoder->Windows Media Audio V2->AVI Mux->File writer(Filename.wma)
关于DirectSound
DirectSound是DirectX API的音频(waveaudio)组件之一,它可以提供快速的混音、硬件加速功能,并且可以直接访问相关设备,当然,最主要的是它提供的功能与现有的(?将来的呢?)设备驱动程序保持兼容性。
DirectSound允许进行波型声音的捕获、重放,也可以通过控制硬件和相应的驱动来获得更多的服务。
DirectSound的优势当然和DirectX的其它组件一样——速度,它允许你最大效率的使用硬件,并拥有良好的兼容性(其实别的都好说,就要这两样就够了:P)。使用DirectSound可以做到什么呢?1、很方便的了解硬件能力,并且根据当前计算机硬件配置硬件来决定最好的解决问题的方法。2、弥补驱动程序的不足——通过属性设置以便硬件能力可以完全发挥,即便是驱动程序没有很好的支持该功能。3、短传输延迟时间的混音为了快速的响应流。4、3-D声音5、声音的捕获DirectSound核心
DirectSound设备 这部分描述了将怎样枚举可以使用的声音设备、为一设备创造DirectSound对象、使用对象的方法来设置合作级别、检验设备的能力、创造声音缓冲、配置系统扬声器和压缩数据。枚举可以使用的声音设备 一般的情况下,可能并不需要枚举可以使用的声音设备,使用缺省设备不会带来什么麻烦(相信用户-上帝:P的设置),但是如果你希望将程序做得更“面对对象”一些,给用户更多更好的选择(很多3D GAME都可以让用户来选择显卡,道理大同小异),那你就需要使用到枚举可供使用的声音设备了。
枚举可供使用的声音设备首先要写一回调函数,在程序每找到一可供使用的声音设备时调用,在那个函数里你可以做任何事,并且它可以拥有任何的合法的名字,但是你必须作为DSEnumCallback声明它,回调函数必须返回一BOOL,TRUE则继续列表,FALSE就退出枚举过程了。
和显示设备的枚举差不多,下面就是载自Dsenum.c的几段代码。由于本人认为使用得不多就没怎么研究(其实也是很简单的:P),所以就不再累赘,后面还有更令人兴奋的东西呢!代码如下://回调函数
BOOL CALLBACK DSEnumProc(LPGUID lpGUID,LPCTSTR lpszDesc,LPCTSTR lpszDrvName,LPVOID lpContext )
{
HWND hCombo = *(HWND *)lpContext;
LPGUID lpTemp = NULL; if ( lpGUID != NULL )
{
if (( lpTemp = malloc( sizeof(GUID))) == NULL )
return( TRUE ); memcpy( lpTemp, lpGUID, sizeof(GUID));
} ComboBox_AddString( hCombo, lpszDesc );
ComboBox_SetItemData( hCombo,
ComboBox_FindString( hCombo, 0, lpszDesc ), lpTemp ); //编辑者注:此句有误
return( TRUE );
}
HRESULT hr = DirectSoundCreate(NULL, &lpds, NULL));该函数的第一个参数是硬件设备,NULL表示使用默认的设备,第二个参数是远程指针LPDIRECTSOUND的地址,也就是创造的DirectSound对象放置的地址,第三个参数必须为NULL,暂时没有用。
当没有相应的设备或设备在别的程序的控制下不能响应你的呼叫时,函数返回出错,这时,如果你的程序继续工作,所有和DirectSound对象相关的操作都将不可进行!设置合作级因为WINDOWS是一多任务环境,可以允许多个应用程序同时工作,当然也会产生多个程序在同时里使用同一设备工作的情况,通过合作级别,DirectX可以保证所有的程序在使用同一设备时不会发生冲突(大家和平共处岂不是一件乐事),所以每个使用DirectSound的程序都应该有一合作级别用来决定允许访问的设备。
DirectSound有四种合作级别:标准级、优先级、独占级和写主缓冲级(write-primary,写是主要的动作),其中游戏普遍使用优先级这种级别可以使程序在同一采样条件下作出最柔韧的输出(MS的文档也很有文学味的嘛!)。//C的例子,会换成C++的吗?不会说NO吧!
HRESULT hr = lpDirectSound->lpVtbl->SetCooperativeLevel( lpDirectSound, hwnd, DSSCL_PRIORITY );标准级(DSSCL_NORMAL):该级别只能使用22KHZ、立体声(STEREO)、8位的音乐,并且不能直接的写主缓冲,也不能使用压缩过的声音。优先级(DSSCL_PAIORITY):可以实现硬件混合(hardware mixing),可以设置主缓冲的声音格式(可以根据需要来使用不同质量的音乐)和压缩过的音乐。独占级(DSSCL_EXCLUSIVE):当应用程序在前台工作时,其它程序是不可使用声音的。写主缓冲级(DSSCL_WRITEPRIMARY):最高的合作级,程序可以直接的操纵主缓冲,而且程序必须直接的写主缓冲区(最基层的操作)。在这种级别,第二缓冲将不可用。
除了该级别外,所有试图LOCK主缓冲的操作都将失败,也就是说只有该级别可以对主缓冲进行写操作!
当使用写主缓冲级的程序处于前台时,后台所有程序的第二缓冲都将停止且丢失,而如果这时使用写主缓冲级的程序转到后台工作,它的主缓冲也将丢失并且在又一次转到前台工作时应该还原(restore)。更多的信息将在缓冲区管理里阐述(现在还没有翻译:P不过用过了DDraw以后这些东西应该很熟悉了才是)。
如果要设置写主缓冲级,先应该确定现在是否可以使用该级别——使用IDirectSound::GetCaps函数,检查DSCAPS结构里是否有DSCAPS_EMULDRIVER标志。检索硬件信息DirectSound允许应用程序检索硬件信息,当然,在一般情况下,这样做是不必要的,因为DirectSound可以自动有效的使用硬件加速,我们完全可以不用去管硬件是否具有某些能力,不过为了提高程序的效率,这样做还是是有用处的。
检索硬件信息使用IDirectSound::GetCaps方法,例如:DSCAPS dscaps;dscaps.dwSize = sizeof(DSCAPS);
HRESULT hr = lpDirectSound->lpVtbl->GetCaps(lpDirectSound,&dscaps);扬声器的设置DirectSound的扬声器设置可以用来调节输出音量的大小和优化3D效果。
在WIN98和WIN2000,可以通过IDirectSound::GetSpeakerConfig来获得当前扬声器的设置,并通过IDirectSound::SetSpeakerConfig来改变扬声器设置;而在WIN95里IDirectSound::GetSpeakerConfig只是简单的返回一默认值或是返回使用IDirectSound::SetSpeakerConfig设置后的值。压缩应用程序可以通过IDirectSound::Compact来获得最多的可用内存,当然从前面对合作级别的讨论我们可以发现使用压缩的前提是程序的合作级别至少应该是优先级。
基础(又是费话连篇)
在初始化DirectSound时,它会自动地为你的程序创建一主缓冲,这个主缓冲的作用就是混音并送到输出设备。
除了主缓冲外,程序至少还应该创建一个辅助缓冲,辅助缓冲的作用是储存将要使用的声音,它可以在不使用的时候释放掉(费话,不过这也就是暗示我们主缓冲是不可释放的)。你可以在同一段物理内存上创建两个或更多的辅助缓冲(使用IDirectSound::DuplicateSoundBuffer方法),但是如果最初的缓冲(原本)所在的硬件内存资源不支持多缓冲,那么这个调用将以失败告终。
DirectSound还可以同时播放多个声音,当然其大前提是硬件允许。
DirectSound播放一声音只需要很短的时间延迟,如果在播放声音的同时来播放动画,你将感觉不到延迟,但是如果DirectSound需要通过软件仿真来完成这一动作,那么延迟时间将延长5-8倍。
通常情况下,你并不需要和主缓冲打交道,DirectSound会自己来管理它的,除非你要使用自己写的混音部分,这时,DirectSound就会让你自行管理主缓冲,更详细的讲解见主缓冲的存取部分。静态缓冲和流缓冲在应用程序里,辅助缓冲可以有两种——静态缓冲(一段内存空间一段完整的声音;好处在于可以一次将全部的声音存入缓冲)和流缓冲(并不将全部的数据一次读入缓冲,而是在播放声音时动态的读入;其好处在于占用空间较小),它们可以分别适应不同的程序需求。
一般的说,如果声音是需要再三播放的,而且容量有限(好比游戏音效),那么使用静态缓冲就更有助于提高程序的效率,相反,如果是很冗长的音乐,还是使用流缓冲的好。创建辅助缓冲//创建辅助缓冲的例子
BOOL AppCreateBasicBuffer( LPDIRECTSOUND lpDirectSound, LPDIRECTSOUNDBUFFER *lplpDsb )
{
PCMWAVEFORMAT pcmwf;
DSBUFFERDESC dsbdesc;
HRESULT hr; //设置PCMWAVEFORMAT结构
memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT));
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.wf.nChannels = 2;
pcmwf.wf.nSamplesPerSec = 22050;
pcmwf.wf.nBlockAlign = 4;
pcmwf.wf.nAvgBytesPerSec =
pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
pcmwf.wBitsPerSample = 16; //设置DSBUFFERDESC结构
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); //将结构置0.
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
//使用默认的设置(音量之类)
dsbdesc.dwFlags = DSBCAPS_CTRLDEFAULT;
//3秒钟长度的缓冲(3-second buffer)
dsbdesc.dwBufferBytes = 3 * pcmwf.wf.nAvgBytesPerSec;
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
//创建缓冲
hr = lpDirectSound->lpVtbl->CreateSoundBuffer(lpDirectSound,
&dsbdesc, lplpDsb, NULL);
if SUCCEEDED(hr)
{
//成功
return TRUE;
}
else
{
//失败
*lplpDsb = NULL;
return FALSE;
}
}很简单是吧,只要填两个STRUCT就OK了。因为DirectSound对先创建的缓冲优先分配硬件资源,所以你应该先创建重要的缓冲。如果你事先声明要创建一硬件缓冲(和放在显存里的表面差不多),就应该在DSBUFFERDESC结构里设置DSBCAPS_LOCHARDWARE标志,但是如果你得不到足够的硬件资源(硬件内存或混音容量hardware memory or mixing capacity),将无法创建缓冲。
创建缓冲时,也可以声明是静态缓冲(设置DSBCAPS_STATIC标志)还是流缓冲;默认值是流缓冲(上面就是使用的默认值)。
缓冲是和DirectSound对象相关联的,如果释放了DirectSound对象,则它所有的缓冲也都将被释放。