• 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  读写方式

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <string.h>
    4. #include <unistd.h>
    5. #include <malloc.h>
    6. #include <wait.h>
    7. #include <sys/types.h>
    8. #include <sys/stat.h>
    9. #include <fcntl.h>
    10. #include <sys/ioctl.h>
    11. #include <sys/mman.h>
    12. static unsigned int t=0;
    13. static unsigned int q=0;
    14. int main(void){
    15. struct riff{
    16. char id[4];
    17. int size;
    18. char type[4];
    19. }ri;
    20. struct fmt{
    21. char id[4]; //fmt
    22. unsigned int size;
    23. unsigned short format_tag; //1
    24. unsigned short channels; //1
    25. unsigned int samples_per_sec; //22.05khz,44.1,48
    26. unsigned int bytes_per_sec; //每秒播发的字节数
    27. unsigned short block_align; //数据块对齐单位,一次采样的大小,值为声道数 * 量化位数 / 8
    28. unsigned short bits_per_sample; //16,24,32
    29. }fm;
    30. struct data{
    31. char id[4];//data
    32. unsigned int size;
    33. }da;
    34. FILE *f=fopen("/home/wzpc/1.wav","r+b");
    35. FILE *file=fopen("/home/wzpc/sample.wav","w+b"); //生成wav文件
    36. fseek(f, 0, SEEK_END);
    37. int size = ftell(f);
    38. fseek(f, 0, SEEK_SET);
    39. int fd=open("/home/wzpc/1.wav",O_RDONLY);
    40. char *m=mmap(NULL,size,PROT_READ,MAP_SHARED,fd,0);
    41. // unsigned int a=40;
    42. // 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
    43. // printf("%d\n",len);
    44. for(int t=0;t<size;t++){
    45. if((m[t]=='R')&&(m[t+1]=='I')&&(m[t+2]=='F')&&(m[t+3])=='F'){
    46. memcpy(&ri,&m[t],sizeof(ri));
    47. printf("%s\n",ri.id);
    48. printf("%d\n",ri.size);
    49. printf("%s\n",ri.type);
    50. printf("--------------------------------------\n");
    51. typedef struct riff RIFF;
    52. RIFF r={
    53. {'R','I','F','F'},
    54. 3382308,
    55. {'W','A','V','E'}
    56. };
    57. q=size;
    58. fseek(file,0,SEEK_SET);
    59. fwrite(&r,12,1,file);
    60. }
    61. }
    62. for(t=0;t<size;t++){
    63. if((m[t]=='f')&&(m[t+1]=='m')&&(m[t+2]=='t')){
    64. printf("t:%d\n",t);
    65. memcpy(&fm,&m[t],sizeof(fm));
    66. printf("%s\n",fm.id);
    67. printf("%d\n",fm.size);
    68. printf("%d\n",fm.format_tag);
    69. printf("%d\n",fm.channels);
    70. printf("%d\n",fm.samples_per_sec);
    71. printf("%d\n",fm.bytes_per_sec);
    72. printf("%d\n",fm.block_align);
    73. printf("%d\n",fm.bits_per_sample);
    74. printf("---------------------------------------\n");
    75. typedef struct fmt FMT;
    76. FMT m1={
    77. {'f','m','t',' '}, //必须要加' '
    78. 16,
    79. 1, //pcm
    80. 2, //两声道
    81. 44100, //每秒采样频率
    82. 176400, //每秒播发的字节数:声道数*采样频率*采样宽度/8=2*44100*16/8=17600
    83. 4, //声道数*采样宽度/8=2*16/8=4
    84. 16 // 采样宽度:8,16,24,32
    85. };
    86. fwrite(&m1,24,1,file);
    87. }
    88. }
    89. for(int t=0;t<size;t++){
    90. if((m[t]=='d')&&(m[t+1]=='a')&&(m[t+2]=='t')&&(m[t+3])=='a'){
    91. printf("t:%d\n",t);
    92. memcpy(&da,&m[t],sizeof(da));
    93. printf("%s\n",da.id);
    94. printf("%d\n",da.size);
    95. printf("--------------------------------------\n");
    96. typedef struct data DATA;
    97. DATA d={
    98. {'d','a','t','a'},
    99. 3382272
    100. };
    101. fwrite(&d,8,1,file);
    102. fwrite(&m[44],(size-44),1,file); //此内容为纯音频数据,由alsa部分输入
    103. }
    104. }
    105. //---------------------------------------------------------------------------------------------------
    106. fclose(file);
    107. munmap(m,size);
    108. puts("采集over");
    109. return 0;
    110. }

  • 相关阅读:
    关于 SAP UI5 所有控件的共同祖先 - sap.ui.base.ManagedObject
    论文辅助笔记:t2vec 数据预处理
    谈谈前端性能优化-面试版
    Java异常
    SQLAlchemy学习-1.环境准备与基础使用
    A8. 无人机编队飞行定位分析与讨论-大结局
    SSCI及SCI撰写|立足于审稿进行论文修改
    深入解析docker内核网桥
    公司要招个程序员,34岁以上两年一跳的不要,开出工资以为看错了
    超全的Python完全版电子书——从基础到爬虫、分析等高级应用,限时下载
  • 原文地址:https://blog.csdn.net/m0_59802969/article/details/134009905