徐 晋
(中国船舶集团第七一五研究所,浙江 杭州 310000)
在研究水声目标时,由于研究人员不知道什么时间会出现特征音频,所以就会对整个实验进行全程录音;这就会出现录音时长较长且录音文件较大的问题,为后续对目标音频的特征分析带来困难。为了解决该问题,研究人员可以使用音频编辑软件对感兴趣的音频进行裁剪后再做分析。现在市面上已经有了许多非常优秀的商业音频编辑软件,例如Cool Edit等。但是由于软件版权和系统环境的限制,就导致了在某些特定场景下无法使用该类软件。通过运用Qt的跨平台特性,可以开发1款拥有自主知识产权的跨平台音频编辑软件。该文主要讨论了如何开发1款基于Qt的WAV音频剪切软件,从而解决前文中所提到的问题。
该软件使用Qt Creator平台进行开发。Qt Creator是Qt推出的1款轻量级集成开发环境,它包括项目生成向导、高级的C++代码编辑器、浏览文件及类的工具、集成了Qt Designer、Qt Assistant、Qt Linguist、图形化的 GDB 调试前端,集成 qmake构建工具等。Qt Creator具有跨平台的特性,其开发的软件可以在Windows、Linux、VxWork以及移动平台上部署[1]。
WAV音频裁剪软件的功能模块主要分为波形显示模块、播放控制模块、音频剪切模块以及音频录制模块。
波形显示模块主要具备绘制音频文件的时域幅度图像、绘制时长坐标、管理水平Slider的样式以及操作控制等功能。
播放控制模块主要具备载入音频文件、控制音频文件的播放以及控制媒体音量等功能。
音频裁剪模块实现了对剪切音频文件的静态参数,该函数的4个参数分别是待裁剪文件的绝对路径、裁剪后文件的保存路径、舍弃前段音频文件时长以及舍弃的后端音频文件时长。
音频录制模块主要具备音频录制以及控制音频录制的功能。最后将各个模块整合成音频剪切软件,打通功能模块之间的接口并调用,从而实现功能菜单栏。
WAV为微软公司开发的1种声音文件格式,它符合RIFF文件的规范,可以用来保存Windows平台的音频信息资源,广泛应用于Windows平台及其应用程序。WAV文件通常使用声道数、采样频率和采样位数来表示声音。采样位数分为8位、16位和24位;声道分为单声道和立体声,单声道振幅数据为n×1的矩阵点,立体声为n×2的矩阵点,采样频率一般有11025 Hz(11 kHz)、22050 Hz(22 kHz)和44100 Hz(44 kHz)3种[2]。WAV文件的基本格式见表1。
表1 WAV文件的基本格式
通过解析WAV文件可以获取各个时刻的音频振幅信息,也可以按照其格式编辑WAV文件,从而达到剪切的效果。
2.2.1 时域幅度图像绘制
自定义1个基于QWiget的波形显示类WaveDisplay,重载其PainEvent()函数。在PainEvent()函数中调用QPainter的drawLine()函数绘制时域幅度图像,幅度数据可以通过对WAV文件数据块解析的方式获得。根据WAV文件声道数的不同,采用不同的绘制方式。为了支持波形图像的缩放功能,在绘制时需要代入图像的尺寸信息,关键代码如下。
2.2.2 时长坐标绘制
通过调用播放控制模块的预留接口, 可以将WAV文件的时长信息精确到毫秒。绘制时长坐标分为绘制文字和绘制标尺线;使用QPainter的drawText()函数绘制文字,由于文字显示的“xx:xx:xx:xxx”字符串较长,如果要让字符在首部与尾部完整的显示,就需要进行左右搬移,这就会导致字符串之间的间隔不统一,因此在首部与尾部不绘制文字。使用QPainter的drawLine()函数绘制标尺线,标尺分为长横线和短竖线;为了适应缩放,长横线与时域幅度图像等宽;短竖线每绘制若干格就标注1个刻度信息。需要注意的是,每一格坐标的长度会随着缩放比例的变化而变化,如果单格长度过长就会显得坐标不够美观;因此,时长坐标格数应该随着缩放比例的变化而变化。在该软件中,当缩放比例小于5倍时,2个标注之间绘制5格;当缩放比例大于5倍时,2个标注之间绘制10格。
2.2.3 水平Slider的样式管理
使用Qt自带的QSlider来实现用水平Slider去表示当前显示的幅度波形在全局幅度波形中的位置。QSlider总长度表示WAV文件的全长,滑块长度表示当前可视范围内的时长。通过设置QSlider的样式表,可以控制滑块的长度;调用QSlider的SetValue()函数可以设定滑块的位置。
2.2.4 操作控制
按住鼠标左键拖拽可以实现选中的操作。需要重载鼠标按下事件(mousePressEvent)、鼠标移动事件(mouseMoveEvent)以及鼠标松开事件(mouseReleaseEvent)。按下鼠标左键时记录按下点的位置坐标,拖拽时记录下最新的位置坐标,松开鼠标左键视为完成拖拽操作,根据起始点与结束点生成选中区域。
调用setContextMenuPolicy(Qt::ActionsContextMenu)函数设置菜单按照默认方式弹出即右键弹出。在有选中区域的情况下单击鼠标右键,再单击另存为按钮就可以调用音频裁剪模块对选中区域进行裁剪。
重载波形显示模块的鼠标滚轮事件(wheelEvent)可以实现对鼠标滚轮的操作。滚动滚轮调整可视窗口的前后位置;按住Ctrl键时,滚动滚轮调整缩放比例,缩放比例最小为1.0即不做缩放。
Qt为音视频的播放和控制、相机拍摄以及收音机等多媒体应用提供了强大的支持。Qt5使用了全新的Qt Multimedia模块来实现多媒体的功能,Qt4中用来实现多媒体功能的Phonon模块已经被移除。该软件使用Qt Multimedia模块中的QMediaPlayer类来实现音频的播放。QMediaPlayer类提供了一些接口函数来控制音频播放,例如paly()、pause()以及stop()等。
播放控制模块包括界面上的控制按钮、播放进度条以及音量条与时间信息的显示。
新建类型为QMediaPlayer的指针,使用SetMedia()函数为其设置待播放的WAV文件。读取WAV 的时长信息,并使用该信息绘制时长坐标与设置进度条。调用play()函数开始播放WAV文件。建立1个执行周期为50 ms的计时器,每当计时器完成1轮计时就可以获取播放进度,并使用播放进度在波形显示模块绘制进度标识线以及更新播放时间的信息。根据播放的情况对播放按钮设置不同的图标。
音量控制使用SetVolume()函数,设定范围在0音量~100音量之间,0表示静音;根据静音的情况为音量按钮设置不同的图标。
音频裁剪模块通过1个静态函数来实现,静态函数实际上是1个全局函数,不依赖1个类的对象,不创建对象也可以调用。静态函数只能访问类中静态成员的变量。函数的4个输入参数分别为待裁剪文件的绝对路径、裁剪后文件的保存路径、舍弃前段音频文件的时长以及舍弃后段音频文件的时长。函数中应当添加前后裁剪长度总和不得超过文件总长度的判断条件。
使用fopen()函数读取待剪裁WAV文件,并将WAV文件的RIFF头、数据类型标识符以及格式块等信息存入本地定义的结构。计算前后裁剪量后就可以得到裁剪后文件的大小。将裁剪后的文件大小填入之前保存的WAV文件的RIFF头与格式块,使用fwrite()函数将修改后的WAV文件的RIFF头与格式块写入新的WAV文件,最后写入裁剪后的数据;具体实现代码如下。
QAudioInput类提供了1个接口,用于从音频输入设备中接收音频数据。可以使用系统默认的音频输入设备来构建音频输入;也可以使用特定的QAudioDeviceInfo创建QAudioInput。创建音频输入时,还应该设定QAudioFormat用于确定录制音频的声道数、采样率以及采样位数等参数。调用QAudioInput类的start()函数开始录制,调用stop()函数结束录制,并生成.raw格式的原始音频文件。为.raw文件添加WAV的RIFF头、数据类型标识符和格式块,再另存为.wav格式就能得到WAV格式的录音文件。格式块中的声道数、采样率以及采样位数等参数信息应当按照录音文件的特征填写。
通过该文所论述的方法,可以开发1款基于Qt的WAV音频剪切软件。该软件主要用于解决研究人员在研究过程中遇到的WAV音频文件过大和时长过长等问题。该软件利用了Qt的跨平台特性,可以在多种平台上运行。开发该软件的最初目的就是为了解决研究人员现阶段所遇到的问题,因此难免存在适应性窄以及界面不够美观等问题,未来可以继续对该软件进行迭代优化,添加更多功能,例如支持多种音频文件格式、添加一系列降噪滤波算法、音频的插入以及编辑等。