Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QAudioInput::byteReady() and QIODevice::read() giving different number of bytes

Tags:

qt

qt4.8

I am having a doubt with the following code snippet…

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() method is giving me a particular number of bytes and am passing these number of bytes to the read() of QIODevice which will return me the number of bytes read.

The problem is that bytesRead is not equal to bytesToRead. And am getting fixed number of bytes from read method i.e 320, 640, 960, 1280, etc. and this depends on byteToRead.

like image 309
shofee Avatar asked Mar 12 '12 09:03

shofee


2 Answers

There is no direct relation between the QAudioInput::bytesReady() and the QIODevice on which it is writing its samples.

QAudioInput maintains internally a IO device (system dependent) to the audio system, which is analog to a read-only QIODevice. When you call bytesReady, it returns the number of bytes available to be read, analog to QIODevice::bytesAvailable(). Those have not yet been written to the output QIODevice, so when you do the m_audioInputIODevice->read just after it, without processing events, you're actually getting the samples which have been written earlier, not the ones still in the audio buffer.

This, plus the buffering of the IODevice, explains why the numbers might be different, and I don't see a way to synchronize them together.

Actually, you should do:

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

to get whatever is available from the IODevice, up to your available buffer space.

like image 66
Chris Browet Avatar answered Nov 06 '22 16:11

Chris Browet


Better yet:

Use ->readAll() which returns a QByteArray "qba"

...then use sz=qba.size() which will tell you what you GOT (may be zero)

...then do something with it using sz and qba.data();

...seems to be without bugs unlike much of QAudioInput, which is incredibly broken, for instance, arbitrary sample rate limit of 48000 under Windows but not OSX, pull mode uses foreground thread so will break up constantly in any real situation, bytesReady() is meaningless... Worst. Qt. Routine. Evar!

like image 2
fyngyrz Avatar answered Nov 06 '22 14:11

fyngyrz