在本页

QAudioSink Class

QAudioSink 类提供了一个向音频输出设备发送音频数据的接口。更多

头文件: #include <QAudioSink>
CMake.QAudioSink 类 find_package(Qt6 REQUIRED COMPONENTS Multimedia)
target_link_libraries(mytarget PRIVATE Qt6::Multimedia)
qmake: QT += multimedia
继承: QObject

公共函数

QAudioSink(const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr)
QAudioSink(const QAudioDevice &audioDevice, const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr)
virtual ~QAudioSink() override
(since 6.10) qsizetype bufferFrameCount() const
qsizetype bufferSize() const
qsizetype bytesFree() const
qint64 elapsedUSecs() const
QtAudio::Error error() const
QAudioFormat format() const
(since 6.10) qsizetype framesFree() const
bool isNull() const
qint64 processedUSecs() const
void reset()
void resume()
(since 6.10) void setBufferFrameCount(qsizetype value)
void setBufferSize(qsizetype value)
void setVolume(qreal volume)
QIODevice *start()
(since 6.11) void start(Callback &&cb)
void start(QIODevice *device)
QtAudio::State state() const
void stop()
void suspend()
qreal volume() const

信号

void stateChanged(QtAudio::State state)

详细说明

您可以使用系统默认的音频输出设备构建音频输出。也可以使用特定的QAudioDevice 创建 QAudioSink。创建音频输出时,您还应发送用于播放的QAudioFormat (详见QAudioFormat 类说明)。

QAudioSink 可在两种不同模式下使用:

  • 从应用程序线程使用QIODevice
  • 从音频线程使用基于回调的接口

QIODevice 接口

开始播放音频流时,只需调用start() 并输入QIODevice 。然后,QAudioSink 就会从 io 设备获取所需的数据。因此,播放音频文件的过程非常简单:

QFilesourceFile;// 类成员。QAudioSink*audio;// class member.{ sourceFile.setFileName("/tmp/test.raw"); sourceFile.open(QIODevice::ReadOnly);    QAudioFormatformat;// 设置格式,例如format.setSampleRate(44100); format.setChannelCount(1); format.setSampleFormat(QAudioFormat::Int16);    QAudioDeviceinfo(QMediaDevices::defaultAudioOutput());if(!info.isFormatSupported(format)) {        qWarning() << "Raw audio format not supported by backend, cannot play audio.";
       return; } audio= newQAudioSink(format, this); connect(audioQAudioSink::stateChanged, this, &AudioInputExample::handleStateChanged); audio->start(&sourceFile); }

假设音频系统和输出设备支持该文件,文件就会开始播放。如果运气不佳,请检查error() 函数是否有问题。

文件播放完毕后,我们需要停止设备:

void AudioOutputExample::stopAudioOutput()
{
    audio->stop();
    sourceFile.close();
    delete audio;
}

在任何时候,QAudioSink 都会处于以下四种状态之一:激活、暂停、停止或空闲。这些状态由QtAudio::State 枚举描述。

线程模型和缓冲

QIODevice 接口设计用于应用程序线程。无等待环形缓冲区用于与音频线程通信。环形缓冲区的大小可通过setBufferSize() 进行配置,默认为 250 毫秒。该缓冲区的状态可通过bytesFree() 查询。如果 ringbuffer 中的数据用完,音频线程将向音频设备发送静音,状态将变为QtAudio::IdleState ,当QIODevice 中有更多数据时,状态将恢复为QtAudio::ActiveState

回调接口

实现低音频延迟的首选方法是使用基于回调的接口。它允许您直接向音频设备写入音频数据,而无需通过QIODevice 。具体方法是调用start(),并在音频线程中调用回调函数。每当音频后端需要数据时,就会以QSpan<SampleType> 调用该回调函数。

QAudioSink*floatphase;//  class  member.   QAudioFormatformat;// 设置格式,例如format.setSampleRate(44100); format.setChannelCount(2); format.setSampleFormat(QAudioFormat::Float);    QAudioDeviceinfo(QMediaDevices::defaultAudioOutput());if(!info.isFormatSupported(format)) {        qWarning() << "Raw audio format not supported by backend, cannot play audio.";
       return; } audio= newQAudioSink(format, this);floatphaseIncrement= 2 *M_PI* 220.0 /format.sampleRate();// 220 Hz 正弦波 audio->start([&phase,phaseIncrement](QSpan<float>interleavedAudioBuffer) {// 音频回调不应调用任何可能阻塞的函数 // 用正弦波填充音频缓冲区 const intsampleCount=interleavedAudioBuffer.size()/ 2;// Stereo, so divide by 2 for(inti= 0; i<sampleCount;++i) {floatsample=std::sin(phase); interleavedAudioBuffer[i* 2] =sample;// Left channelinterleavedAudioBuffer[i* 2 + 1] =sample;// Right channelphase+=phaseIncrement;//Increment phase for next sample} });if(audio->error()== QtAudio::Error::NoError) {// 除了其他 start() 签名外,如果 // * 后端没有实现基于回调的 IO(所有主要 // 平台 都有该 API  ,启动音频回调将失败 // * 音频回调的签名与 format.sampleFormat() 不匹配
        qWarning() << "Error starting audio output:" << audio->errorString();
    } }

与基于QIODevice 的接口不同,QAudioSink 只能处于激活、暂停和停止状态。使用回调时,setBufferSize() API 不可用,回调参数的大小由音频后端决定。

注意: 该 API 仅适用于支持回调 API 的平台:苹果的 CoreAudio(macOS、iOS 等)、Windows、Linux(使用 PulseAudio 或 PipeWire 后端)和安卓。

注意: 回调将在软实时音频线程上调用。必须确保回调不会阻塞,因为这可能会导致音频中断或掉线。这包括执行阻塞 IO、锁定互斥、分配内存或任何其他可能阻塞的操作。有关最佳实践,请参考 Ross Bencina 的文章《实时音频编程 101:时间不等人。还可以考虑使用 clang 的实时 sanitizer验证音频回调。

状态和错误处理

状态变化通过stateChanged() 信号报告。例如,您可以使用该信号更新应用程序的图形用户界面;这里的普通例子就是更改play/pause 按钮的状态。您可以通过suspend(),stop(),reset(),resume() 和start() 直接请求状态更改。

当遇到错误时,QAudioSink 将进入StoppedState 。可使用error() 函数检索error type 。有关可能报告的错误的描述,请参阅QtAudio::Error 枚举。调用stop() 或reset() 会将错误状态重置为NoError

您可以通过连接stateChanged() 信号来检查错误:

void AudioOutputExample::handleStateChanged(QtAudio::State newState)
{
    switch (newState) {
        case QtAudio::IdleState:
            // Finished playing (no more data)
            AudioOutputExample::stopAudioOutput();
            break;

        case QtAudio::StoppedState:
            // Stopped for other reasons
            if (audio->error() != QtAudio::NoError) {
                // Error handling
            }
            break;

        default:
            // ... other cases as appropriate
            break;
    }
}

另请参阅 QAudioSourceQAudioDevice

成员函数文档

[explicit] QAudioSink::QAudioSink(const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr)

构建新的音频输出并将其附加到parent 。默认音频输出设备与输出format 参数一起使用。如果format 被默认初始化,格式将被设置为音频设备的首选格式。

[explicit] QAudioSink::QAudioSink(const QAudioDevice &audioDevice, const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr)

构建一个新的音频输出,并将其连接到parent 。由audioDevice 引用的设备与输出format 参数一起使用。如果format 已默认初始化,则格式将设置为audioDevice 的首选格式。

[override virtual noexcept] QAudioSink::~QAudioSink()

销毁此音频输出。

这将释放所有已使用的系统资源和缓冲区。

[since 6.10] qsizetype QAudioSink::bufferFrameCount() const

返回音频缓冲区的大小(以帧为单位)。

如果在start() 之前调用,则返回平台默认值。如果在start() 之前调用,但之前调用过setBufferSize() 或setBufferFrameCount() ,则返回setBufferSize()setBufferFrameCount() 设置的值。如果在start() 之后调用,则返回实际使用的缓冲区大小。这可能与之前由setBufferSize()setBufferFrameCount() 设置的值不同。

此函数在 Qt 6.10 中引入。

另请参阅 setBufferFrameCount() 和bufferSize

qsizetype QAudioSink::bufferSize() const

以字节为单位返回音频缓冲区大小。

如果在start() 之前调用,则返回平台默认值。如果在start() 之前调用,但之前调用了setBufferSize() 或setBufferFrameCount() ,则返回setBufferSize()setBufferFrameCount() 设置的值。如果在start() 之后调用,则返回实际使用的缓冲区大小。这可能与setBufferSize()setBufferFrameCount() 之前设置的值不同。

另请参阅 setBufferSize() 和bufferFrameCount

qsizetype QAudioSink::bytesFree() const

返回音频缓冲区中可用的空闲字节数。

注意: 返回值只有在QtAudio::ActiveStateQtAudio::IdleState 状态下有效,否则返回 0。

另请参阅 framesFree

qint64 QAudioSink::elapsedUSecs() const

返回调用start() 后的微秒数,包括闲置和挂起状态下的时间。

QtAudio::Error QAudioSink::error() const

返回错误状态。

QAudioFormat QAudioSink::format() const

返回正在使用的QAudioFormat

[since 6.10] qsizetype QAudioSink::framesFree() const

返回音频缓冲区中可用的空闲帧数。

注意: 返回值仅在QtAudio::ActiveStateQtAudio::IdleState 状态下有效,否则返回 0。

此函数在 Qt 6.10 中引入。

另请参阅 bytesFree

bool QAudioSink::isNull() const

如果QAudioSink 实例是null ,则返回true ,否则返回false

qint64 QAudioSink::processedUSecs() const

返回调用start() 后处理的音频数据量(以微秒为单位)。

void QAudioSink::reset()

立即停止音频输出并丢弃当前缓冲区中的任何音频数据。推送到QIODevice 的所有待处理音频数据将被忽略。

另请参阅 stop() 。

void QAudioSink::resume()

suspend() 之后恢复处理音频数据。

state() 设置为调用suspend() 时音频汇的状态。如果音频 sink 的状态不是QtAudio::SuspendedState ,则此函数不会执行任何操作。

[since 6.10] void QAudioSink::setBufferFrameCount(qsizetype value)

将音频缓冲区大小设置为value (以帧数为单位)。

注意: 该函数可在start() 之前随时调用。start() 之后的调用将被忽略。不应认为所设置的缓冲区大小就是实际使用的缓冲区大小,在start() 之后随时调用bufferFrameCount() 可返回实际使用的缓冲区大小。

此函数在 Qt 6.10 中引入。

另请参阅 bufferFrameCount() 和setBufferSize

void QAudioSink::setBufferSize(qsizetype value)

将音频缓冲区的大小设置为value ,单位为字节。

注意: 该函数可在start() 之前随时调用。start() 之后的调用将被忽略。不应假定所设置的缓冲区大小就是实际使用的缓冲区大小,在start() 之后随时调用bufferSize() 可返回实际使用的缓冲区大小。

另请参阅 bufferSize() 和setBufferFrameCount

void QAudioSink::setVolume(qreal volume)

将输出音量设置为volume

音量从0.0 (静音)到1.0 (全音量)线性缩放。超出此范围的值将被箝位。

默认音量为1.0

注意: 调整音量将改变该音频流的音量,而不是全局音量。

用户界面音量控制通常应以非线性方式缩放。例如,使用对数刻度将使感知响度产生线性变化,这正是用户通常期望从音量控制中获得的效果。更多详情,请参阅QtAudio::convertVolume() 。

另请参见 volume().

QIODevice *QAudioSink::start()

返回用于向系统音频输出传输数据的内部QIODevice 的指针。该设备已经打开,write() 可以直接向其写入数据。

注意: 在停止数据流或启动另一个数据流后,指针将失效。

如果QAudioSink 能够访问系统的音频设备,state() 将返回QtAudio::IdleStateerror() 将返回QtAudio::NoError ,并发出stateChanged() 信号。

如果在此过程中出现问题,error() 将返回QtAudio::OpenError,state() 将返回QtAudio::StoppedState 并发出stateChanged() 信号。

另请参阅 QIODeviceQIODevice interface

[since 6.11] template <typename Callback, QtAudio::if_audio_sink_callback<Callback> = true> void QAudioSink::start(Callback &&cb)

使用回调函数启动QAudioSink ,该函数将在软实时音频线程上调用。回调函数是一个可调用的函数,它将QSpan<SampleType> 作为参数,SampleType 必须与QAudioSink 的格式QAudioFormat::SampleFormat 匹配。跨度需要用交错音频数据填充。

如果QAudioSink 能够成功启动,error() 将返回QtAudio::NoError

如果在此过程中出现问题,error() 将返回QtAudio::OpenErrorstate() 将返回QtAudio::StoppedState ,并发出stateChanged() 信号。

注意: 该 API 仅适用于支持回调 API 的平台:Apple 的 CoreAudio(macOS、iOS 等)、Windows、Linux(使用 PulseAudio 或 PipeWire 后端)和 Android。

注意: 回调将在软实时音频线程上调用。必须确保回调不会阻塞,因为这可能会导致音频故障或中断。这包括执行阻塞 IO、锁定互斥、分配内存或任何其他可能阻塞的操作。有关最佳实践,请参考 Ross Bencina 的文章:实时音频编程 101:时间不等人。还可以考虑使用 clang 的实时 sanitizer验证音频回调。

此函数在 Qt 6.11 中引入。

另请参见 Callback interface

void QAudioSink::start(QIODevice *device)

开始将音频数据从device 传输到系统的音频输出端。device 必须在ReadOnlyReadWrite 模式下打开。

如果QAudioSink 能够成功输出音频数据,state() 将返回QtAudio::ActiveStateerror() 将返回QtAudio::NoError ,并发出stateChanged() 信号。

如果在此过程中出现问题,error() 将返回QtAudio::OpenError,state() 将返回QtAudio::StoppedState 并发出stateChanged() 信号。

另请参阅 QIODeviceQIODevice interface

QtAudio::State QAudioSink::state() const

返回音频处理的状态。

[signal] void QAudioSink::stateChanged(QtAudio::State state)

该信号在设备state 发生变化时发出。这是音频输出的当前状态。

注: 在 Qt 6.6 之前(包括 Qt 6.6),QtAudio 命名空间名为 QAudio。该信号的字符串连接必须使用QAudio::State 作为参数类型:connect(source, SIGNAL(stateChanged(QAudio::State)), ...);

void QAudioSink::stop()

停止音频输出,脱离系统资源。

error() 设为QtAudio::NoError ,将state() 设为QtAudio::StoppedState ,并发出stateChanged() 信号。

注意: 在 Linux 和 Darwin 系统中,此操作会同步耗尽底层音频缓冲区,因此可能会导致缓冲区有效载荷延迟。要立即重置所有缓冲区,请使用reset 方法。

另请参阅 reset().

void QAudioSink::suspend()

停止处理音频数据,保留缓冲音频数据。

state() 设置为QtAudio::SuspendedState ,并发出stateChanged() 信号。

qreal QAudioSink::volume() const

返回介于 0.0 和 1.0 之间的体积。

另请参阅 setVolume()。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.