how do i get amplitude levels of audio from audio buffer which contains char* data.
-
sir,
the code is given below.how do i take the amplitude levels from _buffer.format.setSampleRate(44100); format.setChannelCount(1); format.setSampleSize(24); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); ************************************************************************ QByteArray _buffer; QIODevice *device; _buffer= device->read(2000); char *data=_buffer.data();
-
Your computation assumes that the format you got is the one you requested and use matching hard coded values. You should check what you actually got and then adapt the values.
@SGaist
sir,
sir, thank you very much for the clue you give.i fixed the problem in the application and it works fine.The working code is given below.i did the following steps to fix the problem.
- reduced the input volume by using QAudinput :: setVolume(0.009) function.
- converted the *data to to qint8 from uchar
input_G->setVolume(0.009); xy_device = new XYSeriesIODevice(this,m_series); xy_device->open(QIODevice::WriteOnly); //if crash check m_series is null input_G->start(xy_device); }
qint64 XYSeriesIODevice::writeData(const char *data, qint64 maxSize) { static const int resolution = 4; if (m_buffer.isEmpty()) { m_buffer.reserve(sampleCount); for (int i = 0; i < sampleCount; ++i) m_buffer.append(QPointF(i, 0)); } int start = 0; const int availableSamples = int(maxSize) / resolution; if (availableSamples < sampleCount) { start = sampleCount - availableSamples; for (int s = 0; s < start; ++s) m_buffer[s].setY(m_buffer.at(s + availableSamples).y()); } for (int s = start; s < sampleCount; ++s, data += resolution){ qreal y=qreal(qint8(*data))/qreal(128); m_buffer[s].setY(y*.75);} m_series->replace(m_buffer); return (sampleCount - start) * resolution; }
-
Hi,
You need to go through the values of the buffer content and then calculate it.
-
@SGaist
sir,
i used the code in audio example to depict audio data in qml chartview.it works fine on ubuntu desktop but on an android device it depicts data without any audio input. the code is given below and the screenshot of the application on both devices .code_text static const int resolution = 4; int sampleCount=2000; if (m_buffer.isEmpty()) { m_buffer.reserve(sampleCount); for (int i = 0; i < sampleCount; ++i) m_buffer.append(QPointF(i, 0)); } int start = 0; const int availableSamples = int(len) / resolution; if (availableSamples < sampleCount) { start = sampleCount - availableSamples; for (int s = 0; s < start; ++s) m_buffer[s].setY(m_buffer.at(s + availableSamples).y()); } for (int s = start; s < sampleCount; ++s, data += resolution) m_buffer[s].setY(qreal(uchar(*data) -128) / qreal(128)); qDebug()<<qreal(uchar(*data) -128) / qreal(128); m_series->replace(m_buffer);
qml part
code_text ChartView{ id:chart_view width: page1.width height: page1.height*.50 theme: ChartView.ChartThemeDark property bool openGL: true property bool openGLSupported: true onOpenGLChanged: { if (openGLSupported) { series("audio signal").useOpenGL = openGL; } } ValueAxis { id: xAxis min: 0 max: 2000 titleText: "samples" } ValueAxis { id: yAxis min: -1 max: 1 } LineSeries{ name:"audio signal" id: lineSeries1 axisX: xAxis axisY: yAxis useOpenGL: chart_view.openGL } Component.onCompleted: { if (!series("audio signal").useOpenGL) { openGLSupported = false openGL = false } recorder.setSeries(chart_view.series(0)); } } }
-
Not knowing how you get the data in the first place, I can't say anything.
-
@SGaist
sir the code is given below.import QtQuick 2.15 import QtQuick.Window 2.15 import QtCharts 2.3 import Recorder 0.1 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") Recorder{id:rec_model} ChartView { id:chart_view width: 400 height: 300 theme: ChartView.ChartThemeBrownSand antialiasing: true ValueAxis { id: xAxis min: 0 max: 2000 titleText: "samples" } ValueAxis { id: yAxis min: -1 max: 1 } LineSeries{ name:"audio signal" id: lineSeries1 axisX: xAxis axisY: yAxis // useOpenGL: chart_view.openGL } Component.onCompleted: { rec_model.setSeries(chart_view.series(0)); } } }
#ifndef RECORDER_H #define RECORDER_H #include <QObject> #include<QAudioInput> #include<QAudioDeviceInfo> #include<QAudioFormat> #include<QXYSeries> #include<QDebug> #include<QAbstractSeries> #include <QtCore/QPointF> #include <QtCore/QVector> #include<QAbstractSeries> using namespace QtCharts; using namespace std; class Recorder : public QObject { Q_OBJECT public: explicit Recorder(QObject *parent = nullptr); static const int sampleCount = 2000; public slots: void depict(); void setSeries(QAbstractSeries *value); signals: private: QIODevice* iodevice; QXYSeries *series; QAudioInput* audioinput; QVector<QPointF> _points; QAudioFormat format; }; #endif // RECORDER_H
#include "recorder.h" #include <QtCharts/QXYSeries> Recorder::Recorder(QObject *parent) : QObject(parent) { // Set up the desired format, for example: format.setSampleRate(8000); format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice(); if (!info.isFormatSupported(format)) { qWarning() << "Default format not supported, trying to use the nearest."; format = info.nearestFormat(format); } if(format.isValid()){ qDebug()<<"using nearest format"<<format; audioinput=new QAudioInput(format, this); } if(audioinput->state()==QAudio::StoppedState){ iodevice=audioinput->start(); qDebug()<<audioinput->state(); bool status= iodevice->open(QIODevice::ReadOnly); qDebug()<<"iodevice status"<<status; if(status){ connect(iodevice,SIGNAL(readyRead()),SLOT(depict())); } } } void Recorder::depict() { qint64 maxlen=2000; QByteArray _buffer; _buffer.resize(2000); maxlen=iodevice->read(_buffer.data(),maxlen); char* data=_buffer.data(); if(maxlen>0){ static const int resolution = 4; if (_points.isEmpty()) { _points.reserve(sampleCount); for (int i = 0; i < sampleCount; ++i) _points.append(QPointF(i, 0)); } int start = 0; const int availableSamples = int(maxlen) / resolution; if (availableSamples < sampleCount) { start = sampleCount - availableSamples; for (int s = 0; s < start; ++s) _points[s].setY(_points.at(s + availableSamples).y()); } for (int s = start; s < sampleCount; ++s, data +=1) _points[s].setY(qreal(uchar(*data) -128) / qreal(128)); series->replace(_points); } } void Recorder::setSeries(QAbstractSeries *value) { if (value) { QXYSeries* xySeries = static_cast<QXYSeries*>(value); qDebug()<<xySeries->name(); series=xySeries;} }
-
You do not use the format information for your computations.
-
@SGaist said in how do i get amplitude levels of audio from audio buffer which contains char* data.:
You do not use the format information for your computations.
sir, i dont know how to calculate using the format.could you please tell me how do i do that?
-
Your computation assumes that the format you got is the one you requested and use matching hard coded values. You should check what you actually got and then adapt the values.
-
Your computation assumes that the format you got is the one you requested and use matching hard coded values. You should check what you actually got and then adapt the values.
@SGaist
sir,
sir, thank you very much for the clue you give.i fixed the problem in the application and it works fine.The working code is given below.i did the following steps to fix the problem.
- reduced the input volume by using QAudinput :: setVolume(0.009) function.
- converted the *data to to qint8 from uchar
input_G->setVolume(0.009); xy_device = new XYSeriesIODevice(this,m_series); xy_device->open(QIODevice::WriteOnly); //if crash check m_series is null input_G->start(xy_device); }
qint64 XYSeriesIODevice::writeData(const char *data, qint64 maxSize) { static const int resolution = 4; if (m_buffer.isEmpty()) { m_buffer.reserve(sampleCount); for (int i = 0; i < sampleCount; ++i) m_buffer.append(QPointF(i, 0)); } int start = 0; const int availableSamples = int(maxSize) / resolution; if (availableSamples < sampleCount) { start = sampleCount - availableSamples; for (int s = 0; s < start; ++s) m_buffer[s].setY(m_buffer.at(s + availableSamples).y()); } for (int s = start; s < sampleCount; ++s, data += resolution){ qreal y=qreal(qint8(*data))/qreal(128); m_buffer[s].setY(y*.75);} m_series->replace(m_buffer); return (sampleCount - start) * resolution; }