Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Simultaneously record and play audio



  • Hi all,

    I want to record and play audio at the same time with Qt.

    I have read through the provided examples and I have also read through this: https://www.codeproject.com/Articles/421287/Cross-Platform-Microphone-Audio-Processing-Utility

    I have tried to piece together a bar minimal program. This is the best I have - this program records the audio and saves it to a .wav file but I have been unable to figure out how to play the audio back at the time it is being recorded:

        QAudioRecorder *m_audioRecorder = new QAudioRecorder;
        QAudioProbe *m_probe = new QAudioProbe;
    
        int i = 0;
        int audioSampleRate;
        for(int sampleRate: m_audioRecorder->supportedAudioSampleRates()){
            if(i == 0){
                audioSampleRate = sampleRate;
                i++;
            }
        }
    
    
        QAudioEncoderSettings settings;
        settings.setCodec(m_audioRecorder->audioInputs().first());
        settings.setSampleRate(audioSampleRate);
        settings.setChannelCount(1);
        settings.setEncodingMode(QMultimedia::ConstantQualityEncoding);
    
        QString fileName = QLatin1String("february.wav");
     bool output_location_set = m_audioRecorder->setOutputLocation(QUrl::fromLocalFile(fileName));
    
    
        QAudioFormat formatOut;
        formatOut.setSampleRate(22050);
        formatOut.setChannelCount(1);
        formatOut.setSampleRate(16);
        formatOut.setCodec("audio/pcm");
        formatOut.setByteOrder(QAudioFormat::LittleEndian);
        formatOut.setSampleType(QAudioFormat::SignedInt);
    
        QAudioOutput *audioOut;
        audioOut = new QAudioOutput(deviceOut, formatOut, 0);
        audioOut->setVolume(1);
        audioOut->start();
    
        QThread::sleep(10);
    
        QTextStream(stdout) << "	period of sleep is completed" << endl;
        m_audioRecorder->stop();
        QTextStream(stdout) << "	recording has stopped" << endl;
    
    
    

    Any idea as to what to do or how to move forward or what I'm doing wrong ?

    Please and thank you!



  • @learnthetruth I have also read through and tried to implement this: https://forum.qt.io/topic/10399/how-to-record-and-play-sound-simultaneously/2

    But I feel that it is an outdated post in some aspects. And not entirely fitting my circumstances. I don't need a GUI and this appears to use a function from the widgets module



  • @learnthetruth Which Widgets specific function are you talking about? Skimming that thread, nothing widgets/GUI specific jumps out at me.

    Basically, don't sleep. Use something like a QTimer that will trigger a signal where you can tell the input and output devices to stop. The event loop needs to be able to be active, and service the devices for the recording/playback to work.



  • Okay, but then no recording happens. :(


  • Lifetime Qt Champion

    @learnthetruth Please show your code



  • @jsulm

    Okay, first file is the .h file and the next one is the .cpp file

    #ifndef MYAUDIORECORDER_H
    #define MYAUDIORECORDER_H
    
    #include <QAudioFormat>
    #include <QAudioDeviceInfo>
    #include <QTextStream>
    #include <QAudioInput>
    #include <QAudioOutput>
    #include <QObject>
    #include <QAudioRecorder>
    #include <QAudioProbe>
    #include <QUrl>
    #include <QThread>
    
    class MyAudioRecorder : public QObject
    {
        Q_OBJECT
    
    public:
        MyAudioRecorder();
    
        int audioSampleRate;
        QAudioEncoderSettings settings;
    
        QAudioFormat formatIn;
        QAudioFormat formatOut;
    
        QAudioInput *m_audioInput;
        QAudioOutput *m_audioOutput;
    
        QAudioDeviceInfo m_InputDevice;
        QAudioDeviceInfo m_OutputDevice;
    
        QIODevice *m_input;
        QIODevice *m_output;
    
        QAudioDeviceInfo deviceIn;
        QAudioDeviceInfo deviceOut;
    
        QAudioRecorder *m_audioRecorder;
        QAudioProbe *m_probe;
    
        void getFormat();
        void createAudioInput();
        void createAudioOutput();
        void beginAudio();
    
    };
    
    #endif // MYAUDIORECORDER_H
    
    

    #include "myaudiorecorder.h"

    MyAudioRecorder::MyAudioRecorder() {
    getFormat();
    createAudioInput();
    createAudioOutput();
    }

    void MyAudioRecorder::getFormat(){
    formatIn.setSampleSize(8);
    formatIn.setCodec("audio/pcm");
    formatIn.setByteOrder(QAudioFormat::LittleEndian);
    formatIn.setSampleType(QAudioFormat::UnSignedInt);

    formatOut.setSampleSize(16);
    formatOut.setCodec("audio/pcm");
    formatOut.setByteOrder(QAudioFormat::LittleEndian);
    formatOut.setSampleType(QAudioFormat::UnSignedInt);
    
    
    // QAudioDeviceInfo deviceIn = QAudioDeviceInfo::defaultInputDevice();
    deviceIn = QAudioDeviceInfo::availableDevices(QAudio::AudioInput).at(2);
    if(!deviceIn.isFormatSupported(formatIn)){
        QTextStream(stdout) << " default formatIn not supported " << endl;
        formatIn = deviceIn.nearestFormat(formatIn);
    } else {
        QTextStream(stdout) << " default formatIn supported " << endl;
        QTextStream(stdout) << " deviceIn.deviceName(): " << deviceIn.deviceName() << endl;
    }
    
    // QAudioDeviceInfo deviceOut = QAudioDeviceInfo::defaultOutputDevice();
    deviceOut = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).at(1);
    if(!deviceOut.isFormatSupported(formatOut)) {
        QTextStream(stdout) << "default formatOut not supported " << endl;
        formatOut = deviceOut.nearestFormat(formatOut);
    } else {
        QTextStream(stdout) << " default formatOut supported " << endl;
        QTextStream(stdout) << " deviceOut.deviceName(): " << deviceOut.deviceName() << endl;
    }
    

    }

    void MyAudioRecorder::createAudioInput(){
    m_audioInput = new QAudioInput(m_InputDevice, formatIn, 0);
    }

    void MyAudioRecorder::createAudioOutput(){
    m_audioOutput = new QAudioOutput(m_OutputDevice, formatOut, 0);
    }

    void MyAudioRecorder::beginAudio(){
    m_output = m_audioOutput->start();
    m_input = m_audioInput->start();
    }


  • Lifetime Qt Champion

    Hi,

    I don't see anywhere code to connect your input to your output.



  • Okay. I have a working solution - though the output produces a lot of static with the audio from the microphone (note: the .h file is the same as what has been previously posted)

    Anyone know how to fix the static output problem?

    #include "testrecord.h"
    
    TestRecord::TestRecord() {
        getFormat();
        createAudioInput();
        createAudioOutput();
    }
    
    
    void TestRecord::getFormat(){
        formatIn.setSampleSize(8);
        formatIn.setCodec("audio/pcm");
        formatIn.setByteOrder(QAudioFormat::LittleEndian);
        formatIn.setSampleType(QAudioFormat::UnSignedInt);
    
        deviceIn = QAudioDeviceInfo::defaultInputDevice();
        if(!deviceIn.isFormatSupported(formatIn)){
            QTextStream(stdout) << " default formatIn not supported " << endl;
            formatIn = deviceIn.nearestFormat(formatIn);
        }
    
        deviceOut = QAudioDeviceInfo::defaultOutputDevice();
        if(!deviceOut.isFormatSupported(formatOut)) {
            QTextStream(stdout) << "1. default formatOut not supported " << endl;
            formatOut = deviceOut.nearestFormat(formatOut);
        }
    
    }
    
    void TestRecord::createAudioInput(){
        m_InputDevice = QAudioDeviceInfo::defaultInputDevice();
        m_audioInput = new QAudioInput(m_InputDevice, formatIn, 0);
    }
    
    void TestRecord::createAudioOutput(){
        m_OutputDevice = QAudioDeviceInfo::defaultOutputDevice();
        m_audioOutput = new QAudioOutput(m_OutputDevice, formatOut, 0);
    }
    
    void TestRecord::beginAudio(){
        m_output = m_audioOutput->start();
        m_audioInput->start(m_output);
    }
    

Log in to reply