美文网首页
基础篇_6.音频编码PCM

基础篇_6.音频编码PCM

作者: Allan_Wang | 来源:发表于2018-11-30 15:22 被阅读0次

    学习整理的相关章节链接:
    基础篇_1.音视频学习框架
    基础篇_2. 颜色空间模型 RBG、YUV、HSV
    基础篇_3.图像编码之Bmp
    基础篇_4.音频基础概念
    基础篇_5.音频数据采集
    基础篇_6.音频编码PCM
    基础篇_7.音频编码WAV
    基础篇_8.音频编码MP3\AAC

    1.什么是PCM音频数据

    PCM(Pulse Code Modulation)也被称为脉冲编码调制。在基础篇_5.音频数据采集我们有简要介绍过PCM音频数据是未经压缩的音频采样数据裸流,它是由模拟信号经过采样、量化、编码转换成的标准的数字音频数据。

    2.PCM音频数据是如何存储的

    如果是单声道的音频文件,采样数据按时间的先后顺序依次存入(有的时候也会采用LRLRLR方式存储,只是另一个声道的数据为0),如果是双声道的话就按照LRLRLR的方式存储,存储的时候还和机器的大小端有关。大端模式如下图所示:

    image

    3.PCM音频数据中常用的专业术语

    一般我们描述PCM音频数据的参数的时候有如下描述方式

    44100HZ 16bit stereo: 每秒钟有 44100 次采样, 采样数据用 16 位(2字节)记录, 双声道(立体声);
    22050HZ 8bit mono:每秒钟有 22050 次采样, 采样数据用 8 位(1字节)记录, 单声道;

    44100Hz指的是采样率,它的意思是每秒取样44100次。采样率越大,存储数字音频所占的空间就越大。
    16bit指的是采样精度,意思是原始模拟信号被采样后,每一个采样点在计算机中用16位(两个字节)来表示。采样精度越高越能精细地表示模拟信号的差异。

    一般来说PCM数据中的波形幅值越大,代表音量越大。

    4.PCM音频数据的处理

    4.1.分离PCM音频数据左右声道的数据

    因为PCM音频数据是按照LRLRLR的方式来存储左右声道的音频数据的,所以我们可以通过将它们交叉的读出来的方式来分离左右声道的数据

    int simplest_pcm16le_split(char *url){
        FILE *fp=fopen(url,"rb+");
        FILE *fp1=fopen("output_l.pcm","wb+");
        FILE *fp2=fopen("output_r.pcm","wb+");
        unsigned char *sample=(unsigned char *)malloc(4);
        while(!feof(fp)){
            fread(sample,1,4,fp);
            //L
            fwrite(sample,1,2,fp1);
            //R
            fwrite(sample+2,1,2,fp2);
        }
        free(sample);
        fclose(fp);
        fclose(fp1);
        fclose(fp2);
        return 0;
    }
    

    4.2.降低某个声道的音量

    因为对于PCM音频数据而言,它的幅值(即该采样点采样值的大小)代表音量的大小,所以我们可以通过减小某个声道的数据的值来实现降低某个声道的音量

    int simplest_pcm16le_halfvolumeleft(char *url){
        FILE *fp=fopen(url,"rb+");
        FILE *fp1=fopen("output_halfleft.pcm","wb+");
        int cnt=0;
        unsigned char *sample=(unsigned char *)malloc(4);
        while(!feof(fp)){
            short *samplenum=NULL;
            fread(sample,1,4,fp);
            samplenum=(short *)sample;
            *samplenum=*samplenum/2;
            //L
            fwrite(sample,1,2,fp1);
            //R
            fwrite(sample+2,1,2,fp1);
            cnt++;
        }
        printf("Sample Cnt:%d\n",cnt);
        free(sample);
        fclose(fp);
        fclose(fp1);
        return 0;
    }
    

    节选自:https://www.cnblogs.com/CoderTian/p/6657844.html

    相关文章

      网友评论

          本文标题:基础篇_6.音频编码PCM

          本文链接:https://www.haomeiwen.com/subject/gqjhcqtx.html