【问题标题】:How to save recordings to *.wav?如何将录音保存到 *.wav?
【发布时间】:2018-09-27 11:14:57
【问题描述】:

我试图更改我的代码以将录音保存到 wav 文件。稍后我必须将其导入 MATLAB。 它可以像.*pcm 或.*wav 一样保存。但我想用(例如 VLC 播放器)外部播放器播放它。

QAudioFormat format;
Conf values;
format.setSampleRate(values.getSampRate());
format.setChannelCount(values.getChannel());
format.setSampleSize(values.getSampSize());
format.setCodec(values.getCodec());
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);

在配置文件中我有配置:

samp_rate=88200
channel=1
samp_size=24
codec=Audio/PCM
byte_order=QAudioFormat::LittleEndian
sample_type=QAudioFormat::SignedInt

保存文件外观:

m_audio->startrecording(fn+".pcm");

我将 pcm 更改为 wav - 文件将被记录,但我无法使用 VLC 打开它(只需手动输入采样率、字节顺序导入 Audacity)。是因为原始数据吗?如何保存我的录音,如包含样本大小、采样率的 wav 文件...?

音频.cpp

// ************************************************************************************************
// Audio-Class
// ************************************************************************************************

#include "Audio.h"
#include "Conf.h"
#include "Measure.h"

// ************************************************************************************************

Audio::Audio(Conf *conf)
{
    m_conf = conf;
    AudioRecord();
}

// ************************************************************************************************
//Initialization and signal-slot connection

void Audio::AudioRecord()
{

QAudioFormat format;
Conf values;
format.setSampleRate(values.getSampRate());
format.setChannelCount(values.getChannel());
format.setSampleSize(values.getSampSize());
format.setCodec(values.getCodec());
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);

QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
if (!info.isFormatSupported(format))
{
    qWarning() << "Default format not supported";
    format = info.nearestFormat(format);
}

m_audio = new QAudioInput(format, this);
connect(m_audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));

}

// ************************************************************************************************
//Start recording method

void Audio::startrecording(QString rec_file_path)
{
    m_file.setFileName(rec_file_path);
    m_file.open(QIODevice::WriteOnly);
    m_audio->start(&m_file);
}

// ************************************************************************************************
//Stop recording

void Audio::stoprecording()
{
    m_audio->stop();
    m_file.close();
}

// ************************************************************************************************
//Recording DEBUG output

void Audio::handleStateChanged(QAudio::State newState)
{
    switch (newState)
    {
        case QAudio::StoppedState:
            if (m_audio->error() != QAudio::NoError)
            {
                qDebug() << "Error!!";
            } else
            {
                qDebug() << "Finished recording";
            }
            break;

        case QAudio::ActiveState:
            qDebug() << "Started recording";
            break;

        default:

            break;
    }
}

// ************************************************************************************************

音频.h

// ************************************************************************************************
// Audio-HEADER-file
// ************************************************************************************************

#ifndef AUDIO_H
#define AUDIO_H

// ************************************************************************************************
// Includes

#include <QDebug>
#include <QObject>
#include "Conf.h"
#include <QAudioInput>
#include <QDateTime>
#include <QTimer>


// ************************************************************************************************
// Define

#define SAVE_AUDIO_PATH "/home/nikitajarocky/workspace/QT/UART_PC/IO/"

// ************************************************************************************************
// Class variables and methods

class Audio : public QObject
{
    Q_OBJECT
public:
    explicit Audio(Conf *conf);
    void start(QString file_name);
    void stop();
    void startrecording(QString);
    void stoprecording();

signals:

public slots:
    void handleStateChanged(QAudio::State);
    void AudioRecord();

private:
    Conf *m_conf;
    Conf *m_samp_rate;    
    QAudioInput *m_audio;
    QFile m_file;
};

// ************************************************************************************************

#endif // AUDIO_H

【问题讨论】:

  • 需要写入原始数据的header(通常为44字节长)才能将其转为wav格式。为此,我使用基于 Internet 上的代码的类。使用很简单,使用文件名和格式调用构造函数,将原始音频数据提供给它,然后调用关闭函数或让析构函数来完成!看这里(忽略AudioOutput类)stackoverflow.com/a/50112936/2014561
  • 非常感谢 Antonio,我尝试更改我的代码!
  • 您好,我可以在 MATLAB 中将 pcm 转换为 wav 吗?我该怎么做?
  • 我不使用 MATLAB,所以我不知道转换是如何工作的。但是你能从原始数据创建一个.wav 文件并用 VLC 媒体播放器播放吗?将.wav 文件导入 MATLAB 时是否遇到问题?请提供更多信息! ;)
  • 您好 Antonio,我尝试将您的代码集成到我的 (QT) 中,但出现很多错误。我的 AudioRecord.cpp 看起来是这样的:(另外看上面!)

标签: qt wav


【解决方案1】:

更简单的方法是使用QAudioRecorder,它处理标题的写入并处理音频捕获。

如果您的目标只是录制,它可以帮助您避免大的变化。

看例子:

audio.h:

#ifndef AUDIO_H
#define AUDIO_H

#include <QtCore>
#include <QtMultimedia>

class Audio : public QObject
{
    Q_OBJECT
public:
    explicit Audio(QObject *parent = nullptr);
    ~Audio();

public slots:
    QStringList audioInputs();
    bool record(const QString &path, const QString &audio_input = QString());
    void stop();

private:
    QAudioRecorder *m_recorder;
};

#endif // AUDIO_H

audio.cpp:

#include "audio.h"

Audio::Audio(QObject *parent) : QObject(parent)
{
    m_recorder = new QAudioRecorder(this);
}

Audio::~Audio()
{
    stop();
}

QStringList Audio::audioInputs()
{
    return m_recorder->audioInputs();
}

bool Audio::record(const QString &path, const QString &audio_input)
{
    QAudioEncoderSettings audio_settings;
    audio_settings.setCodec("audio/pcm");
    audio_settings.setChannelCount(1);
    audio_settings.setSampleRate(44100);

    m_recorder->setEncodingSettings(audio_settings);
    m_recorder->setOutputLocation(path);
    m_recorder->setAudioInput(audio_input);

    m_recorder->record();

    if (m_recorder->state() == QAudioRecorder::RecordingState)
    {
        qDebug() << "Recording...";
        return true;
    }
    else
    {
        qDebug() << qPrintable(m_recorder->errorString());
        return false;
    }
}

void Audio::stop()
{
    if (m_recorder->state() == QAudioRecorder::RecordingState)
    {
        m_recorder->stop();
        qDebug() << "Recording stopped";
    }
    else
    {
        qDebug() << "Nothing to stop";
    }
}

使用示例(录制5秒):

#include <QtCore>
#include "audio.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Audio audio;
    audio.record("file.wav");
    QTimer::singleShot(5 * 1000, &audio, &Audio::stop);

    return a.exec();
}

【讨论】:

  • 请看我上面的回答!
  • 非常感谢您的工作!但是我应该在哪里写一个标题?重要的想法是制作 WAV 文件,以后可以用 MATLAB 进行检查!
  • 与 audiorecord 并行我正在通过 UART 录制文本数据(见下文)
  • 请注意QAudioRecorder是一个高级记录器,你不需要直接写header因为QAudioRecorder是根据编码器设置为你做的。上面的例子创建了设备audio_input.wav文件(如果没有通过音频输入,则使用默认设备),所以用record(wav_path)函数开始录制,用stop()函数停止!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 2018-05-15
  • 2012-09-23
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多