本文主要介绍如何从麦克风进行音频采集,并使用qml-charts模块进行显示波形图显示
- 首先关于使用电脑的麦克风设备进行音频采集到内存,可以参考QtQuick音频采集
- 继承抽象类QIODevice,并重写readData()和writeData()两个方法,readData是从外部读取数据,暂且不用管它,我们最主要的是重写writeData()方法,将数据写入到qml中的ChartView
- 首先在main.qml传入要操作的序列
Item {
visible: true
width: 640
height: 480
ChartView{
id:chartView
animationOptions: chartView.NoAnimation
theme: chartView.ChartThemeBlueIcy
property bool openGL: true
property bool openGLSupported: true
anchors.fill: parent
Component.onCompleted: {
dataSource.setSeries(chartView.series(0));//传入要操作的序列QXYSeries
}
Component.onDestruction: {
dataSource.setSeries(0);//销毁时传空,在写入数据时对QXYSeries做非空判断
}
ValueAxis{
id:axisY1
min: -1
max: 1
}
ValueAxis{
id:axisX
min: 0
max: 2000
}
LineSeries{
id: lineSeries
name: "Audio Sample"
axisX: axisX
axisY: axisY1
useOpenGL: chartView.openGL
}
}
}
- 在DataSource从qml设置QXYSeries,这里需要注意的是在ChartView销毁时需要将它设置为null,具体请看ChartView中 Component.onDestruction()信号,若不如此,控件在销毁时仍在执行update操作,这时会出现崩溃现象。
void DataSource::setSeries(QAbstractSeries *series)
{
m_series = static_cast<QXYSeries *>(series);
}
- writeData()和readData()都是重载函数,这里其实是接收到录音设备的数据,然后我们将录音数据“写入”到波形图上
qint64 DataSource::writeData(const char * data, qint64 maxSize)
{
if(m_series)
{
qint64 range = 2000;
QVector<QPointF> oldPoints = m_series->pointsVector();
//qDebug() << oldPoints.size();
QVector<QPointF> points;
int resolution = 4;
if (oldPoints.count() < range) {
points = m_series->pointsVector();
} else {
for (int i = maxSize/resolution; i < oldPoints.count(); i++)
points.append(QPointF(i - maxSize/resolution, oldPoints.at(i).y()));
}
qint64 size = points.count();
for (int k = 0; k < maxSize/resolution; k++)
points.append(QPointF(k + size, ((quint8)data[resolution * k] - 128)/128.0));
m_series->replace(points);
}
return maxSize;
}
-
- 最后在main()函数完成初始化等
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQuickView viewer;
QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);
viewer.setTitle(QStringLiteral("Audio Sample"));
QAudioFormat formatAudio;
formatAudio.setSampleRate(8000);
formatAudio.setChannelCount(1);
formatAudio.setSampleSize(8);
formatAudio.setCodec("audio/pcm");
formatAudio.setByteOrder(QAudioFormat::LittleEndian);
formatAudio.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo inputDevices = QAudioDeviceInfo::defaultInputDevice();
QAudioInput* m_audioInput = new QAudioInput(inputDevices,formatAudio);
DataSource* dataSource = new DataSource();
dataSource->open(QIODevice::WriteOnly);
m_audioInput->start(dataSource);
viewer.rootContext()->setContextProperty("dataSource", dataSource);
viewer.setSource(QUrl("qrc:/main.qml"));
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
viewer.setColor(QColor("#404040"));
viewer.show();
return app.exec();
}
效果图如下