socket
socket

Reputation: 1203

QAudioInput record sounds failed

For my purpose, I want to use Qt5.1 to record sounds in WAV format, 16000Hz, 16bit and 1 channel, but the sounds are all 32bit by default. So I must find a class that can set "Bit Size" and the class is QAudioFormat for there's a function setBitSize() in the class. So I can no longer use QAudioRecorder class for it can not take QAudioFormat as parameter but QAudioInput do. And I use QAudioInput to record sounds with the code below:

#include<QAudioFormat>
#include<QAudioInput>
#include<QString>
#include<QFile>
#include<QDebug>

int main()
{
    QFile output;
    output.setFileName("record.raw");
    output.open(QIODevice::WriteOnly);
    QAudioFormat settings;
    settings.setCodec("audio/PCM");
    settings.setSampleRate(16000);
    settings.setSampleSize(16);
    settings.setChannelCount(1);
    settings.setByteOrder(QAudioFormat::LittleEndian);
    settings.setSampleType(QAudioFormat::UnSignedInt);
    QAudioInput *audio=new QAudioInput(settings);
    audio->start(&output);
    sleep(3);
    audio->stop();
    output.close();
    delete audio;
    return 0;
}

Well, after the program ran, the record.wav was still empty. I have successfully recorded the sounds using QAudioRecorder, and the only different is the QAudioRecorder class has setAudioInput() function (ie. "audio->setAudioInput("alsa:default");). So I think maybe it's the point of the problem, but QAudioInput has no function like this. That's my problem, maybe you can give my some advice and Thanks a lot:-)

Upvotes: 2

Views: 2314

Answers (2)

wizmer
wizmer

Reputation: 930

I'm glad to have found someone with the same issue as mine. I've been trying to record from a microphone with QAudioRecorder but with a different sample size for a few days already. Thanks to your example I've succeeded by getting rid of QAudioRecorder. So it's my turn to help you.

I think while the program is in the sleep function it's not recording anymore. You need to use the concept of signal and slots provided by Qt to to record while the timer is running.

#include "AudioInput.h"

void AudioInput::setup(){
  output.setFileName("record.raw");
  output.open(QIODevice::WriteOnly);
  QAudioFormat settings;
  settings.setCodec("audio/PCM");
  settings.setSampleRate(16000);
  settings.setSampleSize(16);
  settings.setChannelCount(1);
  settings.setByteOrder(QAudioFormat::LittleEndian);
  settings.setSampleType(QAudioFormat::UnSignedInt);
  audio=new QAudioInput(settings);
  audio->start(&output);
  QTimer::singleShot(3000, this, SLOT(terminateRecording()));
}

void AudioInput::terminateRecording(){
  audio->stop();
  output.close();
  delete audio;
}

I put your code in one class called AudioInput and the only difference is that I replaced sleep(3000) by QTimer::singleShot(3000, this, SLOT(terminateRecording()));. Contrary to sleep this function won't freeze the program during 3s but will just send a signal to terminateRecording() at the end of the time.

Here is the rest of the code:

int main(int argc, char** argv){ 
  QCoreApplication app(argc,argv);
  AudioInput t;
  t.setup();

  app.exec();
  return 0;
}

and the header:

class AudioInput : public QObject{
  Q_OBJECT
  public Q_SLOTS:
    void terminateRecording();

 public:
    void setup();


 private:
    QAudioInput *audio;
    QFile output;
};

Upvotes: 3

DevtelSoftware
DevtelSoftware

Reputation: 183

so basically the problem you seem to have is that the backend does not support the settings that you try to push into the QAudioInput. Luckily Qt has a way of getting the nearest usable format and here's hot to set it:

void AudioInput::setup(){
  output.setFileName("record.raw");
  output.open(QIODevice::WriteOnly);
  QAudioFormat settings;
  settings.setCodec("audio/PCM");
  settings.setSampleRate(16000);
  settings.setSampleSize(16);
  settings.setChannelCount(1);
  settings.setByteOrder(QAudioFormat::LittleEndian);
  settings.setSampleType(QAudioFormat::SignedInt);

  QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
  if (!info.isFormatSupported(settings)) {
      settings = info.nearestFormat(settings);      // This is the magic line
      settings.setSampleRate(16000);
      qDebug() << "Raw audio format not supported by backend. Trying the nearest format.";
  }

  audio=new QAudioInput(settings);
  audio->start(&output);
  QTimer::singleShot(3000, this, SLOT(terminateRecording()));
}

Upvotes: 0

Related Questions