本文主要是介绍Qt录音机,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近做项目, 需要一个麦克风音量监听的功能:
找了好多这方面的资料, 不知道为什么 总之很少,
在此总结一下, 发贴一枚..
\
不啰嗦了, 直接上代码了:
#ifndef AUDIORECORDER_H
#define AUDIORECORDER_H#include <QFile>
#include <QWidget>
#include <QPushButton>
#include <QAudioInput>
#include <QAudioOutput>
#include <QAudioDeviceInfo>#include "ui_AudioRecorder.h"class AudioRecorder : public QWidget
{Q_OBJECTpublic:AudioRecorder(QWidget *parent = 0);~AudioRecorder();private:int AddWavHeader(char *);int ApplyVolumeToSample(short iSample);void InitMonitor();void CreateAudioInput();void CreateAudioOutput();private slots:void OnRecordStart();void OnRecordStop();void OnRecordPlay();void OnRecordSave();void OnStateChange(QAudio::State s);void OnReadMore();void OnSliderValueChanged(int);void OnTimeOut();private:Ui::Recorder ui;int miVolume;int miMaxValue;private:QAudioFormat mFormatFile;QFile *mpOutputFile;QAudioInput *mpAudioInputFile; // 负责读写文件QAudioOutput *mpAudioOutputFile;QAudioFormat mFormatSound;QAudioInput *mpAudioInputSound; // 负责监听声音QAudioOutput *mpAudioOutputSound;QIODevice *mpInputDevSound;QIODevice *mpOutputDevSound;
};#endif // AUDIORECORDER_H
#include "AudioRecorder.h"
#include <QLayout>
#include <QDebug>
#include <QTimer>
#include <QFileDialog>
#include <QMessageBox>#define BufferSize 14096struct HEADER
{char RIFFNAME[4];unsigned long nRIFFLength;char WAVNAME[4];char FMTNAME[4];unsigned long nFMTLength;unsigned short nAudioFormat;unsigned short nChannleNumber;unsigned long nSampleRate;unsigned long nBytesPerSecond;unsigned short nBytesPerSample;unsigned short nBitsPerSample;char DATANAME[4];unsigned long nDataLength;
};AudioRecorder::AudioRecorder(QWidget *parent): QWidget(parent)
{ui.setupUi(this);miMaxValue = 0;miVolume = ui.horizontalSlider->value();mpOutputFile = NULL;mpAudioInputFile = NULL;mpAudioOutputFile = NULL;mpAudioInputSound = NULL;mpAudioOutputSound = NULL;mpInputDevSound = NULL;mpInputDevSound = NULL;ui.btn_stop->setDisabled(true);ui.btn_play->setDisabled(true);ui.btn_save->setDisabled(true);mpOutputFile = new QFile();mpOutputFile->setFileName(tr("record.raw"));//mFormatFile.setFrequency(8000);//mFormatFile.setChannels(1);mFormatFile.setSampleSize(16);mFormatFile.setSampleType(QAudioFormat::SignedInt);mFormatFile.setByteOrder(QAudioFormat::LittleEndian);mFormatFile.setCodec("audio/pcm");QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());if (!info.isFormatSupported(mFormatFile)) {qWarning("input default mFormatFile not supported try to use nearest");mFormatFile = info.nearestFormat(mFormatFile);}QAudioDeviceInfo info1(QAudioDeviceInfo::defaultOutputDevice());if (!info1.isFormatSupported(mFormatFile)) {qWarning() << "output default mFormatFile not supported - trying to use nearest";// mFormatFile = info.nearestFormat(mFormatSound);qWarning() << "output no support input mFormatFile.";return;}if(mFormatFile.sampleSize() != 16) {qWarning("audio device doesn't support 16 bit support %d bit samples, example cannot run",
<span style="white-space:pre"> </span>mFormatFile.sampleSize());mpAudioInputFile = 0;return;}mpAudioInputFile = NULL;mpAudioOutputFile = NULL;connect(ui.btn_start, SIGNAL(clicked()), this,SLOT(OnRecordStart()));connect(ui.btn_stop, SIGNAL(clicked()), this,SLOT(OnRecordStop()));connect(ui.btn_play, SIGNAL(clicked()), this,SLOT(OnRecordPlay()));connect(ui.btn_save, SIGNAL(clicked()), this,SLOT(OnRecordSave()));InitMonitor();
}AudioRecorder::~AudioRecorder()
{}void AudioRecorder::OnRecordStart()
{mpOutputFile->open(QIODevice::WriteOnly | QIODevice::Truncate);mpAudioInputFile = new QAudioInput(mFormatFile, this);mpAudioInputFile->start(mpOutputFile);ui.btn_start->setDisabled(true);ui.btn_stop->setDisabled(false);ui.btn_play->setDisabled(true);ui.btn_save->setDisabled(true);
}void AudioRecorder::OnRecordPlay()
{mpOutputFile->open(QIODevice::ReadOnly | QIODevice::Truncate);mpAudioOutputFile = new QAudioOutput(mFormatFile, this);connect(mpAudioOutputFile, SIGNAL(stateChanged(QAudio::State)), this,SLOT(OnStateChange(QAudio::State)));mpAudioOutputFile->start(mpOutputFile);ui.btn_start->setDisabled(true);ui.btn_stop->setDisabled(false);ui.btn_play->setDisabled(true);ui.btn_save->setDisabled(true);
}void AudioRecorder::OnRecordStop()
{if(mpAudioInputFile != NULL){mpAudioInputFile->stop();delete mpAudioInputFile;mpAudioInputFile = NULL;}if(mpAudioOutputFile != NULL){mpAudioOutputFile->stop();delete mpAudioOutputFile;mpAudioOutputFile = NULL;}mpOutputFile->close();ui.btn_start->setDisabled(false);ui.btn_stop->setDisabled(true);ui.btn_play->setDisabled(false);ui.btn_save->setDisabled(false);
}void AudioRecorder::OnRecordSave()
{QString filename = QFileDialog::getSaveFileName(this,tr("choose a filename to save under"),QDir::currentPath(),"Wav(*.wav)");if(filename.length() == 0) {QMessageBox::information(NULL, tr("filename"), tr("You didn't select any files."));} else {if(AddWavHeader((filename+tr(".wav")).toLatin1().data())>0)QMessageBox::information(NULL, tr("Save"), tr("Success Save :") + filename);}
}void AudioRecorder::OnStateChange(QAudio::State state)
{if(state == QAudio::IdleState)OnRecordStop();
}int AudioRecorder::AddWavHeader(char *filename)
{// 开始准备WAV的文件头HEADER DestionFileHeader;DestionFileHeader.RIFFNAME[0] = 'R';DestionFileHeader.RIFFNAME[1] = 'I';DestionFileHeader.RIFFNAME[2] = 'F';DestionFileHeader.RIFFNAME[3] = 'F';DestionFileHeader.WAVNAME[0] = 'W';DestionFileHeader.WAVNAME[1] = 'A';DestionFileHeader.WAVNAME[2] = 'V';DestionFileHeader.WAVNAME[3] = 'E';DestionFileHeader.FMTNAME[0] = 'f';DestionFileHeader.FMTNAME[1] = 'm';DestionFileHeader.FMTNAME[2] = 't';DestionFileHeader.FMTNAME[3] = 0x20;DestionFileHeader.nFMTLength = 16; // 表示 FMT 的长度DestionFileHeader.nAudioFormat = 1; //这个表示a law PCMDestionFileHeader.DATANAME[0] = 'd';DestionFileHeader.DATANAME[1] = 'a';DestionFileHeader.DATANAME[2] = 't';DestionFileHeader.DATANAME[3] = 'a';DestionFileHeader.nBitsPerSample = 16;DestionFileHeader.nBytesPerSample = 2; //DestionFileHeader.nSampleRate = 8000; //DestionFileHeader.nBytesPerSecond = 16000;DestionFileHeader.nChannleNumber = 1;int nFileLen = 0;int nSize = sizeof(DestionFileHeader);FILE *fp_s = NULL;FILE *fp_d = NULL;fp_s = fopen("record.raw", "rb");if (fp_s == NULL)return -1;fp_d = fopen(filename, "wb+");if (fp_d == NULL)return -2;int nWrite = fwrite(&DestionFileHeader, 1, nSize, fp_d);if (nWrite != nSize){fclose(fp_s);fclose(fp_d);return -3;}while( !feof(fp_s)){char readBuf[4096];int nRead = fread(readBuf, 1, 4096, fp_s);if (nRead > 0){fwrite(readBuf, 1, nRead, fp_d);}nFileLen += nRead;}fseek(fp_d, 0L, SEEK_SET);DestionFileHeader.nRIFFLength = nFileLen - 8 + nSize;DestionFileHeader.nDataLength = nFileLen;nWrite = fwrite(&DestionFileHeader, 1, nSize, fp_d);if (nWrite != nSize){fclose(fp_s);fclose(fp_d);return -4;}fclose(fp_s);fclose(fp_d);return nFileLen;
}void AudioRecorder::InitMonitor()
{mFormatSound.setSampleSize(16); //set sample sze to 16 bitmFormatSound.setSampleType(QAudioFormat::UnSignedInt ); //Sample type as usigned integer samplemFormatSound.setByteOrder(QAudioFormat::LittleEndian); //Byte ordermFormatSound.setCodec("audio/pcm"); //set codec as simple audio/pcmQAudioDeviceInfo infoIn(QAudioDeviceInfo::defaultInputDevice());if (!infoIn.isFormatSupported(mFormatSound)){//Default format not supported - trying to use nearestmFormatSound = infoIn.nearestFormat(mFormatSound);}QAudioDeviceInfo infoOut(QAudioDeviceInfo::defaultOutputDevice());if (!infoOut.isFormatSupported(mFormatSound)){//Default format not supported - trying to use nearestmFormatSound = infoOut.nearestFormat(mFormatSound);}CreateAudioInput();CreateAudioOutput();mpOutputDevSound = mpAudioOutputSound->start();mpInputDevSound = mpAudioInputSound->start();connect(mpInputDevSound, SIGNAL(readyRead()), SLOT(OnReadMore()));connect(ui.horizontalSlider, SIGNAL(valueChanged(int)),this, SLOT(OnSliderValueChanged(int)));
}void AudioRecorder::CreateAudioInput()
{if (mpInputDevSound != 0) {disconnect(mpInputDevSound, 0, this, 0);mpInputDevSound = 0;}QAudioDeviceInfo inputDevice(QAudioDeviceInfo::defaultInputDevice());mpAudioInputSound = new QAudioInput(inputDevice, mFormatSound, this);
}void AudioRecorder::CreateAudioOutput()
{QAudioDeviceInfo outputDevice(QAudioDeviceInfo::defaultOutputDevice());mpAudioOutputSound = new QAudioOutput(outputDevice, mFormatSound, this);
}int AudioRecorder::ApplyVolumeToSample(short iSample)
{//Calculate volume, Volume limited to max 30000 and min -30000return std::max(std::min(((iSample * miVolume) / 50) ,20000), -20000);
}void AudioRecorder::OnSliderValueChanged(int value)
{miVolume = value;
}void AudioRecorder::OnReadMore()
{//Return if audio input is nullif(!mpAudioInputSound)return;QByteArray _Buffer(BufferSize, 0);//Check the number of samples in input bufferqint64 len = mpAudioInputSound->bytesReady();//Limit sample sizeif(len > 4096)len = 4096;//Read sound samples from input device to bufferqint64 l = mpInputDevSound->read(_Buffer.data(), len);if(l > 0) {//Assign sound samples to short arrayshort* resultingData = (short*)_Buffer.data();short *outdata=resultingData;outdata[ 0 ] = resultingData [ 0 ];int iIndex;if(false) {//Remove noise using Low Pass filter algortm[Simple algorithm used to remove noise]for ( iIndex=1; iIndex < len; iIndex++ ) {outdata[ iIndex ] = 0.333 * resultingData[iIndex ] + ( 1.0 - 0.333 ) * outdata[ iIndex-1 ];}}miMaxValue = 0;for ( iIndex=0; iIndex < len; iIndex++ ) {//Cange volume to each integer data in a sampleint value = ApplyVolumeToSample( outdata[ iIndex ]);outdata[ iIndex ] = value;miMaxValue = miMaxValue>=value ? miMaxValue : value;}//write modified sond sample to outputdevice for playback audiompOutputDevSound->write((char*)outdata, len);QTimer::singleShot(1000, this, SLOT(OnTimeOut()));}
}void AudioRecorder::OnTimeOut()
{ui.progress->setValue(miMaxValue);
}
代码已上传: http://download.csdn.net/detail/robertkun/7421767
这篇关于Qt录音机的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!