Qt文档阅读笔记-Audio Example解析
Posted IT1995
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt文档阅读笔记-Audio Example解析相关的知识,希望对你有一定的参考价值。
这个例子很有意思,今天分析了下,在此记录下笔记,方便下次查阅。
这个例子展示了画动态数据(麦克风输入的数据)
界面如下:
关键文件如下:
这里官方给出的解释就没了,后面我自己补充下。
首先要学习两个类,分别是:QAudioInput和QAudioFormat
具体可以查本人的这篇博文-Qt文档阅读笔记-QAudioInput&QAudioFormat解析与实例。
首先在main.cpp中的关键代码:
const QAudioDeviceInfo inputDevice = QAudioDeviceInfo::defaultInputDevice();
if (inputDevice.isNull())
QMessageBox::warning(nullptr, "audio",
"There is no audio input device available.");
return -1;
这里查询了当前系统中是否设置了麦克风,如果没有,就直接退出了。
在Widget.cpp中配置了QAudioFormat相关属性,如下:
QAudioFormat formatAudio;
formatAudio.setSampleRate(8000);
formatAudio.setChannelCount(1);
formatAudio.setSampleSize(8);
formatAudio.setCodec("audio/pcm");
formatAudio.setByteOrder(QAudioFormat::LittleEndian);
formatAudio.setSampleType(QAudioFormat::UnSignedInt);
参数 | 描述 |
Sample Rate | 每秒音频的Hertz |
Number of channels | 单声道还是双声道 |
Sample size | 数据按8位存还是16位存 |
Sample type | 存储的类型是int还是unsigned int还是float |
Byte order | 存成大端还是小端 |
最后说下最有意思的类XYSeriesIODevice。对应的
xyseriesiodevice.h:
#ifndef XYSERIESIODEVICE_H
#define XYSERIESIODEVICE_H
#include <QtCore/QIODevice>
#include <QtCore/QPointF>
#include <QtCore/QVector>
#include <QtCharts/QChartGlobal>
QT_CHARTS_BEGIN_NAMESPACE
class QXYSeries;
QT_CHARTS_END_NAMESPACE
QT_CHARTS_USE_NAMESPACE
class XYSeriesIODevice : public QIODevice
Q_OBJECT
public:
explicit XYSeriesIODevice(QXYSeries *series, QObject *parent = nullptr);
static const int sampleCount = 2000;
protected:
qint64 readData(char *data, qint64 maxSize) override;
qint64 writeData(const char *data, qint64 maxSize) override;
private:
QXYSeries *m_series;
QVector<QPointF> m_buffer;
;
#endif // XYSERIESIODEVICE_H
xyseriesiodevice.cpp:
#include "xyseriesiodevice.h"
#include <QtCharts/QXYSeries>
#include <QDebug>
XYSeriesIODevice::XYSeriesIODevice(QXYSeries *series, QObject *parent) :
QIODevice(parent),
m_series(series)
qint64 XYSeriesIODevice::readData(char *data, qint64 maxSize)
Q_UNUSED(data)
Q_UNUSED(maxSize)
return -1;
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)
m_buffer[s].setY(qreal(uchar(*data) - 128) / qreal(128));
m_series->replace(m_buffer);
return (sampleCount - start) * resolution;
这里最关键的代码是这个:
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)
m_buffer[s].setY(qreal(uchar(*data) - 128) / qreal(128));
m_series->replace(m_buffer);
return (sampleCount - start) * resolution;
整个曲线x轴长度是:
static const int sampleCount = 2000;
y轴长度:
axisY->setRange(-1, 1);
音频大小是:
formatAudio.setSampleType(QAudioFormat::UnSignedInt);
这个函数data每次会传320个字节过来,换成UnsignedInt就是80个UnsignedInt。
下面这一段是对x轴数据都初始化:
if (m_buffer.isEmpty())
m_buffer.reserve(sampleCount);
for (int i = 0; i < sampleCount; ++i)
m_buffer.append(QPointF(i, 0));
下面是将数据网x轴左方向移动1920个坐标:
if (availableSamples < sampleCount)
start = sampleCount - availableSamples;
for (int s = 0; s < start; ++s)
m_buffer[s].setY(m_buffer.at(s + availableSamples).y());
将刚刚采集的音频放到最后80坐标里面(1920~2000)
for (int s = start; s < sampleCount; ++s, data += resolution)
m_buffer[s].setY(qreal(uchar(*data) - 128) / qreal(128));
这里-128是为了使得y轴有负数,除以128是因为。
axisY->setRange(-1, 1);
Y轴坐标是-1,到1之间。
以上是关于Qt文档阅读笔记-Audio Example解析的主要内容,如果未能解决你的问题,请参考以下文章
Qt文档阅读笔记-Simple Chat Example解析
Qt文档阅读笔记-Broadcast Sender Example解析
Qt文档阅读笔记-QtConcurrent Progress Dialog Example解析
Qt文档阅读笔记-Broadcast Receiver Example解析