65.9K
CodeProject 正在变化。 阅读更多。
Home

Qt 中的跨平台麦克风音频处理实用程序。

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (23投票s)

2012年7月14日

CPOL

3分钟阅读

viewsIcon

91531

downloadIcon

3717

麦克风音频的简单信号处理实现。

引言

本文介绍了如何从麦克风录制音频并使用DSP算法处理音频样本。 在本文中,我使用QAudioInputQAudioOutput类来录制和回放输入音频,并使用低通滤波器算法来降低输入音频中的噪声。 在这里,我试图用Qt解释低级音频处理。 这里我没有解释任何复杂的DSP算法。 这只是一个更好的跨平台音频处理实用程序的起点。 您可以实现自己的算法或任何复杂的算法来扩展您的想法。 我使用Qt的音频输入和音频输出示例来开发这个实用程序。

背景

在最近的项目中,我遇到了同时录制和回放音频的一些问题。 我在网上搜索了相关内容,发现很多论坛讨论了同时捕获音频并播放到扬声器的问题。 没有人给出任何使用Qt进行此操作的正确答案。 经过一些研究工作,我终于成功地同时录制和回放音频。

使用代码

TARGET指定输出文件名 (TARGET = ApplicationName)

TEMPLATE指定其编译后的输出类型。 将其分配给一个应用程序 (TEMPLATE = app)

添加项目中使用的所有源文件和头文件。

将表单设计资源添加到 FORMS += mainwindow.ui。 这将为您的应用程序创建用户界面

在 Qt Creator 中启动一个新的 Qt Widget 项目。向导将创建启动桌面应用程序所需的所有文件。 为了

链接到多媒体模块,将 QT += multimedia 行添加到您的 AppNamae .pro 文件中

QT       += core gui
             multimedia
 
TARGET = MyAudio
TEMPLATE = app
 
SOURCES += main.cpp
        mainwindow.cpp
 
HEADERS  += mainwindow.h
FORMS    += mainwindow.ui

在开始音频处理之前,初始化音频格式频率、通道、采样率等。使用 QAudioFormat 来初始化音频。

音频格式指定音频流中数据的排列方式,即如何解释流。 编码本身由用于流的 codec() 指定。

除了编码之外,QAudioFormat 还包含其他参数,这些参数进一步指定音频数据的排列方式。 这些是频率、通道数、采样大小、采样类型和字节顺序。 下表更详细地描述了这些内容

m_format.setFrequency(8000); //set frequency to 8000
m_format.setChannels(1); //set channels to mono
m_format.setSampleSize(16); //set sample sze to 16 bit
m_format.setSampleType(QAudioFormat::UnSignedInt ); //Sample type as usigned integer sample
m_format.setByteOrder(QAudioFormat::LittleEndian); //Byte order
m_format.setCodec("audio/pcm"); //set codec as simple audio/pcm

QAudioDeviceInfo infoIn(QAudioDeviceInfo::defaultInputDevice());
if (!infoIn.isFormatSupported(m_format))
{
    //Default format not supported - trying to use nearest
    m_format = infoIn.nearestFormat(m_format);
}

QAudioDeviceInfo infoOut(QAudioDeviceInfo::defaultOutputDevice());

if (!infoOut.isFormatSupported(m_format))
{
   //Default format not supported - trying to use nearest
    m_format = infoOut.nearestFormat(m_format);
}

使用 IO 设备和音频格式创建音频输入和输出对象。

QAudioInput 类提供了一个用于从音频输入设备接收音频数据的接口。

QAudioOutput 类提供了一个用于将音频数据发送到音频输出设备的接口。

m_audioInput = new QAudioInput(m_Inputdevice, m_format, this);
m_audioOutput = new QAudioOutput(m_Outputdevice, m_format, this);

启动音频输入和音频输出,并将 readyRead() SIGNAL 连接到 readMore() SLOT。

readyRead () 信号在每次有新数据可从设备读取时发出。 它仅在有新数据可用时再次发出,例如当您的网络套接字上收到新的网络数据负载时,或者当新的数据块已附加到您的设备时。

//Audio output device
m_output= m_audioOutput->start();
 //Audio input device
m_input = m_audioInput->start();
//connect readyRead signal to readMre slot.
//Call readmore when audio samples fill in inputbuffer
connect(m_input, SIGNAL(readyRead()), SLOT(readMore()));

从输入设备读取声音样本到缓冲区。

 qint64 l = m_input->read(m_buffer.data(), len);

实现了低通滤波器算法来降低输入音频中的噪声,以产生平滑的声音。

int iIndex;
if(ui->chkRemoveNoise->checkState() == Qt::Checked)
{
    //Remove noise using Low Pass filter algortm[Simple algorithm used to remove noise]
    for ( iIndex=1; iIndex < len; iIndex++ )
    {
        outdata[ iIndex ] = 0.333 * resultingData[iIndex ] + ( 1.0 - 0.333 ) * outdata[ iIndex-1 ];
    }
}

对音频样本应用音量以调整输出音量。 将一个整数乘以音频样本以调整其幅度。

for ( iIndex=0; iIndex < len; iIndex++ )
{
 //Cange volume to each integer data in a sample
 outdata[ iIndex ] = ApplyVolumeToSample( outdata[ iIndex ]);
}

int MainWindow::ApplyVolumeToSample(short iSample)
{
    //Calculate volume, Volume limited to  max 35535 and min -35535
    return std::max(std::min(((iSample * m_iVolume) / 50) ,35535), -35535);
}

最后将修改后的音频样本回放到扬声器。 这将播放从麦克风到扬声器的修改后的音频。

//write modified sond sample to outputdevice for playback audio
m_output->write((char*)outdata, len);

您可以在 readMore() 函数中实现您自己的算法。 这里我实现了低通滤波器算法来降低输入音频中的噪声。 有很多复杂的音频滤波算法可用于产生完美的音频滤波,低通是该列表中最简单的算法。 显示了如何在低级音频处理中更改音量。

参考

Qt 中的跨平台麦克风音频处理实用程序 - CodeProject - 代码之家
© . All rights reserved.