QAudioInput::byteReady()和QIODevice::read()返回的字节数不同

7
我对以下代码片段有疑问...
const qint64 bytesReady = m_audioInput->bytesReady();
const qint64 bytesSpace = m_buffer.size() - m_dataLength;
const qint64 bytesToRead = qMin(bytesReady, bytesSpace);
const qint64 bytesRead = m_audioInputIODevice->read(m_buffer.data() + m_dataLength, bytesToRead);

`bytesReady()` 方法给我返回一个特定数量的字节,然后我将这些字节数传递给 `QIODevice` 的 `read()` 方法,该方法会返回读取的字节数。
问题在于 `bytesRead` 不等于 `bytesToRead`。而且我从 `read()` 方法中获取的字节数是固定的,即 320、640、960、1280 等,这取决于 `bytesToRead`。

你能否尝试在循环中执行它?例如 while(bytesReady = m_audioInput->bytesReady() >0 ){...} 并告诉我发生了什么?你是如何初始化使用的 QAudioFormat 的?你确定 QAudioDeviceInfo::isFormatSupported() 返回 true 吗? - UmNyobe
一切都运行良好,问题出在上面的代码片段......其实不是问题,而是疑问,因为我的代码正在成功运行。 - shofee
你是什么时候阅读的?你使用 QIODevice::readyread() 信号吗? - UmNyobe
是的,我正在使用readyRead()信号。 - shofee
显而易见的问题,但是 bytesSpace > bytesReady,对吗? - Chris Browet
是的,koying,它总是更大... - shofee
2个回答

8

QAudioInput::bytesReady()与其写入样本的QIODevice之间没有直接关系。

QAudioInput在内部维护一个IO设备(系统相关),类似于只读的QIODevice。调用bytesReady时,它会返回可供读取的字节数,类似于QIODevice::bytesAvailable()。这些字节尚未写入输出QIODevice中,因此如果您不处理事件而直接在其后调用m_audioInputIODevice->read,则实际上获取的是先前已写入的样本,而不是仍在音频缓冲区中的样本。

这加上IODevice的缓冲解释了为什么数字可能不同,我看不到将它们同步在一起的方法。

实际上,您应该这样做:

const qint64 bytesRead = m_audioInputIODevice->read(m_buffer.data() + m_dataLength, bytesSpace);

从IODevice中获取任何可用的内容,直到您的缓冲区空间不足为止。


关于这个问题,当你调用bytesReady时,QAudioInput还没有将样本写入IODevice,因此当你执行m_audioInputIODevice->read时,实际上获取的是旧的样本。 - shofee
首次阅读将向您呈现自 void QAudioInput::start(QIODevice *device) 开始,QAudioInput 已经写入到输出 QIODevice 中的内容。 - Chris Browet

2
更好的方法是:
使用->readAll(),它返回一个QByteArray "qba"
然后使用sz=qba.size()来告诉你得到了多少数据(可能为零)
然后使用szqba.data()进行一些操作
这似乎没有错误,与许多QAudioInput不同,后者非常糟糕。例如,在Windows下有48000个任意采样率限制,但在OSX下没有;拉模式使用前台线程,因此在任何实际情况下都会不断中断;bytesReady()没有意义……最糟糕的Qt例程!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接