经过阅读多个关于wav格式文件的文档最终做出此工具,这里将核心部分分享给大家。
Qt音频编辑工具
具体功能有
打开,播放,暂停,停止
打开wav格式的音频文件
播放通过播放线程进行
核心功能有
淡入淡出
插入静音
复制赞贴,剪切
音量放大减小
滚动播放,点击播放
波形缩放显示,显示对应时间区域
首先,我们看看打开wav
//获取文件的指针
char* ch;
QByteArray ba = wavFilePath.toLatin1(); // must
ch=ba.data();
FILE *file=fopen(ch,"rb");
if(!file)
{
qDebug()<<"Open Failed";
return;
}
//把指针移动到文件的结尾 ,获取文件长度
fseek(file,0,SEEK_END);
//获取文件长度
fileLength = ftell(file);
playTimeMaxNum = fileLength/1764;//最多可以播放文件长度/每10毫秒1764个字节
//定义数组长度
threadFileBuffer = new char[(int)fileLength+1];
//把指针移动到文件开头 因为我们一开始把指针移动到结尾,如果不移动回来 会出错
rewind(file);
wfh=(WavFormatHeader*)malloc(sizeof(WavFormatHeader));
memset((char*)wfh,0,sizeof(wfh));
fread((char*)wfh,1,sizeof(WavFormatHeader),file);
//读文件.
fseek(file,44,SEEK_SET);
fread(threadFileBuffer,1,fileLength,file);
fseek(file,0,SEEK_END);
qDebug()<<"wfh->Channel"<<wfh->Channel;
qDebug()<<"wfh->SampleFreq"<<wfh->SampleFreq;
qDebug()<<"wfh->PCMBitSize"<<wfh->PCMBitSize;
//把读到的文件最后一位 写为0 要不然系统会一直寻找到0后才结束
threadFileBuffer[(int)fileLength]=0;
totalData.clear ();
for(int i = 0; i < fileLength;i++)
{
totalData.append (threadFileBuffer[i]);
}
这里注意的是:
PCM裸流1秒的数据量是44100×16×2/8=176400字节,那么10毫秒的数据量就是1764字节,所以定时器定时10毫秒,每隔10毫秒从数组中顺序读取1746个字节。
复制一段波形
void WaveDataThread::copyDataPross()
{
qDebug()<<"recordCutAreaDataStartP"<<(int)recordCutAreaDataStartP;
qDebug()<<"recordCutAreaDataEndP"<<(int)recordCutAreaDataEndP;
clipboardData_L.clear ();
clipboardData_R.clear ();
if(recordCutAreaDataStartP < recordCutAreaDataEndP)
{
for(int i = recordCutAreaDataStartP; i < recordCutAreaDataEndP;i++)
{
if(recordPassageway == PASSAGEWAY_1){
clipboardData_L.append (data_L.at (i));
}else
{
clipboardData_L.append (data_L.at (i));
clipboardData_R.append (data_R.at (i));
}
}
}else
{
for(int i = recordCutAreaDataEndP; i < recordCutAreaDataStartP;i++)
{
if(recordPassageway == PASSAGEWAY_1){
clipboardData_L.append (data_L.at (i));
}else
{
clipboardData_L.append (data_L.at (i));
clipboardData_R.append (data_R.at (i));
}
}
}
}
波形的绘制
void QAudioWave::drawData(QPainter *painter)
{
QPen pen;
pen.setColor(QColor(0x4B,0xF3,0xA7)); //波形图画笔
painter->setPen(pen); //设置画笔
if(recordPassageway == PASSAGEWAY_1)
{
painter->drawLines(points_L);
}else{
painter->drawLines(points_L);
painter->drawLines(points_R);
}
painter->drawLines(points_R);
}