本文主要介紹如何從麥克風進行音頻採集,並使用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();
}
效果圖如下