QT Audio框架中QAudioSink获取音频样本:notify()信号未找到求助
解决QAudioSink无法触发notify()信号及获取音频样本的问题
一、修复notify()信号无法触发的问题
QAudioSink的notify()信号确实存在,但需要满足两个前提才会生效:
- 必须先调用
setNotifyInterval()设置通知间隔(单位:毫秒),否则信号永远不会触发 - 建议使用Qt5及以上版本的新信号槽语法(编译时检查错误,避免宏定义的拼写问题)
修改后的代码示例:
QString Filename = "mysound.wav"; SourceAudio.setFileName(Filename); SourceAudio.open(QIODevice::ReadOnly); QAudioFormat audioFormat; audioFormat.setSampleRate(44100); audioFormat.setChannelCount(1); audioFormat.setSampleFormat(QAudioFormat::Int16); pAudioSink = new QAudioSink(audioFormat, this); // 设置通知间隔,比如每20毫秒触发一次 pAudioSink->setNotifyInterval(20); // 使用新信号槽语法替代SIGNAL/SLOT宏 connect(pAudioSink, &QAudioSink::stateChanged, this, &YourClass::HandleStateChanged); connect(pAudioSink, &QAudioSink::notify, this, &YourClass::processAudioIn); pAudioSink->start(&SourceAudio);
注意:如果仍提示信号不存在,检查是否包含了<QAudioSink>头文件,以及Qt版本是否低于Qt5(Qt4及更早版本的QAudioSink无此信号)。
二、更可靠的音频样本获取方式
依赖notify()信号只能按时间间隔触发,无法精准对应每一批被读取的音频样本。更直接的方式是自定义QIODevice子类,拦截QAudioSink的音频数据读取过程,实时获取样本:
1. 自定义处理设备类
#include <QIODevice> #include <QFile> class AudioProcessingDevice : public QIODevice { Q_OBJECT public: explicit AudioProcessingDevice(QFile *sourceFile, QObject *parent = nullptr) : QIODevice(parent), m_sourceFile(sourceFile) {} protected: // 重写readData,拦截音频数据读取 qint64 readData(char *data, qint64 maxSize) override { qint64 bytesRead = m_sourceFile->read(data, maxSize); if (bytesRead > 0) { // 根据音频格式转换为样本数组(这里对应Int16格式) qint16 *samples = reinterpret_cast<qint16*>(data); int sampleCount = bytesRead / sizeof(qint16); // 在这里处理音频样本,比如分析、存储等 processSamples(samples, sampleCount); // 也可以通过信号将样本传递到外部处理 emit samplesReady(samples, sampleCount); } return bytesRead; } // 只读设备无需实现writeData qint64 writeData(const char *data, qint64 maxSize) override { Q_UNUSED(data); Q_UNUSED(maxSize); return 0; } signals: void samplesReady(qint16 *samples, int count); private: void processSamples(qint16 *samples, int count) { // 示例:遍历处理每个样本 for (int i = 0; i < count; ++i) { // 自定义处理逻辑,比如归一化、滤波等 // samples[i] = ... } } QFile *m_sourceFile; };
2. 使用自定义设备
QString Filename = "mysound.wav"; QFile *sourceAudio = new QFile(Filename, this); sourceAudio->open(QIODevice::ReadOnly); // 创建自定义处理设备 AudioProcessingDevice *processingDevice = new AudioProcessingDevice(sourceAudio, this); processingDevice->open(QIODevice::ReadOnly); // 连接样本处理信号 connect(processingDevice, &AudioProcessingDevice::samplesReady, this, &YourClass::processAudioSamples); QAudioFormat audioFormat; audioFormat.setSampleRate(44100); audioFormat.setChannelCount(1); audioFormat.setSampleFormat(QAudioFormat::Int16); pAudioSink = new QAudioSink(audioFormat, this); connect(pAudioSink, &QAudioSink::stateChanged, this, &YourClass::HandleStateChanged); // 将自定义设备传给QAudioSink pAudioSink->start(processingDevice);
这种方式能保证每一批被QAudioSink读取的音频样本都被实时处理,比依赖notify()信号更精准可靠。
内容的提问来源于stack exchange,提问作者user4006295
相关产品推荐
相关产品推荐

