当前语音识别的sdk一般要求使用的 输入音频流的音频格式为pcm, 单声道,16bits, 小端序。采样率16k.
接下来我们在树莓派3B+的QT中设置一个录制音频,结束录制,播放音频的三个按钮.
void Widget::on_startRecord_clicked()
{
audioDeviceListI = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
QList<QAudioDeviceInfo>::iterator it;
for (it = audioDeviceListI.begin(); it != audioDeviceListI.end(); it++) {
qDebug() << "get ALL INPUT device name:"+(*it).deviceName();
if ((*it).isNull()) {
qDebug() << "is NULL device name:"+(*it).deviceName();
}
}
qDebug() << "-------INPUT-------"+audioDeviceListI.at(14).deviceName();
audioDeviceListI2 = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
QList<QAudioDeviceInfo>::iterator it2;
for (it2 = audioDeviceListI2.begin(); it2 != audioDeviceListI2.end(); it2++) {
qDebug() << "get ALL OUTPUT device name:"+(*it2).deviceName();
if ((*it2).isNull()) {
qDebug() << "is NULL device name:"+(*it2).deviceName();
}
}
qDebug() << "-------OUTPUT-------"+audioDeviceListI2.at(14).deviceName();
qDebug() << "start record ..........";
inputFile.setFileName("/home/pi/test.pcm");
inputFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
QAudioFormat format;
format.setSampleRate(16000);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info(audioDeviceListI.at(14));
if (!info.isFormatSupported(format))
{
qWarning() << "default format not supported try to use nearest";
format = info.nearestFormat(format);
}
audioInput = new QAudioInput(info,format, this);
audioInput->start(&inputFile);
qDebug() << "record begin!";
}
start按钮的槽函数中我们首先遍历当前树莓派3b+中所有的语音输入设备,在其中找到关键词 "plughw:CARD="的语音设备(一般我们使用语音设备时选择该项即可),这里我已经知道了是容器中下标为14的成员,直接给打印了出来,后续知道了我们可以直接给制定,不需要遍历了,因为此处似乎会影响运行速度,点击按钮后不能及时的录制音频.
void Widget::on_stopRecord_clicked()
{
audioInput->stop();
inputFile.close();
delete audioInput;
qDebug() << "record end!";
}
stop按钮的槽函数作用是停止录制保存音频文件.没什么好说的!接下来讲一下播放的槽函数.
void Widget::on_playRecord_clicked()
{
outputFile.close();
if (audioOutput) {
delete audioOutput;
}
qDebug() << "play record file.....";
outputFile.setFileName("/home/pi/test.pcm");
outputFile.open(QIODevice::ReadOnly);
QAudioFormat format;
format.setSampleRate(16000);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info(audioDeviceListI2.at(14));
if (!info.isFormatSupported(format))
{
qWarning() << "default format not supported try to use nearest";
format = info.nearestFormat(format);
}
audioOutput = new QAudioOutput(info,format, this);
audioOutput->start(&outputFile);
// inputFile.close();
// delete audioOutput;
qDebug() << "play record file over.....";
}
头文件Widget.h
private:
QList<QAudioDeviceInfo> audioDeviceListI;
QList<QAudioDeviceInfo> audioDeviceListI2;
QFile inputFile;
QFile outputFile;
QAudioInput *audioInput;
QAudioOutput *audioOutput;
上面的代码仅仅是一个表示QT能正常录制pcm音频的demo,代码还有一些需要优化的地方.例如可以把QAudioFormat类的成员做内部私有变量,该成员的属性设置可以放在构造函数中,这样可以减少重复代码量等