MP3编码中huffman table选取完全注解

JPEG编码原理及解码分析 JPEG 阅读详情

/**

 * Choose the Huffman table that will encode ix[begin..end] with            

 * the fewest bits.                                                         

 * Note: This code contains knowledge about the sizes and characteristics   

 * of the Huffman tables as defined in the IS (Table B.7), and will not work

 * with any arbitrary tables.

 *

 * 选取合适的 huffman table.

 *

 * ix[samp_per_frame2]   量化后的信号

 * begin             address_begin

 * end               address_end

 */

int new_choose_table( int                 ix[samp_per_frame2],

                    unsigned int           begin,

                    unsigned int           end )

{

    int i, max;   //

    int choice[2]; //

    int sum[2];    /*

                * sum[0] 记录table[index]下ix[begin, end]编码所需要的位元数

                * sum[1] 记录table[index+1]下ix[begin, end]编码所需要的位元数

                *

                * index是通过 "对[0, 14]号表进行循环" 计算得来的.

                */

   

    /* 从region中查找出最大的值, 该值是用来和15做比较的, 之后选表的时候需要用到该值得 */

    max = ix_max( ix, begin, end );

    /* 如果查出最大的值是0, 那么这个区段估计就是zero区段, 而不是big_value或者count1了 */

    if( !max ) return 0;

   

    /*

     *

     */

    choice[0] = 0;

    choice[1] = 0;

   

    /*

     * linbits are used when values larger than 15 has to be encoded

     *

     * 由于标准中所提供的32个表中,并非所有的表都能用,而且有大量的码表只是linbits不同。

     * 因此如何存储这些码表,并能够很方便地进行查询、编码,是编码过程中很关键的问题之一。

     * 但提出的“多级索引”方法可以很好地的解决这一问题。过程如图2所示。对可能的表有不同的

     * 处理方式

     *

     * 正常表 如表15,即每一级索引都是对应于表15的各项信息。

    * 无效表 如表14,其最终的指向是码表零,即相当于无效表。

    * 雷同表 如表16和17实际上只是在第II级索引的linbits不同,其最后的Huffman数据是相

     *        同的。通过这样的多级码表地址索引可以很好的解决程序的模块化实现。

     *

     * 参考 << MP3编码法之研究与实现 >> Page26

     *

     * huffman表共有34个, 其中2个表给count1使用, 另外32个表给big_value使用. big_value区间

     * 分成3个子区间region0, region1, region2. 各个region拥有各自的huffmantable.

     * huffman表0-14的最大值不超过15(也就是说只能针对最大值不超过15的子区间编码), 表15-31的最

     * 小值皆为15, 如果要针对超过15的频线编码, 就需要使用linbits的方法.

     *

     * 何谓linbits方法?

     * ESCAPE = 量化后的值 - 15

     * 可编码之最大值 = 15 + pow(2, linbits);

     *

     * ----------------------------------------------------------------------

     * [0,  14]号表供max<15的region使用

     * [15, 31]号表供max>=15的region使用

     * [32, 33]号表供count1使用

     */

    if( max < 15 )

    {

    /* try tables with no linbits. 不使用linbits方法, 此时使用huffmantable 0-14

     * 如果max小于15, 则表在[0,14]范围上选表. 0-14号表是为这样的频谱设计的.

     * 这时候不需要使用 linbits 机制.

     */

        /*

         *

         */

        for ( i=14; i--; ) // 对[0, 14]号表进行循环

        {

        /* 为什么是 ht[i].xlen > max

         * 而不是 ht[i].ylen > max 呢?

         * 

         */

            if ( ht[i].xlen > max )

        {

              choice[ 0 ] = i;

                break;

        }

        }

       

        /* 计算ix[begin, end]编码所需要的位元数. */

       sum[ 0 ] = count_bit( ix, begin, end, choice[0] );

      

       /*

        * [0,14]号表并不是全使用的, 只有2,5,7,10,13号表可能被使用.

        * 其他表有什么作用还不清楚.

        *

        * 这个观点是错误的, 起初我认为只有2,5,7,10,13号表是可被使用的, 现在发现

        * 不是这样的, 似乎是所有的表都是可用的. 而一些论文上也确实是说 2,5,7,10,13号表

        * 被使用, 有一部分不被使用。

        * 从shine的代码实现上来看似乎所有表都可使用. 这里需要深究.

        */

       switch ( choice[0] )

       {

           /*

            * 注意这里的逻辑, 觉得好奇怪.

            * 之前是有通过 "对[0, 14]号表进行循环" 来查找到合适的huffman table的

            * 但是这里会根据查找到的table[index]而来再用table[index+1]计算

            * table[index+1]下ix[begin, end]编码所需要的位元数. 而且对于不同的

            * table[index], 其逻辑是不一样的, 不知道规范是如何对此定义的.

            * 日后定要回来温习这里的疑惑!

            *

            * ????????????????????????

            *

            * 看它的逻辑, 好象是table[index] 与 table[index+1] 都可以用来对ix[begin, end]

            * 进行编码的, 但是要找更合适的, 那就是看在使用哪个table的时候所需要的位元数更小.

            *

            */

            case 2:

               // table[2], table[3]是同一个阶层的.

               // 所谓同一个阶层的意思就是, 一个给定的ix[begin, end]如果可以使用

               // table[2]编码的话, 那使用table[3]也是可以的, 至于是选table[2]

               // 还是选table[3], 那就要看二者哪个所需要的位元数更低了.

               //

               // 往下看的话会发现table[5]和table[6]是一个阶层的

               // table[7], table[8]和table[9]是一个阶层的

               // table[10], table[11]和table[12]是一个阶层的

               // table[13]和table[15]是一个阶层的

            sum[ 1 ] = count_bit( ix, begin, end, 3 );

            if ( sum[1] <= sum[0] )

                choice[ 0 ] = 3;

            break;

            case 5:

            sum[ 1 ] = count_bit( ix, begin, end, 6 );

            if ( sum[1] <= sum[0] )

                choice[ 0 ] = 6;

            break;

            case 7:

               /* 对比采用table[7], table[8], table[9]哪个码表才能占用位元数更小 */

            sum[ 1 ] = count_bit( ix, begin, end, 8 );

            if ( sum[1] <= sum[0] )

            {

                  choice[ 0 ] = 8;

                  sum[ 0 ] = sum[ 1 ];

            }

            sum[ 1 ] = count_bit( ix, begin, end, 9 );

            if ( sum[1] <= sum[0] )

                choice[ 0 ] = 9;

            break;

            case 10:

            sum[ 1 ] = count_bit( ix, begin, end, 11 );

            if ( sum[1] <= sum[0] )

            {

                  choice[ 0 ] = 11;

                  sum[ 0 ] = sum[ 1 ];

            }

            sum[ 1 ] = count_bit( ix, begin, end, 12 );

            if ( sum[1] <= sum[0] )

                choice[ 0 ] = 12;

            break;

            case 13:

            sum[ 1 ] = count_bit( ix, begin, end, 15 );

            if ( sum[1] <= sum[0] )

                choice[ 0 ] = 15;

            break;

       }

    }

    else

    {

    /* try tables with linbits

     * max>=15就需要从[15,31]号表范围内选了, [32, 33]是提供为count1使用的.

     * 这时候就需要使用 linbits 机制了.

     *

     * 何谓linbits方法?

     * ESCAPE = 量化后的值 - 15

     * 可编码之最大值 = 15 + pow(2, linbits);

     */

       max -= 15;

      

    /* [15,31]号表又可分为[15, 23], [24, 31]两个部分

     *

     * 先从[15,23]号表中选出合适的table[index_1]

     * 再从[24,31]号表中选出合适的table[index_2]

     *

     * 然后比较采用table[index_1]压缩ix[begin, end]还是

     * 采用table[index_2]压缩ix[begin, end]能使用更少的位元数.

     */

       for( i=15; i<24; i++ )

       {

        if( ht[i].linmax >= max )

        {

              choice[ 0 ] = i;

              break;

        }

       }

       for(i=24; i<32; i++)

       {

        if( ht[i].linmax >= max )

        {

              choice[ 1 ] = i;

              break;

        }

       }

      

       sum[0] = count_bit( ix, begin, end, choice[0] );

       sum[1] = count_bit( ix, begin, end, choice[1] );

      

       if ( sum[1] < sum[0] )   choice[0] = choice[1];

    }

   

    return choice[0];

}

 

其中

1.

sum[ 0 ] = count_bit( ix, begin, end, choice[0] );

这个函数是计算使用choice[0]这个表的时候, 压缩ix[begin,---end]所需要的位元数, 暂不考虑其实现

 

2

.huffmantable需要要规范中去查找到。

 

3.

 

/*

注意观察就知道了,哈哈!!!!

 

查看 标准<< 11172_3_ANNEXAB >> 之 Table 3-B.7. Huffman codes for Layer III

 

*table

static HUFFBITS     t1HB[]    = {1, 1,  1,  0};

                            {1, 001,01, 000}

*********************************************

*hlen

static unsigned char t1l[]   = {1, 3, 2, 3};

 

*********************************************

Huffman code table 1

 x  y hlen hcod

 0  0  1   1

 0  1  3   001

 1  0  2   01

 1  1  3   000

 

 

 

*/

 

 

 

 

 

// -----------------------------------------------------------------------------------

#define NOREF -1

struct huffcodetab ht[HTN] =

{

/* xlen   ylen linbits  linmax   *table  *hlen  */

   

    // ------------ [0, 14]使用 ------------

    {0, 0,     0,      0,     NULL,  NULL},

    {2, 2,     0,      0,     t1HB, t1l},

    {3, 3,     0,      0,     t2HB, t2l},

    {3, 3,     0,      0,     t3HB, t3l},

    {0, 0,     0,      0,     NULL,  NULL},// Apparently not used

    {4, 4,     0,      0,     t5HB, t5l},

    {4, 4,     0,      0,     t6HB, t6l},

    {6, 6,     0,      0,     t7HB, t7l},

    {6, 6,     0,      0,     t8HB, t8l},

    {6, 6,     0,      0,     t9HB, t9l},

    {8, 8,     0,      0,     t10HB, t10l},

    {8, 8,     0,      0,     t11HB, t11l},

    {8, 8,     0,      0,     t12HB, t12l},

    {16,    16,    0,      0,     t13HB, t13l},

    {0, 0,     0,      0,     NULL,  NULL},// Apparently not used

   

    // ------------ [15, 31]使用 ------------

    {16,    16,    0,      0,     t15HB, t15l},

    {16,    16,    1,      1,     t16HB, t16l},

    {16,    16,    2,      3,     t16HB, t16l},

    {16,    16,    3,      7,     t16HB, t16l},

    {16,    16,    4,      15,    t16HB, t16l},

    {16,    16,    6,      63,    t16HB, t16l},

    {16,    16,    8,     255,   t16HB, t16l},

    {16,    16,    10,    1023,  t16HB, t16l},

    {16,    16,    13,    8191,  t16HB, t16l},

    {16,    16,    4,      15,    t24HB, t24l},

    {16,    16,    5,      31,    t24HB, t24l},

    {16,    16,    6,      63,    t24HB, t24l},

    {16,    16,    7,     127,   t24HB, t24l},

    {16,    16,    8,     255,   t24HB, t24l},

    {16,    16,    9,     511,   t24HB, t24l},

    {16,    16,    11,    2047,  t24HB, t24l},

    {16,    16,    13,    8191,  t24HB, t24l},

   

    // ------------ [32, 33]count1使用 ------------

    {1,     16,    0,      0,     t32HB, t32l},

    {1,     16,    0,      0,     t33HB, t33l},

};

 

 

请注意查看shine的实现

 

MP3解码详解(还清高高手指点)2 接下来是decode.c代码,代码绝代正确。本人使用很好 #include #include #include "common.h" #include "decode.h" #include "huffman.h"   void decode_info(Bit_stream_struc *bs, frame_params *fr_ps) {     layer *hdr = 阅读详情

相关推荐

详解Huffman压缩原理和c++代码实现

目录    一、为什么用Huffman压缩        1、文件在计算机中存储形式 和 常见的读写方式        2、Huffman    二、Huffman的实现        编码篇        1、统计频率        2、建立Huffman树        3、获取Huffman编码表        4、编码        译码篇        1、获取Huffman译码表   ...

qq_41625370的博客 9215

mp3文件解码- 哈夫曼码区

哈夫曼码区 花了很多时间才完全摸透了这个部分,参考很多代码和博文,学士论文,在这个过程中,尝试发邮件和各个技术论坛的消息向大神请教,还遇到过文章主人不知道自己的内容被盗用的情况,作为敲门砖向其提供了被盗链接之后,就没有回音了,我的问题也被忽略了。 期间下载了N份完整的mp3解码代码,大部分是 /****************************************************...

兔子别跑的博客 1041

FPGA实现MP3解码技术深入解析

本文还有配套的精品资源,点击获取 简介:在数字音频处理领域,FPGA技术广泛应用于高速低延迟的场景,包括MP3音频解码。MP3作为有损压缩格式,通过离散余弦变换(DCT)、量化和熵编码等技术压缩音频数据。文章深入探讨了FPGA在实现MP3解码中的应用,包括帧同步、解码头部信息、熵解码、反量化、IDCT以及重采样和声道重构等关键步骤。此外,强调了FPGA设计需要在功耗、面积和...

weixin_42181686的博客 1877

MP3解码之哈夫曼解码快速算法

      哈夫曼(huffman)解码用查表法,数据组织采用树形结构,若采用二叉树,一次处理一位(bit),效率是比较低的。从一些杂志上看到关于哈夫曼(huffman)解码的快速算法介绍,直接用位流索引一次处理N(4&lt;N&lt;=32)位,这种方法实际上是不可行的,原因是构造出的码表很长,如果一次处理8位,可以编写程序构造出码表,不过可以肯定的是码表的长度会超过我们事先的想象,以至于没有多...

lfp001的专栏 529

纯C语言实现的MP3解码器VC工程实践

本文还有配套的精品资源,点击获取 简介:MP3解码程序是计算机音频处理的关键,它允许用户在PC上播放MP3文件。本VC工程使用纯C语言编写,未使用任何类库,提供了深入理解解码过程的机会。解码过程涉及多个步骤,包括帧头解析、熵编码解码、频域到时域转换、窗函数应用、Layer III处理、声道合成及比特流同步。开发者可以通过源代码深入学习音频处理,并探索扩展到其他音频格式或优化...

weixin_33622085的博客 1297

非常简练的mp3解码器的代码

非常简练实用的mp3解码器代码,研究算法的同志们可以研究研究。

jpeg压缩简单介绍及huffman table

一、jpeg压缩流程的简单介绍 jpeg压缩是基于YUV颜色空间进行压缩编码的,首先将RGB转化成YUV,然后将像素值减去128,将像素值转化到范围-128~127。后要进行采样,一般来说有3中采样方式:4:4:4,4:2:2和4:1:1;4:4:4即不进行下采样,4:1:1是指一个2x2的单元,采样4个Y,1个V和1个U(具体想了解采样的可以看下其它博客)。后直接进行8x8的DCT变换,将时域像...

shayashi的博客 6700

Huffman coding table

有4个m文件,可以进行霍夫曼编码,里面的doc文件有详细使用描述,欢迎下载。

小苹果WP(实验吧-隐写术)

本文由荒原之梦原创,原文链接:http://zhaokaifeng.com/?p=706 前言:本文是实验吧训练题库里隐写术部分的一道题:“小苹果”的Write Up. 题目链接:http://www.shiyanbar.com/ctf/1928 解题文件: 观察题目发现这很像是一个二维码,拿手机扫描一下得到这个: \u7f8a\u7531\u5927\u4e95\u592b\u59...

考研数学课程、高等数学课程、线性代数课程、考研数一真题解析、考研数二真题解析、考研数三真题解析、考研数学讲义、考研数学资料、考研数学学习规划、考研数学辅导、考研数学习题、考研数学提分、荒原之梦考研数学 1450

MP3的解码程序,包括哈夫曼编码

MP3的解码程序,包括哈夫曼编码 MP3的解码程序,包括哈夫曼编码 主要c语言实现

论文研究-基于Huffman码表索引的MP3Stego隐写分析方法.pdf

MP3Stego是经典的MP3音频隐写算法之一。通过分析MP3Stego隐写算法对编码器内循环模块的影响,发现哈夫曼码表索引值在隐写前后发生了不同程度的改变。在此基础上,从待检测的MP3音频的解码参数中提取Huffman码表索引值,计算其二阶差分值,将其作为隐写分析的特征,结合SVM支持向量机实现隐写分析。实验结果表明,所提取的特征能够有效地反映MP3Stego算法在不同嵌入速率下的隐写痕迹。

[原创]桓泽学音频编解码(7):MP3 和 AAC 中huffman解码原理,优化设计与参考代码中实现...

1 不同标准中的huffman解码原理 1.1标准MP3的huffman解码原理 在MP3即mpeg-1 audio标准中,无噪声编码模块的输入是一组576个己量化的频谱数据。无噪声编码首先对频谱进行无噪声的动态范围压缩。编码模块最多可以分别对四个模值超过1的系数进行编码,并且在量化系数队列中保留符号位,用来传送符号。 为了使格组量化频谱系数所需的比特数最少,无噪声编码...

dg0418的博客 476

如何点亮一颗sensor

要点亮一个sensor需要从,时钟、sensorI2C,供电,reset脚,mipi的配置几个方面一一确认。 reset脚拉高 给sensor的时钟有没有。(目前用到的常为24MHZ) 供电 查看sensor的数据手册,看有几个电源,用示波器量一下是否为手册规定的电压 比如:DVDD 数字电压: AVDD模拟电压 DOVDD芯片引脚出来的电压等为多少。 sensor的I2C能否抓到 将I2C的口对应上,用示波器量取i2c的波形。 检查有应答并且数据正确。读写地址是否正...

weixin_40787463的博客 3652

MP3解码流程简介之二

MP3解码流程

antion182的博客 323

别再花钱买商业软件了!这4款免费DIC工具,从散斑生成到应变分析全搞定

本文介绍了4款免费开源的DIC(数字图像相关技术)工具,涵盖从散斑生成到应变分析的全流程,帮助用户零成本构建专业级DIC工作流。这些工具在精度、算法透明度和生态整合方面具有优势,适用于材料力学和实验力学研究,可替代昂贵的商业软件。

weixin_42525369的博客 171

航空大数据——项目资源汇总及开源(四)

ADS-B项目开源大礼包

cyc头发还挺多的博客 4991

JPEG文件中默认Huffman表说明

一、简述          关于JPEG中Huffman的说明,具体可参见《ISO/IEC10918-1, 1993(e), Annex C》。          在JPEG文件中,其数据包含有Huffman表数据,但这里面的Huffman表并不能直接应用于解码,还需要进行一些转换,以生成可以直接应用于解码的表。本文,即是说明如何进行转换。 二、Huffman表数据          在J

fzh2712的专栏 1万+

嵌入式系统实战:DroneCAN协议栈移植与避坑指南

本文详细介绍了在嵌入式系统中移植DroneCAN协议栈的完整流程与实战技巧。内容涵盖移植前的准备工作、内存管理优化、CRC校验实现、多帧数据处理及硬件平台适配等关键环节,并以STM32F4为例提供了具体的移植步骤和避坑指南,帮助开发者高效完成DroneCAN在嵌入式设备上的集成与应用。

solidity8miner的博客 557

读取JPEG头文件中的huffman表

读取JPEG头文件中的huffman表 实验工具:UltrEdit、Matlab 实验目的:提取出JPEG头文件中的huffman表段,并构建huffman映射。 在讲实验前,先了解一下JPEG的格式。 一.JPEG格式 JPEG格式是一种常见的图像文件压缩格式,是一些未压缩图像(如Tiff格式、bmp格式、png格式等),在经过JPEG压缩后形成的图像文件。图像的内容上会有一些肉眼...

尘功常的自由之路 4053

区块链技术概述:从比特币到Web3.0

区块链技术正重塑数字世界的信任机制。本文系统梳理了区块链的发展路径:从比特币的PoW共识和UTXO模型,到以太坊的智能合约和账户体系,直至Web3.0的去中心化互联网愿景。文章详细解析了区块链的核心特性(去中心化、不可篡改等)和数据结构,通过流程图展示了比特币交易生命周期和智能合约执行流程,并对比了Web2.0与Web3.0的关键差异。最后,用Python代码实现了包含区块类、交易处理和挖矿机制的简易区块链系统,为理解区块链底层原理提供了实践参考。

闲人编程的博客 460

YOLO11改进-注意力-引入多尺度注意力聚合(MSAA)模块

对来自backbone的特征进行细化处理。通过空间和通道两个路径的操作,增强了空间和通道方面的特征信息,使得输出的特征图在空间和通道维度上都更加优质。1. 在空间细化路径中,通过对不同核大小的卷积进行求和以及一系列的空间特征聚合操作,实现了多尺度空间信息的融合。2. 在通道聚合路径中,通过全局平均池化、卷积和激活等操作生成通道注意力图,并与空间细化后的图相结合,实现了通道维度上的多尺度信息融合。

qq_64693987的博客 4679

mp3的霍夫曼解码

mp3的数据结构 :struct coded_word {          1:codeword           2:linbitsx                    3:signx                     4:linbitsy           5:signy          }只有数据1肯定存在,2,3,4,5可能存在。举例:Huffman code table

xiayu98020214的专栏 1854

Vue3 - 超详细最新 wangEditor V5 富文本编辑器安装引入及使用教程,提供工具栏配置、基础富文本功能、API使用示例教程等(新手小白快速引入并植入到项目中)

vue3,wangEditorv5富文本编辑器,wangEditorv5官方文档,vue3最新安装wangEditorv5富文本详细使用教程,vue3使用wangEditorv5编辑器示例代码,vue3网站网页安装植入富文本编辑器教程,vue3wangEditor使用api,vue3安装富文本控制台出现报错如何解决,vue3wangEditor-v5工具栏配置,vue3中使用富文本编译器wangEditor5的方法,wangeditor5在vue3中的全使用过程,vue3超详细最新wangedi

🏆 前端领域优质创作者 4253
上一篇: 2005国内IC Design House一览
下一篇: Shine 和 8hz-mp3
xiaomantoubaba
博客等级 码龄23年 75粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值