【小程序】PCM音量变化

音频数据可以进行很多处理,音量变化是其中一种。尝试将单声道16位采样精度的wav文件的音量,进行大小变化。

目录

  • 功能要求
  • 程序效果
  • 实现步骤
  • 代码示例

功能要求

将单声道16位采样精度的wav文件的音量,进行大小变化。 最小实现,输入直接在代码中给定。 1.输入: 转换前文件:a.wav 转换后文件:b.wav 音量增大倍数:3

2.wav文件头 使用标准头部结构:

类型

大小

资源交换文件标志

4字节

“RIFF”

文件总大小

4字节

与文件大小相关

WAV文件标志

4字节

“WAVE”

波形文件标志

4字节

“fmt ”

wav格式描述块大小

4字节

18

PCM波形格式种类

2字节

1,表示线性PCM编码

通道数

2字节

1,表示单声道

采样频率

4字节

40000次/秒

波形数据传输速率

4字节

80000字节/秒

每帧大小

2字节

2字节

采样精度

2字节

16

额外描述信息

2字节

空,表示没有额外信息

PCM数据开始标志

4字节

“data”

PCM数据大小

4字节

与数据大小相关

程序效果

【小程序】PCM音量变化_第1张图片

音量大小变为原来的3倍。

实现步骤

【小程序】PCM音量变化_第2张图片

wav头直接读取拷贝,PCM数据帧部分,每一帧分别乘以系数3之后,写入转换后文件。

代码示例

  1. #include
  2. #include
  3.  
  4. int main()
  5. {
  6.     //wav文件头结构
  7.     struct WavHead
  8.     {
  9.         char RIFFId[4];//资源交换文件标志
  10.         unsigned long int RIFFSize;//从下个地址到文件尾的总字节数
  11.         char RIFFType[4];//WAV文件标志
  12.  
  13.         char formatId[4];//波形格式标志
  14.         char formatSize[4]; //wav格式表述块大小
  15.         short int audioFormat; //格式种类,“1”表示“线性PCM编码”
  16.         short int numChannels; //通道数,“1”表示“单声道”,“2”表示“双声道”
  17.         unsigned long int sampleRate; //采样频率
  18.         unsigned long int byteRate; //波形数据传输速率(每秒平均字节数)
  19.         short int blockAlign; //DATA数据块长度
  20.         short int bitsPerSample; //PCM位宽
  21.  
  22.         short int cbSize; //可选部分,额外的描述信息
  23.         char dataId[4];//PCM音频数据部分开始标志
  24.         unsigned long int dataSize; //PCM音频数据部分大小
  25.     }wavHead;
  26.         
  27.     
    //文件操作用的指针
  28.     FILE *fp_source = NULL;
  29.     FILE *fp_target = NULL;
  30.  
  31.     unsigned int frame_size = 16; //帧大小为16bits,根据实际情况调整
  32.     short int *frame_buffer = NULL; //读取每帧的指针,根据实际情况调整
  33.     int vol = 3; //变化系数,3表示变为原来的3倍
  34.  
  35.     fp_source = fopen("a.wav", "rb"); //以只读方式打开a.wav文件
  36.     fp_target = fopen("c.wav", "wb+"); //以刷新写入方式打开b.wav文件
  37.  
  38.     //打开失败时返回错误
  39.     if ((NULL==fp_source) || (NULL==fp_target))
  40.     {
  41.         printf("open file error.\n");
  42.         return -1;
  43.     }
  44.  
  45.     //读取wav头并写入新文件
  46.     fread(&wavHead, 1, sizeof(wavHead), fp_source);
  47.     fwrite(&wavHead, 1, sizeof(wavHead), fp_target);
  48.  
  49.     //读取每一帧音频数据,并进行系数变化
  50.     frame_buffer = (short int*)malloc(frame_size);
  51.     while (frame_size == fread(frame_buffer, 1, frame_size, fp_source))
  52.     {
  53.         *frame_buffer = *frame_buffer*vol;
  54.         //如果超过了最大值,或小于最小值,直接赋成极值情况
  55.         if (*frame_buffer < -0x8000)
  56.         {
  57.             *frame_buffer = -0x8000;
  58.         }else if (*frame_buffer > 0x7FFF)
  59.         {
  60.             *frame_buffer = 0x7FFF;
  61.         }
  62.  
  63.         fwrite(frame_buffer, 1, frame_size, fp_target);
  64.     }
  65.  
  66.     //释放文件资源,释放动态内存指针
  67.     fclose(fp_source);
  68.     fclose(fp_target);
  69.     free(frame_buffer);
  70.  
  71.     return 0;
  72. }

你可能感兴趣的:(练习集)