Qt QAudioOutput 推送模式

标签 qt audio

我有一个关于使用 QAudioOutput 以特定采样率直接将样本写入声音输出设备的问题。我正在编写一个模拟器,以每帧为基础模拟声音芯片,然后获取一个包含一帧音频样本的缓冲区,我想将其写入音频输出。目前,为了测试我的音频输出例程,我分配了一个巨大的(5 分钟)缓冲区来放入随机数,如下所示:

标题:

uint16_t *audio_outputBuffer;
uint32_t audio_bytesRemainingToRead;
QAudioOutput *audio_outputStream;
QIODevice *audio_outputDevice;

执行:
audio_outputBuffer = (uint16_t *) malloc((96000 * 4) * 300);
int i = 0;

uint16_t *tempAudioBuffer = audio_outputBuffer;
for(i = 0; i < ((96000 * 4) * 150); i++) {
    *tempAudioBuffer = (uint16_t) rand() & 0xFFFF;
    tempAudioBuffer++;
}

audio_bytesRemainingToRead = (96000 * 4) * 300;

接下来,我使用一些基本参数设置我的音频设备:
// Set up the format
QAudioFormat format;
format.setFrequency(96000); // Usually this is specified through an UI option
format.setChannels(2);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);

// There's code here to notify the user of inability to match the format and choose an action, which is omitted for clarity

// Create audio output stream, set up signals
audio_outputStream = new QAudioOutput(format, this);

connect(audio_outputStream, SIGNAL(stateChanged(QAudio::State)), this, SLOT(audio_stateChanged(QAudio::State)));

audio_outputDevice = audio_outputStream->start();

然后,在由 QTimer 以 60 FPS 调用的计时器滴答例程中,我执行以下代码将音频数据的“块”写入 QAudioOutput 的缓冲区:
if(audio_outputDevice->isOpen() && audio_outputStream->state() != QAudio::StoppedState) {
    qint64 bytesOfAudioWrittenToDevice = audio_outputDevice->write((char *) audio_outputBuffer, audio_outputStream->periodSize());
    audio_bytesRemainingToRead -= bytesOfAudioWrittenToDevice;
    qDebug() << "Wrote" << bytesOfAudioWrittenToDevice << "bytes of audio to output device. Remaining bytes to read:" << audio_bytesRemainingToRead;
    qDebug() << "Free bytes in audio output:" << audio_outputStream->bytesFree();
}

开始音频输出过程后,我会在控制台上得到以下输出:
Current audio state: 3 Error: 0 
Wrote 2048 bytes of audio to output device. Remaining bytes to read: 115197952 
Free bytes in audio output: 6144 
Current audio state: 0 Error: 0 
Wrote 2048 bytes of audio to output device. Remaining bytes to read: 115195904 
Free bytes in audio output: 4096 
Wrote 2048 bytes of audio to output device. Remaining bytes to read: 115193856 
Free bytes in audio output: 2048
Wrote 2048 bytes of audio to output device. Remaining bytes to read: 115191808 
Free bytes in audio output: 0 (This and the above line is repeated forever)

对我来说,看起来 QAudioOutput 没有将它的内部缓冲区刷新到声卡,这与整个“我的电脑没有声音”的事情是一致的。

什么会导致这个问题,我该如何解决?

(顺便说一下,我正在 Mac OS X 10.7.4 上针对 Qt 4.8.1 编译我的代码。)

感谢您提供任何答案。

最佳答案

前面只是想指出:这不是 Qt 错误。为什么?答案是在 WAV 规范中,8 位样本总是无符号的,而 16 位样本总是有符号的。任何其他组合都不起作用。这是设备相关的,框架对此无能为力。

所以这将不起作用,因为您已经设置了 16 位样本大小和无符号整数格式。
是的,解决方案是:您必须将样本类型设置为 16 位分辨率的签名:

format.setSampleType(QAudioFormat::SignedInt);

相反,对于 8 位样本,您必须输入:
format.setSampleType(QAudioFormat:UnsignedInt);

此外,这个非常相似的问题(相同的问题,但使用 8 位)向您表明,在 Qt 中使用有符号或无符号样本并不是一个特殊问题,而是样本大小和类型的组合很重要(对于音频设备) , 不适用于 Qt ;) QAudioOutput in Qt5 is not producing any sound

恕我直言,Qt 没有通过强制正确的格式来处理这些情况是一个缺陷,但并非缺乏功能。

您可以在本页的注释部分了解更多相关信息:https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

关于Qt QAudioOutput 推送模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15651407/

相关文章:

iphone - 如何使用音频队列服务播放下一个文件

c++ - Qt 在背景项上传播绘制事件

qt - 我如何实现按钮,该按钮包含一个操作(QAction)并且可以在 QtDesigner 的设计时与一个连接?

audio - 声音剪辑在LiveCode中不起作用

python - 峰值频率python的时间戳

c# - 如何将计算机音频传递给程序以进行可视化?

c++ - 使 TableView 的列适合其内容的大小

qt - 在Windows中从Qt使用Google Test

macos - 在 MacOS X 下使用 Qt 在前台启动应用程序

java - Java的AudioFormat.isBigEndian和AudioFormat.Encoding.PCM_SIGNED的C#等效项