summaryrefslogtreecommitdiffstats
path: root/apps/codecs/mp3_enc.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-11-06 18:07:30 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-11-06 18:07:30 +0000
commit0f5cb94aa4a334366a746fcbb22f3335ca413265 (patch)
tree8f89a96628c1810d51ee9816daf78edb8c76fcd4 /apps/codecs/mp3_enc.c
parent0b22795e26ee09de14f6ac23219adeda12f2fd5b (diff)
downloadrockbox-0f5cb94aa4a334366a746fcbb22f3335ca413265.tar.gz
rockbox-0f5cb94aa4a334366a746fcbb22f3335ca413265.zip
Big Patch adds primarily: Samplerate and format selection to recording for SWCODEC. Supprort for samplerates changing in playback (just goes with the recording part inseparably). Samplerates to all encoders. Encoders can be configured individually on a menu specific to the encoder in the recording menu. File creation is delayed until flush time to reduce spinups when splitting. Misc: statusbar icons for numbers are individual digits to display any number. Audio buffer was rearranged to maximize memory available to recording and properly reinitialized when trashed. ColdFire PCM stuff moved to target tree to avoid a complicated mess when adding samplerate switching. Some needed API changes and to neaten up growing gap between hardware and software codecs.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11452 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/mp3_enc.c')
-rw-r--r--apps/codecs/mp3_enc.c1182
1 files changed, 726 insertions, 456 deletions
diff --git a/apps/codecs/mp3_enc.c b/apps/codecs/mp3_enc.c
index 3caca94f35..cb727ce01e 100644
--- a/apps/codecs/mp3_enc.c
+++ b/apps/codecs/mp3_enc.c
@@ -32,20 +32,19 @@
#ifndef SIMULATOR
+#include <inttypes.h>
#include "codeclib.h"
-CODEC_HEADER
+CODEC_ENC_HEADER
-#ifdef USE_IRAM
-extern char iramcopy[];
-extern char iramstart[];
-extern char iramend[];
-extern char iedata[];
-extern char iend[];
-#endif
-
-
-#define SAMP_PER_FRAME 1152
+#define ENC_PADDING_FRAMES1 2
+#define ENC_PADDING_FRAMES2 4
+#define ENC_DELAY_SAMP 576
+#define ENC_DELAY_SIZE (ENC_DELAY_SAMP*4)
+#define SAMP_PER_FRAME1 1152
+#define SAMP_PER_FRAME2 576
+#define PCM_CHUNK_SIZE1 (SAMP_PER_FRAME1*4)
+#define PCM_CHUNK_SIZE2 (SAMP_PER_FRAME2*4)
#define SAMPL2 576
#define SBLIMIT 32
#define HTN 16
@@ -54,15 +53,16 @@ extern char iend[];
#define putlong(c, s) if(s+sz <= 32) { cc = (cc << s) | c; sz+= s; } \
else { putbits(cc, sz); cc = c; sz = s; }
-enum e_byte_order { order_unknown, order_bigEndian, order_littleEndian };
-
-typedef unsigned long uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
-
+#ifdef USE_IRAM
+extern char iramcopy[];
+extern char iramstart[];
+extern char iramend[];
+extern char iedata[];
+extern char iend[];
+#endif
typedef struct {
- int type; /* 0=(22.05,24,16kHz) 1=(44.1,48,32kHz) */
+ 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;
@@ -73,21 +73,20 @@ typedef struct {
/* Side information */
typedef struct {
- uint32 part2_3_length;
+ uint32_t part2_3_length;
int count1; /* number of 0-1-quadruples */
- uint32 global_gain;
- uint32 table_select[4];
- uint32 region_0_1;
- uint32 address1;
- uint32 address2;
- uint32 address3;
+ 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;
long max_val;
} side_info_t;
typedef struct {
- enum e_byte_order byte_order;
side_info_t cod_info[2][2];
mpeg_t mpg;
long frac_per_frame;
@@ -98,19 +97,18 @@ typedef struct {
int ResvSize;
int channels;
int granules;
- int resample;
long samplerate;
} config_t;
typedef struct {
int bitpos; /* current bitpos for writing */
- uint32 bbuf[263];
+ uint32_t bbuf[263];
} BF_Data;
struct huffcodetab {
int len; /* max. index */
- const uint8 *table; /* pointer to array[len][len] */
- const uint8 *hlen; /* pointer to array[len][len] */
+ const uint8_t *table; /* pointer to array[len][len] */
+ const uint8_t *hlen; /* pointer to array[len][len] */
};
struct huffcodebig {
@@ -127,102 +125,105 @@ struct huffcodebig {
#define shft_n(x,n) ((x) >> n)
#define SQRT 724 /* sqrt(2) * 512 */
-short mfbuf [2*(1152+512)] IBSS_ATTR; /* 3328 Bytes */
-int sb_data [2][2][18][SBLIMIT] IBSS_ATTR; /* 13824 Bytes */
-int mdct_freq [SAMPL2] IBSS_ATTR; /* 9216 Bytes */
-short enc_data [SAMPL2] IBSS_ATTR; /* 4608 Bytes */
-uint32 scalefac [23] IBSS_ATTR; /* 92 Bytes */
-BF_Data CodedData IBSS_ATTR; /* 1056 Bytes */
-int ca [8] IBSS_ATTR; /* 32 Bytes */
-int cs [8] IBSS_ATTR; /* 32 Bytes */
-int cx [9] IBSS_ATTR; /* 36 Bytes */
-int win [18][4] IBSS_ATTR; /* 288 Bytes */
-short enwindow [15*27+24] IBSS_ATTR; /* 862 Bytes */
-short int2idx [4096] IBSS_ATTR; /* 8192 Bytes */
-uint8 ht_count [2][2][16] IBSS_ATTR; /* 64 Bytes */
-uint32 tab01 [ 16] IBSS_ATTR; /* 64 Bytes */
-uint32 tab23 [ 9] IBSS_ATTR; /* 36 Bytes */
-uint32 tab56 [ 16] IBSS_ATTR; /* 64 Bytes */
-uint32 tab1315 [256] IBSS_ATTR; /* 1024 Bytes */
-uint32 tab1624 [256] IBSS_ATTR; /* 1024 Bytes */
-uint32 tab789 [ 36] IBSS_ATTR; /* 144 Bytes */
-uint32 tabABC [ 64] IBSS_ATTR; /* 256 Bytes */
-uint8 t1HB [ 4] IBSS_ATTR;
-uint8 t2HB [ 9] IBSS_ATTR;
-uint8 t3HB [ 9] IBSS_ATTR;
-uint8 t5HB [ 16] IBSS_ATTR;
-uint8 t6HB [ 16] IBSS_ATTR;
-uint8 t7HB [ 36] IBSS_ATTR;
-uint8 t8HB [ 36] IBSS_ATTR;
-uint8 t9HB [ 36] IBSS_ATTR;
-uint8 t10HB [ 64] IBSS_ATTR;
-uint8 t11HB [ 64] IBSS_ATTR;
-uint8 t12HB [ 64] IBSS_ATTR;
-uint8 t13HB [256] IBSS_ATTR;
-uint8 t15HB [256] IBSS_ATTR;
-uint16 t16HB [256] IBSS_ATTR;
-uint16 t24HB [256] IBSS_ATTR;
-uint8 t1l [ 8] IBSS_ATTR;
-uint8 t2l [ 9] IBSS_ATTR;
-uint8 t3l [ 9] IBSS_ATTR;
-uint8 t5l [ 16] IBSS_ATTR;
-uint8 t6l [ 16] IBSS_ATTR;
-uint8 t7l [ 36] IBSS_ATTR;
-uint8 t8l [ 36] IBSS_ATTR;
-uint8 t9l [ 36] IBSS_ATTR;
-uint8 t10l [ 64] IBSS_ATTR;
-uint8 t11l [ 64] IBSS_ATTR;
-uint8 t12l [ 64] IBSS_ATTR;
-uint8 t13l [256] IBSS_ATTR;
-uint8 t15l [256] IBSS_ATTR;
-uint8 t16l [256] IBSS_ATTR;
-uint8 t24l [256] IBSS_ATTR;
-struct huffcodetab ht [HTN] IBSS_ATTR;
-
-static config_t cfg;
+static short mfbuf [2*(1152+512)] IBSS_ATTR; /* 3328 Bytes */
+static int sb_data [2][2][18][SBLIMIT] IBSS_ATTR; /* 13824 Bytes */
+static int mdct_freq [SAMPL2] IBSS_ATTR; /* 9216 Bytes */
+static short enc_data [SAMPL2] IBSS_ATTR; /* 4608 Bytes */
+static uint32_t scalefac [23] IBSS_ATTR; /* 92 Bytes */
+static BF_Data CodedData IBSS_ATTR; /* 1056 Bytes */
+static int ca [8] IBSS_ATTR; /* 32 Bytes */
+static int cs [8] IBSS_ATTR; /* 32 Bytes */
+static int cx [9] IBSS_ATTR; /* 36 Bytes */
+static int win [18][4] IBSS_ATTR; /* 288 Bytes */
+static short enwindow [15*27+24] IBSS_ATTR; /* 862 Bytes */
+static short int2idx [4096] IBSS_ATTR; /* 8192 Bytes */
+static uint8_t ht_count [2][2][16] IBSS_ATTR; /* 64 Bytes */
+static uint32_t tab01 [ 16] IBSS_ATTR; /* 64 Bytes */
+static uint32_t tab23 [ 9] IBSS_ATTR; /* 36 Bytes */
+static uint32_t tab56 [ 16] IBSS_ATTR; /* 64 Bytes */
+static uint32_t tab1315 [256] IBSS_ATTR; /* 1024 Bytes */
+static uint32_t tab1624 [256] IBSS_ATTR; /* 1024 Bytes */
+static uint32_t tab789 [ 36] IBSS_ATTR; /* 144 Bytes */
+static uint32_t tabABC [ 64] IBSS_ATTR; /* 256 Bytes */
+static uint8_t t1HB [ 4] IBSS_ATTR;
+static uint8_t t2HB [ 9] IBSS_ATTR;
+static uint8_t t3HB [ 9] IBSS_ATTR;
+static uint8_t t5HB [ 16] IBSS_ATTR;
+static uint8_t t6HB [ 16] IBSS_ATTR;
+static uint8_t t7HB [ 36] IBSS_ATTR;
+static uint8_t t8HB [ 36] IBSS_ATTR;
+static uint8_t t9HB [ 36] IBSS_ATTR;
+static uint8_t t10HB [ 64] IBSS_ATTR;
+static uint8_t t11HB [ 64] IBSS_ATTR;
+static uint8_t t12HB [ 64] IBSS_ATTR;
+static uint8_t t13HB [256] IBSS_ATTR;
+static uint8_t t15HB [256] IBSS_ATTR;
+static uint16_t t16HB [256] IBSS_ATTR;
+static uint16_t t24HB [256] IBSS_ATTR;
+static uint8_t t1l [ 8] IBSS_ATTR;
+static uint8_t t2l [ 9] IBSS_ATTR;
+static uint8_t t3l [ 9] IBSS_ATTR;
+static uint8_t t5l [ 16] IBSS_ATTR;
+static uint8_t t6l [ 16] IBSS_ATTR;
+static uint8_t t7l [ 36] IBSS_ATTR;
+static uint8_t t8l [ 36] IBSS_ATTR;
+static uint8_t t9l [ 36] IBSS_ATTR;
+static uint8_t t10l [ 64] IBSS_ATTR;
+static uint8_t t11l [ 64] IBSS_ATTR;
+static uint8_t t12l [ 64] IBSS_ATTR;
+static uint8_t t13l [256] IBSS_ATTR;
+static uint8_t t15l [256] IBSS_ATTR;
+static uint8_t t16l [256] IBSS_ATTR;
+static uint8_t t24l [256] IBSS_ATTR;
+static struct huffcodetab ht [HTN] IBSS_ATTR;
+
+static unsigned pcm_chunk_size IBSS_ATTR;
+static unsigned samp_per_frame IBSS_ATTR;
+
+static config_t cfg IBSS_ATTR;
static struct codec_api *ci;
-static int enc_channels;
+static char *res_buffer;
-static const uint8 ht_count_const[2][2][16] =
+static const uint8_t ht_count_const[2][2][16] =
{ { { 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 t1HB_const[4] = {1,1,1,0};
-static const uint8 t2HB_const[9] = {1,2,1,3,1,1,3,2,0};
-static const uint8 t3HB_const[9] = {3,2,1,1,1,1,3,2,0};
-static const uint8 t5HB_const[16] = {1,2,6,5,3,1,4,4,7,5,7,1,6,1,1,0};
-static const uint8 t6HB_const[16] = {7,3,5,1,6,2,3,2,5,4,4,1,3,3,2,0};
+static const uint8_t t1HB_const[4] = {1,1,1,0};
+static const uint8_t t2HB_const[9] = {1,2,1,3,1,1,3,2,0};
+static const uint8_t t3HB_const[9] = {3,2,1,1,1,1,3,2,0};
+static const uint8_t t5HB_const[16] = {1,2,6,5,3,1,4,4,7,5,7,1,6,1,1,0};
+static const uint8_t t6HB_const[16] = {7,3,5,1,6,2,3,2,5,4,4,1,3,3,2,0};
-static const uint8 t7HB_const[36] =
+static const uint8_t t7HB_const[36] =
{ 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 t8HB_const[36] =
+static const uint8_t t8HB_const[36] =
{ 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 t9HB_const[36] =
+static const uint8_t t9HB_const[36] =
{ 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 t10HB_const[64] =
+static const uint8_t t10HB_const[64] =
{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 t11HB_const[64] =
+static const uint8_t t11HB_const[64] =
{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 t12HB_const[64] =
+static const uint8_t t12HB_const[64] =
{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 t13HB_const[256] =
+static const uint8_t t13HB_const[256] =
{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,
@@ -234,7 +235,7 @@ static const uint8 t13HB_const[256] =
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 t15HB_const[256] =
+static const uint8_t t15HB_const[256] =
{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,
@@ -246,7 +247,7 @@ static const uint8 t15HB_const[256] =
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 t16HB_const[256] =
+static const uint16_t t16HB_const[256] =
{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,
@@ -261,7 +262,7 @@ static const uint16 t16HB_const[256] =
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 t24HB_const[256] =
+static const uint16_t t24HB_const[256] =
{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,
@@ -276,7 +277,7 @@ static const uint16 t24HB_const[256] =
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 tab1315_const[256] =
+static const uint32_t tab1315_const[256] =
{ 0x010003,0x050005,0x070006,0x080008,0x090008,0x0a0009,0x0a000a,0x0b000a,
0x0a000a,0x0b000b,0x0c000b,0x0c000c,0x0d000c,0x0d000c,0x0e000d,0x0e000e,
0x040005,0x060005,0x080007,0x090008,0x0a0009,0x0a0009,0x0b000a,0x0b000a,
@@ -310,18 +311,18 @@ static const uint32 tab1315_const[256] =
0x0d000d,0x0e000d,0x0f000d,0x10000d,0x10000d,0x10000d,0x11000d,0x10000e,
0x11000e,0x11000e,0x12000e,0x12000e,0x15000f,0x14000f,0x15000f,0x12000f };
-static const uint32 tab01_const[16] =
+static const uint32_t tab01_const[16] =
{ 0x10004,0x50005,0x50005,0x70006,0x50005,0x80006,0x70006,0x90007,
0x50005,0x70006,0x70006,0x90007,0x70006,0x90007,0x90007,0xa0008 };
-static const uint32 tab23_const[ 9] =
+static const uint32_t tab23_const[ 9] =
{ 0x10002,0x40003,0x70007,0x40004,0x50004,0x70007,0x60006,0x70007,0x80008 };
-static const uint32 tab56_const[16] =
+static const uint32_t tab56_const[16] =
{ 0x10003,0x40004,0x70006,0x80008,0x40004,0x50004,0x80006,0x90007,
0x70005,0x80006,0x90007,0xa0008,0x80007,0x80007,0x90008,0xa0009 };
-static const uint32 tab789_const[36] =
+static const uint32_t tab789_const[36] =
{0x00100803,0x00401004,0x00701c06,0x00902407,0x00902409,0x00a0280a,0x00401004,
0x00601005,0x00801806,0x00902807,0x00902808,0x00a0280a,0x00701c05,0x00701806,
0x00902007,0x00a02808,0x00a02809,0x00b02c0a,0x00802407,0x00902807,0x00a02808,
@@ -329,7 +330,7 @@ static const uint32 tab789_const[36] =
0x00b0300a,0x00c0300b,0x00902809,0x00a02809,0x00b02c0a,0x00c02c0a,0x00c0340b,
0x00c0340b};
-static const uint32 tabABC_const[64] =
+static const uint32_t tabABC_const[64] =
{0x00100804,0x00401004,0x00701806,0x00902008,0x00a02409,0x00a0280a,0x00a0240a,
0x00b0280a,0x00401004,0x00601405,0x00801806,0x00902007,0x00a02809,0x00b02809,
0x00a0240a,0x00a0280a,0x00701806,0x00801c06,0x00902007,0x00a02408,0x00b02809,
@@ -341,7 +342,7 @@ static const uint32 tabABC_const[64] =
0x00a0240a,0x00a0240a,0x00b0280a,0x00c02c0b,0x00c0300b,0x00d0300b,0x00d0300b,
0x00d0300c};
-static const uint32 tab1624_const[256] =
+static const uint32_t tab1624_const[256] =
{0x00010004,0x00050005,0x00070007,0x00090008,0x000a0009,0x000a000a,0x000b000a,
0x000b000b,0x000c000b,0x000c000c,0x000c000c,0x000d000c,0x000d000c,0x000d000c,
0x000e000d,0x000a000a,0x00040005,0x00060006,0x00080007,0x00090008,0x000a0009,
@@ -380,34 +381,34 @@ static const uint32 tab1624_const[256] =
0x000c0009,0x000c0009,0x000c0009,0x000d0009,0x000d0009,0x000d0009,0x000d000a,
0x000d000a,0x000d000a,0x000d000a,0x000a0006};
-static const uint8 t1l_const[8] = {1,3,2,3,1,4,3,5};
-static const uint8 t2l_const[9] = {1,3,6,3,3,5,5,5,6};
-static const uint8 t3l_const[9] = {2,2,6,3,2,5,5,5,6};
-static const uint8 t5l_const[16] = {1,3,6,7,3,3,6,7,6,6,7,8,7,6,7,8};
-static const uint8 t6l_const[16] = {3,3,5,7,3,2,4,5,4,4,5,6,6,5,6,7};
+static const uint8_t t1l_const[8] = {1,3,2,3,1,4,3,5};
+static const uint8_t t2l_const[9] = {1,3,6,3,3,5,5,5,6};
+static const uint8_t t3l_const[9] = {2,2,6,3,2,5,5,5,6};
+static const uint8_t t5l_const[16] = {1,3,6,7,3,3,6,7,6,6,7,8,7,6,7,8};
+static const uint8_t t6l_const[16] = {3,3,5,7,3,2,4,5,4,4,5,6,6,5,6,7};
-static const uint8 t7l_const[36] =
+static const uint8_t t7l_const[36] =
{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 t8l_const[36] =
+static const uint8_t t8l_const[36] =
{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 t9l_const[36] =
+static const uint8_t t9l_const[36] =
{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 t10l_const[64] =
+static const uint8_t t10l_const[64] =
{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 t11l_const[64] =
+static const uint8_t t11l_const[64] =
{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 t12l_const[64] =
+static const uint8_t t12l_const[64] =
{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 t13l_const[256] =
+static const uint8_t t13l_const[256] =
{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,
@@ -419,7 +420,7 @@ static const uint8 t13l_const[256] =
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 t15l_const[256] =
+static const uint8_t t15l_const[256] =
{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,
@@ -430,7 +431,7 @@ static const uint8 t15l_const[256] =
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 t16l_const[256] =
+static const uint8_t t16l_const[256] =
{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,
@@ -442,7 +443,7 @@ static const uint8 t16l_const[256] =
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 t24l_const[256] =
+static const uint8_t t24l_const[256] =
{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,
@@ -491,8 +492,8 @@ static const struct huffcodebig ht_big[HTN] =
static const struct
{
- uint32 region0_cnt;
- uint32 region1_cnt;
+ uint32_t region0_cnt;
+ uint32_t region1_cnt;
} subdv_table[23] =
{ {0, 0}, /* 0 bands */
{0, 0}, /* 1 bands */
@@ -519,7 +520,7 @@ static const struct
{6, 7}, /* 22 bands */
};
-static const uint32 sfBand[6][23] =
+static const uint32_t sfBand[6][23] =
{
/* Table B.2.b: 22.05 kHz */
{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
@@ -747,9 +748,13 @@ static const int order[32] =
{ 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 bitr_index[2][15] =
-{ {0, 8,16,24,32,40,48,56, 64, 80, 96,112,128,144,160},
- {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320} };
+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},
@@ -837,35 +842,55 @@ static const int win_const[18][4] = {
{ 134, -146,-3352,-3072 } };
/* forward declarations */
-int HuffmanCode( short *ix, int *xr, uint32 begin, uint32 end, int table);
-int HuffmanCod1( short *ix, int *xr, uint32 begin, uint32 end, int table);
-void putbits(uint32 val, uint32 nbit);
-int find_best_2( short *ix, uint32 start, uint32 end, const uint32 *table,
- uint32 len, int *bits);
-int find_best_3( short *ix, uint32 start, uint32 end, const uint32 *table,
- uint32 len, int *bits);
-int count_bit1 ( short *ix, uint32 start, uint32 end, int *bits );
-int count_bigv ( short *ix, uint32 start, uint32 end, int table0, int table1,
+static int HuffmanCode( short *ix, int *xr, uint32_t begin, uint32_t end, int table);
+static int HuffmanCod1( short *ix, int *xr, uint32_t begin, uint32_t end, int table);
+static void putbits(uint32_t val, uint32_t nbit);
+static int find_best_2( short *ix, uint32_t start, uint32_t end, const uint32_t *table,
+ uint32_t len, int *bits);
+static int find_best_3( short *ix, uint32_t start, uint32_t end, const uint32_t *table,
+ uint32_t len, int *bits);
+static int count_bit1 ( short *ix, uint32_t start, uint32_t end, int *bits );
+static int count_bigv ( short *ix, uint32_t start, uint32_t end, int table0, int table1,
int *bits);
-void encodeSideInfo( side_info_t si[2][2] )
+static void encodeSideInfo( side_info_t si[2][2] )
{
int gr, ch, header;
- uint32 cc=0, sz=0;
+ uint32_t cc=0, sz=0;
- header = 0xfff00000;
- header |= cfg.mpg.type << 19; /* mp3 type: 1 */
- header |= 1 << 17; /* mp3 layer: 1 */
- header |= 1 << 16; /* mp3 crc: 0 */
+ /*
+ * 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
+ */
+
+ header = (0xfff00000) | /* frame sync (AAAAAAAAA AAA)
+ mp3 type (upper): 1 (B) */
+ (0x01 << 17) | /* mp3 layer: 01 (CC) */
+ ( 0x1 << 16) | /* mp3 crc: 1 (D) */
+ ( 0x1 << 2); /* mp3 org: 1 (L) */
+ header |= cfg.mpg.type << 19;
header |= cfg.mpg.bitr_id << 12;
header |= cfg.mpg.smpl_id << 10;
header |= cfg.mpg.padding << 9;
header |= cfg.mpg.mode << 6;
- header |= 1 << 2; /* mp3 original: 1 */
+ /* no emphasis (bits 0-1) */
putbits( header, 32 );
- if(cfg.mpg.type)
+ if(cfg.mpg.type == 1)
{ /* MPEG1 */
if(cfg.channels == 2) { putlong( 0, 20); }
else { putlong( 0, 18); }
@@ -910,7 +935,7 @@ void encodeSideInfo( side_info_t si[2][2] )
/* 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. */
-void Huffmancodebits( short *ix, int *xr, side_info_t *gi )
+static void Huffmancodebits( short *ix, int *xr, side_info_t *gi )
{
int region1 = gi->address1;
int region2 = gi->address2;
@@ -944,10 +969,10 @@ void Huffmancodebits( short *ix, int *xr, side_info_t *gi )
}
}
-int HuffmanCod1( short *ix, int *xr, uint32 begin, uint32 end, int tbl)
+int HuffmanCod1( short *ix, int *xr, uint32_t begin, uint32_t end, int tbl)
{
- uint32 cc=0, sz=0;
- uint32 i, d, p;
+ uint32_t cc=0, sz=0;
+ uint32_t i, d, p;
int sumbit=0, s=0, l=0, v, w, x, y;
#define sgnv (xr[i+0] < 0 ? 1 : 0)
#define sgnw (xr[i+1] < 0 ? 1 : 0)
@@ -995,10 +1020,10 @@ int HuffmanCod1( short *ix, int *xr, uint32 begin, uint32 end, int tbl)
}
/* Implements the pseudocode of page 98 of the IS */
-int HuffmanCode( short *ix, int *xr, uint32 begin, uint32 end, int table)
+int HuffmanCode( short *ix, int *xr, uint32_t begin, uint32_t end, int table)
{
- uint32 cc=0, sz=0, code;
- uint32 i, xl=0, yl=0, idx;
+ uint32_t cc=0, sz=0, code;
+ uint32_t i, xl=0, yl=0, idx;
int x, y, bit, sumbit=0;
#define sign_x (xr[i+0] < 0 ? 1 : 0)
#define sign_y (xr[i+1] < 0 ? 1 : 0)
@@ -1008,9 +1033,9 @@ int HuffmanCode( short *ix, int *xr, uint32 begin, uint32 end, int table)
if( table > 15 )
{ /* ESC-table is used */
- uint32 linbits = ht_big[table-16].linbits;
- uint16 *hffcode = table < 24 ? t16HB : t24HB;
- uint8 *hlen = table < 24 ? t16l : t24l;
+ uint32_t linbits = ht_big[table-16].linbits;
+ uint16_t *hffcode = table < 24 ? t16HB : t24HB;
+ uint8_t *hlen = table < 24 ? t16l : t24l;
for(i=begin; i<end; i+=2)
{
@@ -1088,14 +1113,14 @@ int HuffmanCode( short *ix, int *xr, uint32 begin, uint32 end, int table)
return sumbit;
}
-void putbits(uint32 val, uint32 nbit)
+void putbits(uint32_t val, uint32_t nbit)
{
int new_bitpos = CodedData.bitpos + nbit;
int ptrpos = CodedData.bitpos >> 5;
val = val & (0xffffffff >> (32 - nbit));
- /* data fit in one uint32 */
+ /* data fit in one uint32_t */
if(((new_bitpos - 1) >> 5) == ptrpos)
CodedData.bbuf[ptrpos] |= val << ((32 - new_bitpos) & 31);
else
@@ -1114,9 +1139,9 @@ void putbits(uint32 val, uint32 nbit)
/* of the Huffman tables as defined in the IS (Table B.7), and will not */
/* work with any arbitrary tables. */
/***************************************************************************/
-int choose_table( short *ix, uint32 begin, uint32 end, int *bits )
+int choose_table( short *ix, uint32_t begin, uint32_t end, int *bits )
{
- uint32 i;
+ uint32_t i;
int max, table0, table1;
for(i=begin,max=0; i<end; i++)
@@ -1158,10 +1183,10 @@ int choose_table( short *ix, uint32 begin, uint32 end, int *bits )
}
}
-int find_best_2(short *ix, uint32 start, uint32 end, const uint32 *table,
- uint32 len, int *bits)
+int find_best_2(short *ix, uint32_t start, uint32_t end, const uint32_t *table,
+ uint32_t len, int *bits)
{
- uint32 i, sum = 0;
+ uint32_t i, sum = 0;
for(i=start; i<end; i+=2)
sum += table[ix[i] * len + ix[i+1]];
@@ -1178,10 +1203,10 @@ int find_best_2(short *ix, uint32 start, uint32 end, const uint32 *table,
}
}
-int find_best_3(short *ix, uint32 start, uint32 end, const uint32 *table,
- uint32 len, int *bits)
+int find_best_3(short *ix, uint32_t start, uint32_t end, const uint32_t *table,
+ uint32_t len, int *bits)
{
- uint32 i, j, sum = 0;
+ uint32_t i, j, sum = 0;
int sum1 = 0;
int sum2 = 0;
int sum3 = 0;
@@ -1211,9 +1236,9 @@ int find_best_3(short *ix, uint32 start, uint32 end, const uint32 *table,
/*************************************************************************/
/* Function: Count the number of bits necessary to code the subregion. */
/*************************************************************************/
-int count_bit1(short *ix, uint32 start, uint32 end, int *bits )
+int count_bit1(short *ix, uint32_t start, uint32_t end, int *bits )
{
- uint32 i, sum = 0;
+ uint32_t i, sum = 0;
for(i=start; i<end; i+=2)
sum += t1l[4 + ix[i] * 2 + ix[i+1]];
@@ -1223,10 +1248,10 @@ int count_bit1(short *ix, uint32 start, uint32 end, int *bits )
return 1; /* this is table1 */
}
-int count_bigv(short *ix, uint32 start, uint32 end, int table0,
+int count_bigv(short *ix, uint32_t start, uint32_t end, int table0,
int table1, int *bits )
{
- uint32 i, sum0, sum1, sum=0, bigv=0, x, y;
+ uint32_t i, sum0, sum1, sum=0, bigv=0, x, y;
/* ESC-table is used */
for(i=start; i<end; i+=2)
@@ -1264,7 +1289,7 @@ int calc_runlen( short *ix, side_info_t *si )
int p, i, sum = 0;
for(i=SAMPL2; i-=2; )
- if(*(uint32*)&ix[i-2]) /* !!!! short *ix; !!!!! */
+ if(*(uint32_t*)&ix[i-2]) /* !!!! short *ix; !!!!! */
break;
si->count1 = 0;
@@ -1899,276 +1924,275 @@ void mdct_long(int *out, int *in)
out[16] = ct - st;
}
-static int find_bitrate_index(int type, int bitrate)
+static int find_bitrate_index(int type, int bitrate, bool stereo)
{
- int i;
+ if (type == 1 && !stereo && bitrate > 160)
+ bitrate = 160;
- for(i=0;i<14;i++)
- if(bitrate == bitr_index[type][i])
- break;
-
- return i;
+ return ci->round_value_to_list32(bitrate,
+ &bitr_index[type][1], 14, true) + 1;
}
static int find_samplerate_index(long freq, int *mp3_type)
-{ /* MPEG 2 */ /* MPEG 1 */
- static long mpeg[2][3] = { {22050, 24000, 16000}, {44100, 48000, 32000} };
- int mpg, rate;
-
- /* set default values: MPEG1 at 44100/s */
- *mp3_type = 1;
-
- for(mpg=0; mpg<2; mpg++)
- for(rate=0; rate<3; rate++)
- if(freq == mpeg[mpg][rate])
- { *mp3_type = mpg; return rate; }
-
- return 0;
+{
+ 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;
}
-void init_mp3_encoder_engine(bool stereo, int quality, int sample_rate)
+bool init_mp3_encoder_engine(int sample_rate,
+ int num_channels,
+ struct encoder_config *enc_cfg)
{
- /* keep in sync with rec_quality_info_afmt in id3.h/.c */
- static int bitr_s[9] = { 64, 96, 128, 160, 192, 224, 320, 64, 64 };
- static int bitr_m[9] = { 64, 96, 128, 160, 160, 160, 160, 64, 64 };
- uint32 avg_byte_per_frame;
-
- if(quality == 0 && stereo && sample_rate >= 32000)
- { /* use MPEG2 format */
- sample_rate >>= 1;
- cfg.resample = 1;
- cfg.granules = 1;
- }
- else
- { /* use MPEG1 format */
- cfg.resample = 0;
- cfg.granules = 2;
- }
+ const bool stereo = num_channels > 1;
+ uint32_t avg_byte_per_frame;
+
+ 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.mpg.bitr_id = find_bitrate_index(cfg.mpg.type,
+ enc_cfg->mp3_enc.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;
+ pcm_chunk_size = PCM_CHUNK_SIZE1;
+ samp_per_frame = SAMP_PER_FRAME1;
+ }
+ else
+ {
+ cfg.granules = 1;
+ pcm_chunk_size = PCM_CHUNK_SIZE2;
+ samp_per_frame = SAMP_PER_FRAME2;
+ }
- cfg.byte_order = order_bigEndian;
- cfg.samplerate = sample_rate;
- cfg.channels = stereo ? 2 : 1;
- cfg.mpg.mode = stereo ? 0 : 3; /* 0=stereo, 3=mono */
- cfg.mpg.bitrate = stereo ? bitr_s[quality] : bitr_m[quality];
- cfg.mpg.smpl_id = find_samplerate_index(cfg.samplerate, &cfg.mpg.type);
- cfg.mpg.bitr_id = find_bitrate_index(cfg.mpg.type, cfg.mpg.bitrate);
- cfg.mpg.num_bands = num_bands[stereo ? cfg.mpg.type : 2][cfg.mpg.bitr_id];
-
- memcpy(scalefac, sfBand[cfg.mpg.smpl_id + 3*cfg.mpg.type], sizeof(scalefac));
- memset(mfbuf , 0 , sizeof(mfbuf ));
- memset(mdct_freq , 0 , sizeof(mdct_freq ));
- memset(enc_data , 0 , sizeof(enc_data ));
- memset(sb_data , 0 , sizeof(sb_data ));
- memset(&CodedData, 0 , sizeof(CodedData ));
- memcpy(ca , ca_const , sizeof(ca ));
- memcpy(cs , cs_const , sizeof(cs ));
- memcpy(cx , cx_const , sizeof(cx ));
- memcpy(win , win_const , sizeof(win ));
- memcpy(enwindow , enwindow_const , sizeof(enwindow ));
- memcpy(int2idx , int2idx_const , sizeof(int2idx ));
- memcpy(ht_count , ht_count_const , sizeof(ht_count ));
- memcpy( tab01 , tab01_const , sizeof(tab01 ));
- memcpy( tab23 , tab23_const , sizeof(tab23 ));
- memcpy( tab56 , tab56_const , sizeof(tab56 ));
- memcpy( tab1315 , tab1315_const , sizeof(tab1315 ));
- memcpy( tab1624 , tab1624_const , sizeof(tab1624 ));
- memcpy( tab789 , tab789_const , sizeof(tab789 ));
- memcpy( tabABC , tabABC_const , sizeof(tabABC ));
- memcpy( t1HB , t1HB_const , sizeof(t1HB ));
- memcpy( t2HB , t2HB_const , sizeof(t2HB ));
- memcpy( t3HB , t3HB_const , sizeof(t3HB ));
- memcpy( t5HB , t5HB_const , sizeof(t5HB ));
- memcpy( t6HB , t6HB_const , sizeof(t6HB ));
- memcpy( t7HB , t7HB_const , sizeof(t7HB ));
- memcpy( t8HB , t8HB_const , sizeof(t8HB ));
- memcpy( t9HB , t9HB_const , sizeof(t9HB ));
- memcpy(t10HB , t10HB_const , sizeof(t10HB ));
- memcpy(t11HB , t11HB_const , sizeof(t11HB ));
- memcpy(t12HB , t12HB_const , sizeof(t12HB ));
- memcpy(t13HB , t13HB_const , sizeof(t13HB ));
- memcpy(t15HB , t15HB_const , sizeof(t15HB ));
- memcpy(t16HB , t16HB_const , sizeof(t16HB ));
- memcpy(t24HB , t24HB_const , sizeof(t24HB ));
- memcpy( t1l , t1l_const , sizeof(t1l ));
- memcpy( t2l , t2l_const , sizeof(t2l ));
- memcpy( t3l , t3l_const , sizeof(t3l ));
- memcpy( t5l , t5l_const , sizeof(t5l ));
- memcpy( t6l , t6l_const , sizeof(t6l ));
- memcpy( t7l , t7l_const , sizeof(t7l ));
- memcpy( t8l , t8l_const , sizeof(t8l ));
- memcpy( t9l , t9l_const , sizeof(t9l ));
- memcpy(t10l , t10l_const , sizeof(t10l ));
- memcpy(t11l , t11l_const , sizeof(t11l ));
- memcpy(t12l , t12l_const , sizeof(t12l ));
- memcpy(t13l , t13l_const , sizeof(t13l ));
- memcpy(t15l , t15l_const , sizeof(t15l ));
- memcpy(t16l , t16l_const , sizeof(t16l ));
- memcpy(t24l , t24l_const , sizeof(t24l ));
- memcpy(ht , ht_const , sizeof(ht ));
-
- ht[ 0].table = NULL; ht[ 0].hlen = NULL; /* Apparently not used */
- ht[ 1].table = t1HB; ht[ 1].hlen = t1l;
- ht[ 2].table = t2HB; ht[ 2].hlen = t2l;
- ht[ 3].table = t3HB; ht[ 3].hlen = t3l;
- ht[ 4].table = NULL; ht[ 4].hlen = NULL; /* Apparently not used */
- ht[ 5].table = t5HB; ht[ 5].hlen = t5l;
- ht[ 6].table = t6HB; ht[ 6].hlen = t6l;
- ht[ 7].table = t7HB; ht[ 7].hlen = t7l;
- ht[ 8].table = t8HB; ht[ 8].hlen = t8l;
- ht[ 9].table = t9HB; ht[ 9].hlen = t9l;
- ht[10].table = t10HB; ht[10].hlen = t10l;
- ht[11].table = t11HB; ht[11].hlen = t11l;
- ht[12].table = t12HB; ht[12].hlen = t12l;
- ht[13].table = t13HB; ht[13].hlen = t13l;
- ht[14].table = NULL; ht[14].hlen = NULL; /* Apparently not used */
- ht[15].table = t15HB; ht[15].hlen = t15l;
-
- /* Figure average number of 'bytes' per frame */
- avg_byte_per_frame = SAMPL2 * 16000 * cfg.mpg.bitrate / (2 - cfg.mpg.type);
- avg_byte_per_frame = avg_byte_per_frame / cfg.samplerate;
- cfg.byte_per_frame = avg_byte_per_frame / 64;
- cfg.frac_per_frame = avg_byte_per_frame & 63;
- cfg.slot_lag = 0;
- cfg.sideinfo_len = 32 + (cfg.mpg.type ? (cfg.channels == 1 ? 136 : 256)
- : (cfg.channels == 1 ? 72 : 136));
+ memcpy(scalefac, sfBand[cfg.mpg.smpl_id + 3*cfg.mpg.type], sizeof(scalefac));
+ memset(mfbuf , 0 , sizeof(mfbuf ));
+ memset(mdct_freq , 0 , sizeof(mdct_freq ));
+ memset(enc_data , 0 , sizeof(enc_data ));
+ memset(sb_data , 0 , sizeof(sb_data ));
+ memset(&CodedData, 0 , sizeof(CodedData ));
+ memcpy(ca , ca_const , sizeof(ca ));
+ memcpy(cs , cs_const , sizeof(cs ));
+ memcpy(cx , cx_const , sizeof(cx ));
+ memcpy(win , win_const , sizeof(win ));
+ memcpy(enwindow , enwindow_const , sizeof(enwindow ));
+ memcpy(int2idx , int2idx_const , sizeof(int2idx ));
+ memcpy(ht_count , ht_count_const , sizeof(ht_count ));
+ memcpy( tab01 , tab01_const , sizeof(tab01 ));
+ memcpy( tab23 , tab23_const , sizeof(tab23 ));
+ memcpy( tab56 , tab56_const , sizeof(tab56 ));
+ memcpy( tab1315 , tab1315_const , sizeof(tab1315 ));
+ memcpy( tab1624 , tab1624_const , sizeof(tab1624 ));
+ memcpy( tab789 , tab789_const , sizeof(tab789 ));
+ memcpy( tabABC , tabABC_const , sizeof(tabABC ));
+ memcpy( t1HB , t1HB_const , sizeof(t1HB ));
+ memcpy( t2HB , t2HB_const , sizeof(t2HB ));
+ memcpy( t3HB , t3HB_const , sizeof(t3HB ));
+ memcpy( t5HB , t5HB_const , sizeof(t5HB ));
+ memcpy( t6HB , t6HB_const , sizeof(t6HB ));
+ memcpy( t7HB , t7HB_const , sizeof(t7HB ));
+ memcpy( t8HB , t8HB_const , sizeof(t8HB ));
+ memcpy( t9HB , t9HB_const , sizeof(t9HB ));
+ memcpy(t10HB , t10HB_const , sizeof(t10HB ));
+ memcpy(t11HB , t11HB_const , sizeof(t11HB ));
+ memcpy(t12HB , t12HB_const , sizeof(t12HB ));
+ memcpy(t13HB , t13HB_const , sizeof(t13HB ));
+ memcpy(t15HB , t15HB_const , sizeof(t15HB ));
+ memcpy(t16HB , t16HB_const , sizeof(t16HB ));
+ memcpy(t24HB , t24HB_const , sizeof(t24HB ));
+ memcpy( t1l , t1l_const , sizeof(t1l ));
+ memcpy( t2l , t2l_const , sizeof(t2l ));
+ memcpy( t3l , t3l_const , sizeof(t3l ));
+ memcpy( t5l , t5l_const , sizeof(t5l ));
+ memcpy( t6l , t6l_const , sizeof(t6l ));
+ memcpy( t7l , t7l_const , sizeof(t7l ));
+ memcpy( t8l , t8l_const , sizeof(t8l ));
+ memcpy( t9l , t9l_const , sizeof(t9l ));
+ memcpy(t10l , t10l_const , sizeof(t10l ));
+ memcpy(t11l , t11l_const , sizeof(t11l ));
+ memcpy(t12l , t12l_const , sizeof(t12l ));
+ memcpy(t13l , t13l_const , sizeof(t13l ));
+ memcpy(t15l , t15l_const , sizeof(t15l ));
+ memcpy(t16l , t16l_const , sizeof(t16l ));
+ memcpy(t24l , t24l_const , sizeof(t24l ));
+ memcpy(ht , ht_const , sizeof(ht ));
+
+ ht[ 0].table = NULL; ht[ 0].hlen = NULL; /* Apparently not used */
+ ht[ 1].table = t1HB; ht[ 1].hlen = t1l;
+ ht[ 2].table = t2HB; ht[ 2].hlen = t2l;
+ ht[ 3].table = t3HB; ht[ 3].hlen = t3l;
+ ht[ 4].table = NULL; ht[ 4].hlen = NULL; /* Apparently not used */
+ ht[ 5].table = t5HB; ht[ 5].hlen = t5l;
+ ht[ 6].table = t6HB; ht[ 6].hlen = t6l;
+ ht[ 7].table = t7HB; ht[ 7].hlen = t7l;
+ ht[ 8].table = t8HB; ht[ 8].hlen = t8l;
+ ht[ 9].table = t9HB; ht[ 9].hlen = t9l;
+ ht[10].table = t10HB; ht[10].hlen = t10l;
+ ht[11].table = t11HB; ht[11].hlen = t11l;
+ ht[12].table = t12HB; ht[12].hlen = t12l;
+ ht[13].table = t13HB; ht[13].hlen = t13l;
+ ht[14].table = NULL; ht[14].hlen = NULL; /* Apparently not used */
+ ht[15].table = t15HB; ht[15].hlen = t15l;
+
+ /* Figure average number of 'bytes' per frame */
+ avg_byte_per_frame = SAMPL2 * 16000 * cfg.mpg.bitrate / (2 - cfg.mpg.type);
+ avg_byte_per_frame = avg_byte_per_frame / cfg.samplerate;
+ cfg.byte_per_frame = avg_byte_per_frame / 64;
+ cfg.frac_per_frame = avg_byte_per_frame & 63;
+ cfg.slot_lag = 0;
+ cfg.sideinfo_len = 32 + (cfg.mpg.type ? (cfg.channels == 1 ? 136 : 256)
+ : (cfg.channels == 1 ? 72 : 136));
+
+ return true;
}
-
-enum codec_status codec_start(struct codec_api* api)
+static void to_mono_mm(void) ICODE_ATTR;
+static void to_mono_mm(void)
{
- int i, ii, gr, k, ch, shift, gr_cnt;
- int max, min;
- long *buffer;
- int chunk_size, num_chunks;
- int enc_buffer_size;
- int enc_quality;
- uint32 *mp3_chunk_ptr;
- bool cpu_boosted = true; /* start boosted */
+ /* |llllllllllllllll|rrrrrrrrrrrrrrrr| =>
+ * |mmmmmmmmmmmmmmmm|mmmmmmmmmmmmmmmm|
+ */
+ uint32_t *samp = (uint32_t *)&mfbuf[2*512];
+ uint32_t *samp_end = samp + samp_per_frame;
- /* Generic codec initialisation */
- ci = api;
-
-#ifdef USE_IRAM
- memcpy(iramstart, iramcopy, iramend - iramstart);
- memset(iedata, 0, iend - iedata);
-#endif
-
- if(ci->enc_get_inputs == NULL ||
- ci->enc_set_parameters == NULL ||
- ci->enc_alloc_chunk == NULL ||
- ci->enc_free_chunk == NULL ||
- ci->enc_wavbuf_near_empty == NULL ||
- ci->enc_get_wav_data == NULL ||
- ci->enc_set_header_callback == NULL )
- return CODEC_ERROR;
+ inline void to_mono(uint32_t **samp)
+ {
+ int32_t lr = **samp;
+ int32_t m = ((int16_t)lr + (lr >> 16)) >> 1;
+ *(*samp)++ = (m << 16) | (uint16_t)m;
+ } /* to_mono */
- ci->cpu_boost(true);
+ do
+ {
+ to_mono(&samp);
+ to_mono(&samp);
+ to_mono(&samp);
+ to_mono(&samp);
+ to_mono(&samp);
+ to_mono(&samp);
+ to_mono(&samp);
+ to_mono(&samp);
+ }
+ while (samp < samp_end);
+} /* to_mono_mm */
+
+#ifdef ROCKBOX_LITTLE_ENDIAN
+/* Swaps a frame to big endian */
+static inline void byte_swap_frame32(uint32_t *dst, uint32_t *src,
+ size_t size) ICODE_ATTR;
+static inline void byte_swap_frame32(uint32_t *dst, uint32_t *src,
+ size_t size)
+{
+ uint32_t *src_end = SKIPBYTES(src, size);
- *ci->enc_set_header_callback = NULL;
- ci->enc_get_inputs(&enc_buffer_size, &enc_channels, &enc_quality);
+ do
+ {
+ *dst++ = swap32(*src++);
+ *dst++ = swap32(*src++);
+ *dst++ = swap32(*src++);
+ *dst++ = swap32(*src++);
+ *dst++ = swap32(*src++);
+ *dst++ = swap32(*src++);
+ *dst++ = swap32(*src++);
+ *dst++ = swap32(*src++);
+ }
+ while(src < src_end);
+} /* byte_swap_frame32 */
+#endif /* ROCKBOX_LITTLE_ENDIAN */
- init_mp3_encoder_engine(enc_channels == 2, enc_quality, 44100);
+static void encode_frame(char *buffer, struct enc_chunk_hdr *chunk) ICODE_ATTR;
+static void encode_frame(char *buffer, struct enc_chunk_hdr *chunk)
+{
+ int gr, gr_cnt;
+ int max, min;
- /* must be 4byte aligned */
- chunk_size = (sizeof(long) + cfg.byte_per_frame + 1 + 3) & ~3;
- num_chunks = enc_buffer_size / chunk_size;
+ /* encode one mp3 frame in this loop */
+ CodedData.bitpos = 0;
+ memset(CodedData.bbuf, 0, sizeof(CodedData.bbuf));
- /* inform the main program about the buffer dimensions */
- ci->enc_set_parameters(chunk_size, num_chunks, SAMP_PER_FRAME,
- NULL, 0, AFMT_MPA_L3);
+ 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;
-#ifdef CPU_COLDFIRE
- asm volatile ("move.l #0, %macsr"); /* integer mode */
-#endif
+ cfg.mean_bits = (8 * cfg.byte_per_frame + 8 * cfg.mpg.padding
+ - cfg.sideinfo_len) / cfg.granules / cfg.channels;
- /* main application waits for this flag during encoder loading */
- ci->enc_codec_loaded = true;
+ /* shift out old samples */
+ memcpy(mfbuf, mfbuf + 2*cfg.granules*576, 4*512);
- /* main encoding loop */
- while(!ci->stop_codec)
+ if (chunk->flags & CHUNKF_START_FILE)
{
- while((buffer = (long*)ci->enc_get_wav_data(SAMP_PER_FRAME*4)) != NULL)
- {
- if(ci->stop_codec)
- break;
-
- if(ci->enc_wavbuf_near_empty() == 0)
- {
- if(!cpu_boosted)
- {
- ci->cpu_boost(true);
- cpu_boosted = true;
- }
- }
+ /* prefix silent samples for encoder delay */
+ memset(mfbuf + 2*512, 0, ENC_DELAY_SIZE);
+ /* read new samples to iram for further processing */
+ memcpy(mfbuf + 2*512 + ENC_DELAY_SIZE/2,
+ buffer, pcm_chunk_size - ENC_DELAY_SIZE);
+ chunk->num_pcm = samp_per_frame - ENC_DELAY_SAMP;
+ }
+ else
+ {
+ /* read new samples to iram for further processing */
+ memcpy(mfbuf + 2*512, buffer, pcm_chunk_size);
+ chunk->num_pcm = samp_per_frame;
+ }
- /* encode one mp3 frame in this loop */
- CodedData.bitpos = 0;
- memset(CodedData.bbuf, 0, sizeof(CodedData.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;
+ if (cfg.channels == 1)
+ to_mono_mm();
- cfg.mean_bits = (8 * cfg.byte_per_frame + 8 * cfg.mpg.padding
- - cfg.sideinfo_len) / cfg.granules / cfg.channels;
+ cfg.ResvSize = 0;
+ gr_cnt = cfg.granules * cfg.channels;
+ CodedData.bitpos = cfg.sideinfo_len; /* leave space for mp3 header */
- /* shift out old samples */
- memcpy(mfbuf, mfbuf + 2*cfg.granules*576, 4*512);
- /* read new samples to iram for further processing */
- memcpy((uint32*)(mfbuf + 2*512), buffer, 4*SAMP_PER_FRAME);
+ for(gr=0; gr<cfg.granules; gr++)
+ {
+ short *wk = mfbuf + 2*286 + gr*1152;
+ int ch;
- if(cfg.resample) /* downsample to half of original */
- for(i=2*512; i<2*512+2*SAMP_PER_FRAME; i+=4)
- {
- mfbuf[i/2+512] = (short)(((int)mfbuf[i+0] + mfbuf[i+2]) >> 1);
- mfbuf[i/2+513] = (short)(((int)mfbuf[i+1] + mfbuf[i+3]) >> 1);
- }
+ /* 16bit packed wav data can be windowed efficiently on coldfire */
+ window_subband1(wk, sb_data[0][1-gr][0], sb_data[1][1-gr][0]);
- if(cfg.channels == 1) /* mix left and right channels to mono */
- for(i=2*512; i<2*512+2*SAMP_PER_FRAME; i+=2)
- mfbuf[i] = mfbuf[i+1] = (short)(((int)mfbuf[i] + mfbuf[i+1]) >> 1);
+ for(ch=0; ch<cfg.channels; ch++)
+ {
+ int ii, k, shift;
- cfg.ResvSize = 0;
- gr_cnt = cfg.granules * cfg.channels;
- CodedData.bitpos = cfg.sideinfo_len; /* leave space for mp3 header */
+ wk = mfbuf + 2*286 + gr*1152 + ch;
- for(gr=0; gr<cfg.granules; gr++)
+ /* 36864=4*18*16*32 */
+ for(k=0; k<18; k++, wk+=64)
{
- short *wk = mfbuf + 2*286 + gr*1152;
-
- /* 16bit packed wav data can be windowed efficiently on coldfire */
- window_subband1(wk, sb_data[0][1-gr][0], sb_data[1][1-gr][0]);
-
- for(ch=0; ch<cfg.channels; ch++)
- {
- int band;
- int *mdct;
-
- wk = mfbuf + 2*286 + gr*1152 + ch;
-
- /* 36864=4*18*16*32 */
- for(k=0; k<18; k++, wk+=64)
+ window_subband2(wk, sb_data[ch][1-gr][k]);
+ /* Compensate for inversion in the analysis filter */
+ if(k & 1)
{
- window_subband2(wk, sb_data[ch][1-gr][k]);
- /* Compensate for inversion in the analysis filter */
- if(k & 1)
+ int band;
for(band=1; band<32; band+=2)
- sb_data[ch][1-gr][k][band] *= -1;
+ sb_data[ch][1-gr][k][band] *= -1;
}
+ }
- /* Perform imdct of 18 previous + 18 current subband samples */
- /* for integer precision do this loop twice (if neccessary) */
- shift = k = 14;
- for(ii=0; ii<2 && k; ii++)
+ /* Perform imdct of 18 previous + 18 current subband samples
+ for integer precision do this loop twice (if neccessary)
+ */
+ shift = k = 14;
+ for(ii=0; ii<2 && k; ii++)
+ {
+ int *mdct = mdct_freq;
+ int band;
+
+ cfg.cod_info[gr][ch].additStep = 4 * (14 - shift);
+
+ for(band=0; band<cfg.mpg.num_bands; band++, mdct+=18)
{
- mdct = mdct_freq;
- cfg.cod_info[gr][ch].additStep = 4 * (14 - shift);
- for(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];
@@ -2176,16 +2200,20 @@ enum codec_status codec_start(struct codec_api* api)
/* 9216=4*32*9*8 */
for(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]);
+ 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 */
@@ -2193,67 +2221,309 @@ enum codec_status codec_start(struct codec_api* api)
/* Perform aliasing reduction butterfly */
if(band != 0)
- for(k=7; k>=0; --k)
- {
- int bu, bd;
- bu = shft15(mdct[k]) * ca[k] + shft15(mdct[-1-k]) * cs[k];
- bd = shft15(mdct[k]) * cs[k] - shft15(mdct[-1-k]) * ca[k];
- mdct[-1-k] = bu;
- mdct[ k ] = bd;
- }
- }
-
- max = min = 0;
- for(k=0; k<576; k++)
- {
+ {
+ for(k=7; k>=0; --k)
+ {
+ int bu, bd;
+ bu = shft15(mdct[k]) * ca[k] +
+ shft15(mdct[-1-k]) * cs[k];
+ bd = shft15(mdct[k]) * cs[k] -
+ shft15(mdct[-1-k]) * ca[k];
+ mdct[-1-k] = bu;
+ mdct[ k ] = bd;
+ }
+ }
+ }
+
+ max = min = 0;
+ for(k=0; k<576; k++)
+ {
mdct_freq[k] = shft13(mdct_freq[k]);
if(max < mdct_freq[k]) max = mdct_freq[k];
if(min > mdct_freq[k]) min = mdct_freq[k];
- }
+ }
- max = (max > -min) ? max : -min;
- cfg.cod_info[gr][ch].max_val = (long)max;
+ max = (max > -min) ? max : -min;
+ cfg.cod_info[gr][ch].max_val = (long)max;
- /* calc new shift for higher integer precision */
- for(k=0; max<(0x3c00>>k); k++);
+ /* calc new shift for higher integer precision */
+ for(k=0; max<(0x3c00>>k); k++);
shift = 12 - k;
- }
+ }
- cfg.cod_info[gr][ch].quantStep += cfg.cod_info[gr][ch].additStep;
+ cfg.cod_info[gr][ch].quantStep +=
+ cfg.cod_info[gr][ch].additStep;
- /* bit and noise allocation */
- iteration_loop(mdct_freq, &cfg.cod_info[gr][ch], gr_cnt--);
- /* write the frame to the bitstream */
- Huffmancodebits(enc_data, mdct_freq, &cfg.cod_info[gr][ch]);
+ /* bit and noise allocation */
+ iteration_loop(mdct_freq, &cfg.cod_info[gr][ch],
+ gr_cnt--);
+ /* write the frame to the bitstream */
+ Huffmancodebits(enc_data, mdct_freq,
+ &cfg.cod_info[gr][ch]);
- cfg.cod_info[gr][ch].quantStep -= cfg.cod_info[gr][ch].additStep;
+ cfg.cod_info[gr][ch].quantStep -=
+ cfg.cod_info[gr][ch].additStep;
- if(cfg.granules == 1)
- memcpy(sb_data[ch][0], sb_data[ch][1], sizeof(sb_data[ch][0]));
- }
+ if(cfg.granules == 1)
+ {
+ memcpy(sb_data[ch][0], sb_data[ch][1],
+ sizeof(sb_data[ch][0]));
}
+ }
+ }
+
+ chunk->enc_size = cfg.byte_per_frame + cfg.mpg.padding;
- mp3_chunk_ptr = (uint32*)ci->enc_alloc_chunk();
- mp3_chunk_ptr[0] = cfg.byte_per_frame + cfg.mpg.padding; //(CodedData.bitpos + 7) >> 3;
/* finish this chunk by adding sideinfo header data */
CodedData.bitpos = 0;
encodeSideInfo( cfg.cod_info );
- /* allocate mp3 chunk, set chunk size, copy chunk to enc_buffer */
- memcpy(&mp3_chunk_ptr[1], CodedData.bbuf, mp3_chunk_ptr[0]);
- ci->enc_free_chunk();
+#ifdef ROCKBOX_BIG_ENDIAN
+ /* copy chunk to enc_buffer */
+ memcpy(chunk->enc_data, CodedData.bbuf, chunk->enc_size);
+#else
+ /* swap frame to big endian */
+ byte_swap_frame32(chunk->enc_data, CodedData.bbuf, chunk->enc_size);
+#endif
+} /* encode_frame */
+
+/* called very often - inline */
+static inline bool is_file_data_ok(struct enc_file_event_data *filed) ICODE_ATTR;
+static inline bool is_file_data_ok(struct enc_file_event_data *filed)
+{
+ return filed->rec_file >= 0 && (long)filed->chunk->flags >= 0;
+} /* is_event_ok */
- ci->yield();
+/* called very often - inline */
+static inline bool on_write_chunk(struct enc_file_event_data *data) ICODE_ATTR;
+static inline bool on_write_chunk(struct enc_file_event_data *data)
+{
+ if (!is_file_data_ok(data))
+ return false;
+
+ if (data->chunk->enc_data == NULL)
+ {
+#ifdef ROCKBOX_HAS_LOGF
+ ci->logf("mp3 enc: NULL data");
+#endif
+ return true;
+ }
+
+ if (ci->write(data->rec_file, data->chunk->enc_data,
+ data->chunk->enc_size) != (ssize_t)data->chunk->enc_size)
+ return false;
+
+ data->num_pcm_samples += data->chunk->num_pcm;
+ return true;
+} /* on_write_chunk */
+
+static bool on_start_file(struct enc_file_event_data *data)
+{
+ if ((data->chunk->flags & CHUNKF_ERROR) || *data->filename == '\0')
+ return false;
+
+ data->rec_file = ci->open(data->filename, O_RDWR|O_CREAT|O_TRUNC);
+
+ if (data->rec_file < 0)
+ return false;
+
+ /* reset sample count */
+ data->num_pcm_samples = 0;
+ return true;
+} /* on_start_file */
+
+static bool on_end_file(struct enc_file_event_data *data)
+{
+ if (!is_file_data_ok(data))
+ return false;
+
+ ci->fsync(data->rec_file);
+ ci->close(data->rec_file);
+ data->rec_file = -1;
+
+ return true;
+} /* on_end_file */
+
+static void on_rec_new_stream(struct enc_buffer_event_data *data)
+{
+ int num_frames = cfg.mpg.type == 1 ?
+ ENC_PADDING_FRAMES1 : ENC_PADDING_FRAMES2;
+
+ if (data->flags & CHUNKF_END_FILE)
+ {
+ /* add silent frames to end - encoder will also be flushed for start
+ of next file if any */
+ memset(res_buffer, 0, pcm_chunk_size);
+
+ /* the initial chunk given for the end is at enc_wr_index */
+ while (num_frames-- > 0)
+ {
+ data->chunk->enc_data = ENC_CHUNK_SKIP_HDR(data->chunk->enc_data,
+ data->chunk);
+
+ encode_frame(res_buffer, data->chunk);
+ data->chunk->num_pcm = samp_per_frame;
+
+ ci->enc_finish_chunk();
+ data->chunk = ci->enc_get_chunk();
}
+ }
+ else if (data->flags & CHUNKF_PRERECORD)
+ {
+ /* nothing to add and we cannot change prerecorded data */
+ }
+ else if (data->flags & CHUNKF_START_FILE)
+ {
+ /* starting fresh ... be sure to flush encoder first */
+ struct enc_chunk_hdr *chunk = ENC_CHUNK_HDR(res_buffer);
- if(ci->enc_wavbuf_near_empty())
+ chunk->flags = 0;
+ chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);
+
+ while (num_frames-- > 0)
{
- if(cpu_boosted)
+ memset(chunk->enc_data, 0, pcm_chunk_size);
+ encode_frame(chunk->enc_data, chunk);
+ }
+ }
+} /* on_rec_new_stream */
+
+static void enc_events_callback(enum enc_events event, void *data) ICODE_ATTR;
+static void enc_events_callback(enum enc_events event, void *data)
+{
+ if (event == ENC_WRITE_CHUNK)
+ {
+ if (on_write_chunk((struct enc_file_event_data *)data))
+ return;
+ }
+ else if (event == ENC_START_FILE)
+ {
+ if (on_start_file((struct enc_file_event_data *)data))
+ return;
+ }
+ else if (event == ENC_END_FILE)
+ {
+ if (on_end_file((struct enc_file_event_data *)data))
+ return;
+ }
+ else if (event == ENC_REC_NEW_STREAM)
+ {
+ on_rec_new_stream((struct enc_buffer_event_data *)data);
+ return;
+ }
+ else
+ {
+ return;
+ }
+
+ ((struct enc_file_event_data *)data)->chunk->flags |= CHUNKF_ERROR;
+} /* enc_events_callback */
+
+static bool enc_init(void)
+{
+ struct enc_inputs inputs;
+ struct enc_parameters params;
+
+ if (ci->enc_get_inputs == NULL ||
+ ci->enc_set_parameters == NULL ||
+ ci->enc_get_chunk == NULL ||
+ ci->enc_finish_chunk == NULL ||
+ ci->enc_pcm_buf_near_empty == NULL ||
+ ci->enc_get_pcm_data == NULL ||
+ ci->enc_unget_pcm_data == NULL )
+ return false;
+
+ ci->enc_get_inputs(&inputs);
+
+ if (inputs.config->afmt != AFMT_MPA_L3)
+ return false;
+
+ init_mp3_encoder_engine(inputs.sample_rate, inputs.num_channels,
+ inputs.config);
+
+ /* configure the buffer system */
+ params.afmt = AFMT_MPA_L3;
+ params.chunk_size = cfg.byte_per_frame + 1;
+ params.enc_sample_rate = cfg.samplerate;
+ /* need enough reserved bytes to hold one frame of pcm samples + hdr
+ for padding and flushing */
+ params.reserve_bytes = ENC_CHUNK_HDR_SIZE + pcm_chunk_size;
+ params.events_callback = enc_events_callback;
+ ci->enc_set_parameters(&params);
+
+ res_buffer = params.reserve_buffer;
+
+#ifdef CPU_COLDFIRE
+ asm volatile ("move.l #0, %macsr"); /* integer mode */
+#endif
+
+ return true;
+} /* enc_init */
+
+enum codec_status codec_start(struct codec_api* api)
+{
+ bool cpu_boosted;
+
+ /* Generic codec initialisation */
+ ci = api;
+
+#ifdef USE_IRAM
+ memcpy(iramstart, iramcopy, iramend - iramstart);
+ memset(iedata, 0, iend - iedata);
+#endif
+
+ if (!enc_init())
+ {
+ ci->enc_codec_loaded = -1;
+ return CODEC_ERROR;
+ }
+
+ /* main application waits for this flag during encoder loading */
+ ci->enc_codec_loaded = 1;
+
+ ci->cpu_boost(true);
+ cpu_boosted = true;
+
+ /* main encoding loop */
+ while (!ci->stop_codec)
+ {
+ char *buffer;
+
+ while ((buffer = ci->enc_get_pcm_data(pcm_chunk_size)) != NULL)
+ {
+ struct enc_chunk_hdr *chunk;
+
+ if (ci->stop_codec)
+ break;
+
+ if (!cpu_boosted && ci->enc_pcm_buf_near_empty() == 0)
+ {
+ ci->cpu_boost(true);
+ cpu_boosted = true;
+ }
+
+ chunk = ci->enc_get_chunk();
+ chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);
+
+ encode_frame(buffer, chunk);
+
+ if (chunk->num_pcm < samp_per_frame)
+ {
+ ci->enc_unget_pcm_data(pcm_chunk_size - chunk->num_pcm*4);
+ chunk->num_pcm = samp_per_frame;
+ }
+
+ ci->enc_finish_chunk();
+
+ ci->yield();
+ }
+
+ if (cpu_boosted && ci->enc_pcm_buf_near_empty())
{
ci->cpu_boost(false);
cpu_boosted = false;
}
- }
+
ci->yield();
}
@@ -2261,12 +2531,12 @@ enum codec_status codec_start(struct codec_api* api)
ci->cpu_boost(false);
/* reset parameters to initial state */
- ci->enc_set_parameters(0, 0, 0, 0, 0, 0);
+ ci->enc_set_parameters(NULL);
/* main application waits for this flag during encoder removing */
- ci->enc_codec_loaded = false;
+ ci->enc_codec_loaded = 0;
return CODEC_OK;
-}
+} /* codec_start */
-#endif
+#endif /* ndef SIMULATOR */