⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windows下处理audio.txt

📁 vc sound_rar的源文件,如果有用说声
💻 TXT
字号:
发信人: jingjm (jingjm), 信区: VisualC
标  题: Windows下处理Audio
发信站: BBS 水木清华站 (Wed Jan  9 17:36:35 2002)

   WINDOWS下对音频的处理,大致可分为两部分,即音频的输入、输出, 和ACM压缩
处理。

  在WINDOWS下可以调用诸如sndPlaySound等API来播放一个WAV文件,但那显然
不是我们要做的。必须 能够直接对音频数据进行处理。在WINDOWS下,也为之提供
了一系列的API,以waveIn和waveOut开头的 一组API就是干这个的。

  先说输入吧。常用的相关API为waveInOpen(打开一个音频输入设备)、
aveInPrepareHeader(为一个即 将在waveInAddBuffer中调用的输入缓冲区准备
头部)、waveInAddBuffer(添加一个输入用的数据缓冲区)、 waveInStart(开
始录音)、waveInClose(关闭音频输入设备)等几个,以及需要在waveInOpen中
指定的 一个回调函数或者线程,其作用是在一个数据缓冲区被录满后被调用,以
对这些数据进行处理,和其他 一些相关的操作。

  首先你得确定一下你需要用什么回调方式,即在某个时间片的音频数据被录完
后,Windows将通过这个 回调来激活对这些数据的处理过程,一般用到的无非是
UNCTION、THREAD和EVENT这几类,而比较方便 简单的就是FUNCTION和THREAD了。
UNCTION方式是指Windows会调用你这个函数,而THREAD则是由 Windows来激活你
所指定的线程。这些都在waveInOpen中指定。其函数原型为:

MRESULT waveInOpen( LPHWAVEIN phwi, UINT uDeviceID,LPWAVEFORMATEX pwfx,

WORD dwCallback,DWORD dwCallbackInstance,DWORD fdwOpen);

  其中:phwi是返回的句柄存放地址,uDeviceID是要打开的音频设备ID号,一
般都指定为WAVE_MAPPER。 dwCallback则为指定的回调函数或线程等的地址,
dwOpen指定回调方式,dwCallbackInstance为需要向回调 函数或线程送入的用户
参数。至于那个pwfx,则比较关键,它指定了要以什么音频格式打开音频输入设备
, 它是一个结构WAVEFORMATEX:
ypedef struct { WORD wFormatTag;
ORD nChannels;
WORD nSamplesPerSec;
WORD nAvgBytesPerSec;
ORD nBlockAlign;
ORD wBitsPerSample;
ORD cbSize;
 WAVEFORMATEX;
  如果你的机器上的WIN9X安装时选择了音频压缩,你就可以在wFormatTag中指
定一些压缩的音频格式, 如G723.1,TURE DSP,等之类。不过一般都是选用
AVEFORMAT_PCM格式,即未压缩的音频格式,至于 压缩,可以在录完后调用下面
将要谈到的ACM单独进行。
  nChannels为声道数,1或者2。nSamplesPerSec为每秒采样数,8000、11025、
2050、44100为几个标准值, 其他的非标准值我倒没试过行不行。
AvgBytesPerSec为每秒平均的字节数,在PCM方式中就等于
Channels*nSamplesPerSec*wBitsPerSample/8, 但对于其它的压缩的音频格式,
由于很多压缩方式是按时间片进行的,如G723.1,就是以30ms为一个压缩单位,
这样,nAvgBytesPerSec只是一个大概的数字,并不准确,程序中的计算是不应该
以这个量为准的。这一点在 下面的压缩音频输出和ACM音频压缩中非常重要。
BlockAlign是一个比较特殊的值,表示对音频处理时的最小处理单位, 对于PCM
非压缩,它就是wBitsPerSample*nChannels/8,而对于非压缩格式,则表示压缩/
解压处理的最小单位了, 如G723.1,就是30ms的数据大小(20bytes或者24bytes
)。wBitsPerSample就是每采样值的位数,8或者16。 cbSize则是表示该
AVEFORMATEX的结构在标准的头部之后还有多少字节数,对于很多非PCM的音频格
式, 有一些自己的定义格式参数,这些就紧跟在标准的WAVEFORMATEX后面,其大
小就由cbSize指定。对于PCM格式 而言,为0,或者忽略不检查。

  这样,指定了这些参数后,你应该就能够打开音频输入设备了。下面要做的事
情就是准备几个 用做录音的缓冲区。就我而言,常准备多个缓冲区,并在回调中
循环使用。另外,你还得考虑好录得的音频数据放 哪儿,比如一个临时文件,你
就得准备好文件的句柄。对于缓冲区,得使用waveInPerpareHeader准备一下头部
, 这个API比较简单,如果你是循环使用缓冲区,对每个缓冲区也只需要调用一次
aveInPrepareHeader。

  一切准备好之后,就可以调用waveInAddBuffer和waveInStart开始录音了,只
要你一调用这个waveInStart,录音就开始了, 即使这个缓冲区录满之后你没有加
入新的缓冲区进去,录音也不会停,只是这中间的语音数据全都丢了。当通过
aveInAddBuffer送入的缓冲区被录满后,Windows就会通过你在waveInOpen中指定
的方式进行回调,你得在回调中把录好的语音数据取出来,并且,如果还想继续
录音的话,得将下一个缓冲区添加进去。考虑到这个处理是有时间延迟的,而且
音频对时间很敏感,一般都要先预加入若干个缓冲区,比如,你一共定义了8个缓
冲区,而为了 保险起见,最好保证任一时刻至少有3个缓冲区可被录音使用,那么
在开始录音时,则先加入4个缓冲区,然后 在回调中,如果当前录好的缓冲区第n
个,则对第(n+4)%8调用waveInAddBuffer,这时,还有第(n+1)%8,(n+2)%8,
n+3)%8这三个缓冲区可用,即基本上就可以保证所录得音频中不会有断开的间隔
。希望我说得够清楚。

  其他的就没什么好说了,想结束录音时,最好在waveInClose之前调用一下
aveInReset,这样可以清掉尚在等待 录音的缓冲区,同时在回调中还必须注意一
下送入参数中的消息种类。


  音频输出部分相对简单一点。对应的API有waveOutOpen、
aveOutPrepareHeader、waveOutWrite以及waveOutClose。 如果你希望直接输出
压缩格式的音频的话,必须注意waveOutOpen中指定的音频格式参数。你必须很清
楚这类格式 的具体参数及其含义。不过,你可以通过下面说到的ACM(Audio
ompress Manager)得到你需要的音频格式的具体 参数,这个格式参数可以直接
用于waveOutOpen。如同音频的输入,waveOutPrepareHeader也是必需的。
waveOutWrite 则是填入输出缓冲区,为了避免间断,也应该保证某一时刻缓冲区
队列中数目足够。


  如果你在安装WIN98时在附件中选择了音频压缩,那么机器上的ACM就可用了。
ACM为Audio Compress Manager。 WIN98提供了一些常用的音频压缩算法程序包,
供用户调用。你可以通过ACM获得本机上所有的音频压缩驱动及其 所支持的音频格
式。

  VC的HELP中有三个相关的例子,ACMAPP、CONV、 CAPS。你可以通过这些例子
大致了解一下ACM的基本用法。OICQ的音频就是通过ACM调用 TRUE DSP进行压缩的
。不过,似乎不是每种ACM格式都能被调用来进行压缩,我只试验成功了L&H和TRUE
DSP两种 方式进行压缩。

  不过ACM中的压缩驱动大多都是针对语音频段,如果用来压缩频带较宽的音频
,如音乐,则效果很差,你可以试试。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -