Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1661169
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: 嵌入式

2011-03-24 00:19:05

作者:Joseph Pan (转载请注明出处http://www.cnblogs.com/weizhoupan/archive/2011/03/20/1989718.html )

  喜欢买碟或者卡拉ok的朋友一定不会对声道这个术语陌生。通常我们在音像店买回来的VCD或者DVD都是双声道的形式,唱片商在录制唱片时往往提供了两个或多个声道,以保存不同的音频内容,以形成立体声效。左声道保存的大多为一些背景声效,如卡拉OK的消音伴唱。而右声道保存的往往是较为主要的声音,比如主唱的歌声。利用多声道技术,听众可以清晰地分辨出各种乐器来自的方向,从而使音乐更富想象力,更加接近于临场感受。

  有时候我们只需要音频里的单声道内容,比如喜欢用电脑录制卡拉ok的朋友就经常为了找歌曲的伴唱而流连于各大伴奏网站。现在的网络翻唱非常流行,很多网络歌手就是先搜索喜欢的歌曲的伴奏,然后利用Adobe Audition(前身就是大名鼎鼎的CoolEdit)录制自己的演唱,然后加一些简单的降噪和压限处理,最后mix到伴奏的音轨里面。尽管利用Audition也可以完成单声道的提取工作,但是操作起来比较复杂。

  其实对WAV的单声道提取并不困难。关键在于对WAV文件格式的理解。

一、WAV的文件头

  WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范。所有的WAV都有一个文件头,这个文件头包含了音频流的编码参数。

偏移地址字节数类型内容
00H~03H4字符资源交换文件标志(RIFF)
04H~07H4长整数从下个地址开始到文件尾的总字节数
08H~0BH4字符WAV文件标志(WAVE)
0CH~0FH4字符波形格式标志(FMT)
10H~13H4整数过滤字节(一般为00000010H)
14H~15H2整数格式种类(值为1,表示数据PCMμ律编码的数据)
16H~17H2整数通道数,单声道为1,双声道为2
18H~1BH4长整数采样频率
1CH~1FH4长整数波形数据传输速率(每秒平均字节数)
20H~21H2整数数据的调整数(按字节计算)
22H~23H2整数样本数据位数

  表1  WAV的文件头

  由表1我们可以得到以下几个重要的信息:

  1. 16H~17H处记录通道数,当值为1时,表示文件为单声道;当值为2时,表示文件为双声道。
  2. 18H~1BH处记录采样频率。它的取值与声卡的支持情况有关。常见的有8000、11025、22050、44100、48000、96000等。其中,44100是大多数歌曲文件采用的标准采样频率。
  3. 22H~23H处记录样本数据位数。即每一个采样的长度。常见的有8位和16位。这里还包含了另外一个信息:若样本的数据位数为n,对于双声道文件,则低n/2位用于存放左声道;高n/2位用于存放右声道。

  根据这三点信息,我们可以自己编程实现单声道的提取。下面我们就来一步步动手实现。由于程序涉及的只是简单的二进制文件读写操作,因此这里只举C#作简单示例,其他语言的处理与之大同小异。

二、文件读取类的编写

  为了方便以后对WAV文件的研究,我们可以先单独写一个WAV文件读取类,专门获取文件头的每一块信息:

WaveAccess

三、单声道提取

  前面提到,若样本的数据位数为n,则对单声道的提取,其实就是提取出n/2的数据。对于任意一位数据,其在新的数据队列中的索引k’与其在源数据队列中的索引k满足如下的映射关系:

k = 2*k’ – k’mod(n/2) + n/2

  但这里有个问题,加入只是将高或者低n/2的数据提取出来合为一个新的文件,则样本的数据位数和文件长度都需要修改为原先的一半,如果没有进行修改,播放速度将变为原来的两倍。

  另外一种解决思路是将我们需要的那n/2的数据提取出来,然后覆盖另外n/2的数据。这样,头文件就不需要进行修改,因为没有任何属性发生了改变,只是文件的内容发生了变化。

  根据上面的思想,对整个WAV文件作一次遍历,每次读入n位数据,如果是要提取左声道,则取出低n/2位数,覆盖高n/2位数;如果是要提取右声道,则取出高n/2位数,覆盖低n/2位数。据此编写singleChannelExtract函数如下:

singleChannelExtract

四、实验结果

  根据上面的分析,完成单声道提取器如图1所示。

  

         图1 单声道提取器

  运行该程序后,点击“open...”按钮,打开文件打开对话框,选中要进行单声道提取的文件。完成后,Format Info栏将显示该wav文件的信息。之后,单击“Extract!”按钮,弹出一个文件保存对话框,选择要保存的路径点确定,开始提取单声道,完成后将提示“Done!”。

  图2和图3分别给出了对一段音频进行右声道提取前和提取后的结果。

  

                        图2 提取右声道前

  

                        图3 提取右声道后

  注意图3中原来的左声道内容已经被右声道的内容覆盖,因此此时虽然还是双声道,但两个声道的内容是一样的,因此在使用上与单声道并没有区别。但如果只想保留一个声道,则可以根据前面的阐述,将每个采样值n/2位内容提取出来并合并成一个文件,再修改头文件相关数据,从而达到需要的结果。

附相关程序下载

阅读(2551) | 评论(0) | 转发(0) |
0

上一篇:WAV音频定长分段切取

下一篇:VC菜单编程

给主人留下些什么吧!~~