在Qt中跨平台麦克风音频处理实用程序代码和实现

11 篇文章 0 订阅

本文介绍了如何从麦克风中录制音频,并利用DSP算法对音频样本进行处理。在本文中,我使用QAudioInput和QAudioOutput类来录制和回放输入音频,并使用低通滤波算法来降低输入音频中的噪声。在这里,我试图解释使用Qt的低电平音频处理,这里我不解释任何复杂的DSP算法。这只是一个更好的跨平台音频处理工具的起点。您可以实现自己的算法或任何复杂的算法来扩展您的思想。我用的是Qt的音频输入

背景

在我最近的项目中,我遇到了一些问题,记录音频和回放一次。我在网上搜索了一下,发现很多论坛都在讨论如何捕捉音频,并一次播放给说话者听。没有人给出使用Qt的正确答案,经过一些研究工作,最后我成功地一次记录和回放音频。

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


TEMPLATE指定编译后的输出类型。将它分配给一个应用程序(TEMPLATE = app)
添加项目中使用的所有源文件和头文件。
添加表单设计资源到FORMS += mainwindow.ui。这将为您的应用程序创建用户界面
在Qt Creator中启动一个新的Qt Widget项目。该向导将创建启动桌面应用程序所需的所有文件。来
在你的AppNamae .pro文件中添加QT += multimedia行:

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

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


音频格式指定音频流中的数据如何排列,即如何解释流。编码本身由用于流的编解码器()指定。
除了编码之外,QAudioFormat还包含其他参数,这些参数进一步指定音频数据的排列方式。它们是频率、通道数、样本大小、样本类型和字节顺序。下表更详细地描述了这些

//C++
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类提供了一个向音频输出设备发送音频数据的接口。

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

启动音频输入和音频输出,并将readyRead() SIGNAL连接到readMore() SLOT。
每当可以从设备读取新数据时,就会发出一次readyRead()信号。只有当有新的数据可用时,它才会再次发出,例如当网络数据的新负载到达您的网络套接字时,或者当一个新的数据块被附加到您的设备时。

//c++

//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);
}

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

m_output->write((char*)outdata, len);

您可以在readMore()函数中实现自己的算法。在这里,我实现了低通滤波算法,以减少输入音频中的噪声。有很多复杂的音频滤波算法可以产生一个完美的音频滤波,Low Pass是其中最简单的算法。演示如何在低电平音频处理中更改音量。

 

代码链接

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Meta.Qing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值