QAudioRecorder disable default output files



  • Hello,

    I am trying to create a recorder based on QAudioRecorder. However I don`t want to use the default containers and files that are sent to "Music" folder. I have a slot to QAudioProbe::audioBufferProbed, and I am trying to get the sample data to my custom container, then send it elsewhere. I tried to disable the default output taht way:

    p_rec->setDefaultOutputLocation(QUrl::fromLocalFile("/"));
    

    Then my connection is as follows:

    connect(p_probe, &QAudioProbe::audioBufferProbed,
                       [=](const QAudioBuffer& buff)
            {
                // not working - sends bad data ...
                QList<utils::sample_data_t> ls;
                utils::sample_data_t sdata = {0, 0};
                sdata.samples = new short[buff.byteCount()];
                sdata.size = (uint32_t) buff.byteCount();
                memcpy(sdata.samples, buff.constData<short>(), buff.byteCount());
                ls.append(sdata);
                iface.put_data((QList<utils::sample_data_t>*)&ls);
            });
    

    but the slot is not working anymore. So I had to return the location to default and that way I keep a copy of the record in Music folder. I dont want to. I want to start recording, get the raw samples from QAudioBuffer and send them elsewere (my plugin for writing WAV files). Is that possible and if not, are there any other suggestions with Qt, so I dont have to fight with ALSA.

    Thanks.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Since you want to do your own recording, why not use QAudioInput and send the data your receive directly to your encoder class ?



  • @SGaist Hello and thanks. I will most certainly will try, then will report back. I had no idea about QAudioInput, just QAudioRecorder and the C alsa lib api.



  • @SGaist
    Hello, I`ve just rewrote my recorder that way:

    p_rec = new QAudioInput(format, this);
                connect(p_rec, &QAudioInput::stateChanged,
                        [=](QAudio::State state)
                {
                    switch (state) {
    
                    case QAudio::StoppedState:
                        break;
    
                    case QAudio::ActiveState: {
                        QByteArray samples = io_handle.readAll();
                        QList<utils::sample_data_t> ls;
                        utils::sample_data_t sdata = {0, 0};
                        sdata.samples = new short[samples.size()];
                        sdata.size = (uint32_t) samples.size();
                        memcpy(sdata.samples, samples.constData(), samples.size());
                        ls.append(sdata);
                        iface.put_data((QList<utils::sample_data_t>*)&ls);
                        break;
                    }
                    default:
                        break;
                    }
                });
            }
            
            if (io_handle.open(QIODevice::ReadOnly | QIODevice::WriteOnly)) {
                p_rec->start(&io_handle);
            }
    
    

    io_handle is a member of QFIle in my QObject inheritee. However I see that I must again give the QFIle some name in order to start the stream. Also, in the slot handling recording, I can't get the samples, they are dumped into that filename of QFile. If I don't specify a filename the stream never starts. This simple example writes samples indeed but I still have this file dependancy. Isn't there any way to just start bufferning the samples with no filename? I have a custom interface that manages files, appends wav headers, swaps them if size or time limits are reached, all I need is to get these samples right.

    Regards.


  • Lifetime Qt Champion

    You don't need a QFile at all.

    If you take the no argument start overload, you'll get a QIODevice pointer to which you can connect the readyRead signal to a custom slot where you can do the data processing you want with the audio data you get from calling readAll.



  • @SGaist
    Yes I saw the QAudio::start() that returns QIODevice pointer, I've tried to handle it's data in my slot, however, when I setup like this:

     connect(p_rec, &QAudioInput::stateChanged,
                        [=](QAudio::State state)
                {
                    switch (state) {
    
                    case QAudio::StoppedState:
                        break;
    
                    case QAudio::ActiveState: {
                        QByteArray samples = r_hdnl->readAll();
                        QList<utils::sample_data_t> ls;
                        utils::sample_data_t sdata = {0, 0};
                        sdata.samples = new short[samples.size()];
                        sdata.size = (uint32_t) samples.size();
                        memcpy(sdata.samples, samples.constData(), samples.size());
                        ls.append(sdata);
                        iface.put_data((QList<utils::sample_data_t>*)&ls);
                        break;
                    }
                    default:
                        break;
                    }
                });
            }
    
            r_hdnl = p_rec->start();
    

    And I place a breakpoint into the lambda slot, I never break in the QAudio::ActiveState... and nothing happens.



  • @mrbitmap
    Aha... sorry, I've noticed that I have to attach the slot to QIODevice. Trying it ASAP. Thanks.



  • @SGaist

    Thanks :) Working fine now. The bad record is my task to fix now, but I got the data. Kind regards. I'll try to mark it SOLVED.


  • Lifetime Qt Champion

    For that last part, click on the "Topic Tools" button and then "Ask as question", then again click on the same button and you'll have "Mark as solved" :)

    To help other people on the forum finding helpful answers, you can also vote for the ones you find interesting :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.