c++qtqtmultimediaqaudiorecorderqaudioinput

Qt: QAudioInput vs QAudioRecorder


I am using Qt Multimedia 5 to analyze audio (FFT, LUFS, and dBFS, etc.) from audio input device. To get audio data, there are two main options, QAudioRecorder and QAudioInput. They can all read audio data with PCM (QAudioInput use QBuffer and QAudioRecorder use QAudioBuffer) and set format (e.g., sample rate), what should I use? I want to know the difference between QAudioRecorder and QAudioInput.


Solution

  • QAudioBuffer is very convenient, and you'd use the QAudioProbe class to get notified whenever a new buffer is available - in Qt 5. QAudioProbe is not supported on Mac OS unfortunately.

    QAudioProbe doesn't exist in Qt 6, and wasn't fully supported in Qt 5 either.

    The only way to access "live" raw audio data in both Qt 5 and Qt 6 with minimal latency is by making your own QIODevice and being fed data from QAudioSource in push mode - see the Audio Source example, specifically the AudioInfo class.

    The process is as follows:

    1. Create an instance of your io device.
    2. Pass it to QAudioSource::start(QIODevice*). The audio source will be writing raw data to the device you provided.
    3. In the device's implementation, you can either work on the data directly, or synthesize a QAudioBuffer instance and send it out in a signal.

    Something like the following would work:

    class AudioProbeDevice : public QIODevice
    {
       Q_OBJECT
       QAudioFormat m_format;
    public:
       AudioProbeDevice (QObject* parent = {}) : QIODevice(parent) {}
       void start(QAudioInput *source)
       {
          Q_ASSERT(source);
          m_format = source->format();     
          open(QIODevice::WriteOnly);
       }
       qint64 readData(char *, qint64) override { return 0; }
       qint64 writeData(const char *data, qint64 count) override
       {
          QAudioBuffer buffer({data, static_cast<int>(count)}, m_format);
          emit audioAvailable(buffer);
          return count;
       }
       Q_SIGNAL void audioAvailable(const QAudioBuffer &buffer);
    };