先上header,header是灵魂
有一些是没用的。
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QString>
#include <QFile>
#include <QAudio>
#include <QAudioFormat>
#include <QAudioInput>
#include <QAudioOutput>
#include <QIODevice>
#include <QTimer>
#include <QTime>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_bn_browse_clicked();
private:
Ui::Widget *ui;
QTime* m_time;
QTimer* m_timer;
uint GetFileOpt();
QFile destFilePcm;
QString path;
QString fname;
QString GenFileName();
enum em_sta{IDLE, REC, PAUSE}eSta = IDLE;
// Audio
QAudioInput *audioIn = nullptr;
QIODevice *inputDev;
uint fmt_sr;
uint fmt_bd;
struct audioStream
{
char aData[1024];
int len;
};
private slots:
//void onReadyRead();
void on_bn_rec_pause_clicked();
void on_bn_stop_clicked();
void on_timer_hit();
};
#endif // WIDGET_H
- 建立Qt GUI工程
- 简单规划下界面布局
- 获得路径
// QFileDialog::Options options = QFlag(GetFileOpt());
// QString selectedFilter;
path = QFileDialog::getExistingDirectory(this,
tr("Get File Directory"),
QString(""));
if(!path.isEmpty())
ui->lineEditFile ->setText(path);
如果需要高级功能可以设置QFileDialog的选项。
- 定时器
定时器需要用到QTimer和QTime。QTimer是定时器,QTime是时间。这里设置了1ms的定时,将定时调用的函数与定时器用connect关联起来:
connect(m_timer,SIGNAL(timeout()),this,SLOT(on_timer_hit()));
void Widget::on_timer_hit()
{
*m_time = m_time->addMSecs(1);
ui->label_timer->setText(m_time->toString("mm:ss:zzz"));
}
这里设置了1ms定时,不知道是否太占资源了。因为长期在嵌入式系统编程,对CPU资源可能有点小心的过分了。
注意m_time->addMSecs(1)的值要重新赋值回来。否则值不会更新。
- 文件相关
fname = GenFileName();
QString fullpath = path+fname+".pcm";
qDebug()<<fullpath;
// 打开文件
destFilePcm.setFileName(fullpath);
destFilePcm.open(QIODevice::WriteOnly | QIODevice::Truncate);
- 音频输入设备相关
主要用到三种类型:QAudioFormat、QAudioDeviceInfo、QAudioInput
// 格式
QAudioFormat format;
fmt_sr = ui->cboxSampRate->currentText().toInt();
fmt_bd = (ui->cboxBitDepth->currentIndex()*16)+16;
format.setSampleRate(fmt_sr);
format.setChannelCount(2);
format.setSampleSize(fmt_bd);
format.setCodec("audio/pcm");
format.setSampleType(QAudioFormat::SignedInt);
format.setByteOrder(QAudioFormat::LittleEndian);
qDebug()<<format.sampleRate();
qDebug()<<format.sampleSize();
auto devlist = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
foreach(QAudioDeviceInfo i ,devlist)
qDebug()<<i.deviceName();
QAudioDeviceInfo info = devlist.at(1);
qDebug()<<info.deviceName()<<"this";
// new: 创建了QAudioInput对象
audioIn = new QAudioInput(info,format, this);
audioIn->start(&destFilePcm);
qDebug()<<"Recoding...";
先配置一个QAudioFormat ,再获得一个录音设备QAudioDeviceInfo,有了这两个就可以创建一个QAudioInput对象。再把从音频输入设备获取的音频流数据写入.pcm文件。最后可以给它写一个文件头,转化成wav格式。我就懒得写了,以前我自己在不同时期,用纯c写了不下5次。
- 播放、停止逻辑
需要设置状态变量。STOP、REC、PAUSE。REC和PAUSE的时候屏蔽掉browse按钮。还有和定时器有关的逻辑,不复杂。
来张图
总之由于Qt的封装性很好,编程也变成了傻瓜式编程。以后如果自己想开发个简单的录音、音频处理处理软件(不敢叫DAW),可以基于此进行。目前这个demo程序就不继续完善了。