⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reservoir.c

📁 功能非常完善的MP3编译码器,输入文件WAV或AIFF,能够方便的嵌入到你自己的系统当中.
💻 C
字号:
/*
			(c) Copyright 1998, 1999 - Tord Jansson
			=======================================

		This file is part of the BladeEnc MP3 Encoder, based on
		ISO's reference code for MPEG Layer 3 compression, and might
		contain smaller or larger sections that are directly taken
		from ISO's reference code.

		All changes to the ISO reference code herein are either
		copyrighted by Tord Jansson (tord.jansson@swipnet.se)
		or sublicensed to Tord Jansson by a third party.

	BladeEnc is free software; you can redistribute this file
	and/or modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "l3side.h"
#include "loop.h"
#include "huffman.h"
#include "l3bitstream.h"
#include "reservoir.h"

/*
  Layer3 bit reservoir:
  Described in C.1.5.4.2.2 of the IS
*/

static int ResvSize = 0; /* in bits */
static int ResvMax  = 0; /* in bits */

void fixStatic_reservoir( void )
{
	ResvSize = 0;
	ResvMax = 0;
}


/*
  ResvFrameBegin:
  Called at the beginning of a frame. Updates the maximum
  size of the reservoir, and checks to make sure main_data_begin
  was set properly by the formatter
*/
void
ResvFrameBegin( frame_params *fr_ps, III_side_info_t *l3_side, int mean_bits, int frameLength )
{
  layer *info;
  int fullFrameBits, mode_gr;
  int expectedResvSize, resvLimit;

  info = fr_ps->header;
	mode_gr = 2;
	resvLimit = 4088; /* main_data_begin has 9 bits in MPEG 1 */

  /*
    main_data_begin was set by the formatter to the
    expected value for the next call -- this should
    agree with our reservoir size
  */
  expectedResvSize = l3_side->main_data_begin * 8;
/*  assert( expectedResvSize == ResvSize ); */

  fullFrameBits = mean_bits * mode_gr;

  /*
    determine maximum size of reservoir:
    ResvMax + frameLength <= 7680;
  */
  if ( frameLength > 7680 )
		ResvMax = 0;
  else
		ResvMax = 7680 - frameLength;

    /*
      limit max size to resvLimit bits because
      main_data_begin cannot indicate a
      larger value
      */
  if ( ResvMax > resvLimit )
		ResvMax = resvLimit;
}

/*
  ResvMaxBits:
  Called at the beginning of each granule to get the max bit
  allowance for the current granule based on reservoir size
  and perceptual entropy.
*/
int
ResvMaxBits( frame_params *fr_ps, III_side_info_t *l3_side, double *pe, int mean_bits )
{
    int more_bits, max_bits, add_bits, over_bits;

    mean_bits /= fr_ps->stereo;
    max_bits = mean_bits;

    if ( max_bits > 4095 )
	max_bits = 4095;

    if ( ResvMax == 0 )
	return max_bits;

    more_bits = (int) (*pe * 3.1 - mean_bits);
    add_bits = 0;
    if ( more_bits > 100 )
    {
	int frac = (ResvSize * 6) / 10;

	if ( frac < more_bits )
	    add_bits = frac;
	else
	    add_bits = more_bits;
    }
    over_bits = ResvSize - ((ResvMax * 8) / 10) - add_bits;
    if ( over_bits > 0 )
	add_bits += over_bits;

    max_bits += add_bits;
    if ( max_bits > 4095 )
	max_bits = 4095;
    return max_bits;
}

/*
  ResvAdjust:
  Called after a granule's bit allocation. Readjusts the size of
  the reservoir to reflect the granule's usage.
*/
void
ResvAdjust( frame_params *fr_ps, gr_info *gi, III_side_info_t *l3_side, int mean_bits )
{
    ResvSize += (mean_bits / fr_ps->stereo) - gi->part2_3_length;
}

/*
  ResvFrameEnd:
  Called after all granules in a frame have been allocated. Makes sure
  that the reservoir size is within limits, possibly by adding stuffing
  bits. Note that stuffing bits are added by increasing a granule's
  part2_3_length. The bitstream formatter will detect this and write the
  appropriate stuffing bits to the bitstream.
*/
void
ResvFrameEnd( frame_params *fr_ps, III_side_info_t *l3_side, int mean_bits )
{
    layer *info;
    gr_info *gi;
    int mode_gr, gr, ch, stereo, ancillary_pad, stuffingBits;
    int over_bits;

    info   = fr_ps->header;
    stereo = fr_ps->stereo;
    mode_gr = 2;
    ancillary_pad = 0;

    /* just in case mean_bits is odd, this is necessary... */
    if ( (stereo == 2) && (mean_bits & 1) )
			ResvSize += 1;

    over_bits = ResvSize - ResvMax;
    if ( over_bits < 0 )
			over_bits = 0;
    
    ResvSize -= over_bits;
    stuffingBits = over_bits + ancillary_pad;

    /* we must be byte aligned */
    if ( (over_bits = ResvSize % 8) )
    {
	stuffingBits += over_bits;
	ResvSize -= over_bits;
    }

    if ( stuffingBits )
    {
	/*
	  plan a: put all into the first granule
	  This was preferred by someone designing a
	  real-time decoder...
	*/
	gi = (gr_info *) &(l3_side->gr[0].ch[0]);	
	
	if ( gi->part2_3_length + stuffingBits < 4095 )
	    gi->part2_3_length += stuffingBits;
	else
	{
	    /* plan b: distribute throughout the granules */
	    for (gr = 0; gr < mode_gr; gr++ )
		for (ch = 0; ch < stereo; ch++ )
		{
		    int extraBits, bitsThisGr;
		    gr_info *gi = (gr_info *) &(l3_side->gr[gr].ch[ch]);
		    if ( stuffingBits == 0 )
			break;
		    extraBits = 4095 - gi->part2_3_length;
		    bitsThisGr = extraBits < stuffingBits ? extraBits : stuffingBits;
		    gi->part2_3_length += bitsThisGr;
		    stuffingBits -= bitsThisGr;
		}
	    /*
	      If any stuffing bits remain, we elect to spill them
	      into ancillary data. The bitstream formatter will do this if
	      l3side->resvDrain is set
	    */
	    l3_side->resvDrain = stuffingBits;
	}
    }
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -