关于WAV文件数据格式请参考WAV文件格式详解。
此份代码实现了PCM数据提取以及32位浮点型PCM数据转16位PCM数据格式。
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
typedef struct RiffChunk
{
char ID[4];
int size;
char Type[4];
} RIFF_CHUNK;
typedef struct FormatChunk
{
char ID[4];
int size;
short AudioFormat;
short NumChannels;
int SampleRate;
int ByteRate;
short BlockAlign;
short BitsPerSample;
} FORMAT_CHUNK;
typedef struct DataChunk
{
char ID[4];
int Size;
} DATA_CHUNK;
typedef struct WavFormat
{
RIFF_CHUNK mRiffChunk;
FORMAT_CHUNK mFormatChunk;
DATA_CHUNK mDataChunk;
} WAV_FORMAT;
static void pcm32Float2pcm16bit(const char* path, const char* data, const int dataLen)
{
if (0 != dataLen % 4)
{
std::cout << "dataLen:" << dataLen << "不为4的倍数!!" << std::endl;
return;
}
std::cout << "float len:" << sizeof(float) << std::endl;
const int _16bitDataLen = dataLen / 4;
short* sample16 = new short[_16bitDataLen];
const float* _32bitData = (float*)data;
for (int level1 = 0; level1 < _16bitDataLen; ++level1)
{
sample16[level1] = (short)floor((_32bitData[level1]) * 32767);
}
std::string name(path);
name.append("_32BitTo16Bit.pcm");
std::ofstream outfile(name.c_str(), std::ofstream::binary | std::ofstream::trunc);
outfile.write((char*)sample16, _16bitDataLen*2);
outfile.flush();
outfile.close();
delete[] sample16;
}
static void savePcmData(const char* path, const char* data, const int dataLen)
{
std::string name(path);
name.append(".pcm");
std::ofstream outfile(name.c_str(), std::ofstream::binary | std::ofstream::trunc);
outfile.write(data, dataLen);
outfile.flush();
outfile.close();
}
int main(int argc, char** argv)
{
if (2 != argc)
{
printf("传入参数有误,只需传入文件名即可!!\n");
for (int level1 = 0; level1 < argc; ++level1)
{
printf("%s\n", argv[level1]);
}
return 0;
}
FILE* fp = NULL;
WAV_FORMAT wav;
errno_t err = fopen_s(&fp, argv[1], "rb");
if (0 != err) {
printf("can't open audio file\n");
printf("err:%d\n", err);
exit(1);
}
std::cout << "file name : " << argv[1] << std::endl;
fread(&wav, 1, sizeof(WAV_FORMAT), fp);
printf("RiffChunk id: %s\n", std::string(wav.mRiffChunk.ID, 4).c_str());
printf("RiffChunk size: %d\n", wav.mRiffChunk.size);
printf("RiffChunk type %s\n", std::string(wav.mRiffChunk.Type, 4).c_str());
printf("FormatChunk id %s\n", std::string(wav.mFormatChunk.ID, 4).c_str());
printf("FormatChunk size: %x\n", wav.mFormatChunk.size);
printf("FormatChunk AudioFormat: %d\n", wav.mFormatChunk.AudioFormat);
printf("FormatChunk NumChannels: %d\n", wav.mFormatChunk.NumChannels);
printf("FormatChunk SampleRate: %d\n", wav.mFormatChunk.SampleRate);
printf("FormatChunk ByteRate: %d\n", wav.mFormatChunk.ByteRate);
printf("FormatChunk BlockAlign: %d\n", wav.mFormatChunk.BlockAlign);
printf("FormatChunk BitsPerSample: %d\n", wav.mFormatChunk.BitsPerSample);
printf("DataChunk id: %s\n", std::string(wav.mDataChunk.ID, 4).c_str());
printf("DataChunk Size: %d\n", wav.mDataChunk.Size);
char* buffer = new char[wav.mDataChunk.Size];
fread(buffer, 1, wav.mDataChunk.Size, fp);
std::string orgName(argv[1]);
std::string baseName = orgName.substr(0, orgName.find("."));
std::cout << "base name:" << baseName << std::endl;
savePcmData(baseName.c_str(), buffer, wav.mDataChunk.Size);
if (32 == wav.mFormatChunk.BitsPerSample)
{
pcm32Float2pcm16bit(baseName.c_str(), buffer, wav.mDataChunk.Size);
}
delete[] buffer;
fclose(fp);
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)