Get sound wave from QAudioInput
-
Hello,
I want to get a sound wave from QAudioInput like here:
This is a python code from here.
This code works bu I want to do that with c++.Here is my code to do that (only for test purpose, I will clean and optimise it later):
code to get audio outputauto io = this->audio->start(); connect(io,&QIODevice::readyRead,[this,io]{ QByteArray buff = io->readAll(); int buffLenght = buff.length(); if (buffLenght>0){ this->processAudioFrame(buff.constData(),buffLenght); } });
code to convert audio QByteArray to list of numbers:
void Window::processAudioFrame(QByteArray data, int lenght){ if(lenght > 0) { short* result = (short *)data.data(); for (int i=0; i < lenght/2; i++ ) { ui->soundView->pushSoundLevel(result[i]/32768.0); } } }
and here in my custom widget the pushSoundLevel and repaintEvent methods:
void SoundWidget::pushSoundLevel(double level){ buffer.push_back(level); buffer.pop_front(); this->update(); } void SoundWidget::paintEvent(QPaintEvent *event){ QPainter p(this); QPolygonF soundWave; for (int x = 0; x<this->buffer.size(); x++){ soundWave<<QPointF(x,(buffer.at(x)*0.2*this->height())+this->height()/2); } QRectF boundingRect = soundWave.boundingRect(); QTransform t; t.scale(this->width()/boundingRect.width(),1); p.setTransform(t); p.drawPolyline(soundWave); }
My QAudioInput's parameters are that:
format.setSampleRate(11025); format.setChannelCount(1); format.setSampleSize(16); format.setSampleType(QAudioFormat::SignedInt); format.setByteOrder(QAudioFormat::LittleEndian); format.setCodec("audio/pcm");
And I have this result:
I think that my problem come from the QByteArray conversion but I don't know why.
I am on Arch linux with Qt 5.15.2.
Thanks for your help.
-
@Robotechnic said in Get sound wave from QAudioInput:
for (int i=0; i < lenght/2; i++ )
I would say it should be
for (int i=0; i < lenght; i+=2 )
-
Ok thanks @jsulm but, unfortunatly, this solution doesn't work as espected
-
@Robotechnic Just realised: result is already short*, so i+=2 is indeed wrong.
-
I think my problem come from the range of the for loop because, when I play static note on a flute I got this graph:
And as you can see around garbage of random values, I have good wave
If someone know how to fix that thanks in advance
I have also removedQRectF boundingRect = soundWave.boundingRect(); QTransform t; t.scale(this->width()/boundingRect.width(),1); p.setTransform(t);
because this create some problems
-
I fixed my problem:
with a qDebug of lenght I have:
data.length() lenght 136 2730 740 1364 1326 1366 414 1364 208 1366 458 1364 As you can see they are not the same so, with this code, my problem is fixed:
void Window::processAudioFrame(QByteArray data){ const short* result = (short *)data.constData(); for (int i=0; i < data.length()/2; i ++ ){ ui->soundView->pushSoundLevel(result[i]); } }