c 读取音频协议WAV文件头(再生成wav文件)

查找wav文件头关键struct 位置,当然也可查找avi文件头。用这个方法找到avi文件data位置后,可直接读出文件的每一帧图片。当然avi数据的标志位不是data,可以是00dc等。

WAV音频头文件有三个关键struct:RIFF, fmt,data。

AVI 视频文件头的关键struct:RIFF, LIST, avih,movi,strl,strh,strf.

 搞懂了wav 音频格式后,可以把wav加入avi视频中,合成带音乐的avi视频,也可以把麦克风的语音录入合成为avi音视频文件。

1.   struct  RIFF {
        char[4]   id;                 //RIFF
        int    size;
        char[4]   type;           //WAV
        
    }
RIFF 下面必须有 fmt   和data   两个块

2.    fmt:

struct fmt{

           char[4]    id;               //fmt

            unsigned   int    size;

            short     format_tag
                         2字节,表示音频数据的格式。如值为1,表示使用PCM格式。

            short     channels
                         2字节,声道数。值为1则为单声道,为2则是双声道。

                unsigned   int   samples_per_sec
           采样率,主要有22.05KHz,44.1kHz和48KHz。

           unsigned   int    bytes_per sec
                             音频的码率,每秒播放的字节数。samples_per_sec * channels *                                                    bits_per_sample /                       8,可以估算出使用缓冲区的大小

          short    block_align
                      数据块对齐单位,一次采样的大小,值为声道数 * 量化位数 / 8,在播放时需要一次                       处理多个该值大小的字节数据。

         short    bits_per_sample
                       音频sample的量化位数,有16位,24位和32位等。

     //    cbSize
       //            扩展区的长度

      }

  3.     data 块

      struct data{

                char [4] id;    //data

                 unsigned  int  size; 

           }

      4.  data 块的size 字节后面紧跟音频数据。

           音频数据按时间先后顺序放入,如采样后数据是8位,刚好一字节,则直接放入,如是16位,则采样数据的低位放在文件的低位,高位放高位。

FILE *   与int   文件描述符之间的互转;

      nt fileno(FILE *tream)

      FILE *fdopen(int fd, const char *mode)     //mode  读写方式


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

static unsigned int t=0;
static unsigned int q=0;


int main(void){
	struct riff{
		char id[4];
		int size;
		char type[4];
	}ri;
	
	struct fmt{
		char id[4];            //fmt
		unsigned int size;
		unsigned short format_tag;      //1
		unsigned short channels;    //1
		unsigned  int  samples_per_sec;        //22.05khz,44.1,48
		unsigned  int  bytes_per_sec;          //每秒播发的字节数		   
		unsigned  short  block_align;         //数据块对齐单位,一次采样的大小,值为声道数 * 量化位数 / 8
		unsigned  short bits_per_sample;       //16,24,32

	}fm;
	struct data{
		char  id[4];//data
		unsigned int size;
	}da;
	
	
	FILE *f=fopen("/home/wzpc/1.wav","r+b");
	FILE *file=fopen("/home/wzpc/sample.wav","w+b");        //生成wav文件
   
   fseek(f, 0, SEEK_END);
   int size = ftell(f);
   
   fseek(f, 0, SEEK_SET);
  
   
	int fd=open("/home/wzpc/1.wav",O_RDONLY);
	char *m=mmap(NULL,size,PROT_READ,MAP_SHARED,fd,0);
	
  //   unsigned int a=40;
 //    unsigned int len=256*256*256*( unsigned char)m[a+3]+256*256*(unsigned char)m[a+2]+256*( unsigned char)m[a+1]+(unsigned char)m[a]; //4字节ascii转int
  //   printf("%d\n",len);
	
		
	for(int t=0;t<size;t++){
		if((m[t]=='R')&&(m[t+1]=='I')&&(m[t+2]=='F')&&(m[t+3])=='F'){
			
			memcpy(&ri,&m[t],sizeof(ri));
			printf("%s\n",ri.id);
			printf("%d\n",ri.size);
			printf("%s\n",ri.type);
			printf("--------------------------------------\n");
			
			typedef struct riff RIFF;
			RIFF r={
				{'R','I','F','F'},
				3382308,
				{'W','A','V','E'}
			};
			
			q=size;
			fseek(file,0,SEEK_SET);
			fwrite(&r,12,1,file);
		
		}
	}
	for(t=0;t<size;t++){
		if((m[t]=='f')&&(m[t+1]=='m')&&(m[t+2]=='t')){
	        printf("t:%d\n",t);
			
			memcpy(&fm,&m[t],sizeof(fm));
			printf("%s\n",fm.id);
			printf("%d\n",fm.size);
			printf("%d\n",fm.format_tag);
			printf("%d\n",fm.channels);
			printf("%d\n",fm.samples_per_sec);
			printf("%d\n",fm.bytes_per_sec);
			printf("%d\n",fm.block_align);
			printf("%d\n",fm.bits_per_sample);
			printf("---------------------------------------\n");
		
			typedef struct fmt FMT;
			FMT m1={
				{'f','m','t',' '},       //必须要加' '
				16,
				1,               //pcm
				2,               //两声道
				44100,           //每秒采样频率
				176400,          //每秒播发的字节数:声道数*采样频率*采样宽度/8=2*44100*16/8=17600
				4,               //声道数*采样宽度/8=2*16/8=4
				16               // 采样宽度:8,16,24,32
				
	  };
		
			fwrite(&m1,24,1,file);
		    
		}
	}
		
		for(int t=0;t<size;t++){
			if((m[t]=='d')&&(m[t+1]=='a')&&(m[t+2]=='t')&&(m[t+3])=='a'){
				
	
			  printf("t:%d\n",t);
			  memcpy(&da,&m[t],sizeof(da));
			  printf("%s\n",da.id);
			  printf("%d\n",da.size);
			  printf("--------------------------------------\n");
			
			  typedef struct data DATA;
			  DATA d={
				  {'d','a','t','a'},
				  3382272
			  };
			  fwrite(&d,8,1,file);
			  fwrite(&m[44],(size-44),1,file);             //此内容为纯音频数据,由alsa部分输入
			}
		}
		
	//---------------------------------------------------------------------------------------------------
	   
	    fclose(file);
		munmap(m,size);
		puts("采集over");
		return 0;
	}
	

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值