You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QT Audio框架中QAudioSink获取音频样本:notify()信号未找到求助

解决QAudioSink无法触发notify()信号及获取音频样本的问题

一、修复notify()信号无法触发的问题

QAudioSink的notify()信号确实存在,但需要满足两个前提才会生效:

  1. 必须先调用setNotifyInterval()设置通知间隔(单位:毫秒),否则信号永远不会触发
  2. 建议使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:05:22