Qt 对 wav 音频文件进行剪切

原理: 保存文件头,再截取数据, 最后将两者进行拼接


#pragma pack(push,1)

// WAV格式

struct WaveHeader
{
	// RIFF 头;
	char				riff_fileid[4];	// "RIFF"		大端	"RIFF"块(0x52494646),标记为RIFF文件格式
	quint32		riff_fileLen;	// 块数据域大小(Chunk Size),即从下一个地址开始,到文件末尾的总字节数,或者文件总字节数-8

	// 数据类型标识符;
	char		waveid[4];			// "WAVE"  类型码(Form Type),WAV文件格式标记,即"WAVE"四个字母

	// 格式块中的块头;
	char		fmt_chkid[4];	//"fmt"	  子块(0x666D7420),注意末尾的空格
	quint32		fmt_chkLen;		// 子块数据域大小   


	// 格式块中的块数据;
	quint16		wFormatTag;        /* format type */   // 编码格式(Audio Format),1代表PCM无损格式
	quint16		nChannels;         /* number of channels (i.e. mono, stereo, etc.) */ // 声道数(Channels),1或2
	quint32		nSamplesPerSec;    /* sample rate */		// 传输速率(Byte Rate),每秒数据字节数,SampleRate * Channels * BitsPerSample / 8
	quint32		nAvgBytesPerSec;   /* for buffer estimation */	// 每秒数据大小		每个采样所需的字节数BlockAlign,BitsPerSample*Channels/8
	quint16		nBlockAlign;       /* block size of data */		// 单个采样位深(Bits Per Sample),可选8、16或32
	quint16		wBitsPerSample;		// "data"子块 (0x64617461)

	char		data_chkid[4];	//"DATA"		// 子块数据域大小(SubChunk Size) 至此,共44字节大小 
	quint32		data_chkLen;				// PCM音频数据

	WaveHeader()
	{
        initHeader();
	}


	// 初始化WAV格式
    void initHeader(quint16 nChannelCnt = 2, quint32 nSampleRate = 44100, quint16 nBitsPerSample = 16)
	{
		strcpy(riff_fileid, "RIFF");
		riff_fileLen = 36;
		strcpy(waveid, "WAVE");

		strcpy(fmt_chkid, "fmt ");
		fmt_chkLen = 16;

		wFormatTag = 1;
		nChannels = nChannelCnt;
		nSamplesPerSec = nSampleRate;
		wBitsPerSample = nBitsPerSample;
		nBlockAlign = nChannels * wBitsPerSample / 8;	// 每秒数据大小(字节) = 采样率 * 声道数 * sample比特数 / 8
		nAvgBytesPerSec = nBlockAlign * nSamplesPerSec;

		strcpy(data_chkid, "data");
		data_chkLen = 0;
	}


	void setDataSize(int len)
	{
		riff_fileLen += len;
		data_chkLen += len;
	}
};

#define WaveHeaderLength	sizeof(WaveHeader)

#pragma pack(pop)
#include <QCoreApplication>
#include <QFile>
#include <QDebug>

#include <fstream>


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    const qint64 SIZE = 1024 * 800;

    QString filename = "E:\\test.wav";
    QFile file(filename);
    file.open(QIODevice::ReadOnly);

	
    QFile fileSave("E:\\save_test.wav");
    fileSave.open(QIODevice::WriteOnly | QIODevice::Truncate);
    char data[SIZE];

    int nHeadSize = sizeof(WaveHeader);
    char* dataHead = new char[nHeadSize];
    int nReadHD = file.read(dataHead, nHeadSize);

    qint64 fileSize = file.size();
    qint64 seekPos = fileSize / 5;	// 文件的起始位置

	// 11K、22K等的WAV文件要从数据的偶数字节截取才行。
	// 而8、16K等可从任意位置截取。
	// 因此将截取位置点调整在偶数就可以了。

    if(0 != seekPos % 2)
        seekPos -= 1;

    file.seek(seekPos);
	// file.seek(8024010);
    qDebug()<<file.pos();
	WaveHeader* pHead = (WaveHeader*)dataHead;
	pHead->data_chkLen = fileSize / 2 - seekPos;		// 保存文件长度
    fileSave.write(dataHead, nHeadSize);
	// 文件的终止位置 fileSize / 2
    for (int i = 0; i < (fileSize / 2); i++)
    {
        int nLen = file.read(data, SIZE);
        if(nLen > 0)
            fileSave.write(data, SIZE);
        else
            break;
    }

    fileSave.close();

    file.close();

    delete dataHead;

    return a.exec();
}

在这里插入图片描述

Qt中,可以使用QAudioDecoder和QAudioEncoder类来实现.wav文件的读写操作。 读取.wav文件: ```cpp QAudioDecoder decoder; decoder.setSourceFilename("audio.wav"); // 设置要读取的.wav文件名 QObject::connect(&decoder, &QAudioDecoder::bufferReady, [&](const QAudioBuffer& buffer){ // 处理读取到的音频数据 const qint16* data = buffer.constData<qint16>(); int sampleCount = buffer.sampleCount(); int channelCount = buffer.channelCount(); int sampleRate = buffer.format().sampleRate(); // 进行相应的处理 }); decoder.start(); // 开始读取.wav文件 ``` 写入.wav文件: ```cpp QAudioEncoderSettings settings; settings.setCodec("audio/pcm"); settings.setSampleRate(44100); settings.setChannelCount(2); settings.setSampleSize(16); settings.setQuality(QMultimedia::HighQuality); QAudioEncoder encoder; encoder.setAudioSettings(settings); encoder.setOutputLocation(QUrl::fromLocalFile("output.wav")); // 设置输出的.wav文件名 QObject::connect(&encoder, &QAudioEncoder::encodedAudioAvailable, [&](const QAudioEncoderControl::EncodedAudioBuffer& buffer){ // 处理编码后的音频数据 const QByteArray& data = buffer.data(); // 进行相应的处理 }); encoder.record(); // 开始录制音频数据 // 在需要录制的地方,使用encoder.encode()将音频数据传递给编码器 encoder.stop(); // 停止录制音频数据,并将编码后的数据写入.wav文件 ``` 请注意,以上代码只是演示了如何使用Qt进行.wav文件的读写操作,具体的实现可能还需要根据实际需求进行适当的调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值