对于音频采集有很多的方式,在windows下存在API可以使用,例如wave;但是QT中有一个强大的音频处理的库,可以实现音频采集,设置采集的参数等。 这里便来记录下对这个库的使用-------QAudioInput。
首先在使用这个库之前,需要先想.pro文件中添加 QT += multimedia ,否则程序会报错。
既然是采集音频,那么首先需要进行一步参数配置,告诉计算机应该以什么样的方式进行数据采集,像是采样率、声道数量、编码方式等;
这样计算机便知道如何去采集数据了,当然参数是可调的,具体配置不同参数可产生什么不同的效果,可以参考QT本身提供的示例程序Audio Recorder Example,在这个程序里可以通过界面来修改个参数值进行采样。
但是只是让计算机知道如何采样还是不够的,还需要让她知道采集何处的数据,计算机上存在这么多的器件,我们需要通过音频输入设备进行采集,则需要告诉计算机一个音频输入设备的序号(这个序号存在与计算机系统数据中),我们需要来获取到这个设备的序号才行啊。
现在已经知道从哪采集数据以及采集方式了,那么便可以使用QAudioInput进行数据采集了。
QTimer应该知道是干什么用的吧,这样便实现录制10s,然后进入stopRecording函数,在stopRecording中来结束录制。
而audioInput->start(),便实现了开始录音并将音频数据写入到文件中;
这样便实现了10s的录音并保存为文件。
但是更多的时候我们采集到音频并不是为了保存到文件,而是想进行编码再通过网络进行发送,那应该怎么做呢?
前面的我们不需要进行任何更改,那些对于我们怎么处理得到的数据并没有影响,我们要做的应该在start函数,不是进行写入文件,而是通过其他方式得到音频数据流;可能有人会说采用先写到文件,再从文件读的方式,那么这就回涉及到文件的读取冲突问题,就是可行那么速度也是很大的问题啊。
这时QT给我们提供了一个重载函数start(),当然她没有任何的参数,在QT手册中是这样给我们介绍的
简单说就是这个函数返回指向内部QIODevice的指针,那么我们就可以通过她来进行数据的读取了吧。
当然streamIn要作为全局来使用,这样我们就得到了指向存放音频数据的内存的指针。
接下来便是判断streamIn指向的内存中是否存在数据,有那就执行获取数据到准备好的数组中。
网上提供了readyRead()信号,但是我尝试之后并不能使用,具体原因可以看 Qt学习篇(三):readyRead误使用 。
这里我使用的方式比较暴力,既然我们已经在进行音频采集了,那么就说明在streamIn中会逐渐积累数据,我是直接延时一段时间,然后就去进行数据转存,嗯 这个方法还是可以用的。
在数据转存中我的不知道出现了什么错误,还在进行修改(保存出的文件完全就是杂音,但是仍然可以微弱的听到原声音),贴上我的代码吧,虽然有错但是可借鉴。
复制代码
其中宏定义如下:
复制代码
此次记录到此结束,最终无损音频文件还没得到呢。
首先在使用这个库之前,需要先想.pro文件中添加 QT += multimedia ,否则程序会报错。
既然是采集音频,那么首先需要进行一步参数配置,告诉计算机应该以什么样的方式进行数据采集,像是采样率、声道数量、编码方式等;
- QAudioFormat format;
- format.setSampleRate(16000);
- format.setChannelCount(2); //设定声道数目,mono(平声道)的声道数目是1;stero(立体声)的声道数目是2
- format.setSampleSize(16);
- format.setCodec("audio/pcm"); //编码器
- format.setByteOrder(QAudioFormat::LittleEndian); //设定高低位,LittleEndian(低位优先)/LargeEndian(高位优先)
- format.setSampleType(QAudioFormat::SignedInt);
但是只是让计算机知道如何采样还是不够的,还需要让她知道采集何处的数据,计算机上存在这么多的器件,我们需要通过音频输入设备进行采集,则需要告诉计算机一个音频输入设备的序号(这个序号存在与计算机系统数据中),我们需要来获取到这个设备的序号才行啊。
- //获取默认的音频输入设备,判断是否支持指定的格式,如果不支持则使用一个邻近的格式
- QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
- if (!info.isFormatSupported(format))
- {
- format = info.nearestFormat(format);
- }
- QTimer::singleShot(10000, this, SLOT(stopRecording()));
- QAudioInput* audioInput;
- audioInput = new QAudioInput(format, NULL);
- audioInput->start(&file);
而audioInput->start(),便实现了开始录音并将音频数据写入到文件中;
- QFile file;
- file.setFileName("test.raw");
- file.open( QIODevice::WriteOnly | QIODevice::Truncate );
但是更多的时候我们采集到音频并不是为了保存到文件,而是想进行编码再通过网络进行发送,那应该怎么做呢?
前面的我们不需要进行任何更改,那些对于我们怎么处理得到的数据并没有影响,我们要做的应该在start函数,不是进行写入文件,而是通过其他方式得到音频数据流;可能有人会说采用先写到文件,再从文件读的方式,那么这就回涉及到文件的读取冲突问题,就是可行那么速度也是很大的问题啊。
这时QT给我们提供了一个重载函数start(),当然她没有任何的参数,在QT手册中是这样给我们介绍的
- Returns a pointer to the internal QIODevice being used to transfer data from the system's audio input. The device will already be open and read() can read data directly from it.
- QIODevice* streamIn;
- streamIn = audioInput->start();
接下来便是判断streamIn指向的内存中是否存在数据,有那就执行获取数据到准备好的数组中。
网上提供了readyRead()信号,但是我尝试之后并不能使用,具体原因可以看 Qt学习篇(三):readyRead误使用 。
这里我使用的方式比较暴力,既然我们已经在进行音频采集了,那么就说明在streamIn中会逐渐积累数据,我是直接延时一段时间,然后就去进行数据转存,嗯 这个方法还是可以用的。
在数据转存中我的不知道出现了什么错误,还在进行修改(保存出的文件完全就是杂音,但是仍然可以微弱的听到原声音),贴上我的代码吧,虽然有错但是可借鉴。
- void getAudio::slogReadData() //现转存时出现错误,导致杂音
- {
- short srcAudio[L_FRAME]={0};
- FILE* fp = fopen("E:/Proj/Em_Lab/AnyMSG_Driect_Table/Transmit/video.qt/test.raw", "a+");
- if (!audioInput)
- {
- qDebug("AudioInput Error");
- return;
- }
- QByteArray dataBuffer(BUFFER_SIZE, 0);
- qint64 len1 = audioInput->bytesReady();
- if (len1 > BUFFER_SIZE)
- {
- qDebug("BUFFER_SIZE too small");
- return;
- }
- qint64 len2 = streamIn->read(dataBuffer.data(), len1);
- tempBuffer.append(dataBuffer.data(), len2); //tempBuffer存放一帧的音频数据,用于编码
- for(int i = 0; i < tempBuffer.length()/(L_FRAME * 2); i++)
- {
- memcpy(srcAudio, tempBuffer.data() + i * L_FRAME * 2, L_FRAME*2);
- fwrite(srcAudio, 1, sizeof(srcAudio), fp);
- }
- fclose(fp);
- tempBuffer.clear();
- }
- #define BUFFER_SIZE 35280
- #define L_FRAME 80
本文详细介绍了如何使用QT的QAudioInput模块进行音频采集,包括设置音频格式、选择默认输入设备、处理不支持的格式以及数据读取。通过创建QAudioInput对象并启动,将音频数据写入文件,同时展示了处理音频数据和防止杂音的方法。
338

被折叠的 条评论
为什么被折叠?



