VC 编写的WAVE测试文件生成器

最近为了调试,写了一个 WAVE 的生成器,能够生成指定采样率,指定格式的 WAVE文件,这样可以在输出端直接查看输出是否是指定的数据。特别注意的是,WAVE 中,使用 int16 (有符号十六进制)来表示当前的信号,更具体来说,负数使用补码来表示。代码如下:

// WaveGenerator.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#pragma pack(push, 1)
struct Chunk1 {          // 'R', 'I', 'F', 'F'
	char chunk_id[4];
	uint32_t chunk_size;
	char format[4];      // 'W', 'A', 'V', 'E'
};

struct Chunk2 {
	char chunk_id[4];
	uint32_t chunk_size;
	int16_t wFormatTag;
	int16_t nChannels;
	int32_t nSamplesPerSec;
	int32_t nAvgBytesPerSec;
	int16_t nBlockAlign;  // => num_channels * bits_per_sample / 8
	int16_t wBitsPerSample;
};

struct Chunk3 {
	char chunk_id[4];
	uint32_t chunk_size;
};
#pragma pack(pop) // 恢复到之前的对齐设置

#define AUDIODURATION  5  // 音频时长,以秒为单位
#define SAMPLEBITS  16  // 采样位
#define SAMPLERATE  96000  // 采样率
#define CHANNELNUM  2  // Channel 数量
int main()
{
	Chunk1 chunk1;
	chunk1.chunk_id[0] = 'R'; chunk1.chunk_id[1] = 'I'; chunk1.chunk_id[2] = 'F'; chunk1.chunk_id[3] = 'F';
	// 数据长度= Chunk123 总长 + RAW 数据长度(双声道,SAMPLEBITS Bits)
	chunk1.chunk_size = sizeof(Chunk1)-8 + sizeof(Chunk2) + sizeof(Chunk3)+ AUDIODURATION* CHANNELNUM *(SAMPLEBITS/8)* SAMPLERATE;
	chunk1.format[0] = 'W'; chunk1.format[1] = 'A'; chunk1.format[2] = 'V'; chunk1.format[3] = 'E';

	Chunk2 chunk2;

	chunk2.chunk_id[0] = 'f'; chunk2.chunk_id[1] = 'm'; chunk2.chunk_id[2] = 't'; chunk2.chunk_id[3] = ' ';
	chunk2.chunk_size = sizeof(Chunk2)-8;
	chunk2.wFormatTag = 0x0001; //PCM 格式
	chunk2.nChannels = CHANNELNUM;
	chunk2.nSamplesPerSec = SAMPLERATE;
	chunk2.nAvgBytesPerSec = CHANNELNUM * SAMPLERATE * (SAMPLEBITS / 8);
	chunk2.nBlockAlign = CHANNELNUM * (SAMPLEBITS / 8);
	chunk2.wBitsPerSample = SAMPLEBITS;

	Chunk3 chunk3;
	chunk3.chunk_id[0] = 'd'; chunk3.chunk_id[1] = 'a'; chunk3.chunk_id[2] = 't'; chunk3.chunk_id[3] = 'a';
	chunk3.chunk_size = AUDIODURATION * CHANNELNUM * SAMPLERATE * (SAMPLEBITS / 8);

	// 打开文件用于写入,以二进制模式
	FILE* file = fopen("C:\\WaveGenerator\\Debug\\example.wav", "wb");
	fwrite(&chunk1, sizeof(chunk1), 1, file);
	fwrite(&chunk2, sizeof(chunk2), 1, file);
	fwrite(&chunk3, sizeof(chunk3), 1, file);
	short int s=0,e=0;
	for (int i = 0; i < AUDIODURATION* SAMPLERATE; i++) {
		//s = sin(i * 2 * 3.1415 / (SAMPLERATE/1000)) * (65535 / 2);
		// 左声道
		s++;
		fwrite(&s, sizeof(s), 1, file);
		// 右声道
		e = 0; 
		fwrite(&e, sizeof(e), 1, file);
	}

	fclose(file);
	//getchar();
}