Plan 9 from Bell Labs’s /usr/web/sources/contrib/cnielsen/bladeenc/l3bitstream.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
			(c) Copyright 1998-2000 - 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.



	------------    Changes    ------------

	2000-12-04  Andre Piotrowski

	-	redesigned, reformatted, slightly optimized
*/

#include	<stdlib.h>
#include	<assert.h>

#include	"system.h"
#include	"common.h"

#include	"l3psy.h"
#include	"loop.h"
#include	"formatbitstream2.h"
#include	"huffman.h"

#include	"l3bitstream.h" /* the public interface */
#include	"l3bitstream-pvt.h"





static	int				stereo = 1;
static	frame_params	*fr_ps  = NULL;

static	int				PartHoldersInitialized = 0;



static	BitHolder		       *headerPH;
static	BitHolder		      *frameSIPH;
static	BitHolder		    *channelSIPH[MAX_CHANNELS];
static	BitHolder		   *spectrumSIPH[MAX_GRANULES][MAX_CHANNELS];
static	BitHolder		 *scaleFactorsPH[MAX_GRANULES][MAX_CHANNELS];
static	BitHolder		    *codedDataPH[MAX_GRANULES][MAX_CHANNELS];
static	BitHolder		 *userSpectrumPH[MAX_GRANULES][MAX_CHANNELS];
static	BitHolder		*userFrameDataPH;



static	BF_FrameData	sFrameData;
static	BF_FrameResults	sFrameResults;





/*
	III_format_bitstream()

	This is called after a frame of audio has been quantized and coded.
	It will write the encoded audio to the bitstream. Note that
	from a layer3 encoder's perspective the bit stream is primarily
	a series of main_data() blocks, with header and side information
	inserted at the proper locations to maintain framing. (See Figure A.7
	in the IS).
*/

void					III_format_bitstream
(
	int						bitsPerFrame,
	frame_params			*in_fr_ps,
	int						l3_enc[2][2][576],
	III_side_info_t			*l3_side,
	III_scalefac_t			*scalefac,
	double					(*xr)[2][576],
	char					*ancillary,
	int						ancillary_bits
)
{
	int						gr, ch, i, mode_gr;

	fr_ps = in_fr_ps;
	stereo = fr_ps->stereo;
	mode_gr = 2;

	if (!PartHoldersInitialized)
	{
		 headerPH = initBitHolder (&sFrameData.header, 16*2);
		frameSIPH = initBitHolder (&sFrameData.frameSI, 4*2);

		for (ch = 0;  ch < MAX_CHANNELS;  ch++)
			channelSIPH[ch] = initBitHolder (&sFrameData.channelSI[ch], 8*2);

		for (gr = 0;  gr < MAX_GRANULES;  gr++)
		{
			for (ch = 0;  ch < MAX_CHANNELS;  ch++)
			{
				  spectrumSIPH[gr][ch] = initBitHolder (&sFrameData.  spectrumSI[gr][ch],  32*2);
				scaleFactorsPH[gr][ch] = initBitHolder (&sFrameData.scaleFactors[gr][ch],  64*2);
				   codedDataPH[gr][ch] = initBitHolder (&sFrameData.   codedData[gr][ch], 576*2);
				userSpectrumPH[gr][ch] = initBitHolder (&sFrameData.userSpectrum[gr][ch],   4*2);
			}
		}
		userFrameDataPH = initBitHolder (&sFrameData.userFrameData, 8*2);

		PartHoldersInitialized = 1;
	}

#if 1
	for (gr = 0;  gr < mode_gr;  gr++)
	{
		for (ch = 0;  ch < stereo;  ch++)
		{
			int						*pi = &l3_enc[gr][ch][0];
			double					*pr =     &xr[gr][ch][0];

			for (i = 0;  i < 576;  i++, pr++, pi++)
				if (*pr < 0  &&  *pi > 0)
					*pi *= -1;
		}
	}
#endif

	encodeSideInfo (l3_side);
	encodeMainData (l3_enc, l3_side, scalefac);
	write_ancillary_data (ancillary, ancillary_bits);

	if (l3_side->resvDrain)
		drain_into_ancillary_data (l3_side->resvDrain);

	sFrameData.frameLength = bitsPerFrame;
	sFrameData.nGranules   = mode_gr;
	sFrameData.nChannels   = stereo;

	writeFrame (&sFrameData, &sFrameResults);

	/* we set this here -- it will be tested in the next loops iteration */
	l3_side->main_data_begin = sFrameResults.nextBackPtr;
}





void					III_FlushBitstream (void)
{
	int						gr, ch;

	if (PartHoldersInitialized)
	{
		exitBitHolder (&sFrameData.header);
		exitBitHolder (&sFrameData.frameSI);

		for (ch = 0;  ch < MAX_CHANNELS;  ch++)
			exitBitHolder (&sFrameData.channelSI[ch]);


		for (gr = 0;  gr < MAX_GRANULES;  gr++)
		{
			for (ch = 0;  ch < MAX_CHANNELS;  ch++)
			{
				exitBitHolder (&sFrameData.  spectrumSI[gr][ch]);
				exitBitHolder (&sFrameData.scaleFactors[gr][ch]);
				exitBitHolder (&sFrameData.   codedData[gr][ch]);
				exitBitHolder (&sFrameData.userSpectrum[gr][ch]);
			}
		}
		exitBitHolder (&sFrameData.userFrameData);

		PartHoldersInitialized = 0;
	}

	/* BF_FlushBitstream (frameData, frameResults); */
}





static	unsigned		slen1_tab[16] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 };
static	unsigned		slen2_tab[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 };





static	void			encodeMainData
(
	int						l3_enc[2][2][576],
	III_side_info_t			*side_info,
	III_scalefac_t			*scalefac
)
{
	int						gr, ch, sfb, b, mode_gr;

	mode_gr = 2;


	for (gr = 0;  gr < mode_gr;  gr++)
		for (ch = 0;  ch < stereo;  ch++)
			scaleFactorsPH[gr][ch]->nrEntries = 0;


	for (gr = 0;  gr < mode_gr;  gr++)
		for (ch = 0;  ch < stereo;  ch++)
			codedDataPH[gr][ch]->nrEntries = 0;


	for (gr = 0;  gr < 2;  gr++)
	{
		for (ch = 0;  ch < stereo;  ch++)
		{
			BitHolder				*ph = scaleFactorsPH[gr][ch];		
			gr_info					*cod_info = &side_info->gr[gr].ch[ch].tt;
			unsigned				slen1 = slen1_tab[cod_info->scalefac_compress];
			unsigned				slen2 = slen2_tab[cod_info->scalefac_compress];
			int						*ix = &l3_enc[gr][ch][0];

			if (cod_info->window_switching_flag  &&  cod_info->block_type == SHORT_TYPE)
			{
				if (cod_info->mixed_block_flag)
				{
					for (sfb = 0;  sfb < 8;  sfb++)
						addBits (ph, scalefac->l[gr][ch][sfb], slen1);

					for (sfb = 3;  sfb < 6;  sfb++)
						for (b = 0;  b < 3;  b++)
							addBits (ph, scalefac->s[gr][ch][sfb][b], slen1);
				}
				else
				{
					for (sfb = 0;  sfb < 6;  sfb++)
						for (b = 0;  b < 3;  b++)
							addBits (ph, scalefac->s[gr][ch][sfb][b], slen1);
				}

				for (sfb = 6;  sfb < 12;  sfb++)
					for (b = 0;  b < 3;  b++)
						addBits (ph, scalefac->s[gr][ch][sfb][b], slen2);
			}
			else if (gr == 0)
			{
				for (sfb = 0;  sfb < 11;  sfb++)
					addBits (ph, scalefac->l[gr][ch][sfb], slen1);

				for (sfb = 11;  sfb < 21;  sfb++)
					addBits (ph, scalefac->l[gr][ch][sfb], slen2);
			}
			else
			{
				if (!side_info->scfsi[ch][0])
					for (sfb = 0;  sfb < 6;  sfb++)
						addBits (ph, scalefac->l[gr][ch][sfb], slen1);

				if (!side_info->scfsi[ch][1])
					for (sfb = 6;  sfb < 11;  sfb++)
						addBits (ph, scalefac->l[gr][ch][sfb], slen1);

				if (!side_info->scfsi[ch][2])
					for (sfb = 11;  sfb < 16;  sfb++)
						addBits (ph, scalefac->l[gr][ch][sfb], slen2);

				if (!side_info->scfsi[ch][3])
					for (sfb = 16;  sfb < 21;  sfb++)
						addBits (ph, scalefac->l[gr][ch][sfb], slen2);
			}

			Huffmancodebits (codedDataPH[gr][ch], ix, cod_info);
		} /* for ch */
	} /* for gr */
} /* main_data */





/*____ encodeSideInfo() _____________________________________________________*/

static	int				encodeSideInfo (III_side_info_t *side_info)
{
	int						gr, ch, scfsi_band, region, b, bits_sent, mode_gr;
	layer					*info = fr_ps->header;

	mode_gr =  2;


	headerPH->nrEntries = 0;

	addBits (headerPH, 0xfff                   , 12);
	addBits (headerPH, 1                       ,  1);
	addBits (headerPH, 4 - 3                   ,  2);   /* 4 - Layer */
	addBits (headerPH, !info->error_protection ,  1);
	addBits (headerPH, info->bitrate_index     ,  4);
	addBits (headerPH, info->sampling_frequency,  2);
	addBits (headerPH, info->padding           ,  1);
	addBits (headerPH, info->extension         ,  1);
	addBits (headerPH, info->mode              ,  2);
	addBits (headerPH, info->mode_ext          ,  2);
	addBits (headerPH, info->copyright         ,  1);
	addBits (headerPH, info->original          ,  1);
	addBits (headerPH, info->emphasis          ,  2);

	bits_sent = 32;

	if (info->error_protection)
	{
		addBits (headerPH, 0, 16);   /* Just a dummy add. Real CRC calculated & inserted in writeSideInfo() */
		bits_sent += 16;
	}


	frameSIPH->nrEntries = 0;

	addBits (frameSIPH, side_info->main_data_begin, 9);

	if (stereo == 2)
		addBits (frameSIPH, side_info->private_bits, 3);
	else
		addBits (frameSIPH, side_info->private_bits, 5);


	for (ch = 0;  ch < stereo;  ch++)
	{
		BitHolder				*ph = channelSIPH[ch];

		ph->nrEntries = 0;

		for (scfsi_band = 0;  scfsi_band < 4;  scfsi_band++)
			addBits (ph, side_info->scfsi[ch][scfsi_band], 1);
	}


	for (gr = 0;  gr < 2;  gr++)
	{
		for (ch = 0;  ch < stereo;  ch++)
		{
			BitHolder				*ph = spectrumSIPH[gr][ch];
			gr_info					*cod_info = &side_info->gr[gr].ch[ch].tt;

			ph->nrEntries = 0;

			addBits (ph, cod_info->part2_3_length       , 12);
			addBits (ph, cod_info->big_values           ,  9);
			addBits (ph, cod_info->global_gain          ,  8);
			addBits (ph, cod_info->scalefac_compress    ,  4);
			addBits (ph, cod_info->window_switching_flag,  1);

			if (cod_info->window_switching_flag)
			{   
				addBits (ph, cod_info->block_type      , 2);
				addBits (ph, cod_info->mixed_block_flag, 1);

				for (region = 0; region < 2; region++)
					addBits (ph, cod_info->table_select[region], 5);

				for (b = 0;  b < 3;  b++)
					addBits (ph, cod_info->subblock_gain[b], 3);
			}
			else
			{
				for (region = 0; region < 3; region++)
					addBits (ph, cod_info->table_select[region], 5);

				addBits (ph, cod_info->region0_count, 4);
				addBits (ph, cod_info->region1_count, 3);
			}

			addBits (ph, cod_info->preflag           , 1);
			addBits (ph, cod_info->scalefac_scale    , 1);
			addBits (ph, cod_info->count1table_select, 1);
		}
	}


	if (stereo == 2)
		bits_sent += 256;
	else
		bits_sent += 136;


	return bits_sent;
}





/*____ write_ancillary_data() _______________________________________________*/

static	void			write_ancillary_data
(
	char					*theData,
	int						lengthInBits
)
{
	int						bytesToSend   = lengthInBits / 8;
	int						remainingBits = lengthInBits % 8;
	unsigned				wrd;

	userFrameDataPH->nrEntries = 0;

	while (bytesToSend--)
	{
		wrd = *theData++;
		addBits (userFrameDataPH, wrd, 8);
	}
	if (remainingBits)
	{
		/* right-justify remaining bits */
		wrd = *theData >> (8 - remainingBits);
		addBits (userFrameDataPH, wrd, remainingBits);
	}
}





/*
	Some combinations of bitrate, Fs, and stereo make it impossible to stuff
	out a frame using just main_data, due to the limited number of bits to
	indicate main_data_length. In these situations, we put stuffing bits into
	the ancillary data...
*/
static	void			drain_into_ancillary_data (int lengthInBits)
{
	int						wordsToSend   = lengthInBits / 32;
	int						remainingBits = lengthInBits % 32;

	/*
		userFrameDataPH->part->nrEntries set by call to write_ancillary_data()
	*/

	while (wordsToSend--)
		addBits (userFrameDataPH, 0, 32);
	if (remainingBits)
		addBits (userFrameDataPH, 0, remainingBits); 
}





/*
	Note the discussion of huffmancodebits() on pages 28
	and 29 of the IS, as well as the definitions of the side
	information on pages 26 and 27.
*/
static	void			Huffmancodebits
(
	BitHolder				*ph,
	int						*ix,
	gr_info					*cod_info
)
{
	int						sfb, window, line, start, end;
	int						stuffingBits, table;

	int						bitsWritten = 0;
	int						bigvalues   = cod_info->big_values * 2;


	/*
		Within each scalefactor band, data is given for successive time windows,
		beginning with window 0 and ending with window 2 (in case of short blocks!
		--- there is only one long block window). Within each window, the quantized
		values are then arranged in order of increasing frequency...
	*/

	/* 1: Write the bigvalues */
	if (bigvalues)
	{
		if (cod_info->window_switching_flag  &&  (cod_info->block_type == SHORT_TYPE))
		{
			int							(*ix_s)[3] = (int (*)[3]) ix;
			int							*scalefac = &sfBandIndex[fr_ps->header->sampling_frequency].s[0];

			table = cod_info->table_select[0];
			if (table)
			{
				if (cod_info->mixed_block_flag)  /* Mixed blocks long, short */
				{
					for (line=0; line<36; line+=2)   /* cod_info->address1 = 36 */
						bitsWritten += writeHuffmanCode (ph, table, ix[line], ix[line+1]);
				}
				else
				{
					for (sfb=0; sfb<3; sfb++)   /* (cod_info->region0_count + 1) / 3 = 3 */
					{
						start = scalefac[sfb];
						end   = scalefac[sfb+1];

						for (window=0; window<3; window++)
							for (line=start; line<end; line+=2)
								bitsWritten += writeHuffmanCode (ph, table, ix_s[line][window], ix_s[line+1][window]);
					}
				}
			}

			table = cod_info->table_select[1];
			if (table)
			{
				for (sfb=3; sfb<SFB_SMAX; sfb++)   /* scalefac[3] = 12 --- 12*3 = 36 */
				{
					start = scalefac[sfb];
					end   = scalefac[sfb+1]; 

					for (window=0; window<3; window++)
						for (line=start; line<end; line+=2)
							bitsWritten += writeHuffmanCode (ph, table, ix_s[line][window], ix_s[line+1][window]);
				}
			}
		}
		else   /* Long blocks */
		{
			int							region1Start = (cod_info->address1 > bigvalues) ? bigvalues : cod_info->address1;
			int							region2Start = (cod_info->address2 > bigvalues) ? bigvalues : cod_info->address2;

			table = cod_info->table_select[0];
			if (table)
				for (line=0; line<region1Start; line+=2)
					bitsWritten += writeHuffmanCode (ph, table, ix[line], ix[line+1]);

			table = cod_info->table_select[1];
			if (table)
				for (line=region1Start; line<region2Start; line+=2)
					bitsWritten += writeHuffmanCode (ph, table, ix[line], ix[line+1]);

			table = cod_info->table_select[2];
			if (table)
				for (line=region2Start; line<bigvalues; line+=2)
					bitsWritten += writeHuffmanCode (ph, table, ix[line], ix[line+1]);
		}
	}

	/* 2: Write count1 area */
	if (cod_info->count1)
	{
		struct huffcodetab		*h = ht + (cod_info->count1table_select + 32);

		int						*pos = ix + bigvalues;
		int						*end = ix + bigvalues + (cod_info->count1 * 4);

		while (pos < end)
		{
			int						len, v, w, x, y;
			int						bits = 0;
			int						p    = 0;

			v = *pos++;  if (v)  bits++, p |= 1;
			w = *pos++;  if (w)  bits++, p |= 2;
			x = *pos++;  if (x)  bits++, p |= 4;
			y = *pos++;  if (y)  bits++, p |= 8;

			addBits (ph, h->table[p], len = h->hlen[p]);

			if (v)  addBits (ph, v<0, 1);
			if (w)  addBits (ph, w<0, 1);
			if (x)  addBits (ph, x<0, 1);
			if (y)  addBits (ph, y<0, 1);

			bitsWritten += bits+len;
		}
	}


	stuffingBits = cod_info->part2_3_length - cod_info->part2_length - bitsWritten;
	if (stuffingBits)
	{
		int						stuffingWords = stuffingBits / 32;
		int						remainingBits = stuffingBits % 32;

		/*
			Due to the nature of the Huffman code
			tables, we will pad with ones
		*/
		while (stuffingWords--)
			addBits (ph, ~0, 32);
		if (remainingBits)
			addBits (ph, ~0, remainingBits);

		bitsWritten += stuffingBits;
	}
}





/*
	Implements the pseudocode of page 98 of the IS

	aaaaaaaaaaaaaaargh --- why don� write the code immediately?
*/

static	int				writeHuffmanCode
(
	BitHolder				*ph,
	int						table,
	int						x,
	int						y
)
{
	struct huffcodetab		*h = ht + table;

	unsigned				signx = (x <= 0) ? (x = -x, 1) : 0;
	unsigned				signy = (y <= 0) ? (y = -y, 1) : 0;

	unsigned				code, cbits, idx;

assert (table);
/*
	if (table == 0)
		return 0;
*/

	if (table > 15)   /* ESC-table is used */
	{
		unsigned				linbits = h->linbits;
		unsigned				ext     = 0;
		unsigned				xbits   = 0;

		if (x)  {if (x > 14)  {ext =                    (x-15);  xbits += linbits;  x = 15;}  ext = (ext << 1) | signx;  xbits++;}
		if (y)  {if (y > 14)  {ext = (ext << linbits) | (y-15);  xbits += linbits;  y = 15;}  ext = (ext << 1) | signy;  xbits++;}

		idx   = x * h->ylen + y;
		code  = h->table[idx];
		cbits = h->hlen[idx];

		addBits (ph, code, cbits);
		addBits (ph, ext , xbits);

		return cbits + xbits;
	}
	else   /* No ESC-words */
	{
		idx   = x * h->ylen + y;
		code  = h->table[idx];
		cbits = h->hlen[idx];

		if (x)  {code = (code << 1) | signx;  cbits++;}
		if (y)  {code = (code << 1) | signy;  cbits++;}

		addBits (ph, code, cbits);

		return cbits;
	}
}




Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.