MPEG编码

实验原理


MPEG-1音频编码器框架图

多相滤波器组(PolyphaseFilter Bank):将PCM样本变换到32个子带的频域信号

如果输入的采样频率为48kHz,那么子带的频率宽度为48/2*32=0.75Hz

心理声学模型(PsychoacousticModel):计算信号中不可听觉感知的部分

计算噪声遮蔽效应

比特分配器(Bit Allocator):根据心理声学模型的计算结果,为每个子带信号分配比特数

装帧(Frame Creation):产生MPEG-I兼容的比特流

临界频带(Critical Band)

 临界频带是指当某个纯音被以它为中心频率、且具有一定带宽的连续噪声所掩蔽时,如果该纯音刚好被听到时的功率等于这一频带内的噪声功率,这个带宽为临界频带宽度。

 掩蔽效应在一定频率范围内不随带宽增大而改变,直至超过某个频率值。通常认为从20Hz16kHz25个临界频带,单位为bark

比例因子的取值和编码

对各个子带每12个样点进行一次比例因子计算。先定出12个 样点中绝对值的最大值。查比例因子表中比这个最大值大的 最小值作为比例因子。用6比特表示。
- 第2层的一帧对应36个子带样值,是第1层的三倍,原 则上要传三个比例因子。为了降低比例因子的传输码率, 采用了利用人耳时域掩蔽特性的编码策略。
- 每帧中每个子带的三个比例因子被一起考虑,划分成 特定的几种模式。根据这些模式,1个、2个或3个比例因 子和比例因子选择信息(每子带2比特)一起被传送。如 果一个比例因子和下一个只有很小的差别,就只传送大 的一个,这种情况对于稳态信号经常出现。
- 使用这一算法后,和第1层相比,第2层传输的比例因 子平均减少了2个,即传输码率由22.5Kb/s降低到了 7.5Kb/s。

比特分配及编码

在调整到固定的码率之前
- 先确定可用于样值编码的有效比特数
- 这个数值取决于比例因子、比例因子选择信息、比特分配信息 以及辅助数据所需比特数
比特分配的过程 :
- 对每个子带计算掩蔽-噪声比MNR,是信噪比SNR – 信掩比 SMR,即:MNR = SNR – SMR。
- 使整个一帧和每个子带的总噪声-掩蔽比最 小。这是一个循环过程,每一次循环使获益 最大的子带的量化级别增加一级,当然所用 比特数不能超过一帧所能提供的最大数目 。
- 第1层一帧用4比特给每个子带的比特分配信 息编码;而第2层只在低频段用4比特,高频 段则用2比特。

代码分析

FILE *output_txt;
char temp[100] = "info.txt"; //info.txt为存储数据帧信息的文件
//end
...
int main (int argc, char **argv)
{
    //add by xrr
    output_txt = fopen(temp, "w");
    if (output_txt == NULL)
        printf("Creating output txt file failed.\n");
    //end
    ...
}
#ifdef NEWENCODE
    ...
#else
    scale_factor_calc (*sb_sample, scalar, nch, frame.sblimit);
    pick_scale (scalar, &frame, max_sc);
    //add by xrr
    int sb, gr, ch;
    if (frameNum == 100)   //选择第100个数据帧
    {
        //输出采样率 
        fprintf(output_txt, "采样频率为 %d kHz. \n 目标码率为 %d kbps.\n",
            header.sampling_frequency, bitrate[header.version][header.bitrate_index]);
        fprintf(output_txt, "输出的为第 %d 帧\n", frameNum); //输出数据帧
        fprintf(output_txt, "分配的比特数为 %d\n", adb);
        fprintf(output_txt, "比例因子为:\n");  //输出比例因子
        for (ch = 0; ch < nch; ch++)//声道
        {
            fprintf(output_txt, "channel[%2d] \n", ch + 1); 
            for (sb = 0; sb < frame.sblimit; sb++) //子带
            {
                fprintf(output_txt, "subband[%2d]:    ", sb + 1);  
                for (gr = 0; gr < 3; gr++) 
                {
                    fprintf(output_txt, "%2d\t", scalar[ch][gr][sb]);
                }
                fprintf(output_txt, "\n");
            }
        }
    }
    //end 
    ...
  }
#endif
...
    //add by xrr
    if (frameNum == 100)
    {
        fprintf(output_txt, "\n分配的比特数为:\n");  //输出比特分配结果
        int ch, sb;
        for (ch = 0; ch < nch; ch++)
        {
            fprintf(output_txt, "channel[%2d] \n", ch + 1); //按声道分配
            for (sb = 0; sb < frame.sblimit; sb++)
            {
                fprintf(output_txt, "subband[%2d]:%2d\n", sb, bit_alloc[ch][sb]);
            }
        }
    }
    //end


实验结果


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值