Qt QAudioOutput推模式

Tri*_*ert 5 audio qt

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

标题:

uint16_t *audio_outputBuffer;
uint32_t audio_bytesRemainingToRead;
QAudioOutput *audio_outputStream;
QIODevice *audio_outputDevice;
Run Code Online (Sandbox Code Playgroud)

执行:

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;
Run Code Online (Sandbox Code Playgroud)

接下来,我使用一些基本参数设置我的音频设备:

// 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();
Run Code Online (Sandbox Code Playgroud)

然后,在我的计时器刻度例程(由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();
}
Run Code Online (Sandbox Code Playgroud)

一旦我开始音频输出过程,我在控制台上得到以下输出:

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)
Run Code Online (Sandbox Code Playgroud)

对我来说,看起来QAudioOutput没有将它的内部缓冲区刷新到声卡上,这与整个"没有声音从我的计算机中传出"的东西一起发生.

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

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

谢谢你的回答.

Tch*_*bam 8

Upfront只想指出:这不是 Qt错误.为什么?答案是,在WAV规范中,8位采样始终是无符号的,而16位采样始终是有符号的.任何其他组合都不起作用.这与设备有关,框架无法做任何事情.

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

format.setSampleType(QAudioFormat::SignedInt);
Run Code Online (Sandbox Code Playgroud)

相反,对于8位样本,您必须放置:

format.setSampleType(QAudioFormat:UnsignedInt);
Run Code Online (Sandbox Code Playgroud)

另外这个非常相似的问题(同样的问题,但是有8位)向你展示了在Qt中使用有符号或无符号样本不是特别的问题,但它是重要的样本大小和类型的组合(对于音频设备) ,不适用于Qt;)Qt5中的QAudioOutput没有产生任何声音

恕我直言,Qt没有通过强制正确的格式来处理这些案件这一事实是一个缺陷,但并不缺乏功能性.

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