Introduction
This article explains how to record audio from microphone and process the audio sample using DSP algorithms. In this article, I am using
the QAudioInput
and QAudioOutput
classes to record and play back to the input audio, and used Low pass filter algorithm to reduce noise in input audio.
Here, I have tried to explain the low level audio processing using Qt. Here I am not explaining anycomplex DSP algorithms. It’s just a starting point
to a better cross platform audio processing utility. You can implement your own algorithms or any complex algorithms to extend your ideas.
I used Qt's audio input and audio output examples to develop this utility.
Background
In my recent project, I met with some issues to record audio and playback at a time. I searched about it in the web and saw a lot of forums discussing
about to capture audio and play back to the speaker at a time. No one given any proper answer to do this using Qt. After some research work finally I
succeeded
to record and playback audio at a time.
Using the code
TARGET specify the output file name (TARGET = ApplicationName)
TEMPLATE specify its compiled output type. Assign it to an application (TEMPLATE = app)
Add all the source and header files are using in your project.
Add Form design resources to FORMS += mainwindow.ui. This will create user interface to your application
In Qt Creator start a new Qt Widget project. The wizard will create all the necessary files to start a desktop application. To
link against the multimedia module, add QT += multimedia line to your AppNamae .pro file:
QT += core gui
multimedia
TARGET = MyAudio
TEMPLATE = app
SOURCES += main.cpp
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
Before starting the audio processing initialize Audio Format Frequency, Channel, Sample Rate etc. Use
QAudioFormat
to initialize audio.
An audio format specifies how data in an audio stream is arranged, i.e, how the stream is to be interpreted. The encoding itself is specified by the
codec()
used for the stream.
In addition to the encoding, QAudioFormat
contains other parameters that further specify how the audio data is arranged. These are the frequency,
the number of channels, the sample size, the sample type, and the byte order. The following table describes these in more detail
m_format.setFrequency(8000); m_format.setChannels(1); m_format.setSampleSize(16); m_format.setSampleType(QAudioFormat::UnSignedInt ); m_format.setByteOrder(QAudioFormat::LittleEndian); m_format.setCodec("audio/pcm");
QAudioDeviceInfo infoIn(QAudioDeviceInfo::defaultInputDevice());
if (!infoIn.isFormatSupported(m_format))
{
m_format = infoIn.nearestFormat(m_format);
}
QAudioDeviceInfo infoOut(QAudioDeviceInfo::defaultOutputDevice());
if (!infoOut.isFormatSupported(m_format))
{
m_format = infoOut.nearestFormat(m_format);
}
Create audio input and output objects with IO device and audio formats.
The QAudioInput
class provides an interface for receiving audio data from an audio input device.
The QAudioOutput
class provides an interface for sending audio data to an audio output device.
m_audioInput = new QAudioInput(m_Inputdevice, m_format, this);
m_audioOutput = new QAudioOutput(m_Outputdevice, m_format, this);
Start audio input and audio output and connect readyRead()
SIGNAL to
readMore()
SLOT.
The readyRead ()
signal is emitted once every time new data is available for reading from the device. It will only be emitted again once new data is available,
such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.
m_output= m_audioOutput->start();
m_input = m_audioInput->start();
connect(m_input, SIGNAL(readyRead()), SLOT(readMore()));
Read sound samples from input device to buffer.
qint64 l = m_input->read(m_buffer.data(), len);
Implemented Low Pass filter algorithm to reduce noise in the input audio to produce smooth sound.
int iIndex;
if(ui->chkRemoveNoise->checkState() == Qt::Checked)
{
for ( iIndex=1; iIndex < len; iIndex++ )
{
outdata[ iIndex ] = 0.333 * resultingData[iIndex ] + ( 1.0 - 0.333 ) * outdata[ iIndex-1 ];
}
}
Apply volume to audio sample for adjusting the output volume. Multiply an integer number to audio sample to adjust its amplitude.
for ( 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);
}
Finally play back the modified audio samples to speaker. This will play modified audio from microphone to speaker.
m_output->write((char*)outdata, len);
You can implement your own algorithms in readMore()
function. Here I implemented Low Pass filter algorithms to reduce noise in input audio.
There are lots of complex audio filtering algorithms are available to produce a perfect audio filtering Low Pass is the simplest
algorithm in that list.
Shows how to change the volume in low level audio processing.
Reference