Qt读取wav文件处理音频数据时的格式转换问题

本文介绍了在使用Qt读取wav文件时遇到的格式转换问题,详细阐述了如何读取表头信息,以及在数据滤波处理过程中遇到的双重for循环卡死问题。关键在于QByteArray与short型之间的类型转换,转换时需要注意高低位的顺序。作者还提到,将读取的wav数据直接写回文件后,出现了明显的噪声,对此感到疑惑,希望能得到解答。
摘要由CSDN通过智能技术生成

在读取文件时用Qfile file.read先读取表头信息再读取音频数据

表头信息读取参考了https://blog.csdn.net/GoForwardToStep/article/details/52789253

数据滤波处理时使用计算出滤波参数后,在线性卷积时发现总会卡死到双重for循环中(下面是已经修改后的)

        for( int i=0; i<nSampleCnt; i++)
        {
            for( int j=0; j<nFilterLen; ++j )
            {
                res[i+j] += (short)(pFilterData[j]*(double)wavData[i]);
            }
        }

后来发现读取文件时使用的是QByteArray,给类型读取时每一位是char型,而数据处理时是short型,所以需要进行一下转换

读取时的转换:

short* wavData;    
QByteArray gbry;
gbry=fileInfo.readAll();
char low;
char high;
for(int i=0;i<WavFileHeader.nDataLength;i+=2){
        high=gbry.at(i+1);
        low=gbry.at(i);
        wavData[i/2]=(high<<4)|low;
}

写入时的转换

您好,关于您的问题,我可以给您一些方向和思路: 1.使用QFile打开WAV文件,找到数据部分的开始位置,也就是"DATA"块。 2.由于WAV文件是二进制格式,可以根据WAV头信息确定一个采样数据的大小。比如16bit的音频,每个采样占据2个字节。所以可以算出DATA块的大小,从而知道最后800个数据的字节数。 3.利用QDataStream读取最后的800字节数据,并转换为int类。 具体实现可以参考以下代码: ``` QFile file("path/to/your/wav/file.wav"); if (!file.open(QIODevice::ReadOnly)) { qWarning("Failed to open file."); return; } // 找到DATA块的位置 qint64 size = file.size(); char buf[5]; qint64 pos = 12; // DATA块开始的偏移量 qint64 dataSize = 0; // DATA块的大小 while (pos < size) { qint64 n = file.read(buf, 4); if (n != 4) { qWarning("Unexpected end of file."); return; } if (qstrncmp(buf, "data", 4) == 0) { file.read(buf, 4); dataSize = qFromLittleEndian<quint32>(reinterpret_cast<const uchar*>(buf)); break; } file.read(buf, 4); pos += 8 + qFromLittleEndian<quint32>(reinterpret_cast<const uchar*>(buf)); } // 读取最后800字节数据,并转换为int类 qint64 offset = pos + dataSize - 800; if (file.seek(offset)) { QByteArray data = file.read(800); QDataStream stream(data); stream.setByteOrder(QDataStream::LittleEndian); // WAV文件是小端字节序 qint16 sample; int value; QList<int> samples; while (!stream.atEnd()) { stream >> sample; value = sample; samples.append(value); } qDebug() << samples; } else { qWarning("Failed to seek file."); return; } file.close(); ``` 注意:上面的示例代码仅供参考,具体实现应根据实际需求进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值