Qt---录音

1.获取麦克风阵列:

    QList<QAudioDeviceInfo> infos = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
    for (int i = 0; i < infos.count(); i++)
    {
        qDebug() << infos.at(i).deviceName();
    }

"麦克风阵列 (Realtek(R) Audio)"

2.QAudioFormat

	QAudioFormat formatAudio;
    formatAudio.setSampleRate(8000);
	formatAudio.setChannelCount(1);
	formatAudio.setSampleSize(16);
	formatAudio.setSampleType(QAudioFormat::SignedInt);
	formatAudio.setByteOrder(QAudioFormat::LittleEndian);
	formatAudio.setCodec("audio/pcm");

音频文件计算大小_比特率和时间求音频大小-CSDN博客

采样频率,声道数,采样位数

什么是大小端?如何确定大小端?-CSDN博客

pcm编码_百度百科 (baidu.com)

3.QList的push_back()

This function is provided for STL compatibility. It is equivalent to append(value).

 4.进行录音测试,获取过程中录入音量的最大值。

#pragma once

#include <QObject>
#include "GNIODevice.h"
#include <QStringList>
#include <QAudioRecorder>
#include <QAudioInput>
#include <QAudioFormat>
#include <QAudioBuffer>
#include <QAudioProbe>
#include <QFile>
#include <QMutex>
#include <qeventloop.h>
class MacController1  : public QObject
{
	Q_OBJECT

public:
	MacController1(QObject *parent);
	~MacController1();
	QStringList getMacList();
	void StartTestingMac(int macIndex);
	void StopTestingMac();
private:
	QAudioFormat formatAudio;
	GNIODevice* device;
	int currentVolume;
	int max_Volume;
    QAudioInput * audioInput;

private:
	void runTest(int index);
public slots:
	void UpdateTestDisplay();
};
#include "MacController1.h"
#include <thread>
MacController1::MacController1(QObject *parent)
	: QObject(parent)
{
	formatAudio.setSampleRate(8000);
	formatAudio.setChannelCount(1);
	formatAudio.setSampleSize(16);
	formatAudio.setSampleType(QAudioFormat::SignedInt);
	formatAudio.setByteOrder(QAudioFormat::LittleEndian);
	formatAudio.setCodec("audio/pcm");
	currentVolume = 0;
	max_Volume = 0;
}

MacController1::~MacController1()
{}
void MacController1::runTest(int index)
{
	device->start();
	audioInput->start(device);
}
void MacController1::StartTestingMac(int macIndex)
{
	device = new GNIODevice(formatAudio, this);
	connect(device, SIGNAL(update()), this, SLOT(UpdateTestDisplay()));
	QAudioDeviceInfo testInfo;
	QList<QAudioDeviceInfo> infos = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
	testInfo = infos.at(macIndex);
	audioInput = new QAudioInput(testInfo,formatAudio, this);
	std::thread test(&MacController1::runTest, this,macIndex);
	test.detach();
}
void MacController1::StopTestingMac()
{
	device->stop();
	audioInput->stop();
	delete device;
	delete audioInput;
	device = nullptr;
	audioInput = nullptr;
	qDebug() << "max_Volume:" << max_Volume;
}
void MacController1::UpdateTestDisplay()
{
	int volume = device->level() * 100;
	if (volume < 0 || volume > 100)
	{
		volume = 0;
	}
	currentVolume = volume;
	if (max_Volume < currentVolume) {
		max_Volume = currentVolume;
	}
}
QStringList MacController1::getMacList()
{
	QList<QAudioDeviceInfo> infos = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
	QStringList ansList;
	for (int i = 0; i < infos.count(); i++)
	{
		ansList.push_back(QString::number(i + 1) + QString::fromLocal8Bit(": ") + infos[i].deviceName());
	}
	return ansList;
}
#pragma once
#include <QIODevice>
#include <QAudioFormat>
class GNIODevice :public QIODevice
{
	Q_OBJECT

public:
    GNIODevice(const QAudioFormat& format, QObject* parent);//音频格式
    ~GNIODevice();

    void start();
    void stop();

    qreal level() const { return m_level; }

    qint64 readData(char* data, qint64 maxlen) override;
    qint64 writeData(const char* data, qint64 len) override;

private:
    const QAudioFormat m_format;
    quint32 m_maxAmplitude;//最大振幅
    qreal m_level; // 0.0 <= m_level <= 1.0

signals:
    void update();
};

#include "GNIODevice.h"
#include <QDebug>
#include <QtEndian>

const int BufferSize = 4096;//缓存大小

GNIODevice::GNIODevice(const QAudioFormat& format, QObject* parent) : QIODevice(parent)
, m_format(format)
, m_maxAmplitude(0)
, m_level(0.0)
{
    //sampleSize,sampleType--->m_maxAmplitude
    switch (m_format.sampleSize()) {
    case 8:
        switch (m_format.sampleType()) {
        case QAudioFormat::UnSignedInt:
            m_maxAmplitude = 255;
            break;
        case QAudioFormat::SignedInt:
            m_maxAmplitude = 127;
            break;
        default:
            break;
        }
        break;
    case 16:
        switch (m_format.sampleType()) {
        case QAudioFormat::UnSignedInt:
            m_maxAmplitude = 65535;
            break;
        case QAudioFormat::SignedInt:
            m_maxAmplitude = 32767;
            break;
        default:
            break;
        }
        break;

    case 32:
        switch (m_format.sampleType()) {
        case QAudioFormat::UnSignedInt:
            m_maxAmplitude = 0xffffffff;
            break;
        case QAudioFormat::SignedInt:
            m_maxAmplitude = 0x7fffffff;
            break;
        case QAudioFormat::Float:
            m_maxAmplitude = 0x7fffffff; // Kind of
        default:
            break;
        }
        break;

    default:
        break;
    }
}

GNIODevice::~GNIODevice()
{
}

void GNIODevice::start()
{
    open(QIODevice::WriteOnly);
}

void GNIODevice::stop()
{
    close();
}

qint64 GNIODevice::writeData(const char* data, qint64 len)
{
    if (m_maxAmplitude) {
        Q_ASSERT(m_format.sampleSize() % 8 == 0);
        const int channelBytes = m_format.sampleSize() / 8;
        const int sampleBytes = m_format.channelCount() * channelBytes;
        Q_ASSERT(len % sampleBytes == 0);
        const int numSamples = len / sampleBytes;

        quint32 maxValue = 0;
        const unsigned char* ptr = reinterpret_cast<const unsigned char*>(data);

        for (int i = 0; i < numSamples; ++i) {
            for (int j = 0; j < m_format.channelCount(); ++j) {
                quint32 value = 0;

                if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
                    value = *reinterpret_cast<const quint8*>(ptr);
                }
                else if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::SignedInt) {
                    value = qAbs(*reinterpret_cast<const qint8*>(ptr));
                }
                else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
                    if (m_format.byteOrder() == QAudioFormat::LittleEndian)
                        value = qFromLittleEndian<quint16>(ptr);
                    else
                        value = qFromBigEndian<quint16>(ptr);
                }
                else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::SignedInt) {
                    if (m_format.byteOrder() == QAudioFormat::LittleEndian)
                        value = qAbs(qFromLittleEndian<qint16>(ptr));
                    else
                        value = qAbs(qFromBigEndian<qint16>(ptr));
                }
                else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
                    if (m_format.byteOrder() == QAudioFormat::LittleEndian)
                        value = qFromLittleEndian<quint32>(ptr);
                    else
                        value = qFromBigEndian<quint32>(ptr);
                }
                else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::SignedInt) {
                    if (m_format.byteOrder() == QAudioFormat::LittleEndian)
                        value = qAbs(qFromLittleEndian<qint32>(ptr));
                    else
                        value = qAbs(qFromBigEndian<qint32>(ptr));
                }
                else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::Float) {
                    value = qAbs(*reinterpret_cast<const float*>(ptr) * 0x7fffffff); // assumes 0-1.0
                }

                maxValue = qMax(value, maxValue);
                ptr += channelBytes;
            }
        }

        maxValue = qMin(maxValue, m_maxAmplitude);
        m_level = qreal(maxValue) / m_maxAmplitude;
    }

    emit update();
    return len;
}

qint64 GNIODevice::readData(char* data, qint64 maxlen)
{
    Q_UNUSED(data)
        Q_UNUSED(maxlen)

        return 0;
}

代码来源于CSDN的一个博主的下载资源。但我暂时找不到是谁了!!!

5.实现录音功能(存在bug)

#pragma once

#include <QObject>
#include "GNIODevice.h"
#include <QStringList>
#include <QAudioRecorder>
#include <QAudioInput>
#include <QAudioFormat>
#include <QAudioBuffer>
#include <QAudioProbe>
#include <QFile>
#include <QMutex>
#include <qeventloop.h>
class MacController2  : public QObject
{
	Q_OBJECT

public:
	MacController2(QObject *parent);
	~MacController2();
	QStringList getMacList();

	void StartRecordingVoice(int macIndex);
	void StopRecordingVoice();
private:
	QAudioInput* audioInput;
	GNIODevice* device;
	QAudioFormat formatAudio;
	QAudioProbe* probe;
	QAudioRecorder* recorder;
	QString fileName;
public slots:
	void processBuffera(const QAudioBuffer& buffer);
};
#include "MacController2.h"
#include "qurl.h"
MacController2::MacController2(QObject *parent)
	: QObject(parent)
{
	probe = nullptr;
	recorder = nullptr;
	fileName = "E:/try/1.wav";
}

MacController2::~MacController2()
{}
QStringList MacController2::getMacList()
{
	QList<QAudioDeviceInfo> infos = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
	QStringList ansList;
	for (int i = 0; i < infos.count(); i++)
	{
		ansList.push_back(QString::number(i + 1) + QString::fromLocal8Bit(": ") + infos[i].deviceName());
	}
	return ansList;
}
void MacController2::StartRecordingVoice(int macIndex)
{
	qDebug() << fileName;

	probe = new QAudioProbe(this);
	connect(probe, &QAudioProbe::audioBufferProbed,
		this, &MacController2::processBuffera); //关联函数

	QAudioDeviceInfo info = QAudioDeviceInfo::availableDevices(QAudio::AudioInput).at(macIndex);

	recorder = new QAudioRecorder(this);
	QAudioEncoderSettings settings = recorder->audioSettings();

	probe->setSource(recorder);

	settings.setCodec("audio/PCM");   // 这些是QAudioRecorder是设置,见名思意
	settings.setBitRate(96000);
	//settings.setSampleRate(44100);
	settings.setChannelCount(2);
	settings.setQuality(QMultimedia::EncodingQuality::HighQuality);
	settings.setEncodingMode(QMultimedia::ConstantQualityEncoding);

	recorder->setAudioSettings(settings);
	recorder->setAudioInput(info.deviceName());
	recorder->setOutputLocation(QUrl::fromLocalFile(fileName));
	recorder->setContainerFormat("audio/wav");
	recorder->record();
}
void MacController2::processBuffera(const QAudioBuffer& buffer)
{
	QByteArray arr;
	qDebug() << "HAS VOICE in mac!";
	//controlVoiceData(false, arr, buffer);
}
void MacController2::StopRecordingVoice()
{
	recorder->stop();
	recorder->deleteLater();
}

噪音其实有点大

QAudioProbe对象probe的槽函数仍在执行

从音频文件在线应用程序中删除背景噪音 - 免费在线音频文件背景噪音清洁器 (aspose.app)

降噪处理了一下

(我在想是不是CPU转动带来的噪声过大呢)

在CentOS中实现Qt录音功能需要进行以下几个步骤: 1. 首先,需要安装Qt开发环境。可以通过在CentOS系统中使用包管理器(如yum或dnf)来安装Qt开发工具包(qt-devel)。 2. 在Qt中使用录音功能,需要引入Qt Multimedia模块。可以在Qt Creator中创建一个新的Qt项目,选择Qt Multimedia模板。 3. 在Qt项目中,使用QAudioRecorder类来实现录音功能。QAudioRecorder是Qt Multimedia模块中的一个类,提供了简单易用的录音功能接口。 4. 设置录音参数。通过QAudioRecorder的setEncodingSettings函数可以设置录音的格式(如采样率、位深度、声道数等)。 5. 开始录音。调用QAudioRecorder的record函数来启动录音。 6. 停止录音。调用QAudioRecorder的stop函数来停止录音。 7. 保存录音文件。通过QAudioRecorder的setOutputLocation函数设置录音文件的保存路径,然后调用QAudioRecorder的outputLocation函数获取保存路径。 8. 编译和运行Qt项目。在Qt Creator中点击“编译”按钮,然后点击“运行”按钮,即可运行Qt录音程序。 总结:在CentOS系统中,可以通过安装Qt开发环境和使用Qt Multimedia模块来实现Qt录音功能。通过QAudioRecorder类的相关函数来设置录音参数、开始录音、停止录音和保存录音文件。编译和运行Qt项目后,即可实现在CentOS系统中录音功能。 (说明:以上回答为简要介绍,具体实现细节可能因系统版本和Qt版本而有所差异,具体操作还需根据实际情况进行调整)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lpl还在学习的路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值