从WAV文件里提取C数组

WAV文件格式请大家自行搜索有关资料,我这里直接给出提取C数组的代码:


/*******************************************************************************
起始地址    占用空间                本地址数字的含义
00H	    4byte	    RIFF,资源交换文件标志。
04H	    4byte	    从下一个地址开始到文件尾的总字节数。高位字节在后面,这里就是001437ECH,
			        换成十进制是1325036byte,算上这之前的8byte就正好1325044byte了。
08H	    4byte	    WAVE,代表wav文件格式。
0CH	    4byte	    FMT ,波形格式标志
10H	    4byte	    00000010H,16PCM,我的理解是用16bit的数据表示一个量化结果。
14H	    2byte	    为1时表示线性PCM编码,大于1时表示有压缩的编码。这里是0001H。
16H	    2byte	    1为单声道,2为双声道,这里是0001H。
18H	    4byte	    采样频率,这里是00002B11H,也就是11025Hz。
1CH	    4byte	    Byte率=采样频率*音频通道数*每次采样得到的样本位数/8,00005622H,
			        也就是22050Byte/s=11025*1*16/2。
20H	    2byte	    块对齐=通道数*每次采样得到的样本位数/8,0002H,也就是2=1*16/8。
22H	    2byte	    样本数据位数,0010H即16,一个量化样本占2byte。
24H	    4byte	    data,一个标志而已。
28H	    4byte	    Wav文件实际音频数据所占的大小,这里是001437C8H即1325000,再加上2CH就正好
                    是1325044,整个文件的大小。
2CH	    不定	    量化数据

===================================================
PCM编码格式问题请参考
https://www.amobbs.com/thread-5652973-1-1.html?_dsign=8977581b
http://www.cnblogs.com/lidabo/p/3729615.html 
*******************************************************************************/ 
#include <stdio.h>
#include <stdlib.h>

#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned long


#define FILE_SCALE	8 	//音频文件质量 8或16	 

//44字节 
typedef struct {
	u8 riff_mark[4];
	u32 file_size;
	u8	wave_str[4];
	u8	fmt_str[4];
	u32 pcm_bit_num;
	u16 pcm_encode;
	u16 sound_channel;
	u32 pcm_sample_freq;
	u32 byte_freq;
	u16 block_alin;
	u16 sample_bits;
	u8	data_str[4]; 
	u32 sound_size;
} WAV_Typedef;

WAV_Typedef WAVFile_Array;

u16 *Sound_Data; 

u8 *Read_Sound_Data;

 

int main()
{
	FILE *fp,*fw;
	int ret;
	int i;
	
	if((fp=fopen("test.wav","rb"))==NULL)	//打开操作不成功
		return 1;
	if((fw=fopen("wav_out.h","w"))==NULL)	//打开操作不成功
		return 1;			
		
	if(fread(&WAVFile_Array,sizeof(WAVFile_Array),1,fp)==1)
		printf("wav file read ok!\n");
	
	printf("资源交换文件标志: %.4s\n",WAVFile_Array.riff_mark);
	printf("文件大小: %d\n",WAVFile_Array.file_size+8);
	printf("文件格式: %.4s\n",WAVFile_Array.wave_str);
	printf("波形格式: %.4s\n",WAVFile_Array.fmt_str);
	printf("PCM: %dbits\n",WAVFile_Array.pcm_bit_num);
	printf("声道: %s\n",WAVFile_Array.sound_channel==1?"单声道":"双声道");
	printf("采样速率: %d\n",WAVFile_Array.pcm_sample_freq);
	printf("码率: %d Bps\n",WAVFile_Array.byte_freq);
	printf("块对齐: %d\n",WAVFile_Array.block_alin);
	printf("采样位宽: %d\n",WAVFile_Array.sample_bits);	
	printf("Data标志: %.4s\n",WAVFile_Array.data_str);	
	printf("声音数据大小: %d\n",WAVFile_Array.sound_size);
			
	Sound_Data=malloc(WAVFile_Array.sound_size);
	Read_Sound_Data=(u8 *)Sound_Data;

	if(Sound_Data==NULL)
	{
		printf("malloc failed!\n");	
		return 2;
	}
	
	//Sound_Data[0]=0x1234;
	//printf("Sound_Data[0]=%x\n",Sound_Data[0]);
	
	fseek(fp,sizeof(WAV_Typedef),SEEK_SET);
#if 0	
	if((ret=fread(Sound_Data,WAVFile_Array.sound_size/2,2,fp))==1)
		printf("sound data read ok!\n");
	else
	{
		printf("sound data read failed! ret=%d\n",ret);	
		return 3;
	}
#else
	for(i=0;i<WAVFile_Array.sound_size;i++)
		Read_Sound_Data[i]=fgetc(fp);
#endif	
	
	{
		int idx=0;
		int line_count=0;
		
		fprintf(fw,"#ifndef __SOUND_DATA_H__\n");
		fprintf(fw,"#define __SOUND_DATA_H__\n\n");
		
		fprintf(fw,"#define SOUND_LENGTH\t%d\n\n",WAVFile_Array.sound_size/2);
#if FILE_SCALE==16		
		fprintf(fw,"const unsigned short SOUND_DATA[SOUND_LENGTH] = {\n\t");
#else
		fprintf(fw,"const unsigned char SOUND_DATA[SOUND_LENGTH] = {\n\t");
#endif		
		
		for(i=0;i<WAVFile_Array.sound_size/2;i++)
		{
			//printf("0x%04x,",Sound_Data[idx]);
			//if() 
#if FILE_SCALE==16 			
			fprintf(fw,"0x%04x, ",(Sound_Data[idx]+0x8000)&0xffff);
#else
			fprintf(fw,"0x%02x, ",((Sound_Data[idx]+0x8000)&0xffff)>>8);
#endif 
			idx++;
			line_count++;
			if(line_count>8-1)
			{
				line_count=0;
				//printf("\n");
				fprintf(fw,"\n\t");
			}
		}
		fprintf(fw,"\n};\n#endif\n");
		
		printf("\n ***** 已转换成头文件 wav_out.h *****\n"); 
	}
	
	
	if(fp!=NULL)
		close(fp);	
	if(fw!=NULL)
		close(fw);	
	
	return 0;	
}
 

最终的效果如下图

难点说明: 为什么将提取出来的数据+0x8000,原因就是16的WAV编码采用的就是 -32767~ 32767

在数轴上就是一个x轴上下波动的波形图,可是单片机的DAC里可没有负信号,所以统一加上0x8000;

很多单片机的DAC都是12位的,那么将转换后的数据(0x7D48)的高12位赋值给DAC即可,损失的低位没有关系;

如果想调节音量,就将DAC里的值乘以一个百分比即可;

  • 9
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值