QAudioSource Class
QAudioSource 类提供了一个用于从音频输入设备接收音频数据的接口。更多内容...
| 头文件: | #include <QAudioSource> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Multimedia) target_link_libraries(mytarget PRIVATE Qt6::Multimedia) |
| qmake: | QT += multimedia |
| 继承自: | QObject |
公共函数
| QAudioSource(const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr) | |
| QAudioSource(const QAudioDevice &audioDevice, const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr) | |
| virtual | ~QAudioSource() override |
(since 6.10) qsizetype | bufferFrameCount() const |
| qsizetype | bufferSize() const |
| qsizetype | bytesAvailable() const |
| qint64 | elapsedUSecs() const |
| QtAudio::Error | error() const |
| QAudioFormat | format() const |
(since 6.10) qsizetype | framesAvailable() const |
| bool | isNull() const |
(since 6.12) qsizetype | nativePeriodFrameCount() const |
| qint64 | processedUSecs() const |
| void | reset() |
| void | resume() |
(since 6.10) void | setBufferFrameCount(qsizetype value) |
| void | setBufferSize(qsizetype value) |
(since 6.12) void | setNativePeriodFrameCount(qsizetype frameCount) |
| 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 来创建QAudioSource。在创建音频输入时,还应传入用于录音的QAudioFormat (详情请参阅QAudioFormat 类的描述)。
QAudioSink 可在两种不同模式下使用:
- 从应用程序线程使用QIODevice
- 从音频线程使用基于回调的接口
QIODevice 接口
QAudioSource 允许您使用音频输入设备录制音频。该类的默认构造函数将使用系统的默认音频设备,但您也可以指定一个QAudioDevice 来指定特定设备。此外,您还需要传入希望用于录制的QAudioFormat 。
启动 QAudioSource 只需调用start() 并传入一个已打开且支持写入的QIODevice 即可。例如,若要录制到文件中,您可以:
QFile destinationFile;// 类成员
QAudioSource*audio; // 类成员
{
destinationFile.setFileName("/tmp/test.raw");
destinationFile.open( QIODevice::WriteOnly|QIODevice::Truncate );
QAudioFormat format;
// 设置所需的格式,例如:
format.setSampleRate(44100);
format.setChannelCount(1);
format.setSampleFormat(QAudioFormat::Int16);
QAudioDevice info=QMediaDevices::defaultAudioInput();
if(!info.isFormatSupported(format)) {
qWarning() << "Default format not supported, trying to use the nearest.";
}
audio= newQAudioSource(格式, this);
connect(audio, &QAudioSource::stateChanged, this, &AudioInputExample::handleStateChanged);
QTimer::singleShot(3000, this, &AudioInputExample::stopRecording);
audio->start(&destinationFile);
// 录制音频 3000 毫秒
}如果输入设备支持指定的格式(可通过 `QAudioDevice::isFormatSupported()` 进行检查),则将开始录音。若遇到任何问题,请使用 `error()` 函数检查具体原因。我们在 `stopRecording() ` 槽中停止录音。
void AudioInputExample::stopRecording()
{
audio->stop();
destinationFile.close();
delete audio;
}在任何时刻,QAudioSource 都会处于以下四种状态之一:活动、暂停、停止或空闲。这些状态由QtAudio::State 枚举类型指定。
QAudioSource 提供了多种方法来测量自录音开始(start())以来经过的时间。processedUSecs() 函数返回已写入流的长度(单位为微秒),即不包含音频输入处于暂停或空闲状态的时间。elapsedUSecs()函数返回自调用start()以来经过的时间,无论QAudioSource此前处于何种状态。
线程模型与缓冲
QIODevice 接口设计为在应用程序线程中使用。它采用无等待环形缓冲区与音频线程进行通信。该环形缓冲区的大小可通过setBufferSize()进行配置,默认值为250毫秒。 可通过 bytesFree() 查询该缓冲区的状态。如果由于应用程序未能及时从QIODevice 读取数据导致环形缓冲区已满,状态将变为QtAudio::IdleState ;一旦应用程序从QIODevice 读取了数据,状态将恢复为QtAudio::ActiveState 。请注意,这种状态变化会导致音频数据丢失,因此应始终尽可能快速地从QIODevice 读取数据,以避免音频中断。
回调接口
实现低音频延迟的首选方法是使用基于回调的接口。它允许您直接从音频设备读取音频数据,而无需通过QIODevice 。具体操作是调用start(),并传入一个将在音频线程中被调用的回调函数。 每当音频后端生成数据时,该回调函数都会被调用,并传入一个QSpan<const SampleType>对象。
QAudioSource*audio; // 类成员。
std::atomic<float>peakLevel;// 类成员。
{
QAudioFormat format;
// 配置格式,例如:
format.setSampleRate(44100);
format.setChannelCount(2);
format.setSampleFormat(QAudioFormat::Float);
QAudioDevice info(QMediaDevices::defaultAudioOutput());
if(!info.isFormatSupported(format)) {
qWarning() << "Raw audio format not supported by backend, cannot capture audio.";
return;
}
audio= newQAudioSource(format, this);
audio->start([&peakLevel](QSpan<float>interleavedAudioBuffer) {
floatlevel=peakLevel.load();
for(floatsample : interleavedAudioBuffer) {
// 根据音频采样计算峰值电平
level=std::max(level,std::abs(sample));
}
peakLevel.store(level);
// 注意:如果需要通知应用程序线程,则需格外谨慎,因为
// 音频回调不应使用任何可能导致阻塞的系统调用。
// 推荐的方案包括自动重置事件(Windows)、eventfd(Linux)或 macOS 上的 kqueue/EVFILT_USER。
});
if(!audio->error()== QtAudio::Error::NoError) {
// 除了其他 start() 签名外,如果出现以下情况,启动音频回调将失败:
// * 后端未实现基于回调的 I/O(该 API 在所有主要
// 平台上均 可用 )
// * 音频回调的签名与 format.sampleFormat() 不匹配
qWarning() << "Error starting audio output:" << audio->errorString();
}
}与基于QIODevice 的接口不同,QAudioSource 只能处于 active、suspended 和 stopped 这三种状态。使用回调时,setBufferSize() API 不可用,回调参数的大小由音频后端决定。
注意:此 API 仅在支持回调 API 的平台上可用:Apple 的 CoreAudio(macOS、iOS 等)、Windows、Linux(使用 PulseAudio 或 PipeWire 后端)以及 Android。
注意:回调 将在软实时音频线程上被调用。必须确保回调不会阻塞,否则可能会导致音频故障或音频中断。这包括执行阻塞式 I/O、锁定互斥量、分配内存或任何其他可能导致阻塞的操作。 有关最佳实践,请参阅 Ross Bencina 的文章《实时音频编程入门:时间不等人》。同时建议使用 clang的实时检查器(Realtime sanitizer)来验证音频回调函数。
状态与错误处理
状态变化通过stateChanged()信号进行报告。您可以通过suspend()、resume()、stop()、reset()和start()直接请求状态变化。
当遇到错误时,QAudioSource将进入StoppedState 状态。可通过error()函数获取error type 。有关可能报告的错误的说明,请参阅QtAudio::Error 枚举。调用stop()或reset()将把错误状态重置为NoError 。
void AudioInputExample::handleStateChanged(QtAudio::State newState)
{
switch (newState) {
case QtAudio::StoppedState:
if (audio->error() != QtAudio::NoError) {
// Error handling
} else {
// Finished recording
}
break;
case QtAudio::ActiveState:
// Started recording - read from IO device
break;
default:
// ... other cases as appropriate
break;
}
}另请参阅 QAudioSink 和QAudioDevice 。
成员函数文档
[explicit] QAudioSource::QAudioSource(const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr)
创建一个新的音频输入,并将其连接到parent 。该参数将使用默认的音频输入设备,其输出参数为format 。如果format 采用默认初始化,则格式将设置为该音频设备的首选格式。
[explicit] QAudioSource::QAudioSource(const QAudioDevice &audioDevice, const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr)
创建一个新的音频输入,并将其连接到parent 。audioDevice 所引用的设备将与输入参数format 配合使用。如果format 采用默认初始化,则格式将设置为audioDevice 的首选格式。
[override virtual noexcept] QAudioSource::~QAudioSource()
销毁这个音频输入。
[since 6.10] qsizetype QAudioSource::bufferFrameCount() const
返回以帧为单位的音频缓冲区大小。
如果在调用start()之前调用此函数,则返回平台的默认值。如果在调用start() 之前调用此函数,但此前已调用setBufferSize()或setBufferFrameCount(),则返回由setBufferSize() 或setBufferFrameCount() 设置的值。如果在调用start() 之后调用此函数,则返回当前实际使用的缓冲区大小。该值可能与先前通过setBufferSize() 或setBufferFrameCount() 设置的值不一致。
该函数在 Qt 6.10 中引入。
另请参阅 setBufferFrameCount() 和bufferSize 。
qsizetype QAudioSource::bufferSize() const
返回音频缓冲区的大小(以字节为单位)。
如果在调用 `start()` 之前调用本函数,则返回平台的默认值。如果在调用 `start() ` 之前调用本函数,但此前已调用过 `setBufferSize()` 或 `setBufferFrameCount()`,则返回由 `setBufferSize() ` 或 `setBufferFrameCount()` 设置的值。如果在调用 `start()` 之后调用本函数,则返回当前实际使用的缓冲区大小。该值可能与先前通过 `setBufferSize() ` 或 `setBufferFrameCount()` 设置的值不一致。
另请参阅 setBufferSize() 和bufferFrameCount 。
qsizetype QAudioSource::bytesAvailable() const
返回可供读取的音频数据量(以字节为单位)。
注意:返回 值仅在处于“QtAudio::ActiveState ”或“QtAudio::IdleState ”状态时有效,否则返回零。
另请参阅 framesAvailable 。
qint64 QAudioSource::elapsedUSecs() const
返回自调用start()以来经过的微秒数,包括处于空闲和挂起状态的时间。
QtAudio::Error QAudioSource::error() const
返回错误状态。
QAudioFormat QAudioSource::format() const
返回当前正在使用的QAudioFormat 。
[since 6.10] qsizetype QAudioSource::framesAvailable() const
返回可按帧读取的音频数据量。
注意:返回值仅在处于QtAudio::ActiveState 或QtAudio::IdleState 状态时有效,否则返回零。
该函数于 Qt 6.10 中引入。
另请参阅 bytesAvailable 。
bool QAudioSource::isNull() const
如果音频源为null ,则返回true ;否则返回false 。
[since 6.12] qsizetype QAudioSource::nativePeriodFrameCount() const
返回本机周期帧数。
若未设置,则返回 -1;否则返回先前通过 `setNativePeriodFrameCount()` 设置的值。
该函数自 Qt 6.12 起引入。
另请参阅 setNativePeriodFrameCount 。
qint64 QAudioSource::processedUSecs() const
返回自调用start()以来处理的音频数据量,单位为微秒。
void QAudioSource::reset()
清除缓冲区中的所有音频数据,并将缓冲区重置为零。
void QAudioSource::resume()
在调用suspend()之后,恢复处理音频数据。
将state() 设置为调用suspend() 时音频接收端所处的状态。如果音频接收端的状态不是QtAudio::SuspendedState ,则此函数不执行任何操作。
[since 6.10] void QAudioSource::setBufferFrameCount(qsizetype value)
将音频缓冲区大小设置为value 帧。
注意:此 函数可在调用start() 之前随时调用。在调用start() 之后,对该函数的调用将被忽略。不应假设所设置的缓冲区大小即为实际使用的缓冲区大小——请在调用start() 之后随时调用bufferFrameCount() 以获取当前实际使用的缓冲区大小。
bufferFrameCount() 和bufferSize() 属性表示使用QIODevice API 时的环形缓冲区大小。原生周期大小通过setNativePeriodFrameCount() 进行控制。
该函数在 Qt 6.10 中引入。
另请参阅 bufferFrameCount() 和setBufferSize 。
void QAudioSource::setBufferSize(qsizetype value)
将音频缓冲区大小设置为value 字节。
注意:此 函数可在调用start() 之前随时调用,但在调用start() 之后对该函数的调用将被忽略。不应假设所设置的缓冲区大小即为实际使用的缓冲区大小,在调用start() 之后任何时候调用bufferSize() 都将返回当前实际使用的缓冲区大小。
bufferFrameCount() 和bufferSize() 属性表示使用QIODevice API 时的环形缓冲区大小。原生周期大小通过setNativePeriodFrameCount() 进行控制。
另请参阅 bufferSize() 和setBufferFrameCount 。
[since 6.12] void QAudioSource::setNativePeriodFrameCount(qsizetype frameCount)
将原生周期帧数设置为frameCount 。
调整操作系统和硬件使用的音频缓冲区大小。默认情况下(未设置时),系统使用一个与平台相关的值,通常为 1024 个帧(在 44100 Hz 时约为 23 毫秒)。
使用较小的数值(64-256)可降低延迟,使用较大的数值(2048-4096)可降低缓冲区溢出(音频丢失)的风险。
有效值为 32 到 4096 之间的 2 的幂(含边界值),或 -1 表示未设置。仅可在音频源已停止时调用。
映射到平台特定的设置:kAudioDevicePropertyBufferFrameSize (macOS)、IAudioClient::bufferDuration (Windows)、PW_KEY_NODE_FORCE_QUANTUM (PipeWire/Linux)和AAudioStreamBuilder_setBufferCapacityInFrames (Android)。
注意:这 与通过setBufferSize() 或setBufferFrameCount() 配置的环形缓冲区是分开的。
该函数在 Qt 6.12 中引入。
另请参阅 nativePeriodFrameCount 。
void QAudioSource::setVolume(qreal volume)
将输入音量设置为volume 。
音量会从0.0 (静音)线性调整至1.0 (最大音量)。超出此范围的值将被限制。
如果设备不支持调节输入音量,则volume 将被忽略,输入音量将保持在1.0。
默认音量为1.0 。
注意: 音量调整 将改变此音频流的音量,而非全局音量。
另请参阅 volume()。
QIODevice *QAudioSource::start()
返回一个指向内部QIODevice 的指针,该指针用于从系统的音频输入端传输数据。该设备此时已处于打开状态,可直接调用read()从其读取数据。
注意: 在流停止后或启动另一个流时,该 指针将失效。
如果QAudioSource 能够访问系统的音频设备,则state()将返回QtAudio::IdleState ,error()将返回QtAudio::NoError ,并发出stateChanged()信号。
如果在此过程中发生问题,error() 将返回QtAudio::OpenError ,state() 将返回QtAudio::StoppedState ,并触发stateChanged() 信号。
另请参阅 QIODevice 和QIODevice interface 。
[since 6.11] template <typename Callback> requires QtAudio::if_audio_source_callback<Callback> void QAudioSource::start(Callback &&cb)
使用一个回调函数启动QAudioSource ,该回调函数将在软实时音频线程上被调用。该回调函数是一个可调用对象,其参数为QSpan<const SampleType>,其中SampleType必须与QAudioSource 格式的QAudioFormat::SampleFormat 相匹配。该span包含交织的音频数据。
如果QAudioSource 能够成功启动,则error()会返回QtAudio::NoError 。
如果在此过程中发生问题,error() 将返回QtAudio::OpenError ,state() 将返回QtAudio::StoppedState ,并触发stateChanged() 信号。
注意:此 API 仅在支持回调 API 的平台上可用:Apple 的 CoreAudio(macOS、iOS 等)、Windows、Linux(使用 PulseAudio 或 PipeWire 后端)以及 Android。
注意:回调 将在软实时音频线程上被调用。必须确保回调不会阻塞,否则可能会导致音频卡顿或掉帧。这包括执行阻塞式 I/O、锁定互斥锁、分配内存或任何其他可能导致阻塞的操作。 有关最佳实践,请参阅 Ross Bencina 的文章《实时音频编程入门:时间不等人》。同时建议使用 clang的实时验证器(Realtime sanitizer)来验证音频回调函数。
该函数于 Qt 6.11 中引入。
另请参阅 Callback interface 。
void QAudioSource::start(QIODevice *device)
开始将音频数据从系统的音频输入端传输到device 。device 必须已在WriteOnly 、Append 或ReadWrite 模式下被打开。
如果QAudioSource 能够成功获取音频数据,则state()将返回QtAudio::ActiveState 或QtAudio::IdleState ,error()将返回QtAudio::NoError ,并触发stateChanged()信号。
如果在此过程中发生问题,error() 将返回QtAudio::OpenError ,state() 将返回QtAudio::StoppedState ,并发出stateChanged() 信号。
另请参阅 QIODevice 和QIODevice interface 。
QtAudio::State QAudioSource::state() const
返回音频处理的状态。
[signal] void QAudioSource::stateChanged(QtAudio::State state)
当设备state 发生变化时,会发出此信号。
注意: 在 Qt 6.6 及更早版本中,QtAudio 的命名空间名为 QAudio。与此信号建立基于字符串的连接时,必须使用QAudio::State 作为参数类型:connect(source, SIGNAL(stateChanged(QAudio::State)), ...);
void QAudioSource::stop()
停止音频输入,并从系统资源中断开连接。
将error()设置为QtAudio::NoError ,将state()设置为QtAudio::StoppedState ,并触发stateChanged()信号。
void QAudioSource::suspend()
停止处理音频数据,同时保留缓冲的音频数据。
将error()设置为QtAudio::NoError ,将state()设置为QtAudio::SuspendedState ,并发出stateChanged()信号。
qreal QAudioSource::volume() const
返回输入音量。
如果设备不支持调节输入音量,则返回值为 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.