Qt录音机

来源:互联网 发布:淘宝推广和运营怎么做 编辑:程序博客网 时间:2024/05/16 17:11

最近做项目, 需要一个麦克风音量监听的功能:

找了好多这方面的资料, 不知道为什么 总之很少, 

在此总结一下, 发贴一枚..

\

不啰嗦了, 直接上代码了: 

#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

3 0