rockbox/lib/rbcodec/codecs/mp3_enc.c
Michael Sevakis 6c868dd48f Remove explicit 'enum codec_command_action' in codec API
Just use long so the compiler potentially doesn't complain about
use of other values not in the enum. It's also the type used
around the system for event ids.

Increase min codec API version.

No functional changes.

Change-Id: If4419b42912f5e4ef673adcdeb69313e503f94cc
2017-12-07 14:41:59 -05:00

3060 lines
118 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 Antonius Hellmann
* Copyright (C) 2006-2013 Michael Sevakis
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
// Shine is an MP3 encoder
// Copyright (C) 1999-2000 Gabriel Bouvigne
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
#include <inttypes.h>
#include <stdio.h>
#include "codeclib.h"
CODEC_ENC_HEADER
#if NUM_CORES > 1
#define MP3_ENC_COP
#endif
typedef struct
{
int type; /* 0=(MPEG2 - 22.05,24,16kHz) 1=(MPEG1 - 44.1,48,32kHz) */
int mode; /* 0=stereo, 1=jstereo, 2=dual, 3=mono */
int bitrate;
int padding;
int num_bands;
long bitr_id;
int smpl_id;
} mpeg_t;
/* Side information */
typedef struct
{
uint32_t part2_3_length;
int count1; /* number of 0-1-quadruples */
uint32_t global_gain;
uint32_t table_select[4];
uint32_t region_0_1;
uint32_t address1;
uint32_t address2;
uint32_t address3;
long quantStep;
long additStep;
uint32_t max_val;
} side_info_t;
typedef struct
{
side_info_t cod_info[2][2];
mpeg_t mpg;
long frac_per_frame;
long byte_per_frame;
long req_byte_per_frame;
long slot_lag;
int sideinfo_len;
int mean_bits;
int resv_size;
int channels;
int granules;
long src_samplerate;
long samplerate;
short *samp_buffer;
unsigned samp_per_frame;
int flush_frames;
int delay;
int padding;
} config_t;
typedef struct
{
int bitpos; /* current bitpos for writing */
uint32_t bbuf[362];
} bf_data;
struct huffcodetab
{
int len; /* max. index */
const uint8_t *table; /* pointer to array[len][len] */
const uint8_t *hlen; /* pointer to array[len][len] */
};
struct huffcodebig
{
int len; /* max. index */
int linbits; /* number of linbits */
int linmax; /* max number stored in linbits */
};
#define shft4(x) (((x) + 8) >> 4)
#define shft9(x) (((x) + 256) >> 9)
#define shft13(x) (((x) + 4096) >> 13)
#define shft15(x) (((x) + 16384) >> 15)
#define shft16(x) (((x) + 32768) >> 16)
#define shft_n(x, n) ( (x) >> (n))
#define SQRT 724 /* sqrt(2) * 512 */
static config_t cfg IBSS_ATTR;
static short mfbuf [2*(1152+512)] IBSS_ATTR
/* for memcpy and 32-bit access */ MEM_ALIGN_ATTR; /* 6656 Bytes */
static int sb_data [2][2][18][32] IBSS_ATTR; /* 9216 Bytes */
static int mdct_freq [576] IBSS_ATTR; /* 2304 Bytes */
static char mdct_sign [576] IBSS_ATTR; /* 576 Bytes */
static short enc_data [576] IBSS_ATTR; /* 1152 Bytes */
static uint32_t scalefac [22] IBSS_ATTR; /* 88 Bytes */
static bf_data coded_data IBSS_ATTR; /* 1448 Bytes */
static uint8_t band_scale_f[22] IBSS_ATTR; /* 22 Bytes */
#ifdef MP3_ENC_COP
/* 2-entry circular buffer to pass subband data between threads */
/* 18432 bytes is way too much for IRAM and it must be in coherent RAM */
static int sb_data_buf[2][2][2][18][32] SHAREDBSS_ATTR
MEM_ALIGN_ATTR;
static int (*sb_data_cod)[2][2][18][32] IBSS_ATTR; /* 4 Bytes */
static int (*sb_data_enc)[2][2][18][32] IBSS_ATTR; /* 4 Bytes */
#endif /* MP3_ENC_COP */
static const uint8_t ht_count[2][2][16] ICONST_ATTR =
{ { { 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1 }, /* table0 */
{ 1, 5, 5, 7, 5, 8, 7, 9, 5, 7, 7, 9, 7, 9, 9,10 } }, /* hleng0 */
{ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, /* table1 */
{ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 } } }; /* hleng1 */
static const uint8_t t1HB[4] ICONST_ATTR =
{ 1, 1, 1, 0 };
static const uint8_t t2HB[9] ICONST_ATTR =
{ 1, 2, 1, 3, 1, 1, 3, 2, 0 };
static const uint8_t t3HB[9] ICONST_ATTR =
{ 3, 2, 1, 1, 1, 1, 3, 2, 0 };
static const uint8_t t5HB[16] ICONST_ATTR =
{ 1, 2, 6, 5, 3, 1, 4, 4, 7, 5, 7, 1, 6, 1, 1, 0 };
static const uint8_t t6HB[16] ICONST_ATTR =
{ 7, 3, 5, 1, 6, 2, 3, 2, 5, 4, 4, 1, 3, 3, 2 ,0 };
static const uint8_t t7HB[36] ICONST_ATTR =
{ 1, 2,10,19,16,10, 3, 3, 7,10, 5, 3,11, 4,13,17, 8, 4,
12,11,18,15,11, 2, 7, 6, 9,14, 3, 1, 6, 4, 5, 3, 2, 0 };
static const uint8_t t8HB[36] ICONST_ATTR =
{ 3, 4, 6,18,12, 5, 5, 1, 2,16, 9, 3, 7, 3, 5,14, 7, 3,
19,17,15,13,10, 4,13, 5, 8,11, 5, 1,12, 4, 4, 1, 1, 0 };
static const uint8_t t9HB[36] ICONST_ATTR =
{ 7, 5, 9,14,15, 7, 6, 4, 5, 5, 6, 7, 7, 6, 8, 8, 8, 5,
15, 6, 9,10, 5, 1,11, 7, 9, 6, 4, 1,14, 4, 6, 2, 6, 0 };
static const uint8_t t10HB[64] ICONST_ATTR =
{ 1, 2,10,23,35,30,12,17, 3, 3, 8,12,18,21,12, 7,
11, 9,15,21,32,40,19, 6,14,13,22,34,46,23,18, 7,
20,19,33,47,27,22, 9, 3,31,22,41,26,21,20, 5, 3,
14,13,10,11,16, 6, 5, 1, 9, 8, 7, 8, 4, 4, 2, 0 };
static const uint8_t t11HB[64] ICONST_ATTR =
{ 3, 4,10,24,34,33,21,15, 5, 3, 4,10,32,17,11,10,
11, 7,13,18,30,31,20, 5,25,11,19,59,27,18,12, 5,
35,33,31,58,30,16, 7, 5,28,26,32,19,17,15, 8,14,
14,12, 9,13,14, 9, 4, 1,11, 4, 6, 6, 6, 3, 2, 0 };
static const uint8_t t12HB[64] ICONST_ATTR =
{ 9, 6,16,33,41,39,38,26, 7, 5, 6, 9,23,16,26,11,
17, 7,11,14,21,30,10, 7,17,10,15,12,18,28,14, 5,
32,13,22,19,18,16, 9, 5,40,17,31,29,17,13, 4, 2,
27,12,11,15,10, 7, 4, 1,27,12, 8,12, 6, 3, 1, 0 };
static const uint8_t t13HB[256] ICONST_ATTR =
{ 1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19,
3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14,
15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16,
22, 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14,
35, 16, 60, 57, 97, 75,114, 91, 54, 73, 55, 41, 48, 53, 23, 24,
58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17,
47, 45, 78, 74,115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15,
72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42,
43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16,
53, 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11,
35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22,
53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7,
34, 32, 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5,
45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3,
48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2,
16, 15, 17, 27, 25, 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1 };
static const uint8_t t15HB[256] ICONST_ATTR =
{ 7, 12, 18, 53, 47, 76,124,108, 89,123,108,119,107, 81,122, 63,
13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36,
19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, 33,
29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29,
52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27,
77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38,
125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30,
109, 53, 49, 94, 88, 75, 66,122, 91, 73, 56, 42, 64, 44, 21, 25,
90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20,
71, 34, 67, 60, 58, 49, 88, 76, 67,106, 71, 54, 38, 39, 23, 15,
109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9,
86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11,
118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7,
91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3,
123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1,
71, 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0 };
static const uint16_t t16HB[256] ICONST_ATTR =
{ 1, 5, 14, 44, 74, 63,110, 93,172, 149, 138,242, 225, 195, 376, 17,
3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68,119, 201, 107, 207, 9,
15, 13, 23, 38, 67, 58,103, 90,161, 72, 127,117, 110, 209, 206, 16,
45, 21, 39, 69, 64,114, 99, 87,158, 140, 252,212, 199, 387, 365, 26,
75, 36, 68, 65,115,101,179,164,155, 264, 246,226, 395, 382, 362, 9,
66, 30, 59, 56,102,185,173,265,142, 253, 232,400, 388, 378, 445, 16,
111, 54, 52,100,184,178,160,133,257, 244, 228,217, 385, 366, 715, 10,
98, 48, 91, 88,165,157,148,261,248, 407, 397,372, 380, 889, 884, 8,
85, 84, 81,159,156,143,260,249,427, 401, 392,383, 727, 713, 708, 7,
154, 76, 73,141,131,256,245,426,406, 394, 384,735, 359, 710, 352, 11,
139,129, 67,125,247,233,229,219,393, 743, 737,720, 885, 882, 439, 4,
243,120,118,115,227,223,396,746,742, 736, 721,712, 706, 223, 436, 6,
202,224,222,218,216,389,386,381,364, 888, 443,707, 440, 437,1728, 4,
747,211,210,208,370,379,734,723,714,1735, 883,877, 876,3459, 865, 2,
377,369,102,187,726,722,358,711,709, 866,1734,871,3458, 870, 434, 0,
12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3 };
static const uint16_t t24HB[256] ICONST_ATTR =
{ 15, 13, 46, 80,146,262,248,434,426,669,653,649,621,517,1032, 88,
14, 12, 21, 38, 71,130,122,216,209,198,327,345,319,297, 279, 42,
47, 22, 41, 74, 68,128,120,221,207,194,182,340,315,295, 541, 18,
81, 39, 75, 70,134,125,116,220,204,190,178,325,311,293, 271, 16,
147, 72, 69,135,127,118,112,210,200,188,352,323,306,285, 540, 14,
263, 66,129,126,119,114,214,202,192,180,341,317,301,281, 262, 12,
249,123,121,117,113,215,206,195,185,347,330,308,291,272, 520, 10,
435,115,111,109,211,203,196,187,353,332,313,298,283,531, 381, 17,
427,212,208,205,201,193,186,177,169,320,303,286,268,514, 377, 16,
335,199,197,191,189,181,174,333,321,305,289,275,521,379, 371, 11,
668,184,183,179,175,344,331,314,304,290,277,530,383,373, 366, 10,
652,346,171,168,164,318,309,299,287,276,263,513,375,368, 362, 6,
648,322,316,312,307,302,292,284,269,261,512,376,370,364, 359, 4,
620,300,296,294,288,282,273,266,515,380,374,369,365,361, 357, 2,
1033,280,278,274,267,264,259,382,378,372,367,363,360,358, 356, 0,
43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3 };
static const uint32_t tab1315[256] ICONST_ATTR =
{ 0x010003,0x050005,0x070006,0x080008,0x090008,0x0a0009,0x0a000a,0x0b000a,
0x0a000a,0x0b000b,0x0c000b,0x0c000c,0x0d000c,0x0d000c,0x0e000d,0x0e000e,
0x040005,0x060005,0x080007,0x090008,0x0a0009,0x0a0009,0x0b000a,0x0b000a,
0x0b000a,0x0b000b,0x0c000b,0x0c000c,0x0d000c,0x0e000c,0x0e000d,0x0e000d,
0x070006,0x080007,0x090007,0x0a0008,0x0b0009,0x0b0009,0x0c000a,0x0c000a,
0x0b000a,0x0c000b,0x0c000b,0x0d000c,0x0d000c,0x0e000d,0x0f000d,0x0f000d,
0x080007,0x090008,0x0a0008,0x0b0009,0x0b0009,0x0c000a,0x0c000a,0x0c000b,
0x0c000b,0x0d000b,0x0d000c,0x0d000c,0x0d000c,0x0e000d,0x0f000d,0x0f000d,
0x090008,0x090008,0x0b0009,0x0b0009,0x0c000a,0x0c000a,0x0d000b,0x0d000b,
0x0c000b,0x0d000b,0x0d000c,0x0e000c,0x0e000c,0x0f000d,0x0f000d,0x10000d,
0x0a0009,0x0a0009,0x0b0009,0x0c000a,0x0c000a,0x0c000a,0x0d000b,0x0d000b,
0x0d000b,0x0d000b,0x0e000c,0x0d000c,0x0f000d,0x0f000d,0x10000d,0x10000e,
0x0a000a,0x0b0009,0x0c000a,0x0c000a,0x0d000a,0x0d000b,0x0d000b,0x0d000b,
0x0d000b,0x0e000c,0x0e000c,0x0e000c,0x0f000d,0x0f000d,0x10000e,0x10000e,
0x0b000a,0x0b000a,0x0c000a,0x0d000b,0x0d000b,0x0d000b,0x0e000b,0x0e000c,
0x0e000c,0x0e000c,0x0f000c,0x0f000c,0x0f000d,0x10000d,0x12000d,0x12000e,
0x0a000a,0x0a000a,0x0b000a,0x0c000b,0x0c000b,0x0d000b,0x0d000b,0x0e000c,
0x0e000c,0x0e000c,0x0e000c,0x0f000d,0x0f000d,0x10000e,0x11000e,0x11000e,
0x0b000a,0x0b000a,0x0c000b,0x0c000b,0x0d000b,0x0d000b,0x0d000c,0x0f000c,
0x0e000c,0x0f000d,0x0f000d,0x10000d,0x10000d,0x10000e,0x12000e,0x11000e,
0x0b000b,0x0c000b,0x0c000b,0x0d000b,0x0d000c,0x0e000c,0x0e000c,0x0f000c,
0x0e000c,0x0f000d,0x10000d,0x0f000d,0x10000d,0x11000e,0x12000f,0x13000e,
0x0c000b,0x0c000b,0x0c000b,0x0d000b,0x0e000c,0x0e000c,0x0e000c,0x0e000c,
0x0f000d,0x0f000d,0x0f000d,0x10000d,0x11000e,0x11000e,0x11000e,0x12000f,
0x0c000c,0x0d000c,0x0d000b,0x0e000c,0x0e000c,0x0f000c,0x0e000d,0x0f000d,
0x10000d,0x10000d,0x11000d,0x11000d,0x11000e,0x12000e,0x12000f,0x12000f,
0x0d000c,0x0d000c,0x0e000c,0x0f000c,0x0f000c,0x0f000d,0x10000d,0x10000d,
0x10000d,0x10000e,0x10000e,0x11000e,0x12000e,0x11000e,0x12000f,0x12000f,
0x0e000d,0x0e000d,0x0e000d,0x0f000d,0x0f000d,0x0f000d,0x11000d,0x10000d,
0x10000e,0x13000e,0x11000e,0x11000e,0x11000f,0x13000f,0x12000e,0x12000f,
0x0d000d,0x0e000d,0x0f000d,0x10000d,0x10000d,0x10000d,0x11000d,0x10000e,
0x11000e,0x11000e,0x12000e,0x12000e,0x15000f,0x14000f,0x15000f,0x12000f };
static const uint32_t tab01[16] ICONST_ATTR =
{ 0x10004,0x50005,0x50005,0x70006,0x50005,0x80006,0x70006,0x90007,
0x50005,0x70006,0x70006,0x90007,0x70006,0x90007,0x90007,0xa0008 };
static const uint32_t tab23[ 9] ICONST_ATTR =
{ 0x10002,0x40003,0x70007,0x40004,0x50004,0x70007,0x60006,0x70007,0x80008 };
static const uint32_t tab56[16] ICONST_ATTR =
{ 0x10003,0x40004,0x70006,0x80008,0x40004,0x50004,0x80006,0x90007,
0x70005,0x80006,0x90007,0xa0008,0x80007,0x80007,0x90008,0xa0009 };
static const uint32_t tab789[36] ICONST_ATTR =
{ 0x100803,0x401004,0x701c06,0x902407,0x902409,0xa0280a,0x401004,0x601005,
0x801806,0x902807,0x902808,0xa0280a,0x701c05,0x701806,0x902007,0xa02808,
0xa02809,0xb02c0a,0x802407,0x902807,0xa02808,0xb02c09,0xb02c09,0xb0300a,
0x802408,0x902408,0xa02809,0xb02c09,0xb0300a,0xc0300b,0x902809,0xa02809,
0xb02c0a,0xc02c0a,0xc0340b,0xc0340b };
static const uint32_t tabABC[64] ICONST_ATTR =
{ 0x100804,0x401004,0x701806,0x902008,0xa02409,0xa0280a,0xa0240a,0xb0280a,
0x401004,0x601405,0x801806,0x902007,0xa02809,0xb02809,0xa0240a,0xa0280a,
0x701806,0x801c06,0x902007,0xa02408,0xb02809,0xc02c0a,0xb02809,0xb0280a,
0x802007,0x902007,0xa02408,0xb02c08,0xc02809,0xc0300a,0xb0280a,0xc02c0a,
0x902408,0xa02808,0xb02809,0xc02c09,0xc02c0a,0xc0300a,0xc02c0a,0xc0300b,
0xa02409,0xb02809,0xc02c0a,0xc0300a,0xd0300a,0xd0340b,0xc0300a,0xd0340b,
0x902409,0xa02409,0xb02409,0xc0280a,0xc02c0a,0xc0300b,0xd0300b,0xd0300c,
0xa0240a,0xa0240a,0xb0280a,0xc02c0b,0xc0300b,0xd0300b,0xd0300b,0xd0300c };
static const uint32_t tab1624[256] ICONST_ATTR =
{ 0x010004,0x050005,0x070007,0x090008,0x0a0009,0x0a000a,0x0b000a,0x0b000b,
0x0c000b,0x0c000c,0x0c000c,0x0d000c,0x0d000c,0x0d000c,0x0e000d,0x0a000a,
0x040005,0x060006,0x080007,0x090008,0x0a0009,0x0b000a,0x0b000a,0x0b000b,
0x0c000b,0x0c000b,0x0c000c,0x0d000c,0x0e000c,0x0d000c,0x0e000c,0x0a000a,
0x070007,0x080007,0x090008,0x0a0009,0x0b0009,0x0b000a,0x0c000a,0x0c000b,
0x0d000b,0x0c000b,0x0d000b,0x0d000c,0x0d000c,0x0e000c,0x0e000d,0x0b0009,
0x090008,0x090008,0x0a0009,0x0b0009,0x0b000a,0x0c000a,0x0c000a,0x0c000b,
0x0d000b,0x0d000b,0x0e000b,0x0e000c,0x0e000c,0x0f000c,0x0f000c,0x0c0009,
0x0a0009,0x0a0009,0x0b0009,0x0b000a,0x0c000a,0x0c000a,0x0d000a,0x0d000b,
0x0d000b,0x0e000b,0x0e000c,0x0e000c,0x0f000c,0x0f000c,0x0f000d,0x0b0009,
0x0a000a,0x0a0009,0x0b000a,0x0b000a,0x0c000a,0x0d000a,0x0d000b,0x0e000b,
0x0d000b,0x0e000b,0x0e000c,0x0f000c,0x0f000c,0x0f000c,0x10000c,0x0c0009,
0x0b000a,0x0b000a,0x0b000a,0x0c000a,0x0d000a,0x0d000b,0x0d000b,0x0d000b,
0x0e000b,0x0e000c,0x0e000c,0x0e000c,0x0f000c,0x0f000c,0x10000d,0x0c0009,
0x0b000b,0x0b000a,0x0c000a,0x0c000a,0x0d000b,0x0d000b,0x0d000b,0x0e000b,
0x0e000c,0x0f000c,0x0f000c,0x0f000c,0x0f000c,0x11000d,0x11000d,0x0c000a,
0x0b000b,0x0c000b,0x0c000b,0x0d000b,0x0d000b,0x0d000b,0x0e000b,0x0e000b,
0x0f000b,0x0f000c,0x0f000c,0x0f000c,0x10000c,0x10000d,0x10000d,0x0c000a,
0x0c000b,0x0c000b,0x0c000b,0x0d000b,0x0d000b,0x0e000b,0x0e000b,0x0f000c,
0x0f000c,0x0f000c,0x0f000c,0x10000c,0x0f000d,0x10000d,0x0f000d,0x0d000a,
0x0c000c,0x0d000b,0x0c000b,0x0d000b,0x0e000b,0x0e000c,0x0e000c,0x0e000c,
0x0f000c,0x10000c,0x10000c,0x10000d,0x11000d,0x11000d,0x10000d,0x0c000a,
0x0d000c,0x0d000c,0x0d000b,0x0d000b,0x0e000b,0x0e000c,0x0f000c,0x10000c,
0x10000c,0x10000c,0x10000c,0x10000d,0x10000d,0x0f000d,0x10000d,0x0d000a,
0x0d000c,0x0e000c,0x0e000c,0x0e000c,0x0e000c,0x0f000c,0x0f000c,0x0f000c,
0x0f000c,0x11000c,0x10000d,0x10000d,0x10000d,0x10000d,0x12000d,0x0d000a,
0x0f000c,0x0e000c,0x0e000c,0x0e000c,0x0f000c,0x0f000c,0x10000c,0x10000c,
0x10000d,0x12000d,0x11000d,0x11000d,0x11000d,0x13000d,0x11000d,0x0d000a,
0x0e000d,0x0f000c,0x0d000c,0x0e000c,0x10000c,0x10000c,0x0f000c,0x10000d,
0x10000d,0x11000d,0x12000d,0x11000d,0x13000d,0x11000d,0x10000d,0x0d000a,
0x0a0009,0x0a0009,0x0a0009,0x0b0009,0x0b0009,0x0c0009,0x0c0009,0x0c0009,
0x0d0009,0x0d0009,0x0d0009,0x0d000a,0x0d000a,0x0d000a,0x0d000a,0x0a0006 };
static const uint8_t t1l[8] ICONST_ATTR =
{ 1,3,2,3,1,4,3,5 };
static const uint8_t t2l[9] ICONST_ATTR =
{ 1,3,6,3,3,5,5,5,6 };
static const uint8_t t3l[9] ICONST_ATTR =
{ 2,2,6,3,2,5,5,5,6 };
static const uint8_t t5l[16] ICONST_ATTR =
{ 1,3,6,7,3,3,6,7,6,6,7,8,7,6,7,8 };
static const uint8_t t6l[16] ICONST_ATTR =
{ 3,3,5,7,3,2,4,5,4,4,5,6,6,5,6,7 };
static const uint8_t t7l[36] ICONST_ATTR =
{ 1, 3, 6, 8, 8, 9, 3, 4, 6, 7, 7, 8, 6, 5, 7, 8, 8, 9,
7, 7, 8, 9, 9, 9, 7, 7, 8, 9, 9,10, 8, 8, 9,10,10,10 };
static const uint8_t t8l[36] ICONST_ATTR =
{ 2, 3, 6, 8, 8, 9, 3, 2, 4, 8, 8, 8, 6, 4, 6, 8, 8, 9,
8, 8, 8, 9, 9,10, 8, 7, 8, 9,10,10, 9, 8, 9, 9,11,11 };
static const uint8_t t9l[36] ICONST_ATTR =
{ 3, 3, 5, 6, 8, 9, 3, 3, 4, 5, 6, 8, 4, 4, 5, 6, 7, 8,
6, 5, 6, 7, 7, 8, 7, 6, 7, 7, 8, 9, 8, 7, 8, 8, 9, 9 };
static const uint8_t t10l[64] ICONST_ATTR =
{ 1, 3, 6, 8, 9, 9, 9,10, 3, 4, 6, 7, 8, 9, 8, 8,
6, 6, 7, 8, 9,10, 9, 9, 7, 7, 8, 9,10,10, 9,10,
8, 8, 9,10,10,10,10,10, 9, 9,10,10,11,11,10,11,
8, 8, 9,10,10,10,11,11, 9, 8, 9,10,10,11,11,11 };
static const uint8_t t11l[64] ICONST_ATTR =
{ 2, 3, 5, 7, 8, 9, 8, 9, 3, 3, 4, 6, 8, 8, 7, 8,
5, 5, 6, 7, 8, 9, 8, 8, 7, 6, 7, 9, 8,10, 8, 9,
8, 8, 8, 9, 9,10, 9,10, 8, 8, 9,10,10,11,10,11,
8, 7, 7, 8, 9,10,10,10, 8, 7, 8, 9,10,10,10,10 };
static const uint8_t t12l[64] ICONST_ATTR =
{ 4, 3, 5, 7, 8, 9, 9, 9, 3, 3, 4, 5, 7, 7, 8, 8,
5, 4, 5, 6, 7, 8, 7, 8, 6, 5, 6, 6, 7, 8, 8, 8,
7, 6, 7, 7, 8, 8, 8, 9, 8, 7, 8, 8, 8, 9, 8, 9,
8, 7, 7, 8, 8, 9, 9,10, 9, 8, 8, 9, 9, 9, 9,10 };
static const uint8_t t13l[256] ICONST_ATTR =
{ 1, 4, 6, 7, 8, 9, 9,10, 9,10,11,11,12,12,13,13,
3, 4, 6, 7, 8, 8, 9, 9, 9, 9,10,10,11,12,12,12,
6, 6, 7, 8, 9, 9,10,10, 9,10,10,11,11,12,13,13,
7, 7, 8, 9, 9,10,10,10,10,11,11,11,11,12,13,13,
8, 7, 9, 9,10,10,11,11,10,11,11,12,12,13,13,14,
9, 8, 9,10,10,10,11,11,11,11,12,11,13,13,14,14,
9, 9,10,10,11,11,11,11,11,12,12,12,13,13,14,14,
10, 9,10,11,11,11,12,12,12,12,13,13,13,14,16,16,
9, 8, 9,10,10,11,11,12,12,12,12,13,13,14,15,15,
10, 9,10,10,11,11,11,13,12,13,13,14,14,14,16,15,
10,10,10,11,11,12,12,13,12,13,14,13,14,15,16,17,
11,10,10,11,12,12,12,12,13,13,13,14,15,15,15,16,
11,11,11,12,12,13,12,13,14,14,15,15,15,16,16,16,
12,11,12,13,13,13,14,14,14,14,14,15,16,15,16,16,
13,12,12,13,13,13,15,14,14,17,15,15,15,17,16,16,
12,12,13,14,14,14,15,14,15,15,16,16,19,18,19,16 };
static const uint8_t t15l[256] ICONST_ATTR =
{ 3, 4, 5, 7, 7, 8, 9, 9, 9,10,10,11,11,11,12,13,
4, 3, 5, 6, 7, 7, 8, 8, 8, 9, 9,10,10,10,11,11,
5, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9,10,10,11,11,11,
6, 6, 6, 7, 7, 8, 8, 9, 9, 9,10,10,10,11,11,11,
7, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,11,11,11,
8, 7, 7, 8, 8, 8, 9, 9, 9, 9,10,10,11,11,11,12,
9, 7, 8, 8, 8, 9, 9, 9, 9,10,10,10,11,11,12,12,
9, 8, 8, 9, 9, 9, 9,10,10,10,10,10,11,11,11,12,
9, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,12,12,12,
9, 8, 9, 9, 9, 9,10,10,10,11,11,11,11,12,12,12,
10, 9, 9, 9,10,10,10,10,10,11,11,11,11,12,13,12,
10, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,13,
11,10, 9,10,10,10,11,11,11,11,11,11,12,12,13,13,
11,10,10,10,10,11,11,11,11,12,12,12,12,12,13,13,
12,11,11,11,11,11,11,11,12,12,12,12,13,13,12,13,
12,11,11,11,11,11,11,12,12,12,12,12,13,13,13,13 };
static const uint8_t t16l[256] ICONST_ATTR =
{ 1, 4, 6, 8, 9, 9,10,10,11,11,11,12,12,12,13, 9,
3, 4, 6, 7, 8, 9, 9, 9,10,10,10,11,12,11,12, 8,
6, 6, 7, 8, 9, 9,10,10,11,10,11,11,11,12,12, 9,
8, 7, 8, 9, 9,10,10,10,11,11,12,12,12,13,13,10,
9, 8, 9, 9,10,10,11,11,11,12,12,12,13,13,13, 9,
9, 8, 9, 9,10,11,11,12,11,12,12,13,13,13,14,10,
10, 9, 9,10,11,11,11,11,12,12,12,12,13,13,14,10,
10, 9,10,10,11,11,11,12,12,13,13,13,13,15,15,10,
10,10,10,11,11,11,12,12,13,13,13,13,14,14,14,10,
11,10,10,11,11,12,12,13,13,13,13,14,13,14,13,11,
11,11,10,11,12,12,12,12,13,14,14,14,15,15,14,10,
12,11,11,11,12,12,13,14,14,14,14,14,14,13,14,11,
12,12,12,12,12,13,13,13,13,15,14,14,14,14,16,11,
14,12,12,12,13,13,14,14,14,16,15,15,15,17,15,11,
13,13,11,12,14,14,13,14,14,15,16,15,17,15,14,11,
9, 8, 8, 9, 9,10,10,10,11,11,11,11,11,11,11, 8 };
static const uint8_t t24l[256] ICONST_ATTR =
{ 4, 4, 6, 7, 8, 9, 9,10,10,11,11,11,11,11,12, 9,
4, 4, 5, 6, 7, 8, 8, 9, 9, 9,10,10,10,10,10, 8,
6, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9,10,10,10,11, 7,
7, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9,10,10,10,10, 7,
8, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,10,10,10,11, 7,
9, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,10, 7,
9, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,10,11, 7,
10, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,10,11,11, 8,
10, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,11,11, 8,
10, 9, 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11, 8,
11, 9, 9, 9, 9,10,10,10,10,10,10,11,11,11,11, 8,
11,10, 9, 9, 9,10,10,10,10,10,10,11,11,11,11, 8,
11,10,10,10,10,10,10,10,10,10,11,11,11,11,11, 8,
11,10,10,10,10,10,10,10,11,11,11,11,11,11,11, 8,
12,10,10,10,10,10,10,11,11,11,11,11,11,11,11, 8,
8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 4 };
static const struct huffcodetab ht[16] ICONST_ATTR =
{ { 0, NULL, NULL }, /* Apparently not used */
{ 2, t1HB, t1l },
{ 3, t2HB, t2l },
{ 3, t3HB, t3l },
{ 0, NULL, NULL }, /* Apparently not used */
{ 4, t5HB, t5l },
{ 4, t6HB, t6l },
{ 6, t7HB, t7l },
{ 6, t8HB, t8l },
{ 6, t9HB, t9l },
{ 8, t10HB, t10l },
{ 8, t11HB, t11l },
{ 8, t12HB, t12l },
{ 16, t13HB, t13l },
{ 0, NULL, NULL }, /* Apparently not used */
{ 16, t15HB, t15l } };
static const struct huffcodebig ht_big[16] ICONST_ATTR =
{ { 16, 1, 1 },
{ 16, 2, 3 },
{ 16, 3, 7 },
{ 16, 4, 15 },
{ 16, 6, 63 },
{ 16, 8, 255 },
{ 16, 10, 1023 },
{ 16, 13, 8191 },
{ 16, 4, 15 },
{ 16, 5, 31 },
{ 16, 6, 63 },
{ 16, 7, 127 },
{ 16, 8, 255 },
{ 16, 9, 511 },
{ 16, 11, 2047 },
{ 16, 13, 8191 } };
static const struct
{
uint32_t region0_cnt;
uint32_t region1_cnt;
} subdv_table[23] ICONST_ATTR =
{ { 0, 0 }, /* 0 bands */
{ 0, 0 }, /* 1 bands */
{ 0, 0 }, /* 2 bands */
{ 0, 0 }, /* 3 bands */
{ 0, 0 }, /* 4 bands */
{ 0, 1 }, /* 5 bands */
{ 1, 1 }, /* 6 bands */
{ 1, 1 }, /* 7 bands */
{ 1, 2 }, /* 8 bands */
{ 2, 2 }, /* 9 bands */
{ 2, 3 }, /* 10 bands */
{ 2, 3 }, /* 11 bands */
{ 3, 4 }, /* 12 bands */
{ 3, 4 }, /* 13 bands */
{ 3, 4 }, /* 14 bands */
{ 4, 5 }, /* 15 bands */
{ 4, 5 }, /* 16 bands */
{ 4, 6 }, /* 17 bands */
{ 5, 6 }, /* 18 bands */
{ 5, 6 }, /* 19 bands */
{ 5, 7 }, /* 20 bands */
{ 6, 7 }, /* 21 bands */
{ 6, 7 }, /* 22 bands */
};
/* Not ICONST: Appropriate table copied to scalefac */
static const uint32_t sf_band[6][22] =
{
/* Table B.2.b: 22.05 kHz */
{ 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96,
116,140,168,200,238,284,336,396,464,522,576 },
/* Table B.2.c: 24 kHz */
{ 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96,
114,136,162,194,232,278,330,394,464,540,576 },
/* Table B.2.a: 16 kHz */
{ 6, 12, 18, 24, 30, 36, 44, 45, 66, 80, 96,
116,140,168,200,238,248,336,396,464,522,576 },
/* Table B.8.b: 44.1 kHz */
{ 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62,
74, 90,110,134,162,196,238,288,342,418,576 },
/* Table B.8.c: 48 kHz */
{ 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60,
72, 88,106,128,156,190,230,276,330,384,576 },
/* Table B.8.a: 32 kHz */
{ 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66,
82,102,126,156,194,240,296,364,448,550,576 } };
/* int2idx[i] = sqrt(i*sqrt(i)); */
static const short int2idx[4096] ICONST_ATTR =
{ 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8,
8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13,
13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18,
18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 22, 22, 22, 22,
23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26,
27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30,
31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34,
34, 35, 35, 35, 35, 36, 36, 36, 36, 36, 37, 37, 37, 37, 38, 38,
38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 40, 41, 41, 41, 41,
42, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 44, 45, 45,
45, 45, 45, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48,
48, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51,
52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55,
55, 55, 55, 55, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58,
58, 58, 58, 58, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61,
61, 61, 61, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 64, 64,
64, 64, 64, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 67, 67,
67, 67, 67, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 70, 70,
70, 70, 70, 70, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 73,
73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75,
76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78,
78, 79, 79, 79, 79, 79, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81,
81, 81, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 84, 84, 84,
84, 84, 84, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 86, 86, 87,
87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89,
89, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 92, 92, 92,
92, 92, 92, 93, 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 95,
95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97,
97, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99,100,100,
100,100,100,100,101,101,101,101,101,101,102,102,102,102,102,102,
103,103,103,103,103,103,104,104,104,104,104,104,104,105,105,105,
105,105,105,106,106,106,106,106,106,107,107,107,107,107,107,107,
108,108,108,108,108,108,109,109,109,109,109,109,110,110,110,110,
110,110,110,111,111,111,111,111,111,112,112,112,112,112,112,112,
113,113,113,113,113,113,114,114,114,114,114,114,115,115,115,115,
115,115,115,116,116,116,116,116,116,117,117,117,117,117,117,117,
118,118,118,118,118,118,118,119,119,119,119,119,119,120,120,120,
120,120,120,120,121,121,121,121,121,121,122,122,122,122,122,122,
122,123,123,123,123,123,123,123,124,124,124,124,124,124,125,125,
125,125,125,125,125,126,126,126,126,126,126,126,127,127,127,127,
127,127,128,128,128,128,128,128,128,129,129,129,129,129,129,129,
130,130,130,130,130,130,131,131,131,131,131,131,131,132,132,132,
132,132,132,132,133,133,133,133,133,133,133,134,134,134,134,134,
134,134,135,135,135,135,135,135,136,136,136,136,136,136,136,137,
137,137,137,137,137,137,138,138,138,138,138,138,138,139,139,139,
139,139,139,139,140,140,140,140,140,140,140,141,141,141,141,141,
141,141,142,142,142,142,142,142,142,143,143,143,143,143,143,143,
144,144,144,144,144,144,144,145,145,145,145,145,145,145,146,146,
146,146,146,146,146,147,147,147,147,147,147,147,148,148,148,148,
148,148,148,149,149,149,149,149,149,149,150,150,150,150,150,150,
150,151,151,151,151,151,151,151,152,152,152,152,152,152,152,153,
153,153,153,153,153,153,154,154,154,154,154,154,154,154,155,155,
155,155,155,155,155,156,156,156,156,156,156,156,157,157,157,157,
157,157,157,158,158,158,158,158,158,158,159,159,159,159,159,159,
159,160,160,160,160,160,160,160,160,161,161,161,161,161,161,161,
162,162,162,162,162,162,162,163,163,163,163,163,163,163,163,164,
164,164,164,164,164,164,165,165,165,165,165,165,165,166,166,166,
166,166,166,166,167,167,167,167,167,167,167,167,168,168,168,168,
168,168,168,169,169,169,169,169,169,169,169,170,170,170,170,170,
170,170,171,171,171,171,171,171,171,172,172,172,172,172,172,172,
172,173,173,173,173,173,173,173,174,174,174,174,174,174,174,174,
175,175,175,175,175,175,175,176,176,176,176,176,176,176,176,177,
177,177,177,177,177,177,178,178,178,178,178,178,178,178,179,179,
179,179,179,179,179,180,180,180,180,180,180,180,180,181,181,181,
181,181,181,181,182,182,182,182,182,182,182,182,183,183,183,183,
183,183,183,184,184,184,184,184,184,184,184,185,185,185,185,185,
185,185,186,186,186,186,186,186,186,186,187,187,187,187,187,187,
187,187,188,188,188,188,188,188,188,189,189,189,189,189,189,189,
189,190,190,190,190,190,190,190,190,191,191,191,191,191,191,191,
192,192,192,192,192,192,192,192,193,193,193,193,193,193,193,193,
194,194,194,194,194,194,194,195,195,195,195,195,195,195,195,196,
196,196,196,196,196,196,196,197,197,197,197,197,197,197,197,198,
198,198,198,198,198,198,199,199,199,199,199,199,199,199,200,200,
200,200,200,200,200,200,201,201,201,201,201,201,201,201,202,202,
202,202,202,202,202,202,203,203,203,203,203,203,203,204,204,204,
204,204,204,204,204,205,205,205,205,205,205,205,205,206,206,206,
206,206,206,206,206,207,207,207,207,207,207,207,207,208,208,208,
208,208,208,208,208,209,209,209,209,209,209,209,209,210,210,210,
210,210,210,210,210,211,211,211,211,211,211,211,211,212,212,212,
212,212,212,212,212,213,213,213,213,213,213,213,213,214,214,214,
214,214,214,214,214,215,215,215,215,215,215,215,215,216,216,216,
216,216,216,216,216,217,217,217,217,217,217,217,217,218,218,218,
218,218,218,218,218,219,219,219,219,219,219,219,219,220,220,220,
220,220,220,220,220,221,221,221,221,221,221,221,221,222,222,222,
222,222,222,222,222,223,223,223,223,223,223,223,223,224,224,224,
224,224,224,224,224,225,225,225,225,225,225,225,225,226,226,226,
226,226,226,226,226,227,227,227,227,227,227,227,227,228,228,228,
228,228,228,228,228,229,229,229,229,229,229,229,229,229,230,230,
230,230,230,230,230,230,231,231,231,231,231,231,231,231,232,232,
232,232,232,232,232,232,233,233,233,233,233,233,233,233,234,234,
234,234,234,234,234,234,234,235,235,235,235,235,235,235,235,236,
236,236,236,236,236,236,236,237,237,237,237,237,237,237,237,238,
238,238,238,238,238,238,238,238,239,239,239,239,239,239,239,239,
240,240,240,240,240,240,240,240,241,241,241,241,241,241,241,241,
242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,
243,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,
245,245,246,246,246,246,246,246,246,246,247,247,247,247,247,247,
247,247,248,248,248,248,248,248,248,248,248,249,249,249,249,249,
249,249,249,250,250,250,250,250,250,250,250,250,251,251,251,251,
251,251,251,251,252,252,252,252,252,252,252,252,253,253,253,253,
253,253,253,253,253,254,254,254,254,254,254,254,254,255,255,255,
255,255,255,255,255,255,256,256,256,256,256,256,256,256,257,257,
257,257,257,257,257,257,257,258,258,258,258,258,258,258,258,259,
259,259,259,259,259,259,259,259,260,260,260,260,260,260,260,260,
261,261,261,261,261,261,261,261,261,262,262,262,262,262,262,262,
262,263,263,263,263,263,263,263,263,263,264,264,264,264,264,264,
264,264,265,265,265,265,265,265,265,265,265,266,266,266,266,266,
266,266,266,267,267,267,267,267,267,267,267,267,268,268,268,268,
268,268,268,268,268,269,269,269,269,269,269,269,269,270,270,270,
270,270,270,270,270,270,271,271,271,271,271,271,271,271,271,272,
272,272,272,272,272,272,272,273,273,273,273,273,273,273,273,273,
274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,
275,276,276,276,276,276,276,276,276,276,277,277,277,277,277,277,
277,277,277,278,278,278,278,278,278,278,278,279,279,279,279,279,
279,279,279,279,280,280,280,280,280,280,280,280,280,281,281,281,
281,281,281,281,281,282,282,282,282,282,282,282,282,282,283,283,
283,283,283,283,283,283,283,284,284,284,284,284,284,284,284,284,
285,285,285,285,285,285,285,285,286,286,286,286,286,286,286,286,
286,287,287,287,287,287,287,287,287,287,288,288,288,288,288,288,
288,288,288,289,289,289,289,289,289,289,289,289,290,290,290,290,
290,290,290,290,291,291,291,291,291,291,291,291,291,292,292,292,
292,292,292,292,292,292,293,293,293,293,293,293,293,293,293,294,
294,294,294,294,294,294,294,294,295,295,295,295,295,295,295,295,
295,296,296,296,296,296,296,296,296,296,297,297,297,297,297,297,
297,297,297,298,298,298,298,298,298,298,298,299,299,299,299,299,
299,299,299,299,300,300,300,300,300,300,300,300,300,301,301,301,
301,301,301,301,301,301,302,302,302,302,302,302,302,302,302,303,
303,303,303,303,303,303,303,303,304,304,304,304,304,304,304,304,
304,305,305,305,305,305,305,305,305,305,306,306,306,306,306,306,
306,306,306,307,307,307,307,307,307,307,307,307,308,308,308,308,
308,308,308,308,308,309,309,309,309,309,309,309,309,309,310,310,
310,310,310,310,310,310,310,311,311,311,311,311,311,311,311,311,
312,312,312,312,312,312,312,312,312,313,313,313,313,313,313,313,
313,313,314,314,314,314,314,314,314,314,314,315,315,315,315,315,
315,315,315,315,316,316,316,316,316,316,316,316,316,317,317,317,
317,317,317,317,317,317,318,318,318,318,318,318,318,318,318,318,
319,319,319,319,319,319,319,319,319,320,320,320,320,320,320,320,
320,320,321,321,321,321,321,321,321,321,321,322,322,322,322,322,
322,322,322,322,323,323,323,323,323,323,323,323,323,324,324,324,
324,324,324,324,324,324,325,325,325,325,325,325,325,325,325,325,
326,326,326,326,326,326,326,326,326,327,327,327,327,327,327,327,
327,327,328,328,328,328,328,328,328,328,328,329,329,329,329,329,
329,329,329,329,330,330,330,330,330,330,330,330,330,330,331,331,
331,331,331,331,331,331,331,332,332,332,332,332,332,332,332,332,
333,333,333,333,333,333,333,333,333,334,334,334,334,334,334,334,
334,334,335,335,335,335,335,335,335,335,335,335,336,336,336,336,
336,336,336,336,336,337,337,337,337,337,337,337,337,337,338,338,
338,338,338,338,338,338,338,338,339,339,339,339,339,339,339,339,
339,340,340,340,340,340,340,340,340,340,341,341,341,341,341,341,
341,341,341,341,342,342,342,342,342,342,342,342,342,343,343,343,
343,343,343,343,343,343,344,344,344,344,344,344,344,344,344,344,
345,345,345,345,345,345,345,345,345,346,346,346,346,346,346,346,
346,346,347,347,347,347,347,347,347,347,347,347,348,348,348,348,
348,348,348,348,348,349,349,349,349,349,349,349,349,349,350,350,
350,350,350,350,350,350,350,350,351,351,351,351,351,351,351,351,
351,352,352,352,352,352,352,352,352,352,352,353,353,353,353,353,
353,353,353,353,354,354,354,354,354,354,354,354,354,355,355,355,
355,355,355,355,355,355,355,356,356,356,356,356,356,356,356,356,
357,357,357,357,357,357,357,357,357,357,358,358,358,358,358,358,
358,358,358,359,359,359,359,359,359,359,359,359,359,360,360,360,
360,360,360,360,360,360,361,361,361,361,361,361,361,361,361,361,
362,362,362,362,362,362,362,362,362,363,363,363,363,363,363,363,
363,363,363,364,364,364,364,364,364,364,364,364,365,365,365,365,
365,365,365,365,365,365,366,366,366,366,366,366,366,366,366,367,
367,367,367,367,367,367,367,367,367,368,368,368,368,368,368,368,
368,368,369,369,369,369,369,369,369,369,369,369,370,370,370,370,
370,370,370,370,370,370,371,371,371,371,371,371,371,371,371,372,
372,372,372,372,372,372,372,372,372,373,373,373,373,373,373,373,
373,373,374,374,374,374,374,374,374,374,374,374,375,375,375,375,
375,375,375,375,375,375,376,376,376,376,376,376,376,376,376,377,
377,377,377,377,377,377,377,377,377,378,378,378,378,378,378,378,
378,378,379,379,379,379,379,379,379,379,379,379,380,380,380,380,
380,380,380,380,380,380,381,381,381,381,381,381,381,381,381,382,
382,382,382,382,382,382,382,382,382,383,383,383,383,383,383,383,
383,383,383,384,384,384,384,384,384,384,384,384,385,385,385,385,
385,385,385,385,385,385,386,386,386,386,386,386,386,386,386,386,
387,387,387,387,387,387,387,387,387,387,388,388,388,388,388,388,
388,388,388,389,389,389,389,389,389,389,389,389,389,390,390,390,
390,390,390,390,390,390,390,391,391,391,391,391,391,391,391,391,
391,392,392,392,392,392,392,392,392,392,393,393,393,393,393,393,
393,393,393,393,394,394,394,394,394,394,394,394,394,394,395,395,
395,395,395,395,395,395,395,395,396,396,396,396,396,396,396,396,
396,397,397,397,397,397,397,397,397,397,397,398,398,398,398,398,
398,398,398,398,398,399,399,399,399,399,399,399,399,399,399,400,
400,400,400,400,400,400,400,400,400,401,401,401,401,401,401,401,
401,401,402,402,402,402,402,402,402,402,402,402,403,403,403,403,
403,403,403,403,403,403,404,404,404,404,404,404,404,404,404,404,
405,405,405,405,405,405,405,405,405,405,406,406,406,406,406,406,
406,406,406,406,407,407,407,407,407,407,407,407,407,407,408,408,
408,408,408,408,408,408,408,408,409,409,409,409,409,409,409,409,
409,410,410,410,410,410,410,410,410,410,410,411,411,411,411,411,
411,411,411,411,411,412,412,412,412,412,412,412,412,412,412,413,
413,413,413,413,413,413,413,413,413,414,414,414,414,414,414,414,
414,414,414,415,415,415,415,415,415,415,415,415,415,416,416,416,
416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,417,
417,418,418,418,418,418,418,418,418,418,418,419,419,419,419,419,
419,419,419,419,419,420,420,420,420,420,420,420,420,420,420,421,
421,421,421,421,421,421,421,421,421,422,422,422,422,422,422,422,
422,422,422,423,423,423,423,423,423,423,423,423,423,424,424,424,
424,424,424,424,424,424,424,425,425,425,425,425,425,425,425,425,
425,426,426,426,426,426,426,426,426,426,426,427,427,427,427,427,
427,427,427,427,427,428,428,428,428,428,428,428,428,428,428,429,
429,429,429,429,429,429,429,429,429,430,430,430,430,430,430,430,
430,430,430,431,431,431,431,431,431,431,431,431,431,432,432,432,
432,432,432,432,432,432,432,433,433,433,433,433,433,433,433,433,
433,434,434,434,434,434,434,434,434,434,434,435,435,435,435,435,
435,435,435,435,435,435,436,436,436,436,436,436,436,436,436,436,
437,437,437,437,437,437,437,437,437,437,438,438,438,438,438,438,
438,438,438,438,439,439,439,439,439,439,439,439,439,439,440,440,
440,440,440,440,440,440,440,440,441,441,441,441,441,441,441,441,
441,441,442,442,442,442,442,442,442,442,442,442,443,443,443,443,
443,443,443,443,443,443,443,444,444,444,444,444,444,444,444,444,
444,445,445,445,445,445,445,445,445,445,445,446,446,446,446,446,
446,446,446,446,446,447,447,447,447,447,447,447,447,447,447,448,
448,448,448,448,448,448,448,448,448,448,449,449,449,449,449,449,
449,449,449,449,450,450,450,450,450,450,450,450,450,450,451,451,
451,451,451,451,451,451,451,451,452,452,452,452,452,452,452,452,
452,452,453,453,453,453,453,453,453,453,453,453,453,454,454,454,
454,454,454,454,454,454,454,455,455,455,455,455,455,455,455,455,
455,456,456,456,456,456,456,456,456,456,456,457,457,457,457,457,
457,457,457,457,457,457,458,458,458,458,458,458,458,458,458,458,
459,459,459,459,459,459,459,459,459,459,460,460,460,460,460,460,
460,460,460,460,460,461,461,461,461,461,461,461,461,461,461,462,
462,462,462,462,462,462,462,462,462,463,463,463,463,463,463,463,
463,463,463,463,464,464,464,464,464,464,464,464,464,464,465,465,
465,465,465,465,465,465,465,465,466,466,466,466,466,466,466,466,
466,466,466,467,467,467,467,467,467,467,467,467,467,468,468,468,
468,468,468,468,468,468,468,469,469,469,469,469,469,469,469,469,
469,469,470,470,470,470,470,470,470,470,470,470,471,471,471,471,
471,471,471,471,471,471,472,472,472,472,472,472,472,472,472,472,
472,473,473,473,473,473,473,473,473,473,473,474,474,474,474,474,
474,474,474,474,474,475,475,475,475,475,475,475,475,475,475,475,
476,476,476,476,476,476,476,476,476,476,477,477,477,477,477,477,
477,477,477,477,477,478,478,478,478,478,478,478,478,478,478,479,
479,479,479,479,479,479,479,479,479,479,480,480,480,480,480,480,
480,480,480,480,481,481,481,481,481,481,481,481,481,481,482,482,
482,482,482,482,482,482,482,482,482,483,483,483,483,483,483,483,
483,483,483,484,484,484,484,484,484,484,484,484,484,484,485,485,
485,485,485,485,485,485,485,485,486,486,486,486,486,486,486,486,
486,486,486,487,487,487,487,487,487,487,487,487,487,488,488,488,
488,488,488,488,488,488,488,488,489,489,489,489,489,489,489,489,
489,489,490,490,490,490,490,490,490,490,490,490,490,491,491,491,
491,491,491,491,491,491,491,492,492,492,492,492,492,492,492,492,
492,492,493,493,493,493,493,493,493,493,493,493,494,494,494,494,
494,494,494,494,494,494,494,495,495,495,495,495,495,495,495,495,
495,496,496,496,496,496,496,496,496,496,496,496,497,497,497,497,
497,497,497,497,497,497,497,498,498,498,498,498,498,498,498,498,
498,499,499,499,499,499,499,499,499,499,499,499,500,500,500,500,
500,500,500,500,500,500,501,501,501,501,501,501,501,501,501,501,
501,502,502,502,502,502,502,502,502,502,502,503,503,503,503,503,
503,503,503,503,503,503,504,504,504,504,504,504,504,504,504,504,
504,505,505,505,505,505,505,505,505,505,505,506,506,506,506,506,
506,506,506,506,506,506,507,507,507,507,507,507,507,507,507,507,
507,508,508,508,508,508,508,508,508,508,508,509,509,509,509,509,
509,509,509,509,509,509,510,510,510,510,510,510,510,510,510,510,
510,511,511,511,511,511,511,511,511,511,511,512,512,512,512,512 };
static const int order[32] ICONST_ATTR =
{ 0, 1, 16, 17, 8, 9, 24, 25, 4, 5, 20, 21, 12, 13, 28, 29,
2, 3, 18, 19,10,11, 26, 27, 6, 7, 22, 23, 14, 15, 30, 31 };
static const int cx[9] ICONST_ATTR =
{ 16135, 10531, 5604, 15396, -2845,-12551, 14189, 8192, 16384 };
static const int ca[8] ICONST_ATTR =
{-16859,-15458,-10269, -5961, -3099, -1342, -465, -121 };
static const int cs[8] ICONST_ATTR =
{ 28098, 28893, 31117, 32221, 32621, 32740, 32765, 32768 };
static const short enwindow[15*20+16] ICONST_ATTR
__attribute__((aligned(4))) =
{ 0, 65, 593, 1766, 22228, 2115, 611, 62,
8, 119, 1419, 10564,-11659,-1635,-154, -9, 464, 100, 91, 0,
0, 69, 604, 1635, 23148, 2363, 643, 62,
7, 107, 1368, 10449,-12733,-1818,-180,-11, 420, 200, 164, 0,
0, 72, 608, 1465, 23979, 2600, 671, 63,
7, 94, 1305, 10265,-13818,-2004,-207,-12, 380, 297, 220, 0,
0, 76, 606, 1256, 24718, 2825, 693, 63,
6, 81, 1232, 10016,-14908,-2192,-236,-14, 342, 392, 262, 0,
0, 78, 597, 1007, 25359, 3033, 712, 63,
6, 68, 1150, 9706,-15995,-2380,-267,-15, 307, 483, 289, 0,
0, 80, 580, 719, 25901, 3224, 726, 62,
6, 54, 1060, 9343,-17072,-2565,-299,-17, 274, 569, 304, 0,
-1, 82, 555, 391, 26339, 3395, 735, 61,
5, 40, 963, 8930,-18131,-2747,-332,-19, 242, 650, 307, 0,
-1, 83, 523, 26, 26672, 3545, 740, 60,
5, 27, 861, 8474,-19164,-2923,-366,-21, 212, 724, 300, 0,
-1, 83, 482, -376, 26900, 3672, 739, 58,
4, 14, 756, 7981,-20163,-3092,-401,-24, 183, 792, 283, 0,
-1, 82, 433, -812, 27022, 3776, 735, 56,
4, 1, 648, 7456,-21122,-3250,-435,-26, 155, 851, 258, 0,
-1, 81, 376, -1281, 27038, 3855, 726, 54,
3, -11, 539, 6907,-22032,-3397,-470,-28, 128, 903, 226, 0,
-1, 78, 312, -1778, 26951, 3910, 713, 52,
3, -22, 430, 6338,-22887,-3530,-503,-31, 102, 946, 188, 0,
-2, 75, 239, -2302, 26761, 3941, 696, 49,
3, -33, 322, 5757,-23678,-3648,-537,-34, 76, 980, 145, 0,
-2, 70, 160, -2848, 26472, 3948, 676, 47,
3, -42, 217, 5167,-24399,-3749,-568,-36, 50, 1004, 99, 0,
-2, 65, 74, -3412, 26087, 3931, 653, 44,
2, -51, 115, 4577,-25045,-3830,-599,-39, 25, 1019, 50, 0,
25610, 3891, 627, 42,-3990, -18, 58, -2,
21226, 10604, 1860, 1458, 576, 130, 60, 8,
};
static const int win[18][4] ICONST_ATTR =
{ { -3072, -134, -146, 3352 },
{ -2747, -362, -471, 3579 },
{ -2387, -529, -831, 3747 },
{ -2004, -632,-1214, 3850 },
{ -1609, -666,-1609, 3884 },
{ -1214, -632,-2004, 3850 },
{ -831, -529,-2387, 3747 },
{ -471, -362,-2747, 3579 },
{ -146, -134,-3072, 3352 },
{ 134,-3072,-3352, -146 },
{ 362,-2747,-3579, -471 },
{ 529,-2387,-3747, -831 },
{ 632,-2004,-3850,-1214 },
{ 666,-1609,-3884,-1609 },
{ 632,-1214,-3850,-2004 },
{ 529, -831,-3747,-2387 },
{ 362, -471,-3579,-2747 },
{ 134, -146,-3352,-3072 } };
static const long sampr_index[2][3] =
{ { 22050, 24000, 16000 }, /* MPEG 2 */
{ 44100, 48000, 32000 } }; /* MPEG 1 */
static const long bitr_index[2][15] =
{ { 0, 8,16,24,32,40,48,56, 64, 80, 96,112,128,144,160 }, /* MPEG 2 */
{ 0,32,40,48,56,64,80,96,112,128,160,192,224,256,320 } }; /* MPEG 1 */
static const int num_bands[3][15] =
{ { 0,10,10,10,10,12,14,16,20,22,24,26,28,30,32 }, /* MPEG 2 Stereo */
{ 0,10,10,10,10,10,12,14,18,24,26,28,30,32,32 }, /* MPEG 1 Stereo */
{ 0,10,12,14,18,24,26,28,30,32,32,32,32,32,32 } }; /* MPEG 1&2 Mono */
#ifdef MP3_ENC_COP
/* Initialize the circular buffer pointers */
static inline void sb_data_buf_init(void)
{
sb_data_cod = &sb_data_buf[0];
sb_data_enc = &sb_data_buf[1];
}
/* Switch the buffers used by CPU and COP */
static inline void sb_data_buf_swap(void)
{
typeof (sb_data_cod) t = sb_data_cod;
sb_data_cod = sb_data_enc;
sb_data_enc = t;
}
#endif /* MP3_ENC_COP */
static void putbits(uint32_t val, uint32_t nbit)
{
int new_bitpos = coded_data.bitpos + nbit;
int ptrpos = coded_data.bitpos >> 5;
val = val & (0xffffffff >> (32 - nbit));
/* data fit in one uint32_t */
if (((new_bitpos - 1) >> 5) == ptrpos)
{
coded_data.bbuf[ptrpos] |= val << ((32 - new_bitpos) & 31);
}
else
{
coded_data.bbuf[ptrpos ] |= val >> ((new_bitpos - 32) & 31);
coded_data.bbuf[ptrpos+1] |= val << ((32 - new_bitpos) & 31);
}
coded_data.bitpos = new_bitpos;
}
#define PUTLONG_INIT() \
uint32_t _cc = 0, _sz = 0
#define putlong_flush() \
putbits(_cc, _sz)
#define putlong(c, s) \
({ uint32_t _c = (c), _s = (s); \
if (_s + _sz <= 32) { _cc = (_cc << _s) | _c; _sz += _s; } \
else { putlong_flush(); _cc = _c; _sz = _s; } })
static inline uint32_t encode_header(int padding, long bitr_id)
{
/*
* MPEG header layout:
* AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
* A (31-21) = frame sync
* B (20-19) = MPEG type
* C (18-17) = MPEG layer
* D (16) = protection bit
* E (15-12) = bitrate index
* F (11-10) = samplerate index
* G (9) = padding bit
* H (8) = private bit
* I (7-6) = channel mode
* J (5-4) = mode extension (jstereo only)
* K (3) = copyright bit
* L (2) = original
* M (1-0) = emphasis
*/
return (0xffe00000 ) /* frame sync (AAAAAAAAA AAA) */
| (0x2 << 19) /* mp3 type (upper): 1 (BB) */
| (cfg.mpg.type << 19)
| (0x1 << 17) /* mp3 layer: 01 (CC) */
| (0x1 << 16) /* mp3 crc: 1 (D) */
| (bitr_id << 12)
| (cfg.mpg.smpl_id << 10)
| (padding << 9)
| (cfg.mpg.mode << 6)
| (0x1 << 2); /* mp3 org: 1 (L) */
/* no emphasis (bits 0-1) */
}
static long calc_frame_size(int bitr_id, long *frac)
{
unsigned long v = bitr_index[cfg.mpg.type][bitr_id];
v = 576 * 16000 * v / (2 - cfg.mpg.type);
v /= cfg.samplerate;
if (frac)
*frac = v % 64;
return v / 64;
}
static void encode_side_info(side_info_t si[2][2])
{
PUTLONG_INIT();
putbits(encode_header(cfg.mpg.padding, cfg.mpg.bitr_id), 32);
if (cfg.mpg.type == 1)
{
/* MPEG1 */
if (cfg.channels == 2) putlong(0, 20);
else putlong(0, 18);
for (int gr = 0; gr < cfg.granules; gr++)
{
for (int ch = 0; ch < cfg.channels; ch++)
{
side_info_t *gi = &si[gr][ch];
putlong(gi->part2_3_length + 42, 12); /* add scale_facs array size */
putlong(gi->address3 >> 1, 9);
putlong(gi->global_gain, 8);
putlong(9, 4); /* set scale_facs compr type */
putlong(gi->table_select[0], 6);
putlong(gi->table_select[1], 5);
putlong(gi->table_select[2], 5);
putlong(gi->region_0_1, 7);
putlong(1 , 2); /* set scale_facs to 1bit */
putlong(gi->table_select[3], 1);
}
}
}
else
{
/* MPEG2 */
if (cfg.channels == 2) putlong(0, 10);
else putlong(0, 9);
for (int ch = 0; ch < cfg.channels; ch++)
{
side_info_t *gi = &si[0][ch];
putlong(gi->part2_3_length + 42, 12); /* add scale_facs array size */
putlong(gi->address3 >> 1, 9);
putlong(gi->global_gain, 8);
putlong(0xca, 9); /* set scale_facs compr type */
putlong(gi->table_select[0], 6);
putlong(gi->table_select[1], 5);
putlong(gi->table_select[2], 5);
putlong(gi->region_0_1 , 7);
putlong(1 , 1); /* set scale_facs to 1bit */
putlong(gi->table_select[3], 1);
}
}
putlong_flush();
}
/* Implements the pseudocode of page 98 of the IS */
static int huffman_code(short *ix, char *xr_sign, uint32_t begin, uint32_t end,
int table)
{
if (table == 0)
return 0;
PUTLONG_INIT();
int sumbit = 0;
#define sign_x xr_sign[i+0]
#define sign_y xr_sign[i+1]
if (table > 15)
{
/* ESC-table is used */
uint32_t linbits = ht_big[table - 16].linbits;
const uint16_t *hffcode = table < 24 ? t16HB : t24HB;
const uint8_t *hlen = table < 24 ? t16l : t24l;
uint32_t xl = 0, yl = 0;
for (uint32_t i = begin; i < end; i += 2)
{
int x = ix[i+0];
int y = ix[i+1];
if (x > 14) { xl = x - 15; x = 15; }
if (y > 14) { yl = y - 15; y = 15; }
uint32_t idx = x * 16 + y;
uint32_t code = hffcode[idx];
int bit = hlen [idx];
if (x)
{
if (x > 14)
{
code = (code << linbits) | xl;
bit += linbits;
}
code = (code << 1) | sign_x;
bit += 1;
}
if (y)
{
if (y > 14)
{
if (bit + linbits + 1 > 32)
{
putlong(code, bit);
sumbit += bit;
code = bit = 0;
}
code = (code << linbits) | yl;
bit += linbits;
}
code = (code << 1) | sign_y;
bit += 1;
}
putlong(code, bit);
sumbit += bit;
}
}
else
{
/* No ESC-words */
const struct huffcodetab *h = &ht[table];
for (uint32_t i = begin; i < end; i += 2)
{
int x = ix[i+0];
int y = ix[i+1];
uint32_t idx = x * h->len + y;
uint32_t code = h->table[idx];
int bit = h->hlen [idx];
if (x)
{
code = (code << 1) | sign_x;
bit += 1;
}
if (y)
{
code = (code << 1) | sign_y;
bit += 1;
}
putlong(code, bit);
sumbit += bit;
}
}
putlong_flush();
return sumbit;
}
static int huffman_cod1(short *ix, char *xr_sign, uint32_t begin,
uint32_t end, int tbl)
{
PUTLONG_INIT();
#define sgnv xr_sign[i+0]
#define sgnw xr_sign[i+1]
#define sgnx xr_sign[i+2]
#define sgny xr_sign[i+3]
int sumbit = 0, s = 0, l = 0;
for (uint32_t i = begin; i < end; i += 4)
{
int v = ix[i+0];
int w = ix[i+1];
int x = ix[i+2];
int y = ix[i+3];
uint32_t p = (v << 3) + (w << 2) + (x << 1) + y;
switch (p)
{
case 0: l=0; s = 0; break;
case 1: l=1; s = sgny; break;
case 2: l=1; s = sgnx; break;
case 3: l=2; s = (sgnx << 1) + sgny; break;
case 4: l=1; s = sgnw; break;
case 5: l=2; s = (sgnw << 1) + sgny; break;
case 6: l=2; s = (sgnw << 1) + sgnx; break;
case 7: l=3; s = (sgnw << 2) + (sgnx << 1) + sgny; break;
case 8: l=1; s = sgnv; break;
case 9: l=2; s = (sgnv << 1) + sgny; break;
case 10: l=2; s = (sgnv << 1) + sgnx; break;
case 11: l=3; s = (sgnv << 2) + (sgnx << 1) + sgny; break;
case 12: l=2; s = (sgnv << 1) + sgnw; break;
case 13: l=3; s = (sgnv << 2) + (sgnw << 1) + sgny; break;
case 14: l=3; s = (sgnv << 2) + (sgnw << 1) + sgnx; break;
case 15: l=4; s = (sgnv << 3) + (sgnw << 2) + (sgnx << 1) + sgny; break;
}
uint32_t d = (ht_count[tbl][0][p] << l) + s;
l = ht_count[tbl][1][p];
putlong(d, l);
sumbit += l;
}
putlong_flush();
return sumbit;
}
/* 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 huffman_code_bits(short *ix, char *xr_sign, side_info_t *gi)
{
int region1 = gi->address1;
int region2 = gi->address2;
int bigvals = gi->address3;
int count1 = bigvals + (gi->count1 << 2);
int i, v;
for (i = v = 0; i < 32; i += 2)
v |= band_scale_f[i >> 1] << (30 - i);
putbits(v, 32); // store scale_facs (part1)
for (v = 0; i < 42; i += 2)
v |= band_scale_f[i >> 1] << (40 - i);
putbits(v, 10); // store scale_facs (part2)
int bits = 0;
if (region1 > 0)
bits += huffman_code(ix, xr_sign, 0, region1, gi->table_select[0]);
if (region2 > region1)
bits += huffman_code(ix, xr_sign, region1, region2, gi->table_select[1]);
if (bigvals > region2)
bits += huffman_code(ix, xr_sign, region2, bigvals, gi->table_select[2]);
if (count1 > bigvals)
bits += huffman_cod1(ix, xr_sign, bigvals, count1, gi->table_select[3]);
int stuff_bits = gi->part2_3_length - bits;
if (stuff_bits > 0)
{
int stuff_words = stuff_bits >> 5;
int remain_bits = stuff_bits & 31;
if (remain_bits)
putbits(~0, remain_bits);
while (stuff_words--)
putbits(~0, 32); /* Huffman code tables leed to padding ones */
}
}
/*************************************************************************/
/* Function: Count the number of bits necessary to code the subregion. */
/*************************************************************************/
static int count_bit1(short *ix, uint32_t start, uint32_t end, int *bits)
{
int sum = 0;
for (uint32_t i = start; i < end; i += 2)
sum += t1l[4 + ix[i] * 2 + ix[i + 1]];
*bits = sum;
return 1; /* this is table1 */
}
static int count_bigv(short *ix, uint32_t start, uint32_t end, int table0,
int table1, int *bits)
{
uint32_t sum = 0, bigv = 0;
/* ESC-table is used */
for (uint32_t i = start; i < end; i += 2)
{
uint32_t x = ix[i+0];
uint32_t y = ix[i+1];
if (x > 14) { x = 15; bigv++; }
if (y > 14) { y = 15; bigv++; }
sum += tab1624[x * 16 + y];
}
int sum0 = (sum >> 16) + bigv * ht_big[table0].linbits;
int sum1 = (sum & 0xffff) + bigv * ht_big[table1].linbits;
if (sum0 <= sum1)
{
*bits = sum0;
return table0;
}
else
{
*bits = sum1;
return table1;
}
}
static int find_best_2(short *ix, uint32_t start, uint32_t end,
const uint32_t *table, uint32_t len, int *bits)
{
uint32_t sum = 0;
for (uint32_t i = start; i < end; i += 2)
sum += table[ix[i] * len + ix[i + 1]];
if ((sum & 0xffff) <= (sum >> 16))
{
*bits = sum & 0xffff;
return 1;
}
else
{
*bits = sum >> 16;
return 0;
}
}
static int find_best_3(short *ix, uint32_t start, uint32_t end,
const uint32_t *table, uint32_t len, int *bits)
{
int sum1 = 0;
int sum2 = 0;
int sum3 = 0;
/* avoid overflow in packed additions: 78*13 < 1024 */
for (uint32_t i = start; i < end;)
{
uint32_t j = i + 2*78 > end ? end : i + 2*78;
uint32_t sum = 0;
for (; i < j; i += 2)
sum += table[ix[i] * len + ix[i + 1]];
sum1 += (sum >> 20);
sum2 += (sum >> 10) & 0x3ff;
sum3 += (sum >> 0) & 0x3ff;
}
int r = 0;
if (sum1 > sum2) { sum1 = sum2; r = 1; }
if (sum1 > sum3) { sum1 = sum3; r = 2; }
*bits = sum1;
return r;
}
/***************************************************************************/
/* Choose the Huffman table that will encode ix[begin..end] with */
/* the fewest bits. */
/* Note: This code contains knowledge about the sizes and characteristic */
/* of the Huffman tables as defined in the IS (Table B.7), and will not */
/* work with any arbitrary tables. */
/***************************************************************************/
static int choose_table(short *ix, uint32_t begin, uint32_t end, int *bits)
{
int max = 0;
for (uint32_t i = begin; i < end; i++)
{
if (ix[i] > max)
max = ix[i];
}
if (max < 16)
{
/* tables without linbits */
/* indx: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
/* len: 0, 2, 3, 3, 0, 4, 4, 6, 6, 6, 8, 8, 8, 16, 0, 16 */
switch (max)
{
case 0: return 0;
case 1: return count_bit1(ix, begin, end, bits);
case 2: return 2 + find_best_2(ix, begin, end, tab23, 3, bits);
case 3: return 5 + find_best_2(ix, begin, end, tab56, 4, bits);
case 4:
case 5: return 7 + find_best_3(ix, begin, end, tab789, 6, bits);
case 6:
case 7: return 10 + find_best_3(ix, begin, end, tabABC, 8, bits);
default: return 13 + find_best_2(ix, begin, end, tab1315, 16, bits)*2;
}
}
else
{
/* tables with linbits */
max -= 15;
int table0, table1;
for (table0 = 0; table0 < 8; table0++)
{
if (ht_big[table0].linmax >= max)
break;
}
for (table1 = 8; table1 < 16; table1++)
{
if (ht_big[table1].linmax >= max)
break;
}
return 16 + count_bigv(ix, begin, end, table0, table1, bits);
}
}
/*************************************************************************/
/* Function: Calculation of rzero, count1, address3 */
/* (Partitions ix into big values, quadruples and zeros). */
/*************************************************************************/
static int calc_runlen(short *ix, side_info_t *si)
{
int i = 576;
while (i -= 2)
{
if (*(uint32_t *)&ix[i - 2]) /* !!!! short *ix; !!!!! */
break;
}
si->count1 = 0;
int sum = 0;
for ( ; i > 3; i -= 4)
{
int v = ix[i-1];
int w = ix[i-2];
int x = ix[i-3];
int y = ix[i-4];
if ((v | w | x | y) <= 1)
{
int p = (y << 3) + (x << 2) + (w << 1) + (v);
sum += tab01[p];
si->count1++;
}
else
{
break;
}
}
si->address3 = i;
if ((sum >> 16) < (sum & 0xffff))
{
si->table_select[3] = 0;
return sum >> 16;
}
else
{
si->table_select[3] = 1;
return sum & 0xffff;
}
}
/*************************************************************************/
/* Function: Quantization of the vector xr ( -> ix) */
/*************************************************************************/
static int quantize_int(int *xr, short *ix, side_info_t *si)
{
static const unsigned int frac_pow[] ICONST_ATTR =
{ 0x10000, 0xd745, 0xb505, 0x9838 };
unsigned s = frac_pow[si->quantStep & 3] >> si->quantStep / 4;
/* check for possible 'out of range' values */
if (((si->max_val + 256) >> 8) * s >= (65536 << 8))
return 0;
if (((si->max_val + 256) >> 8) * s < (4096 << 8))
{
/* all values fit the table size */
for (int i = 576; i--; )
ix[i] = int2idx[(xr[i] * s + 0x8000) >> 16];
}
else
{
/* check each index wether it fits the table */
for (int i = 576; i--; )
{
unsigned idx = (xr[i] * s + 0x08000) >> 16;
if (idx > 4095) ix[i] = int2idx[(idx + 8) >> 4] << 3;
else ix[i] = int2idx[idx];
}
}
return 1;
}
/*************************************************************************/
/* subdivides the bigvalue region which will use separate Huffman tables */
/*************************************************************************/
static void subdivide(side_info_t *si)
{
if (!si->address3)
{
/* no bigvalue region */
si->region_0_1 = 0;
si->address1 = 0;
si->address2 = 0;
}
else
{
/* Calculate scale factor band index */
int scfb = 1;
while (scalefac[scfb] < si->address3)
scfb++;
int count0 = subdv_table[scfb].region0_cnt;
int count1 = subdv_table[scfb].region1_cnt;
si->region_0_1 = (count0 << 3) | count1;
si->address1 = scalefac[count0];
si->address2 = scalefac[count0 + count1 + 1];
}
}
/*******************************************************************/
/* Count the number of bits necessary to code the bigvalues region */
/*******************************************************************/
static int bigv_bitcount(short *ix, side_info_t *gi)
{
int b1 = 0, b2 = 0, b3 = 0;
/* Select huffman code tables for bigvalues regions */
gi->table_select[0] = 0;
gi->table_select[1] = 0;
gi->table_select[2] = 0;
if (gi->address1 > 0) /* region0 */
gi->table_select[0] = choose_table(ix, 0, gi->address1, &b1);
if (gi->address2 > gi->address1) /* region1 */
gi->table_select[1] = choose_table(ix, gi->address1, gi->address2, &b2);
if (gi->address3 > gi->address2) /* region2 */
gi->table_select[2] = choose_table(ix, gi->address2, gi->address3, &b3);
return b1 + b2 + b3;
}
static int quantize_and_count_bits(int *xr, short *ix, side_info_t *si)
{
int bits = 10000;
if (quantize_int(xr, ix, si))
{
bits = calc_runlen(ix, si); /* rzero,count1,address3 */
subdivide(si); /* bigvalues sfb division */
bits += bigv_bitcount(ix,si); /* bit count */
}
return bits;
}
/************************************************************************/
/* The code selects the best quantStep for a particular set of scalefacs*/
/************************************************************************/
static int inner_loop(int *xr, int max_bits, side_info_t *si)
{
int bits;
while ((bits = quantize_and_count_bits(xr, enc_data, si)) < max_bits - 64)
{
if (si->quantStep == 0)
break;
if (si->quantStep <= 2)
si->quantStep = 0;
else
si->quantStep -= 2;
}
while (bits > max_bits)
{
si->quantStep++;
bits = quantize_and_count_bits(xr, enc_data, si);
}
return bits;
}
static void iteration_loop(int *xr, side_info_t *si, int gr_cnt)
{
int max_bits = cfg.mean_bits;
/* distribute reserved bits to remaining granules */
int tar_bits = max_bits + (cfg.resv_size / gr_cnt & ~7);
if (tar_bits > max_bits + max_bits / 2)
tar_bits = max_bits + max_bits / 2;
si->part2_3_length = inner_loop(xr, tar_bits, si);
si->global_gain = si->quantStep + 142 - si->additStep;
/* unused bits of the reservoir can be used for remaining granules */
cfg.resv_size += max_bits - si->part2_3_length;
/* end: distribute the reserved bits to one or two granules */
if (gr_cnt == 1)
{
si->part2_3_length += cfg.resv_size;
/* mp3 format allows max 12bits for granule length */
if (si->part2_3_length > 4092)
{
int remain = (si->part2_3_length - 4092 + 31) >> 5;
si->part2_3_length -= remain << 5;
si[-1].part2_3_length += remain << 5;
while (remain--)
putbits(~0, 32);
}
}
}
/* returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32 */
#ifdef CPU_COLDFIRE
static void ICODE_ATTR window_subband1_s(const short *wk, int a0[32],
int a1[32])
{
for (int k = 0; k < 18; k++, wk += 64, a0 += 32, a1 += 32)
{
const short *wp = enwindow;
const short *x1 = wk;
const short *x2 = x1 - 124;
int s0, s1, t0, t1;
for (int i = -15; i < 0; i++)
{
asm volatile (
"movem.l (%[wp]), %%d0-%%d3 \n"
"move.l (-224*4,%[x2]), %%d4 \n"
"mac.w %%d0u, %%d4u, %%acc0 \n"
"mac.w %%d0u, %%d4l, (-160*4,%[x2]), %%d4, %%acc1 \n"
"mac.w %%d0l, %%d4u, %%acc0 \n"
"mac.w %%d0l, %%d4l, ( -96*4,%[x2]), %%d4, %%acc1 \n"
"mac.w %%d1u, %%d4u, %%acc0 \n"
"mac.w %%d1u, %%d4l, ( -32*4,%[x2]), %%d4, %%acc1 \n"
"mac.w %%d1l, %%d4u, %%acc0 \n"
"mac.w %%d1l, %%d4l, ( 32*4,%[x2]), %%d4, %%acc1 \n"
"mac.w %%d2u, %%d4u, %%acc0 \n"
"mac.w %%d2u, %%d4l, ( 96*4,%[x2]), %%d4, %%acc1 \n"
"mac.w %%d2l, %%d4u, %%acc0 \n"
"mac.w %%d2l, %%d4l, ( 160*4,%[x2]), %%d4, %%acc1 \n"
"mac.w %%d3u, %%d4u, %%acc0 \n"
"mac.w %%d3u, %%d4l, ( 224*4,%[x2]), %%d4, %%acc1 \n"
"mac.w %%d3l, %%d4u, %%acc0 \n"
"mac.w %%d3l, %%d4l, ( 224*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d0u, %%d4u, %%acc2 \n"
"mac.w %%d0u, %%d4l, ( 160*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d0l, %%d4u, %%acc2 \n"
"mac.w %%d0l, %%d4l, ( 96*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d1u, %%d4u, %%acc2 \n"
"mac.w %%d1u, %%d4l, ( 32*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d1l, %%d4u, %%acc2 \n"
"mac.w %%d1l, %%d4l, ( -32*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d2u, %%d4u, %%acc2 \n"
"mac.w %%d2u, %%d4l, ( -96*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d2l, %%d4u, %%acc2 \n"
"mac.w %%d2l, %%d4l, (-160*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d3u, %%d4u, %%acc2 \n"
"mac.w %%d3u, %%d4l, (-224*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d3l, %%d4u, %%acc2 \n"
"mac.w %%d3l, %%d4l, (-256*4,%[x1]), %%d4, %%acc3 \n"
"movem.l (16,%[wp]), %%d0-%%d3 \n"
"mac.w %%d0u, %%d4u, %%acc0 \n"
"mac.w %%d0u, %%d4l, (-192*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d0l, %%d4u, %%acc0 \n"
"mac.w %%d0l, %%d4l, (-128*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d1u, %%d4u, %%acc0 \n"
"mac.w %%d1u, %%d4l, ( -64*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d1l, %%d4u, %%acc0 \n"
"mac.w %%d1l, %%d4l, ( 0*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d2u, %%d4u, %%acc0 \n"
"mac.w %%d2u, %%d4l, ( 64*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d2l, %%d4u, %%acc0 \n"
"mac.w %%d2l, %%d4l, ( 128*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d3u, %%d4u, %%acc0 \n"
"mac.w %%d3u, %%d4l, ( 192*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d3l, %%d4u, %%acc0 \n"
"mac.w %%d3l, %%d4l, ( 256*4,%[x2]), %%d4, %%acc1 \n"
"msac.w %%d0u, %%d4u, %%acc2 \n"
"msac.w %%d0u, %%d4l, ( 192*4,%[x2]), %%d4, %%acc3 \n"
"msac.w %%d0l, %%d4u, %%acc2 \n"
"msac.w %%d0l, %%d4l, ( 128*4,%[x2]), %%d4, %%acc3 \n"
"msac.w %%d1u, %%d4u, %%acc2 \n"
"msac.w %%d1u, %%d4l, ( 64*4,%[x2]), %%d4, %%acc3 \n"
"msac.w %%d1l, %%d4u, %%acc2 \n"
"msac.w %%d1l, %%d4l, ( 0*4,%[x2]), %%d4, %%acc3 \n"
"msac.w %%d2u, %%d4u, %%acc2 \n"
"msac.w %%d2u, %%d4l, ( -64*4,%[x2]), %%d4, %%acc3 \n"
"msac.w %%d2l, %%d4u, %%acc2 \n"
"msac.w %%d2l, %%d4l, (-128*4,%[x2]), %%d4, %%acc3 \n"
"msac.w %%d3u, %%d4u, %%acc2 \n"
"msac.w %%d3u, %%d4l, (-192*4,%[x2]), %%d4, %%acc3 \n"
"msac.w %%d3l, %%d4u, %%acc2 \n"
"msac.w %%d3l, %%d4l, %%acc3 \n"
"movclr.l %%acc0, %%d0 \n"
"move.l %%d0, %[s0] \n"
"movclr.l %%acc1, %%d0 \n"
"move.l %%d0, %[s1] \n"
"movclr.l %%acc2, %%d0 \n"
"move.l %%d0, %[t0] \n"
"movclr.l %%acc3, %%d0 \n"
"move.l %%d0, %[t1] \n"
: [x1] "+a" (x1), [x2] "+a" (x2), [s0] "+m" (s0), [t0] "+m" (t0),
[s1] "+m" (s1), [t1] "+m" (t1)
: [wp] "a" (wp) : "d0", "d1", "d2", "d3", "d4");
a0[30+i*2] = shft4(t0) + shft13(s0) * wp[16];
a0[31+i*2] = shft13(t0) * wp[17] - shft13(s0) * wp[18];
a1[30+i*2] = shft4(t1) + shft13(s1) * wp[16];
a1[31+i*2] = shft13(t1) * wp[17] - shft13(s1) * wp[18];
wp += 20;
x1 -= 2;
x2 += 2;
}
asm volatile (
"move.l ( -32*4,%[x1]), %%d4 \n"
"movem.l (%[wp]), %%d0-%%d3 \n"
"mac.w %%d0u, %%d4u, %%acc0 \n"
"mac.w %%d0u, %%d4l, ( -96*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d0l, %%d4u, %%acc0 \n"
"mac.w %%d0l, %%d4l, (-160*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d1u, %%d4u, %%acc0 \n"
"mac.w %%d1u, %%d4l, (-224*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d1l, %%d4u, %%acc0 \n"
"mac.w %%d1l, %%d4l, ( 32*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d2u, %%d4u, %%acc0 \n"
"mac.w %%d2u, %%d4l, ( 96*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d2l, %%d4u, %%acc0 \n"
"mac.w %%d2l, %%d4l, ( 160*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d3u, %%d4u, %%acc0 \n"
"mac.w %%d3u, %%d4l, ( 224*4,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d3l, %%d4u, %%acc0 \n"
"mac.w %%d3l, %%d4l, ( -16*4,%[x1]), %%d4, %%acc1 \n"
"movem.l (16,%[wp]), %%d0-%%d3 \n"
"mac.w %%d0u, %%d4u, %%acc2 \n"
"mac.w %%d0u, %%d4l, ( -48*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d0l, %%d4u, %%acc2 \n"
"mac.w %%d0l, %%d4l, ( 16*4,%[x1]), %%d4, %%acc3 \n"
"msac.w %%d0l, %%d4u, %%acc2 \n"
"msac.w %%d0l, %%d4l, ( -80*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d1u, %%d4u, %%acc2 \n"
"mac.w %%d1u, %%d4l, ( 48*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d1u, %%d4u, %%acc2 \n"
"mac.w %%d1u, %%d4l, (-112*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d1l, %%d4u, %%acc2 \n"
"mac.w %%d1l, %%d4l, ( 80*4,%[x1]), %%d4, %%acc3 \n"
"msac.w %%d1l, %%d4u, %%acc2 \n"
"msac.w %%d1l, %%d4l, (-144*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d2u, %%d4u, %%acc2 \n"
"mac.w %%d2u, %%d4l, ( 112*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d2u, %%d4u, %%acc2 \n"
"mac.w %%d2u, %%d4l, (-176*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d2l, %%d4u, %%acc2 \n"
"mac.w %%d2l, %%d4l, ( 144*4,%[x1]), %%d4, %%acc3 \n"
"msac.w %%d2l, %%d4u, %%acc2 \n"
"msac.w %%d2l, %%d4l, (-208*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d3u, %%d4u, %%acc2 \n"
"mac.w %%d3u, %%d4l, ( 176*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d3u, %%d4u, %%acc2 \n"
"mac.w %%d3u, %%d4l, (-240*4,%[x1]), %%d4, %%acc3 \n"
"mac.w %%d3l, %%d4u, %%acc2 \n"
"mac.w %%d3l, %%d4l, ( 208*4,%[x1]), %%d4, %%acc3 \n"
"msac.w %%d3l, %%d4u, %%acc2 \n"
"msac.w %%d3l, %%d4l, %%acc3 \n"
"movclr.l %%acc0, %%d0 \n"
"move.l %%d0, %[s0] \n"
"movclr.l %%acc1, %%d0 \n"
"move.l %%d0, %[s1] \n"
"movclr.l %%acc2, %%d0 \n"
"move.l %%d0, %[t0] \n"
"movclr.l %%acc3, %%d0 \n"
"move.l %%d0, %[t1] \n"
: [x1] "+a" (x1), [s0] "+m" (s0), [t0] "+m" (t0),
[s1] "+m" (s1), [t1] "+m" (t1)
: [wp] "a" (wp) : "d0", "d1", "d2", "d3", "d4");
int u = shft4(s0 - t0);
int v = shft4(s0 + t0);
t0 = a0[14];
s0 = a0[15] - t0;
a0[31] = v + t0; /* A0 */
a0[30] = u + s0; /* A1 */
a0[15] = u - s0; /* A2 */
a0[14] = v - t0; /* A3 */
u = shft4(s1 - t1);
v = shft4(s1 + t1);
t1 = a1[14];
s1 = a1[15] - t1;
a1[31] = v + t1; /* A0 */
a1[30] = u + s1; /* A1 */
a1[15] = u - s1; /* A2 */
a1[14] = v - t1; /* A3 */
}
}
static void ICODE_ATTR window_subband1_m(const short *wk, int a0[32])
{
for (int k = 0; k < 18; k++, wk += 32, a0 += 32)
{
const short *wp = enwindow;
const short *x1 = wk;
const short *x2 = x1 - 62;
int s0, t0;
for (int i = -15; i < 0; i++)
{
asm volatile (
"movem.l (%[wp]), %%d0-%%d3 \n"
"move.l (-224*2,%[x2]), %%d4 \n"
"mac.w %%d0u, %%d4u, (-160*2,%[x2]), %%d4, %%acc0 \n"
"mac.w %%d0l, %%d4u, ( -96*2,%[x2]), %%d4, %%acc0 \n"
"mac.w %%d1u, %%d4u, ( -32*2,%[x2]), %%d4, %%acc0 \n"
"mac.w %%d1l, %%d4u, ( 32*2,%[x2]), %%d4, %%acc0 \n"
"mac.w %%d2u, %%d4u, ( 96*2,%[x2]), %%d4, %%acc0 \n"
"mac.w %%d2l, %%d4u, ( 160*2,%[x2]), %%d4, %%acc0 \n"
"mac.w %%d3u, %%d4u, ( 224*2,%[x2]), %%d4, %%acc0 \n"
"mac.w %%d3l, %%d4u, ( 224*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d0u, %%d4u, ( 160*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d0l, %%d4u, ( 96*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d1u, %%d4u, ( 32*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d1l, %%d4u, ( -32*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d2u, %%d4u, ( -96*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d2l, %%d4u, (-160*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d3u, %%d4u, (-224*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d3l, %%d4u, (-256*2,%[x1]), %%d4, %%acc1 \n"
"movem.l (16,%[wp]), %%d0-%%d3 \n"
"mac.w %%d0u, %%d4u, (-192*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d0l, %%d4u, (-128*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d1u, %%d4u, ( -64*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d1l, %%d4u, ( 0*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d2u, %%d4u, ( 64*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d2l, %%d4u, ( 128*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d3u, %%d4u, ( 192*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d3l, %%d4u, ( 256*2,%[x2]), %%d4, %%acc0 \n"
"msac.w %%d0u, %%d4u, ( 192*2,%[x2]), %%d4, %%acc1 \n"
"msac.w %%d0l, %%d4u, ( 128*2,%[x2]), %%d4, %%acc1 \n"
"msac.w %%d1u, %%d4u, ( 64*2,%[x2]), %%d4, %%acc1 \n"
"msac.w %%d1l, %%d4u, ( 0*2,%[x2]), %%d4, %%acc1 \n"
"msac.w %%d2u, %%d4u, ( -64*2,%[x2]), %%d4, %%acc1 \n"
"msac.w %%d2l, %%d4u, (-128*2,%[x2]), %%d4, %%acc1 \n"
"msac.w %%d3u, %%d4u, (-192*2,%[x2]), %%d4, %%acc1 \n"
"msac.w %%d3l, %%d4u, %%acc1 \n"
"movclr.l %%acc0, %%d0 \n"
"move.l %%d0, %[s0] \n"
"movclr.l %%acc1, %%d0 \n"
"move.l %%d0, %[t0] \n"
: [x1] "+a" (x1), [x2] "+a" (x2), [s0] "+m" (s0), [t0] "+m" (t0)
: [wp] "a" (wp) : "d0", "d1", "d2", "d3", "d4");
a0[30+i*2] = shft4(t0) + shft13(s0) * wp[16];
a0[31+i*2] = shft13(t0) * wp[17] - shft13(s0) * wp[18];
wp += 20;
x1--;
x2++;
}
asm volatile (
"move.l ( -32*2,%[x1]), %%d4 \n"
"movem.l (%[wp]), %%d0-%%d3 \n"
"mac.w %%d0u, %%d4u, ( -96*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d0l, %%d4u, (-160*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d1u, %%d4u, (-224*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d1l, %%d4u, ( 32*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d2u, %%d4u, ( 96*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d2l, %%d4u, ( 160*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d3u, %%d4u, ( 224*2,%[x1]), %%d4, %%acc0 \n"
"mac.w %%d3l, %%d4u, ( -16*2,%[x1]), %%d4, %%acc0 \n"
"movem.l (16,%[wp]), %%d0-%%d3 \n"
"mac.w %%d0u, %%d4u, ( -48*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d0l, %%d4u, ( 16*2,%[x1]), %%d4, %%acc1 \n"
"msac.w %%d0l, %%d4u, ( -80*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d1u, %%d4u, ( 48*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d1u, %%d4u, (-112*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d1l, %%d4u, ( 80*2,%[x1]), %%d4, %%acc1 \n"
"msac.w %%d1l, %%d4u, (-144*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d2u, %%d4u, ( 112*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d2u, %%d4u, (-176*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d2l, %%d4u, ( 144*2,%[x1]), %%d4, %%acc1 \n"
"msac.w %%d2l, %%d4u, (-208*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d3u, %%d4u, ( 176*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d3u, %%d4u, (-240*2,%[x1]), %%d4, %%acc1 \n"
"mac.w %%d3l, %%d4u, ( 208*2,%[x1]), %%d4, %%acc1 \n"
"msac.w %%d3l, %%d4u, %%acc1 \n"
"movclr.l %%acc0, %%d0 \n"
"move.l %%d0, %[s0] \n"
"movclr.l %%acc1, %%d0 \n"
"move.l %%d0, %[t0] \n"
: [x1] "+a" (x1), [s0] "+m" (s0), [t0] "+m" (t0)
: [wp] "a" (wp) : "d0", "d1", "d2", "d3", "d4");
int u = shft4(s0 - t0);
int v = shft4(s0 + t0);
t0 = a0[14];
s0 = a0[15] - t0;
a0[31] = v + t0; /* A0 */
a0[30] = u + s0; /* A1 */
a0[15] = u - s0; /* A2 */
a0[14] = v - t0; /* A3 */
}
}
#else /* Generic CPU */
static void ICODE_ATTR window_subband1_s_(const short *wk, int a[32])
{
for (int k = 0; k < 18; k++, wk += 64, a += 32)
{
const short *wp = enwindow;
const short *x1 = wk;
const short *x2 = x1 - 124;
int s, t;
/* x1[-572] .... x1[448] = 1022 */
/* 18*4*16*32 */
for (int i = -15; i < 0; i++)
{
s = (int)x2[-224*2] * wp[ 0]; t = (int)x1[ 224*2] * wp[ 0];
s += (int)x2[-160*2] * wp[ 1]; t += (int)x1[ 160*2] * wp[ 1];
s += (int)x2[- 96*2] * wp[ 2]; t += (int)x1[ 96*2] * wp[ 2];
s += (int)x2[- 32*2] * wp[ 3]; t += (int)x1[ 32*2] * wp[ 3];
s += (int)x2[ 32*2] * wp[ 4]; t += (int)x1[- 32*2] * wp[ 4];
s += (int)x2[ 96*2] * wp[ 5]; t += (int)x1[- 96*2] * wp[ 5];
s += (int)x2[ 160*2] * wp[ 6]; t += (int)x1[-160*2] * wp[ 6];
s += (int)x2[ 224*2] * wp[ 7]; t += (int)x1[-224*2] * wp[ 7];
s += (int)x1[-256*2] * wp[ 8]; t -= (int)x2[ 256*2] * wp[ 8];
s += (int)x1[-192*2] * wp[ 9]; t -= (int)x2[ 192*2] * wp[ 9];
s += (int)x1[-128*2] * wp[10]; t -= (int)x2[ 128*2] * wp[10];
s += (int)x1[- 64*2] * wp[11]; t -= (int)x2[ 64*2] * wp[11];
s += (int)x1[ 0*2] * wp[12]; t -= (int)x2[ 0*2] * wp[12];
s += (int)x1[ 64*2] * wp[13]; t -= (int)x2[- 64*2] * wp[13];
s += (int)x1[ 128*2] * wp[14]; t -= (int)x2[-128*2] * wp[14];
s += (int)x1[ 192*2] * wp[15]; t -= (int)x2[-192*2] * wp[15];
a[30+i*2] = shft4(t) + shft13(s) * wp[16];
a[31+i*2] = shft13(t) * wp[17] - shft13(s) * wp[18];
wp += 20;
x1 -= 2;
x2 += 2;
}
t = (int)x1[- 16*2] * wp[ 8]; s = (int)x1[ -32*2] * wp[0];
t += ((int)x1[- 48*2] - x1[ 16*2]) * wp[ 9]; s += (int)x1[ -96*2] * wp[1];
t += ((int)x1[- 80*2] + x1[ 48*2]) * wp[10]; s += (int)x1[-160*2] * wp[2];
t += ((int)x1[-112*2] - x1[ 80*2]) * wp[11]; s += (int)x1[-224*2] * wp[3];
t += ((int)x1[-144*2] + x1[112*2]) * wp[12]; s += (int)x1[ 32*2] * wp[4];
t += ((int)x1[-176*2] - x1[144*2]) * wp[13]; s += (int)x1[ 96*2] * wp[5];
t += ((int)x1[-208*2] + x1[176*2]) * wp[14]; s += (int)x1[ 160*2] * wp[6];
t += ((int)x1[-240*2] - x1[208*2]) * wp[15]; s += (int)x1[ 224*2] * wp[7];
int u = shft4(s - t);
int v = shft4(s + t);
t = a[14];
s = a[15] - t;
a[31] = v + t; /* A0 */
a[30] = u + s; /* A1 */
a[15] = u - s; /* A2 */
a[14] = v - t; /* A3 */
}
}
static inline void window_subband1_s(const short *wk, int a0[32], int a1[32])
{
window_subband1_s_(wk , a0);
window_subband1_s_(wk + 1, a1);
}
static void ICODE_ATTR window_subband1_m(const short *wk, int a[32])
{
for (int k = 0; k < 18; k++, wk += 32, a += 32)
{
const short *wp = enwindow;
const short *x1 = wk;
const short *x2 = x1 - 62;
int s, t;
/* x1[-286] .... x1[224] = 511 */
/* 18*2*16*32 */
for (int i = -15; i < 0; i++)
{
s = (int)x2[-224] * wp[ 0]; t = (int)x1[ 224] * wp[ 0];
s += (int)x2[-160] * wp[ 1]; t += (int)x1[ 160] * wp[ 1];
s += (int)x2[- 96] * wp[ 2]; t += (int)x1[ 96] * wp[ 2];
s += (int)x2[- 32] * wp[ 3]; t += (int)x1[ 32] * wp[ 3];
s += (int)x2[ 32] * wp[ 4]; t += (int)x1[- 32] * wp[ 4];
s += (int)x2[ 96] * wp[ 5]; t += (int)x1[- 96] * wp[ 5];
s += (int)x2[ 160] * wp[ 6]; t += (int)x1[-160] * wp[ 6];
s += (int)x2[ 224] * wp[ 7]; t += (int)x1[-224] * wp[ 7];
s += (int)x1[-256] * wp[ 8]; t -= (int)x2[ 256] * wp[ 8];
s += (int)x1[-192] * wp[ 9]; t -= (int)x2[ 192] * wp[ 9];
s += (int)x1[-128] * wp[10]; t -= (int)x2[ 128] * wp[10];
s += (int)x1[- 64] * wp[11]; t -= (int)x2[ 64] * wp[11];
s += (int)x1[ 0] * wp[12]; t -= (int)x2[ 0] * wp[12];
s += (int)x1[ 64] * wp[13]; t -= (int)x2[- 64] * wp[13];
s += (int)x1[ 128] * wp[14]; t -= (int)x2[-128] * wp[14];
s += (int)x1[ 192] * wp[15]; t -= (int)x2[-192] * wp[15];
a[30+i*2] = shft4(t) + shft13(s) * wp[16];
a[31+i*2] = shft13(t) * wp[17] - shft13(s) * wp[18];
wp += 20;
x1--;
x2++;
}
t = (int)x1[- 16] * wp[ 8]; s = (int)x1[ -32] * wp[0];
t += ((int)x1[- 48] - x1[ 16]) * wp[ 9]; s += (int)x1[ -96] * wp[1];
t += ((int)x1[- 80] + x1[ 48]) * wp[10]; s += (int)x1[-160] * wp[2];
t += ((int)x1[-112] - x1[ 80]) * wp[11]; s += (int)x1[-224] * wp[3];
t += ((int)x1[-144] + x1[112]) * wp[12]; s += (int)x1[ 32] * wp[4];
t += ((int)x1[-176] - x1[144]) * wp[13]; s += (int)x1[ 96] * wp[5];
t += ((int)x1[-208] + x1[176]) * wp[14]; s += (int)x1[ 160] * wp[6];
t += ((int)x1[-240] - x1[208]) * wp[15]; s += (int)x1[ 224] * wp[7];
int u = shft4(s - t);
int v = shft4(s + t);
t = a[14];
s = a[15] - t;
a[31] = v + t; /* A0 */
a[30] = u + s; /* A1 */
a[15] = u - s; /* A2 */
a[14] = v - t; /* A3 */
}
}
#endif /* CPU */
static void ICODE_ATTR window_subband2_(int a[32])
{
/* 36864=4*18*16*32 */
const short * const wp = enwindow + 20 * 15;
for (int k = 0; k < 18; k++, a += 32)
{
int xr;
xr = a[28] - a[0]; a[0] += a[28]; a[28] = shft9(xr) * wp[-2*20+17];
xr = a[29] - a[1]; a[1] += a[29]; a[29] = shft9(xr) * wp[-2*20+17];
xr = a[26] - a[2]; a[2] += a[26]; a[26] = shft9(xr) * wp[-4*20+17];
xr = a[27] - a[3]; a[3] += a[27]; a[27] = shft9(xr) * wp[-4*20+17];
xr = a[24] - a[4]; a[4] += a[24]; a[24] = shft9(xr) * wp[-6*20+17];
xr = a[25] - a[5]; a[5] += a[25]; a[25] = shft9(xr) * wp[-6*20+17];
xr = a[22] - a[6]; a[6] += a[22]; a[22] = shft9(xr) * SQRT ;
xr = a[23] - a[7]; a[7] += a[23]; a[23] = shft9(xr) * SQRT - a[7];
a[ 7] -= a[ 6];
a[22] -= a[ 7];
a[23] -= a[22];
xr = a[ 6]; a[ 6] = a[31] - xr; a[31] = a[31] + xr;
xr = a[ 7]; a[ 7] = a[30] - xr; a[30] = a[30] + xr;
xr = a[22]; a[22] = a[15] - xr; a[15] = a[15] + xr;
xr = a[23]; a[23] = a[14] - xr; a[14] = a[14] + xr;
xr = a[20] - a[ 8]; a[ 8] += a[20]; a[20] = shft9(xr) * wp[-10*20+17];
xr = a[21] - a[ 9]; a[ 9] += a[21]; a[21] = shft9(xr) * wp[-10*20+17];
xr = a[18] - a[10]; a[10] += a[18]; a[18] = shft9(xr) * wp[-12*20+17];
xr = a[19] - a[11]; a[11] += a[19]; a[19] = shft9(xr) * wp[-12*20+17];
xr = a[16] - a[12]; a[12] += a[16]; a[16] = shft9(xr) * wp[-14*20+17];
xr = a[17] - a[13]; a[13] += a[17]; a[17] = shft9(xr) * wp[-14*20+17];
xr =-a[20] + a[24]; a[20] += a[24]; a[24] = shft9(xr) * wp[-12*20+17];
xr =-a[21] + a[25]; a[21] += a[25]; a[25] = shft9(xr) * wp[-12*20+17];
xr = a[ 4] - a[ 8]; a[ 4] += a[ 8]; a[ 8] = shft9(xr) * wp[-12*20+17];
xr = a[ 5] - a[ 9]; a[ 5] += a[ 9]; a[ 9] = shft9(xr) * wp[-12*20+17];
xr = a[ 0] - a[12]; a[ 0] += a[12]; a[12] = shft9(xr) * wp[ -4*20+17];
xr = a[ 1] - a[13]; a[ 1] += a[13]; a[13] = shft9(xr) * wp[ -4*20+17];
xr = a[16] - a[28]; a[16] += a[28]; a[28] = shft9(xr) * wp[ -4*20+17];
xr =-a[17] + a[29]; a[17] += a[29]; a[29] = shft9(xr) * wp[ -4*20+17];
xr = SQRT * shft9(a[ 2] - a[10]); a[ 2] += a[10]; a[10] = xr;
xr = SQRT * shft9(a[ 3] - a[11]); a[ 3] += a[11]; a[11] = xr;
xr = SQRT * shft9(a[26] - a[18]); a[18] += a[26]; a[26] = xr - a[18];
xr = SQRT * shft9(a[27] - a[19]); a[19] += a[27]; a[27] = xr - a[19];
xr = a[ 2]; a[19] -= a[ 3]; a[ 3] -= xr; a[ 2] = a[31] - xr; a[31] += xr;
xr = a[ 3]; a[11] -= a[19]; a[18] -= xr; a[ 3] = a[30] - xr; a[30] += xr;
xr = a[18]; a[27] -= a[11]; a[19] -= xr; a[18] = a[15] - xr; a[15] += xr;
xr = a[19]; a[10] -= xr; a[19] = a[14] - xr; a[14] += xr;
xr = a[10]; a[11] -= xr; a[10] = a[23] - xr; a[23] += xr;
xr = a[11]; a[26] -= xr; a[11] = a[22] - xr; a[22] += xr;
xr = a[26]; a[27] -= xr; a[26] = a[ 7] - xr; a[ 7] += xr;
xr = a[27]; a[27] = a[6] - xr; a[6] += xr;
xr = SQRT * shft9(a[ 0] - a[ 4]); a[ 0] += a[ 4]; a[ 4] = xr;
xr = SQRT * shft9(a[ 1] - a[ 5]); a[ 1] += a[ 5]; a[ 5] = xr;
xr = SQRT * shft9(a[16] - a[20]); a[16] += a[20]; a[20] = xr;
xr = SQRT * shft9(a[17] - a[21]); a[17] += a[21]; a[21] = xr;
xr =-SQRT * shft9(a[ 8] - a[12]); a[ 8] += a[12]; a[12] = xr - a[ 8];
xr =-SQRT * shft9(a[ 9] - a[13]); a[ 9] += a[13]; a[13] = xr - a[ 9];
xr =-SQRT * shft9(a[25] - a[29]); a[25] += a[29]; a[29] = xr - a[25];
xr =-SQRT * shft9(a[24] + a[28]); a[24] -= a[28]; a[28] = xr - a[24];
xr = a[24] - a[16]; a[24] = xr;
xr = a[20] - xr; a[20] = xr;
xr = a[28] - xr; a[28] = xr;
xr = a[25] - a[17]; a[25] = xr;
xr = a[21] - xr; a[21] = xr;
xr = a[29] - xr; a[29] = xr;
xr = a[17] - a[1]; a[17] = xr;
xr = a[ 9] - xr; a[ 9] = xr;
xr = a[25] - xr; a[25] = xr;
xr = a[ 5] - xr; a[ 5] = xr;
xr = a[21] - xr; a[21] = xr;
xr = a[13] - xr; a[13] = xr;
xr = a[29] - xr; a[29] = xr;
xr = a[ 1] - a[0]; a[ 1] = xr;
xr = a[16] - xr; a[16] = xr;
xr = a[17] - xr; a[17] = xr;
xr = a[ 8] - xr; a[ 8] = xr;
xr = a[ 9] - xr; a[ 9] = xr;
xr = a[24] - xr; a[24] = xr;
xr = a[25] - xr; a[25] = xr;
xr = a[ 4] - xr; a[ 4] = xr;
xr = a[ 5] - xr; a[ 5] = xr;
xr = a[20] - xr; a[20] = xr;
xr = a[21] - xr; a[21] = xr;
xr = a[12] - xr; a[12] = xr;
xr = a[13] - xr; a[13] = xr;
xr = a[28] - xr; a[28] = xr;
xr = a[29] - xr; a[29] = xr;
xr = a[ 0]; a[ 0] += a[31]; a[31] -= xr;
xr = a[ 1]; a[ 1] += a[30]; a[30] -= xr;
xr = a[16]; a[16] += a[15]; a[15] -= xr;
xr = a[17]; a[17] += a[14]; a[14] -= xr;
xr = a[ 8]; a[ 8] += a[23]; a[23] -= xr;
xr = a[ 9]; a[ 9] += a[22]; a[22] -= xr;
xr = a[24]; a[24] += a[ 7]; a[ 7] -= xr;
xr = a[25]; a[25] += a[ 6]; a[ 6] -= xr;
xr = a[ 4]; a[ 4] += a[27]; a[27] -= xr;
xr = a[ 5]; a[ 5] += a[26]; a[26] -= xr;
xr = a[20]; a[20] += a[11]; a[11] -= xr;
xr = a[21]; a[21] += a[10]; a[10] -= xr;
xr = a[12]; a[12] += a[19]; a[19] -= xr;
xr = a[13]; a[13] += a[18]; a[18] -= xr;
xr = a[28]; a[28] += a[ 3]; a[ 3] -= xr;
xr = a[29]; a[29] += a[ 2]; a[ 2] -= xr;
/* Compensate for inversion in the analysis filter */
if (k & 1)
{
for (int band = 1; band < 32; band += 2)
a[band] *= -1;
}
}
}
static inline void window_subband2_m(int a0[32])
{
window_subband2_(a0);
}
static inline void window_subband2_s(int a0[32], int a1[32])
{
window_subband2_(a0);
window_subband2_(a1);
}
static inline void mdct_long(int *out, int *in)
{
int ct, st;
int tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8;
int ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8;
/* 1,2, 5,6, 9,10, 13,14, 17 */
tc1 = in[17] - in[ 9];
tc3 = in[15] - in[11];
tc4 = in[14] - in[12];
ts5 = in[ 0] + in[ 8];
ts6 = in[ 1] + in[ 7];
ts7 = in[ 2] + in[ 6];
ts8 = in[ 3] + in[ 5];
out[17] = (ts5 + ts7 - ts8) * cx[8] - (ts6 - in[4]) * cx[8];
st = (ts5 + ts7 - ts8) * cx[7] + (ts6 - in[4]) * cx[8];
ct = (tc1 - tc3 - tc4) * cx[6];
out[5] = ct + st;
out[6] = ct - st;
tc2 = (in[16] - in[10]) * cx[6];
ts6 = ts6 * cx[7] + in[4] * cx[8];
ct = tc1 * cx[0] + tc2 + tc3 * cx[1] + tc4 * cx[2];
st = -ts5 * cx[4] + ts6 - ts7 * cx[5] + ts8 * cx[3];
out[1] = ct + st;
out[2] = ct - st;
ct = tc1 * cx[1] - tc2 - tc3 * cx[2] + tc4 * cx[0];
st = -ts5 * cx[5] + ts6 - ts7 * cx[3] + ts8 * cx[4];
out[ 9] = ct + st;
out[10] = ct - st;
ct = tc1 * cx[2] - tc2 + tc3 * cx[0] - tc4 * cx[1];
st = ts5 * cx[3] - ts6 + ts7 * cx[4] - ts8 * cx[5];
out[13] = ct + st;
out[14] = ct - st;
ts1 = in[ 8] - in[ 0];
ts3 = in[ 6] - in[ 2];
ts4 = in[ 5] - in[ 3];
tc5 = in[17] + in[ 9];
tc6 = in[16] + in[10];
tc7 = in[15] + in[11];
tc8 = in[14] + in[12];
out[0] = (tc5 + tc7 + tc8) * cx[8] + (tc6 + in[13]) * cx[8];
ct = (tc5 + tc7 + tc8) * cx[7] - (tc6 + in[13]) * cx[8];
st = (ts1 - ts3 + ts4) * cx[6];
out[11] = ct + st;
out[12] = ct - st;
ts2 = (in[7] - in[1]) * cx[6];
tc6 = in[13] * cx[8] - tc6 * cx[7];
ct = tc5 * cx[3] - tc6 + tc7 * cx[4] + tc8 * cx[5];
st = ts1 * cx[2] + ts2 + ts3 * cx[0] + ts4 * cx[1];
out[3] = ct + st;
out[4] = ct - st;
ct =-tc5 * cx[5] + tc6 - tc7 * cx[3] - tc8 * cx[4];
st = ts1 * cx[1] + ts2 - ts3 * cx[2] - ts4 * cx[0];
out[7] = ct + st;
out[8] = ct - st;
ct =-tc5 * cx[4] + tc6 - tc7 * cx[5] - tc8 * cx[3];
st = ts1 * cx[0] - ts2 + ts3 * cx[1] - ts4 * cx[2];
out[15] = ct + st;
out[16] = ct - st;
}
static int find_bitrate_index(int type, int bitrate, bool stereo)
{
if (type == 1 && !stereo && bitrate > 160)
bitrate = 160;
return ci->round_value_to_list32(bitrate,
&bitr_index[type][1], 14, true) + 1;
}
static int find_samplerate_index(long freq, int *mp3_type)
{
int mpeg = freq >= (32000 + 24000) / 2 ? 1 : 0;
int i = ci->round_value_to_list32(freq, sampr_index[mpeg], 3, true);
*mp3_type = mpeg;
return i;
}
static void mp3_encoder_reset(void)
{
ci->memset(&cfg.cod_info, 0, sizeof (cfg.cod_info));
ci->memset(mfbuf , 0, sizeof (mfbuf ));
ci->memset(sb_data , 0, sizeof (sb_data ));
ci->memset(mdct_freq , 0, sizeof (mdct_freq ));
ci->memset(mdct_sign , 0, sizeof (mdct_sign ));
ci->memset(enc_data , 0, sizeof (enc_data ));
ci->memset(&coded_data , 0, sizeof (coded_data ));
ci->memset(band_scale_f , 0, sizeof (band_scale_f));
cfg.slot_lag = 0;
}
static void mp3_encoder_init(unsigned long sample_rate, int num_channels,
unsigned long bitrate)
{
mp3_encoder_reset();
const bool stereo = num_channels > 1;
cfg.channels = stereo ? 2 : 1;
cfg.mpg.mode = stereo ? 0 : 3; /* 0=stereo, 3=mono */
cfg.mpg.smpl_id = find_samplerate_index(sample_rate, &cfg.mpg.type);
cfg.samplerate = sampr_index[cfg.mpg.type][cfg.mpg.smpl_id];
cfg.src_samplerate = sample_rate;
cfg.mpg.bitr_id = find_bitrate_index(cfg.mpg.type, bitrate, stereo);
cfg.mpg.bitrate = bitr_index[cfg.mpg.type][cfg.mpg.bitr_id];
cfg.mpg.num_bands = num_bands[stereo ? cfg.mpg.type : 2][cfg.mpg.bitr_id];
if (cfg.mpg.type == 1)
{
cfg.granules = 2;
cfg.samp_per_frame = 1152;
cfg.flush_frames = 2;
}
else
{
cfg.granules = 1;
cfg.samp_per_frame = 576;
cfg.flush_frames = 3;
}
cfg.delay = 576-16;
cfg.padding = 3*576+16;
cfg.samp_buffer = mfbuf + cfg.channels*512;
ci->memcpy(scalefac, sf_band[cfg.mpg.smpl_id + 3*cfg.mpg.type],
sizeof (scalefac));
/* Figure average number of 'bytes' per frame */
cfg.byte_per_frame = calc_frame_size(cfg.mpg.bitr_id, &cfg.frac_per_frame);
cfg.sideinfo_len = 32 + (cfg.mpg.type ? (cfg.channels == 1 ? 136 : 256)
: (cfg.channels == 1 ? 72 : 136));
cfg.req_byte_per_frame = ALIGN_UP(cfg.byte_per_frame + 1,
sizeof (uint32_t));
}
static void set_scale_facs(int *mdct_freq)
{
int avrg_freq_val = 0;
/* calc average of first 256 frequency values */
for (int i = 0; i < 256; i++)
avrg_freq_val += mdct_freq[i];
avrg_freq_val >>= 8;
/* if max of current band is smaller than average, increase precision */
/* last band keeps untouched (not scaled) */
for (unsigned int k = 0, is = 0; is < scalefac[20]; k++)
{
int max_freq_val = 0;
unsigned ie = scalefac[k];
for (unsigned int i = is; i < ie; i++)
{
if (max_freq_val < mdct_freq[i])
max_freq_val = mdct_freq[i];
}
unsigned int s = 0;
for (; s < 3; s++)
{
if ((max_freq_val << s) > avrg_freq_val)
break;
}
band_scale_f[k] = (unsigned char)s;
for (unsigned int i = is; s && i < ie; i++)
mdct_freq[i] <<= s;
is = ie;
}
}
static inline void window_subband(int gr, int sbd[2][2][18][32])
{
int *a0 = sbd[0][1-gr][0];
if (cfg.channels == 1)
{
window_subband1_m(mfbuf + 286 + gr*576, a0);
window_subband2_m(a0);
}
else
{
int *a1 = sbd[1][1-gr][0];
window_subband1_s(mfbuf + 572 + gr*1152, a0, a1);
window_subband2_s(a0, a1);
}
}
static inline void get_sb_data(int gr)
{
#ifdef MP3_ENC_COP
ci->memcpy(sb_data[0][1-gr], (*sb_data_enc)[0][1-gr],
sizeof (sb_data[0][1-gr]));
if (cfg.channels > 1)
ci->memcpy(sb_data[1][1-gr], (*sb_data_enc)[1][1-gr],
sizeof (sb_data[1][1-gr]));
#else /* !MP3_ENC_COP */
window_subband(gr, sb_data);
#endif /* MP3_ENC_COP */
}
/* Encode one mp3 frame */
static void ICODE_ATTR compress_frame(void)
{
coded_data.bitpos = cfg.sideinfo_len; /* leave space for mp3 header */
ci->memset(coded_data.bbuf, 0, sizeof (coded_data.bbuf));
if ((cfg.slot_lag += cfg.frac_per_frame) >= 64)
{
/* Padding for this frame */
cfg.slot_lag -= 64;
cfg.mpg.padding = 1;
}
else
{
cfg.mpg.padding = 0;
}
cfg.mean_bits = (8 * cfg.byte_per_frame + 8 * cfg.mpg.padding
- cfg.sideinfo_len) / cfg.granules / cfg.channels
- 42; // reserved for scale_facs
cfg.resv_size = 0;
int gr_cnt = cfg.granules * cfg.channels;
for (int gr = 0; gr < cfg.granules; gr++)
{
get_sb_data(gr);
for (int ch = 0; ch < cfg.channels; ch++, gr_cnt--)
{
/* Perform imdct of 18 previous + 18 current subband samples */
/* for integer precision do this loop again (if neccessary) */
int shift = 14 - (cfg.cod_info[gr][ch].additStep >> 2);
for (int ii = 0; ii < 3; ii++)
{
int *mdct = mdct_freq;
cfg.cod_info[gr][ch].additStep = 4 * (14 - shift);
for (int band = 0; band < cfg.mpg.num_bands; band++, mdct += 18)
{
int *band0 = sb_data[ch][ gr][0] + order[band];
int *band1 = sb_data[ch][1-gr][0] + order[band];
int work[18];
/* 9216=4*32*9*8 */
for (int k = -9; k < 0; k++)
{
int a = shft_n(band1[(k+9)*32], shift);
int b = shft_n(band1[(8-k)*32], shift);
int c = shft_n(band0[(k+9)*32], shift);
int d = shft_n(band0[(8-k)*32], shift);
work[k+ 9] = shft16(a * win[k+ 9][0] +
b * win[k+ 9][1] +
c * win[k+ 9][2] +
d * win[k+ 9][3]);
work[k+18] = shft16(c * win[k+18][0] +
d * win[k+18][1] +
a * win[k+18][2] +
b * win[k+18][3]);
}
/* 7200=4*18*100 */
mdct_long(mdct, work);
/* Perform aliasing reduction butterfly */
if (band != 0)
{
for (int k = 7; k >= 0; k--)
{
int bu = shft15(mdct[k]) * ca[k] +
shft15(mdct[-1-k]) * cs[k];
int bd = shft15(mdct[k]) * cs[k] -
shft15(mdct[-1-k]) * ca[k];
mdct[-1-k] = bu;
mdct[ k ] = bd;
}
}
}
uint32_t max = 0;
for (int k = 0; k < 576; k++)
{
if (mdct_freq[k] < 0)
{
mdct_sign[k] = 1; /* negative */
mdct_freq[k] = shft13(-mdct_freq[k]);
}
else
{
mdct_sign[k] = 0; /* positive */
mdct_freq[k] = shft13(mdct_freq[k]);
}
if (max < (uint32_t)mdct_freq[k])
max = (uint32_t)mdct_freq[k];
}
cfg.cod_info[gr][ch].max_val = max;
/* calc new shift for higher integer precision */
int i = 0;
while (max < (0x7800u >> i)) i++, shift--;
while ((max >> i) >= 0x10000u) i++, shift++;
if (i == 0) break;
if (shift < 0) shift = 0;
}
cfg.cod_info[gr][ch].quantStep +=
cfg.cod_info[gr][ch].additStep;
set_scale_facs(mdct_freq);
/* bit and noise allocation */
iteration_loop(mdct_freq, &cfg.cod_info[gr][ch], gr_cnt);
/* write the frame to the bitstream */
huffman_code_bits(enc_data, mdct_sign, &cfg.cod_info[gr][ch]);
cfg.cod_info[gr][ch].quantStep -=
cfg.cod_info[gr][ch].additStep;
if (cfg.granules == 1)
{
ci->memcpy(sb_data[ch][0], sb_data[ch][1],
sizeof (sb_data[ch][0]));
}
}
}
/* finish this chunk by adding sideinfo header data */
coded_data.bitpos = 0;
encode_side_info(cfg.cod_info);
}
/* Process the PCM data in the encoder's input buffer */
static void mp3_enc_encode_frame(void)
{
#ifdef MP3_ENC_COP
for (int gr = 0; gr < cfg.granules; gr++)
window_subband(gr, *sb_data_cod);
#else
compress_frame();
#endif /* MP3_ENC_COP */
/* shift out old samples */
ci->memmove(mfbuf, mfbuf + cfg.channels*cfg.granules*576,
cfg.channels*2*512);
}
/* Get the last encoded frame */
static size_t ICODE_ATTR mp3_enc_get_frame(uint8_t *outbuf)
{
long size = cfg.byte_per_frame + cfg.mpg.padding;
#ifdef ROCKBOX_LITTLE_ENDIAN
/* convert frame to big endian */
const uint32_t *src = coded_data.bbuf;
uint32_t *dst = (uint32_t *)outbuf;
for (long i = 0; i < size; i += sizeof (uint32_t))
*dst++ = swap32(*src++);
#else
ci->memcpy(outbuf, coded_data.bbuf, size);
#endif /* ROCKBOX_LITTLE_ENDIAN */
return size;
}
/*======== Codec section ========*/
/* CRC code lovingly ripped from:
* github.com/CFR-maniac/lame/blob/master/libmp3lame/VbrTag.c */
/* Lookup table for fast CRC computation
* See 'crc_update_lookup'
* Uses the polynomial x^16+x^15+x^2+1 */
static const uint16_t crc16_lookup[256] ICONST_ATTR =
{
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
};
static ssize_t header_size IBSS_ATTR;
static unsigned int mp3_crc16 IBSS_ATTR;
/* fast CRC-16 computation - uses table crc16_lookup 8*/
static inline unsigned int crc_update_lookup(unsigned int value,
unsigned int crc)
{
unsigned int tmp = crc ^ value;
crc = (crc >> 8) ^ crc16_lookup[tmp & 0xff];
return crc & 0xffff;
}
/* Calculate position of 'Info' header */
static int get_info_offset(uint32_t header)
{
uint32_t type = (header & (0x3 << 19)) >> 19;
uint32_t mode = (header & (0x3 << 6)) >> 6;
return type == 3 ? (mode == 3 ? 21 : 36) : (mode == 3 ? 13 : 21);
}
/* Write very basic 'Info' header with delay, padding and a bit of
* miscellaneous info. */
static bool write_info_header(bool first_encode)
{
ssize_t size = cfg.byte_per_frame;
/* By default the MP3 frame header for the info frame is the same as
unpadded audio frames */
uint32_t header = encode_header(0, cfg.mpg.bitr_id);
int i = get_info_offset(header);
if (i + 8 + 36 > size)
{
/* The default frame size too small so find the smallest one that
may accomodate it by increasing the bit rate for this empty
MP3 frame */
int j;
for (j = cfg.mpg.bitr_id + 1; j < 15; j++)
{
size = calc_frame_size(j, NULL);
if (size >= i + 8 + 36)
break;
}
if (j >= 15)
{
/* Shouldn't really happen but... */
header_size = -1;
return true;
}
header = encode_header(0, j);
/* Info offset won't change */
}
uint8_t frame[size];
ci->memset(frame, 0, size);
frame[0] = header >> 24;
frame[1] = header >> 16;
frame[2] = header >> 8;
frame[3] = header >> 0;
/* 'Info' header (CBR 'Xing') */
ci->memcpy(&frame[i], "Info", 4);
/* flags = 0; Info contains no other sections and is 8 bytes */
/* Just mark the LAMEness to indicate header presence; we're not
actually _the_ LAME so 'rbshn' is the version we give */
ci->memcpy(&frame[i + 8], "LAMErbshn", 9);
/* Fill-in some info about us
* reference: http://gabriel.mp3-tech.org/mp3infotag.html
*/
/* Revision + VBR method:
* [7:4] = Revision (0 ??)
* [3:0] = VBR method (CBR)
*/
frame[i + 17] = (0 << 4) | (1 << 0);
/* If first frame since encoder reset is long gone (not unlikely in
prerecording), then the delay is long passed and no trimming done
at the start */
unsigned int delay = first_encode ? cfg.delay : 0;
unsigned int padding = cfg.padding;
/* Delay and padding:
* [23:12] = delay
* [11: 0] = padding
*/
frame[i + 29] = delay >> 4;
frame[i + 30] = (delay << 4) | (padding >> 8);
frame[i + 31] = padding;
/* Misc:
* [7:6] = source frequency
* [ 5] = unwise settings (of course not :)
* [4:2] = stereo mode (mono or stereo)
* [1:0] = noise shaping (who knows, 0)
*/
uint8_t misc;
if (cfg.src_samplerate <= 32000)
misc = (0 << 6);
else if (cfg.src_samplerate <= 44100)
misc = (1 << 6);
else if (cfg.src_samplerate <= 48000)
misc = (2 << 6);
else /* > 48000 */
misc = (3 << 6);
if (cfg.channels > 1)
misc |= (1 << 2); /* Stereo */
frame[i + 32] = misc;
if (ci->enc_stream_write(frame, size) != size)
{
ci->enc_stream_lseek(0, SEEK_SET);
header_size = -1;
return false;
}
header_size = size;
return true;
}
static int ICODE_ATTR on_stream_data(struct enc_chunk_data *data)
{
ssize_t size = data->hdr.size;
if (header_size > 0)
{
/* Header is layed-down; keep running CRC of audio data */
uint8_t *p = data->data;
uint8_t *p_end = p + size;
while (p < p_end)
mp3_crc16 = crc_update_lookup(*p++, mp3_crc16);
}
if (ci->enc_stream_write(data->data, size) != size)
return -1;
return 0;
}
static int on_stream_start(struct enc_chunk_file *file)
{
mp3_crc16 = 0x0000;
if (!write_info_header(file->hdr.aux0))
return -1;
return 0;
}
static int on_stream_end(union enc_chunk_hdr *hdr)
{
ssize_t size = header_size;
if (size <= 0)
return 0; /* No header possible/none yet written */
/* Update audio CRC and header CRC */
uint8_t frame[size];
/* Won't fail this since it could still be useable if some decoder
plays loose with the CRC info (like Rockbox :) */
if (ci->enc_stream_lseek(0, SEEK_SET) != 0 ||
ci->enc_stream_read(frame, size) != size)
return 0;
uint32_t header = (frame[0] << 24) | (frame[1] << 16) |
(frame[2] << 8) | (frame[3] << 0);
int i = get_info_offset(header); /* Get 'Info' header */
/* 'Info' header = 8 bytes */
/* Fill-in audio data CRC16 */
/* On error, fixing data CRC would require scanning file since it
has probably dropped something we tried to write and the likely
reason is that the disk filled; just leave it 0 in that case. */
if (!hdr->err)
{
frame[i + 40] = mp3_crc16 >> 8;
frame[i + 41] = mp3_crc16;
}
/* Fill-in header CRC16 */
unsigned int hdr_crc16 = 0x0000;
for (int j = 0; j < i + 42; j++)
hdr_crc16 = crc_update_lookup(frame[j], hdr_crc16);
frame[i + 42] = hdr_crc16 >> 8;
frame[i + 43] = hdr_crc16;
/* Update file */
if (ci->enc_stream_lseek(0, SEEK_SET) == 0)
ci->enc_stream_write(frame, size);
return 0;
}
#ifdef MP3_ENC_COP
/* Divide encoding duties between CPU and COP -
CPU does the windowing and COP does the remainder of the encoding */
static const char enc_thread_name[] = { "MP3 enc" };
static enum enc_status
{
ENC_SB_EMPTY,
ENC_SB_FULL,
ENC_QUIT,
} enc_status IBSS_ATTR;
static struct semaphore enc_sema IBSS_ATTR;
static struct semaphore cod_sema IBSS_ATTR;
static unsigned int enc_thread_id;
/* Needs one extra loop to drain sb_data_buf */
#define DRAIN_FRAMES 1
static void enc_thread(void)
{
while (1)
{
ci->semaphore_release(&cod_sema);
ci->semaphore_wait(&enc_sema, TIMEOUT_BLOCK);
if (enc_status == ENC_QUIT)
break;
compress_frame();
}
}
#else /* !MP3_ENC_COP */
/* No encoder delay */
#define DRAIN_FRAMES 0
#endif /* MP3_ENC_COP */
static bool enc_thread_init(void *stack, size_t stack_size)
{
#ifdef MP3_ENC_COP
enc_status = ENC_SB_EMPTY;
ci->semaphore_init(&enc_sema, 1, 0);
ci->semaphore_init(&cod_sema, 1, 0);
sb_data_buf_init();
enc_thread_id = ci->create_thread(enc_thread, stack, stack_size,
0, enc_thread_name
IF_PRIO(, PRIORITY_PLAYBACK)
IF_COP(, COP));
if (enc_thread_id == 0)
return false;
#endif /* MP3_ENC_COP */
return true;
(void)stack; (void)stack_size;
}
static inline void enc_thread_compress_frame(void)
{
#ifdef MP3_ENC_COP
sb_data_buf_swap();
ci->semaphore_release(&enc_sema);
#endif /* MP3_ENC_COP */
}
static void enc_thread_stop(void)
{
#ifdef MP3_ENC_COP
enc_status = ENC_QUIT;
ci->semaphore_release(&enc_sema);
ci->thread_wait(enc_thread_id);
#endif /* MP3_ENC_COP */
}
static inline void encode_frame(void)
{
mp3_enc_encode_frame();
}
static inline bool wait_for_frame(void)
{
#ifdef MP3_ENC_COP
ci->semaphore_wait(&cod_sema, TIMEOUT_BLOCK);
if (enc_status == ENC_SB_EMPTY)
{
/* Fill subband data buffer before getting frame from COP */
enc_status = ENC_SB_FULL;
enc_thread_compress_frame();
return false;
}
#endif /* MP3_ENC_COP */
return true;
}
static inline size_t get_frame(uint8_t *buffer)
{
return mp3_enc_get_frame(buffer);
}
/* this is the codec entry point */
enum codec_status codec_main(enum codec_entry_call_reason reason)
{
#ifdef CPU_COLDFIRE
if (reason == CODEC_LOAD)
asm volatile ("move.l #0, %macsr"); /* integer mode */
#endif
return CODEC_OK;
(void)reason;
}
/* this is called for each file to process */
enum codec_status codec_run(void)
{
/* Encoder thread stack goes on our stack - leave 4k for us
Will be optimized away when single-threaded */
uint32_t enc_stack[(DEFAULT_STACK_SIZE+0x1000) / sizeof (uint32_t)];
if (!enc_thread_init(enc_stack, sizeof (enc_stack))) /* MT only */
return CODEC_ERROR;
mp3_encoder_reset();
uint32_t first = 1;
/* Needs to do stream finishing steps to flush-out all samples */
int frames_rem = -1; /* < 0 = indeterminate */
enum { GETBUF_PCM, GETBUF_ENC } getbuf = GETBUF_PCM;
struct enc_chunk_data *data = NULL;
/* main encoding loop */
while (1)
{
intptr_t param;
long action = ci->get_command(&param);
if (action != CODEC_ACTION_NULL)
{
if (action != CODEC_ACTION_STREAM_FINISH)
break;
if (frames_rem < 0)
frames_rem = cfg.flush_frames + DRAIN_FRAMES;
/* Reply with required space */
*(size_t *)param = cfg.req_byte_per_frame;
}
/* First, get PCM data; when available, obtain output buffer */
switch (getbuf)
{
case GETBUF_PCM:
if (LIKELY(frames_rem < 0))
{
/* Encoding audio */
if (!ci->enc_pcmbuf_read(cfg.samp_buffer,
cfg.samp_per_frame))
continue;
ci->enc_pcmbuf_advance(cfg.samp_per_frame);
encode_frame();
}
else if (frames_rem-- > DRAIN_FRAMES)
{
/* Flushing encoder */
ci->memset(cfg.samp_buffer, 0,
cfg.samp_per_frame*cfg.channels*2);
encode_frame();
}
/* else Draining remaining buffered data */
if (!wait_for_frame()) /* MT only */
break;
getbuf = GETBUF_ENC;
case GETBUF_ENC:
data = ci->enc_encbuf_get_buffer(cfg.req_byte_per_frame);
if (!data)
continue;
data->hdr.aux0 = first;
first = 0;
data->hdr.size = get_frame(data->data);
if (frames_rem)
enc_thread_compress_frame(); /* MT only */
data->pcm_count = cfg.samp_per_frame;
ci->enc_encbuf_finish_buffer();
getbuf = GETBUF_PCM;
}
if (!frames_rem)
break;
} /* while */
enc_thread_stop(); /* MT only */
return CODEC_OK;
}
/* this is called by recording system */
int enc_callback(enum enc_callback_reason reason, void *params)
{
if (LIKELY(reason == ENC_CB_STREAM))
{
switch (((union enc_chunk_hdr *)params)->type)
{
case CHUNK_T_DATA:
return on_stream_data(params);
case CHUNK_T_STREAM_START:
return on_stream_start(params);
case CHUNK_T_STREAM_END:
return on_stream_end(params);
}
}
else if (reason == ENC_CB_INPUTS)
{
struct enc_inputs *inputs = params;
mp3_encoder_init(inputs->sample_rate, inputs->num_channels,
inputs->config->mp3_enc.bitrate);
/* Return the actual configuration */
inputs->enc_sample_rate = cfg.samplerate;
}
return 0;
}