在最近的项目中,遇到了同时录制和播放音频的问题。在网络论坛上搜索后,发现许多人都在讨论如何使用Qt同时捕获音频并回放,但没有人给出一个明确的解决方案。经过一番研究,终于成功地同时录制和播放了音频。
本文将介绍如何使用Qt框架进行基本的音频输入和输出处理,以及如何实现低通滤波算法来减少输入音频的噪声。这不是一个复杂的数字信号处理(DSP)算法的解释,而是提供一个跨平台音频处理工具的起点。可以实现自己的算法或任何复杂的算法来扩展想法。
在Qt Creator中启动一个新的Qt Widget项目。向导将创建所有必要的文件以开始桌面应用程序。要链接到多媒体模块,请在.pro文件中添加以下行:
QT += core gui multimedia
TARGET = MyAudio
TEMPLATE = app
SOURCES += main.cpp mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
在开始音频处理之前,需要初始化音频格式,包括频率、通道、采样率等。使用QAudioFormat来初始化音频。
音频格式指定了音频流中数据的排列方式,即如何解释流。编码本身由流使用的编解码器指定。
QAudioFormat m_format;
m_format.setFrequency(8000); // 设置频率为8000
m_format.setChannels(1); // 设置为单声道
m_format.setSampleSize(16); // 设置采样大小为16位
m_format.setSampleType(QAudioFormat::UnSignedInt); // 采样类型为无符号整数
m_format.setByteOrder(QAudioFormat::LittleEndian); // 字节顺序
m_format.setCodec("audio/pcm"); // 设置编解码器为简单的audio/pcm
接下来,创建音频输入和输出对象,并使用IO设备和音频格式。
QAudioInput类提供了从音频输入设备接收音频数据的接口。QAudioOutput类提供了向音频输出设备发送音频数据的接口。
QAudioInput *m_audioInput = new QAudioInput(m_Inputdevice, m_format, this);
QAudioOutput *m_audioOutput = new QAudioOutput(m_Outputdevice, m_format, this);
启动音频输入和输出,并连接readyRead()信号到readMore()槽。
m_output->start();
m_input->start();
connect(m_input, SIGNAL(readyRead()), SLOT(readMore()));
从输入设备读取声音样本到缓冲区,并实现低通滤波算法以减少输入音频的噪声,从而产生平滑的声音。
qint64 l = m_input->read(m_buffer.data(), len);
if (ui->chkRemoveNoise->checkState() == Qt::Checked) {
for (int iIndex = 1; iIndex < len; iIndex++) {
outdata[iIndex] = 0.333 * resultingData[iIndex] + (1.0 - 0.333) * outdata[iIndex - 1];
}
}
对音频样本应用音量,以调整输出音量。将整数乘以音频样本以调整其幅度。
for (int iIndex = 0; iIndex < len; iIndex++) {
outdata[iIndex] = ApplyVolumeToSample(outdata[iIndex]);
}
int MainWindow::ApplyVolumeToSample(short iSample) {
return std::max(std::min(((iSample * m_iVolume) / 50), 35535), -35535);
}
最后,将修改后的音频样本回放到扬声器。这将从麦克风播放修改后的音频到扬声器。
m_output->write((char*)outdata, len);