DirectSound学习笔记:使用WAV数据

使用WAV数据

在Windows 驱动模型(WDM)中,DirectSound硬件缓冲区能够播放任何未压缩或压缩的声音格式,这些格式能够被一个WAVEFORMATEX或WAVEFORMATEXTENSIBLE结构描述,并由硬件支持。软件缓冲区和非WDM硬件缓冲区只支持8位和16位未压缩格式。

波形(WAV)数据通常储存在资源交换文件格式(RIFF)的文件或资源中。数据包括一个WAV格式描述,包含如采样率和输出通道数等参数。

多波段WAV格式

在WDM驱动器中,DirectSound缓冲区支持拥有两个以上输出通道的WAV格式。对于如5.1的扬声器配置,它在前台左,中,右,后台左,右,以及低频增强器处均有扬声器。

WAVEFORMATEXTENSIBLE结构描述了一个多通道波形格式。这个结构是对WAVEFORMATEX的扩展,配置了已经由WAVEFORMATEX中cbSize成员支持的额外字节。当需要WAVEFORMATEX的地方,WAVEFORMATEXTENSIBLE结构能够被转化为WAVEFORMATEX。

如果系统配置的物理扬声器比多波段WAV文件中指定的通道数少,音频数据将被适当混合并输出到现有的扬声器。DirectSound不支持多波段格式的缓冲区的3D处理和效果。企图创建带有DSBCAPS_CTRL3D或DSBCAPS_CTRLFX标识的缓冲区和一个多波段WAV格式将会失败。

读取WAV数据

WAV文件是资源交换文件格式(RIFF),它由若干数量的包含头信息(如声音采样格式)或数据(采样本身)的命名块组成。Win32 API提供了打开和关闭RIFF文件,探索块等函数。这些函数名都以“mmio”开头。

为了以可执行方式存储WAV声音,将WAV文件作为资源进行导入,并为它们命名。注意CWaveFile类期望这些资源是WAVE或WAV类型,并且是可执行模块而不是一个DLL。

DirectSound API 不包含载入声音数据的方法。然而,Dsutil.cpp文件被许多SDK例子程序用来实现若干类,这些类能够被用来从文件,资源或一个内存地址创建声音缓冲区。

使用例子类初始化DirectSound和创建载入缓冲区的步骤包括:
1. 创建一个CSoundManager例子类的对象。
2. 调用CSoundManager::Initialize创建设备对象。
3. 将一个文件或资源名传给CSoundManager::Create或将一个内存地址传给CSoundManager::CreateFromMemory。这些方法返回一个CSound例子类的对象,该类表示一个或多个大小恰能容纳数据的静态缓冲区。(你能够创建多个缓冲区来同时播放多个声音实例)或者,向CStreamingSound例子类传递一个文件或资源名。这个方法返回一个CStreamingSound例子类的对象,它表示了一个单独的流缓冲区。
4. 调用先前步骤中获取的对象中的FillBufferWithSound方法。它将文件,资源或者内存地址中的数据读入缓冲区。对于流缓冲区,它以所能容纳的最大数据为限填充缓冲区,并使用CStreamingSound::HandleWaveStreamNotification在播放缓冲区的同时更新数据。
注意实际的数据读取是由一个CWaveFile对象完成,它是CSound或CStreamingSound对象中的一个受保护成员。你通常不必直接使用CWaveFile类;然而,你能够参考这个类的实现来获取分析WAV数据的信息。

计算一个WAV声音的持续时间

一个波形将要播放的时间长度取决于数据大小和格式。数据大小和格式能够通过调用DirectSound例子框架中的CWaveFile::GetSize和CWaveFile::GetFormat方法获取。
以下例子函数,并没有使用例子类,返回了一个WAV文件的持续时间,以毫秒为单位:

DWORD GetSoundLength(LPSTR strFileName)
{
  CWaveFile
*
 pWav;
  DWORD dwLen 
= 0
;
  DWORD dwSize;
  WAVEFORMATEX
*
 wfx;
 
  pWav 
= new
 CWaveFile();
  
if (SUCCEEDED(pWav->
Open(strFileName, NULL, WAVEFILE_READ)))
  
{
    wfx 
= pWav->
GetFormat();
    dwSize 
= pWav->
GetSize();
    dwLen 
= (DWORD) (1000 * dwSize / wfx->
nAvgBytesPerSec);
    pWav
->
Close();
  }

  
if (pWav) delete pWav;
  
return
 dwLen;
}

你可能感兴趣的:(框架,windows,api,null,dll,扩展)