1.获取麦克风阵列:
QListinfos = 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#include "GNIODevice.h" #include #include #include #include #include #include #include #include #include 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" #includeMacController1::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 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 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#include 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#include 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 (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 (ptr); } else if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::SignedInt) { value = qAbs(*reinterpret_cast (ptr)); } else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::UnSignedInt) { if (m_format.byteOrder() == QAudioFormat::LittleEndian) value = qFromLittleEndian (ptr); else value = qFromBigEndian (ptr); } else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::SignedInt) { if (m_format.byteOrder() == QAudioFormat::LittleEndian) value = qAbs(qFromLittleEndian (ptr)); else value = qAbs(qFromBigEndian (ptr)); } else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::UnSignedInt) { if (m_format.byteOrder() == QAudioFormat::LittleEndian) value = qFromLittleEndian (ptr); else value = qFromBigEndian (ptr); } else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::SignedInt) { if (m_format.byteOrder() == QAudioFormat::LittleEndian) value = qAbs(qFromLittleEndian (ptr)); else value = qAbs(qFromBigEndian (ptr)); } else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::Float) { value = qAbs(*reinterpret_cast (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#include "GNIODevice.h" #include #include #include #include #include #include #include #include #include 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() { QListinfos = 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转动带来的噪声过大呢)
还没有评论,来说两句吧...