--- /dev/null
+/*
+ (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«t 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;
+ }
+}
+
+
+