【问题标题】:QAudioInput record sounds failedQAudioInput 录制声音失败
【发布时间】:2013-12-16 07:40:08
【问题描述】:

出于我的目的,我想使用 Qt5.1 以 WAV 格式录制声音,16000Hz,16 位和 1 通道,但默认情况下声音都是 32 位的。所以我必须找到一个可以设置“位大小”的类,并且该类是 QAudioFormat,因为该类中有一个函数 setBitSize()。所以我不能再使用 QAudioRecorder 类,因为它不能将 QAudioFormat 作为参数,但 QAudioInput 可以。我使用 QAudioInput 来录制声音,代码如下:

#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;
}

好吧,程序运行后,record.wav 还是空的。我已经使用 QAudioRecorder 成功录制了声音,唯一不同的是 QAudioRecorder 类具有 setAudioInput() 函数(即“audio->setAudioInput("alsa:default");)。所以我认为这可能是问题的关键所在, 但是 QAudioInput 没有这样的功能。这是我的问题,也许你可以给我一些建议,非常感谢:-)

【问题讨论】:

    标签: audio qt5 alsa


    【解决方案1】:

    我很高兴找到和我有同样问题的人。几天来,我一直在尝试使用 QAudioRecorder 从麦克风录制,但样本大小不同。感谢您的示例,我成功摆脱了 QAudioRecorder。所以轮到我帮你了。

    我认为当程序处于睡眠功能时,它不再记录。您需要使用 Qt 提供的信号和槽的概念来在计时器运行时进行记录。

    #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;
    }
    

    我将您的代码放在一个名为 AudioInput 的类中,唯一的区别是我将 sleep(3000) 替换为 QTimer::singleShot(3000, this, SLOT(terminateRecording()));。与sleep 不同,此函数不会在 3 秒内冻结程序,而只会在时间结束时向terminateRecording() 发送信号。

    下面是剩下的代码:

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

    和标题:

    class AudioInput : public QObject{
      Q_OBJECT
      public Q_SLOTS:
        void terminateRecording();
    
     public:
        void setup();
    
    
     private:
        QAudioInput *audio;
        QFile output;
    };
    

    【讨论】:

    • 哇~非常感谢!我还发现,当我将代码放入一个类时,它可以工作,但我不知道为什么。或许你就是这么说的,我必须用信号和槽来唤醒我的程序~我很高兴你和我一起解决同样的问题~哈哈~
    【解决方案2】:

    所以基本上您似乎遇到的问题是后端不支持您尝试推送到 QAudioInput 中的设置。幸运的是,Qt 有一种方法可以获取最接近的可用格式,并且设置它很热门:

    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()));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-17
      相关资源
      最近更新 更多