rockbox/lib/rbcodec/codecs/mp3_enc.c

2679 lines
107 KiB
C
Raw Normal View History

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 Antonius Hellmann
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
* 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 "codeclib.h"
CODEC_ENC_HEADER
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
#define SAMPL2 576
#define SBLIMIT 32
#define HTN 16
#define memcpy ci->memcpy
#define memset ci->memset
#define putlong(c, s) if(s+sz <= 32) { cc = (cc << s) | c; sz+= s; } \
else { putbits(cc, sz); cc = c; sz = s; }
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 {
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
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 ResvSize;
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[263];
} 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 */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static short mfbuf [2*(1152+512)] IBSS_ATTR
/* for memcpy and 32-bit access */ MEM_ALIGN_ATTR; /* 3328 Bytes */
static int sb_data [2][2][18][SBLIMIT] IBSS_ATTR; /* 13824 Bytes */
static int mdct_freq [SAMPL2] IBSS_ATTR; /* 2304 Bytes */
static char mdct_sign [SAMPL2] IBSS_ATTR; /* 576 Bytes */
static short enc_data [SAMPL2] IBSS_ATTR; /* 1152 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 config_t cfg IBSS_ATTR;
static uint8_t band_scale_f[22];
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_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_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_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_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_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_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_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_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,
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_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,
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_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,
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_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,
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_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,
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_const[16] =
{ 0x10004,0x50005,0x50005,0x70006,0x50005,0x80006,0x70006,0x90007,
0x50005,0x70006,0x70006,0x90007,0x70006,0x90007,0x90007,0xa0008 };
static const uint32_t tab23_const[ 9] =
{ 0x10002,0x40003,0x70007,0x40004,0x50004,0x70007,0x60006,0x70007,0x80008 };
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_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,
0x00b02c09,0x00b02c09,0x00b0300a,0x00802408,0x00902408,0x00a02809,0x00b02c09,
0x00b0300a,0x00c0300b,0x00902809,0x00a02809,0x00b02c0a,0x00c02c0a,0x00c0340b,
0x00c0340b};
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,
0x00c02c0a,0x00b02809,0x00b0280a,0x00802007,0x00902007,0x00a02408,0x00b02c08,
0x00c02809,0x00c0300a,0x00b0280a,0x00c02c0a,0x00902408,0x00a02808,0x00b02809,
0x00c02c09,0x00c02c0a,0x00c0300a,0x00c02c0a,0x00c0300b,0x00a02409,0x00b02809,
0x00c02c0a,0x00c0300a,0x00d0300a,0x00d0340b,0x00c0300a,0x00d0340b,0x00902409,
0x00a02409,0x00b02409,0x00c0280a,0x00c02c0a,0x00c0300b,0x00d0300b,0x00d0300c,
0x00a0240a,0x00a0240a,0x00b0280a,0x00c02c0b,0x00c0300b,0x00d0300b,0x00d0300b,
0x00d0300c};
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,
0x000b000a,0x000b000a,0x000b000b,0x000c000b,0x000c000b,0x000c000c,0x000d000c,
0x000e000c,0x000d000c,0x000e000c,0x000a000a,0x00070007,0x00080007,0x00090008,
0x000a0009,0x000b0009,0x000b000a,0x000c000a,0x000c000b,0x000d000b,0x000c000b,
0x000d000b,0x000d000c,0x000d000c,0x000e000c,0x000e000d,0x000b0009,0x00090008,
0x00090008,0x000a0009,0x000b0009,0x000b000a,0x000c000a,0x000c000a,0x000c000b,
0x000d000b,0x000d000b,0x000e000b,0x000e000c,0x000e000c,0x000f000c,0x000f000c,
0x000c0009,0x000a0009,0x000a0009,0x000b0009,0x000b000a,0x000c000a,0x000c000a,
0x000d000a,0x000d000b,0x000d000b,0x000e000b,0x000e000c,0x000e000c,0x000f000c,
0x000f000c,0x000f000d,0x000b0009,0x000a000a,0x000a0009,0x000b000a,0x000b000a,
0x000c000a,0x000d000a,0x000d000b,0x000e000b,0x000d000b,0x000e000b,0x000e000c,
0x000f000c,0x000f000c,0x000f000c,0x0010000c,0x000c0009,0x000b000a,0x000b000a,
0x000b000a,0x000c000a,0x000d000a,0x000d000b,0x000d000b,0x000d000b,0x000e000b,
0x000e000c,0x000e000c,0x000e000c,0x000f000c,0x000f000c,0x0010000d,0x000c0009,
0x000b000b,0x000b000a,0x000c000a,0x000c000a,0x000d000b,0x000d000b,0x000d000b,
0x000e000b,0x000e000c,0x000f000c,0x000f000c,0x000f000c,0x000f000c,0x0011000d,
0x0011000d,0x000c000a,0x000b000b,0x000c000b,0x000c000b,0x000d000b,0x000d000b,
0x000d000b,0x000e000b,0x000e000b,0x000f000b,0x000f000c,0x000f000c,0x000f000c,
0x0010000c,0x0010000d,0x0010000d,0x000c000a,0x000c000b,0x000c000b,0x000c000b,
0x000d000b,0x000d000b,0x000e000b,0x000e000b,0x000f000c,0x000f000c,0x000f000c,
0x000f000c,0x0010000c,0x000f000d,0x0010000d,0x000f000d,0x000d000a,0x000c000c,
0x000d000b,0x000c000b,0x000d000b,0x000e000b,0x000e000c,0x000e000c,0x000e000c,
0x000f000c,0x0010000c,0x0010000c,0x0010000d,0x0011000d,0x0011000d,0x0010000d,
0x000c000a,0x000d000c,0x000d000c,0x000d000b,0x000d000b,0x000e000b,0x000e000c,
0x000f000c,0x0010000c,0x0010000c,0x0010000c,0x0010000c,0x0010000d,0x0010000d,
0x000f000d,0x0010000d,0x000d000a,0x000d000c,0x000e000c,0x000e000c,0x000e000c,
0x000e000c,0x000f000c,0x000f000c,0x000f000c,0x000f000c,0x0011000c,0x0010000d,
0x0010000d,0x0010000d,0x0010000d,0x0012000d,0x000d000a,0x000f000c,0x000e000c,
0x000e000c,0x000e000c,0x000f000c,0x000f000c,0x0010000c,0x0010000c,0x0010000d,
0x0012000d,0x0011000d,0x0011000d,0x0011000d,0x0013000d,0x0011000d,0x000d000a,
0x000e000d,0x000f000c,0x000d000c,0x000e000c,0x0010000c,0x0010000c,0x000f000c,
0x0010000d,0x0010000d,0x0011000d,0x0012000d,0x0011000d,0x0013000d,0x0011000d,
0x0010000d,0x000d000a,0x000a0009,0x000a0009,0x000a0009,0x000b0009,0x000b0009,
0x000c0009,0x000c0009,0x000c0009,0x000d0009,0x000d0009,0x000d0009,0x000d000a,
0x000d000a,0x000d000a,0x000d000a,0x000a0006};
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_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_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_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_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_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_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_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,
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_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,
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_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,
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_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,
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_const[HTN] =
{ { 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[HTN] =
{ { 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] =
{ {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 */
};
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},
/* Table B.2.c: 24 kHz */
{0,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 */
{0,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 */
{0,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 */
{0,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 */
{0,4, 8,12,16,20,24,30,36,44,54,66, 82,102,126,156,194,240,296,364,448,550,576} };
static const short int2idx_const[4096] = /* int2idx[i] = sqrt(i*sqrt(i)); */
{
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] =
{ 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 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},
{0,10,10,10,10,10,12,14, 18, 24, 26, 28, 30, 32, 32},
{0,10,12,14,18,24,26,28, 30, 32, 32, 32, 32, 32, 32} };
static const int cx_const[9] =
{ 16135, 10531, 5604, 15396, -2845,-12551, 14189, 8192, 16384 };
static const int ca_const[8] =
{-16859,-15458,-10269, -5961, -3099, -1342, -465, -121 };
static const int cs_const[8] =
{ 28098, 28893, 31117, 32221, 32621, 32740, 32765, 32768 };
static const short enwindow_const[15*27+24] =
{ 0, 65, 593, 1766, 22228, 2115, 611, 62,
8, 119, 1419, 10564,-11659,-1635,-154, -9,
-8, -119,-1419,-10564, 11659, 1635, 154, 9, 464, 100, 91,
0, 69, 604, 1635, 23148, 2363, 643, 62,
7, 107, 1368, 10449,-12733,-1818,-180,-11,
-7, -107,-1368,-10449, 12733, 1818, 180, 11, 420, 200, 164,
0, 72, 608, 1465, 23979, 2600, 671, 63,
7, 94, 1305, 10265,-13818,-2004,-207,-12,
-7, -94,-1305,-10265, 13818, 2004, 207, 12, 380, 297, 220,
0, 76, 606, 1256, 24718, 2825, 693, 63,
6, 81, 1232, 10016,-14908,-2192,-236,-14,
-6, -81,-1232,-10016, 14908, 2192, 236, 14, 342, 392, 262,
0, 78, 597, 1007, 25359, 3033, 712, 63,
6, 68, 1150, 9706,-15995,-2380,-267,-15,
-6, -68,-1150, -9706, 15995, 2380, 267, 15, 307, 483, 289,
0, 80, 580, 719, 25901, 3224, 726, 62,
6, 54, 1060, 9343,-17072,-2565,-299,-17,
-6, -54,-1060, -9343, 17072, 2565, 299, 17, 274, 569, 304,
-1, 82, 555, 391, 26339, 3395, 735, 61,
5, 40, 963, 8930,-18131,-2747,-332,-19,
-5, -40, -963, -8930, 18131, 2747, 332, 19, 242, 650, 307,
-1, 83, 523, 26, 26672, 3545, 740, 60,
5, 27, 861, 8474,-19164,-2923,-366,-21,
-5, -27, -861, -8474, 19164, 2923, 366, 21, 212, 724, 300,
-1, 83, 482, -376, 26900, 3672, 739, 58,
4, 14, 756, 7981,-20163,-3092,-401,-24,
-4, -14, -756, -7981, 20163, 3092, 401, 24, 183, 792, 283,
-1, 82, 433, -812, 27022, 3776, 735, 56,
4, 1, 648, 7456,-21122,-3250,-435,-26,
-4, -1, -648, -7456, 21122, 3250, 435, 26, 155, 851, 258,
-1, 81, 376, -1281, 27038, 3855, 726, 54,
3, -11, 539, 6907,-22032,-3397,-470,-28,
-3, 11, -539, -6907, 22032, 3397, 470, 28, 128, 903, 226,
-1, 78, 312, -1778, 26951, 3910, 713, 52,
3, -22, 430, 6338,-22887,-3530,-503,-31,
-3, 22, -430, -6338, 22887, 3530, 503, 31, 102, 946, 188,
-2, 75, 239, -2302, 26761, 3941, 696, 49,
3, -33, 322, 5757,-23678,-3648,-537,-34,
-3, 33, -322, -5757, 23678, 3648, 537, 34, 76, 980, 145,
-2, 70, 160, -2848, 26472, 3948, 676, 47,
3, -42, 217, 5167,-24399,-3749,-568,-36,
-3, 42, -217, -5167, 24399, 3749, 568, 36, 50, 1004, 99,
-2, 65, 74, -3412, 26087, 3931, 653, 44,
2, -51, 115, 4577,-25045,-3830,-599,-39,
-2, 51, -115, -4577, 25045, 3830, 599, 39, 25, 1019, 50,
25610,3891,627,42,-3990,-18,58,-2,
21226,-21226,10604,-10604,1860,-1860,1458,-1458,576,-576,130,-130,60,-60,8,-8
};
static const int win_const[18][4] = {
{ -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 } };
/* forward declarations */
static int HuffmanCode( short *ix, char *xr_sign, uint32_t begin, uint32_t end, int table);
static int HuffmanCod1( short *ix, char *xr_sign, 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);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static inline uint32_t encodeHeader( 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 calcFrameSize(int bitr_id, long *frac)
{
unsigned long v = bitr_index[cfg.mpg.type][bitr_id];
v = SAMPL2 * 16000 * v / (2 - cfg.mpg.type);
v /= cfg.samplerate;
if (frac)
*frac = v % 64;
return v / 64;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
}
static void encodeSideInfo( side_info_t si[2][2] )
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
int gr, ch;
uint32_t cc=0, sz=0;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
putbits( encodeHeader( 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(gr=0; gr<cfg.granules; gr++)
for(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(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 );
}
}
/* flush remaining bits */
putbits(cc, sz);
}
/* Note the discussion of huffmancodebits() on pages 28 and 29 of the IS,
as well as the definitions of the side information on pages 26 and 27. */
static void Huffmancodebits( 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 stuffBits = 0;
int bits = 0;
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)
if(region1 > 0)
bits += HuffmanCode(ix, xr_sign, 0 , region1, gi->table_select[0]);
if(region2 > region1)
bits += HuffmanCode(ix, xr_sign, region1, region2, gi->table_select[1]);
if(bigvals > region2)
bits += HuffmanCode(ix, xr_sign, region2, bigvals, gi->table_select[2]);
if(count1 > bigvals)
bits += HuffmanCod1(ix, xr_sign, bigvals, count1, gi->table_select[3]);
if((stuffBits = gi->part2_3_length - bits) > 0)
{
int stuffWords = stuffBits >> 5;
int remainBits = stuffBits & 31;
if( remainBits )
putbits( ~0, remainBits );
while( stuffWords-- )
putbits( ~0, 32 ); /* Huffman code tables leed to padding ones */
}
}
int HuffmanCod1( short *ix, char *xr_sign, uint32_t begin, uint32_t end, int tbl)
{
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_sign[i+0]
#define sgnw xr_sign[i+1]
#define sgnx xr_sign[i+2]
#define sgny xr_sign[i+3]
for(i=begin; i<end; i+=4)
{
v = ix[i+0];
w = ix[i+1];
x = ix[i+2];
y = ix[i+3];
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;
}
d = (ht_count[tbl][0][p] << l) + s;
l = ht_count[tbl][1][p];
putlong( d, l );
sumbit += l;
}
/* flush remaining bits */
putbits(cc, sz);
return sumbit;
}
/* Implements the pseudocode of page 98 of the IS */
int HuffmanCode(short *ix, char *xr_sign, uint32_t begin, uint32_t end, int table)
{
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_sign[i+0]
#define sign_y xr_sign[i+1]
if(table == 0)
return 0;
if( table > 15 )
{ /* ESC-table is used */
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)
{
x = ix[ i ];
y = ix[i+1];
if(x > 14) { xl = x - 15; x = 15; }
if(y > 14) { yl = y - 15; y = 15; }
idx = x * 16 + y;
code = hffcode[idx];
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(i=begin; i<end; i+=2)
{
x = ix[i];
y = ix[i+1];
idx = x * h->len + y;
code = h->table[idx];
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;
}
}
/* flush remaining bits */
putbits(cc, sz);
return sumbit;
}
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_t */
if(((new_bitpos - 1) >> 5) == ptrpos)
CodedData.bbuf[ptrpos] |= val << ((32 - new_bitpos) & 31);
else
{
CodedData.bbuf[ptrpos ] |= val >> ((new_bitpos - 32) & 31);
CodedData.bbuf[ptrpos+1] |= val << ((32 - new_bitpos) & 31);
}
CodedData.bitpos = new_bitpos;
}
/***************************************************************************/
/* 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 )
{
uint32_t i;
int max, table0, table1;
for(i=begin,max=0; 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;
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);
}
}
int find_best_2(short *ix, uint32_t start, uint32_t end, const uint32_t *table,
uint32_t len, int *bits)
{
uint32_t i, sum = 0;
for(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;
}
}
int find_best_3(short *ix, uint32_t start, uint32_t end, const uint32_t *table,
uint32_t len, int *bits)
{
uint32_t i, j, sum = 0;
int sum1 = 0;
int sum2 = 0;
int sum3 = 0;
/* avoid overflow in packed additions: 78*13 < 1024 */
for(i=start; i<end; )
{
j = i + 2*78 > end ? end : i + 2*78;
for(sum=0; i<j; i+=2)
sum += table[ix[i] * len + ix[i+1]];
sum1 += (sum >> 20);
sum2 += (sum >> 10) & 0x3ff;
sum3 += (sum >> 0) & 0x3ff;
}
i = 0;
if(sum1 > sum2) { sum1 = sum2; i = 1; }
if(sum1 > sum3) { sum1 = sum3; i = 2; }
*bits = sum1;
return i;
}
/*************************************************************************/
/* Function: Count the number of bits necessary to code the subregion. */
/*************************************************************************/
int count_bit1(short *ix, uint32_t start, uint32_t end, int *bits )
{
uint32_t i, sum = 0;
for(i=start; i<end; i+=2)
sum += t1l[4 + ix[i] * 2 + ix[i+1]];
*bits = sum;
return 1; /* this is table1 */
}
int count_bigv(short *ix, uint32_t start, uint32_t end, int table0,
int table1, int *bits )
{
uint32_t i, sum0, sum1, sum=0, bigv=0, x, y;
/* ESC-table is used */
for(i=start; i<end; i+=2)
{
x = ix[i];
y = ix[i+1];
if(x > 14) { x = 15; bigv++; }
if(y > 14) { y = 15; bigv++; }
sum += tab1624[x * 16 + y];
}
sum0 = (sum >> 16) + bigv * ht_big[table0].linbits;
sum1 = (sum & 0xffff) + bigv * ht_big[table1].linbits;
if(sum0 <= sum1)
{
*bits = sum0;
return table0;
}
else
{
*bits = sum1;
return table1;
}
}
/*************************************************************************/
/* 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 p, i, sum = 0;
for(i=SAMPL2; i-=2; )
if(*(uint32_t*)&ix[i-2]) /* !!!! short *ix; !!!!! */
break;
si->count1 = 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)
{
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)
{
unsigned int i, idx, s, frac_pow[] = { 0x10000, 0xd745, 0xb505, 0x9838 };
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(i=SAMPL2; i--; )
ix[i] = int2idx[(xr[i] * s + 0x8000) >> 16];
}
else
{ /* check each index wether it fits the table */
for(i=SAMPL2; i--; )
{
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)
{
int scfb, count0, count1;
if( !si->address3 )
{ /* no bigvalue region */
si->region_0_1 = 0;
si->address1 = 0;
si->address2 = 0;
}
else
{
/* Calculate scale factor band index */
for(scfb=0; scalefac[scfb] < si->address3; )
scfb++;
count0 = subdv_table[scfb].region0_cnt;
count1 = subdv_table[scfb].region1_cnt;
si->region_0_1 = (count0 << 3) | count1;
si->address1 = scalefac[count0 + 1];
si->address2 = scalefac[count0 + 1 + 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 remain, tar_bits, max_bits = cfg.mean_bits;
/* distribute reserved bits to remaining granules */
tar_bits = max_bits + (cfg.ResvSize / 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.ResvSize += 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.ResvSize;
/* mp3 format allows max 12bits for granule length */
if(si->part2_3_length > 4092)
{
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 */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static void ICODE_ATTR window_subband1(short *wk, int sb0[SBLIMIT],
int sb1[SBLIMIT])
{
int k, i, u, v;
short *wp, *x1, *x2;
#ifdef CPU_COLDFIRE
int s0, s1, t0, t1;
for(k=0; k<18; k++, wk+=64, sb0+=SBLIMIT, sb1+=SBLIMIT)
{
wp = enwindow;
x1 = wk;
x2 = x1 - 124;
for(i=-15; i<0; i++)
{
asm volatile(
"move.l (-224*4,%[x2]), %%d4\n" /* d4 = x2[-224] */
"movem.l (%[wp]), %%d0-%%d3\n" /* load 8 values */
"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, (-256*4,%[x1]), %%d4, %%acc1\n"
"movem.l (16,%[wp]), %%d0-%%d3\n" /* load 8 values */
"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, ( 224*4,%[x1]), %%d4, %%acc1\n"
"movclr.l %%acc0, %%d0\n"
"move.l %%d0, %[s0]\n"
"movclr.l %%acc1, %%d0\n"
"move.l %%d0, %[s1]\n"
"movem.l (%[wp]), %%d0-%%d3\n" /* load 8 values */
"mac.w %%d0u, %%d4u, %%acc0\n"
"mac.w %%d0u, %%d4l, ( 160*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d0l, %%d4u, %%acc0\n"
"mac.w %%d0l, %%d4l, ( 96*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d1u, %%d4u, %%acc0\n"
"mac.w %%d1u, %%d4l, ( 32*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, ( 256*4,%[x2]), %%d4, %%acc1\n"
"movem.l (32,%[wp]), %%d0-%%d3\n" /* load 8 values */
"mac.w %%d0u, %%d4u, %%acc0\n"
"mac.w %%d0u, %%d4l, ( 192*4,%[x2]), %%d4, %%acc1\n"
"mac.w %%d0l, %%d4u, %%acc0\n"
"mac.w %%d0l, %%d4l, ( 128*4,%[x2]), %%d4, %%acc1\n"
"mac.w %%d1u, %%d4u, %%acc0\n"
"mac.w %%d1u, %%d4l, ( 64*4,%[x2]), %%d4, %%acc1\n"
"mac.w %%d1l, %%d4u, %%acc0\n"
"mac.w %%d1l, %%d4l, ( 0*4,%[x2]), %%d4, %%acc1\n"
"mac.w %%d2u, %%d4u, %%acc0\n"
"mac.w %%d2u, %%d4l, ( -64*4,%[x2]), %%d4, %%acc1\n"
"mac.w %%d2l, %%d4u, %%acc0\n"
"mac.w %%d2l, %%d4l, (-128*4,%[x2]), %%d4, %%acc1\n"
"mac.w %%d3u, %%d4u, %%acc0\n"
"mac.w %%d3u, %%d4l, (-192*4,%[x2]), %%d4, %%acc1\n"
"mac.w %%d3l, %%d4u, %%acc0\n"
"mac.w %%d3l, %%d4l, %%acc1\n"
"movclr.l %%acc0, %%d0\n"
"move.l %%d0, %[t0]\n"
"movclr.l %%acc1, %%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");
sb0[30+i*2] = shft4(t0) + shft13(s0) * wp[24];
sb0[31+i*2] = shft13(t0) * wp[25] - shft13(s0) * wp[26];
sb1[30+i*2] = shft4(t1) + shft13(s1) * wp[24];
sb1[31+i*2] = shft13(t1) * wp[25] - shft13(s1) * wp[26];
wp += 27;
x1 -= 2;
x2 += 2;
}
asm volatile(
"move.l ( -32*4,%[x1]), %%d4\n" /* d4 = x1[-32] */
"movem.l (%[wp]), %%d0-%%d3\n" /* load 8 values */
"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"
"movclr.l %%acc0, %%d0\n"
"move.l %%d0, %[s0]\n"
"movclr.l %%acc1, %%d0\n"
"move.l %%d0, %[s1]\n"
"movem.l (16,%[wp]), %%d0-%%d3\n" /* load 8 values */
"mac.w %%d0u, %%d4u, %%acc0\n"
"mac.w %%d0u, %%d4l, ( -48*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d1u, %%d4u, %%acc0\n"
"mac.w %%d1u, %%d4l, ( 16*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d1l, %%d4u, %%acc0\n"
"mac.w %%d1l, %%d4l, ( -80*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d2u, %%d4u, %%acc0\n"
"mac.w %%d2u, %%d4l, ( 48*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d2u, %%d4u, %%acc0\n"
"mac.w %%d2u, %%d4l, (-112*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d3u, %%d4u, %%acc0\n"
"mac.w %%d3u, %%d4l, ( 80*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d3l, %%d4u, %%acc0\n"
"mac.w %%d3l, %%d4l, (-144*4,%[x1]), %%d4, %%acc1\n"
"movem.l (32,%[wp]), %%d0-%%d3\n" /* load 8 values */
"mac.w %%d0u, %%d4u, %%acc0\n"
"mac.w %%d0u, %%d4l, ( 112*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d0u, %%d4u, %%acc0\n"
"mac.w %%d0u, %%d4l, (-176*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d1u, %%d4u, %%acc0\n"
"mac.w %%d1u, %%d4l, ( 144*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d1l, %%d4u, %%acc0\n"
"mac.w %%d1l, %%d4l, (-208*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d2u, %%d4u, %%acc0\n"
"mac.w %%d2u, %%d4l, ( 176*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d2u, %%d4u, %%acc0\n"
"mac.w %%d2u, %%d4l, (-240*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d3u, %%d4u, %%acc0\n"
"mac.w %%d3u, %%d4l, ( 208*4,%[x1]), %%d4, %%acc1\n"
"mac.w %%d3l, %%d4u, %%acc0\n"
"mac.w %%d3l, %%d4l, %%acc1\n"
"movclr.l %%acc0, %%d0\n"
"move.l %%d0, %[t0]\n"
"movclr.l %%acc1, %%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");
u = shft4(s0 - t0);
v = shft4(s0 + t0);
t0 = sb0[14];
s0 = sb0[15] - t0;
sb0[31] = v + t0; /* A0 */
sb0[30] = u + s0; /* A1 */
sb0[15] = u - s0; /* A2 */
sb0[14] = v - t0; /* A3 */
u = shft4(s1 - t1);
v = shft4(s1 + t1);
t1 = sb1[14];
s1 = sb1[15] - t1;
sb1[31] = v + t1; /* A0 */
sb1[30] = u + s1; /* A1 */
sb1[15] = u - s1; /* A2 */
sb1[14] = v - t1; /* A3 */
}
#else
int ch, s, t, *a;
for(ch=0; ch<cfg.channels; ch++)
{
a = ch ? sb1 : sb0;
for(k=0; k<18; k++, wk+=64, a+=SBLIMIT)
{
wp = enwindow;
x1 = wk;
x2 = x1 - 124;
/* x1[-572] .... x1[448] = 1022 */
/* 18*4*16*32 */
for(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[16];
s += (int)x1[-192*2] * wp[ 9]; t += (int)x2[ 192*2] * wp[17];
s += (int)x1[-128*2] * wp[10]; t += (int)x2[ 128*2] * wp[18];
s += (int)x1[- 64*2] * wp[11]; t += (int)x2[ 64*2] * wp[19];
s += (int)x1[ 0*2] * wp[12]; t += (int)x2[ 0*2] * wp[20];
s += (int)x1[ 64*2] * wp[13]; t += (int)x2[- 64*2] * wp[21];
s += (int)x1[ 128*2] * wp[14]; t += (int)x2[-128*2] * wp[22];
s += (int)x1[ 192*2] * wp[15]; t += (int)x2[-192*2] * wp[23];
a[30+i*2] = shft4(t) + shft13(s) * wp[24];
a[31+i*2] = shft13(t) * wp[25] - shft13(s) * wp[26];
wp += 27;
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[10]; s += (int)x1[ -96*2] * wp[1];
t += ((int)x1[- 80*2]+x1[ 48*2]) * wp[12]; s += (int)x1[-160*2] * wp[2];
t += ((int)x1[-112*2]-x1[ 80*2]) * wp[14]; s += (int)x1[-224*2] * wp[3];
t += ((int)x1[-144*2]+x1[112*2]) * wp[16]; s += (int)x1[ 32*2] * wp[4];
t += ((int)x1[-176*2]-x1[144*2]) * wp[18]; s += (int)x1[ 96*2] * wp[5];
t += ((int)x1[-208*2]+x1[176*2]) * wp[20]; s += (int)x1[ 160*2] * wp[6];
t += ((int)x1[-240*2]-x1[208*2]) * wp[22]; s += (int)x1[ 224*2] * wp[7];
u = shft4(s - t);
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 */
}
wk -= 18 * 64 - 1; /* rewind wk (to next channel start) */
}
#endif
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static void ICODE_ATTR window_subband2(short *x1, int a[SBLIMIT])
{
int xr;
short *wp = enwindow;
short *x2 = x1 - 124;
wp += 27 * 15;
x1 -= 2 * 15;
x2 += 2 * 15;
xr = a[28] - a[0]; a[0] += a[28]; a[28] = shft9(xr) * wp[-2*27+25];
xr = a[29] - a[1]; a[1] += a[29]; a[29] = shft9(xr) * wp[-2*27+25];
xr = a[26] - a[2]; a[2] += a[26]; a[26] = shft9(xr) * wp[-4*27+25];
xr = a[27] - a[3]; a[3] += a[27]; a[27] = shft9(xr) * wp[-4*27+25];
xr = a[24] - a[4]; a[4] += a[24]; a[24] = shft9(xr) * wp[-6*27+25];
xr = a[25] - a[5]; a[5] += a[25]; a[25] = shft9(xr) * wp[-6*27+25];
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*27+25];
xr = a[21] - a[ 9]; a[ 9] += a[21]; a[21] = shft9(xr) * wp[-10*27+25];
xr = a[18] - a[10]; a[10] += a[18]; a[18] = shft9(xr) * wp[-12*27+25];
xr = a[19] - a[11]; a[11] += a[19]; a[19] = shft9(xr) * wp[-12*27+25];
xr = a[16] - a[12]; a[12] += a[16]; a[16] = shft9(xr) * wp[-14*27+25];
xr = a[17] - a[13]; a[13] += a[17]; a[17] = shft9(xr) * wp[-14*27+25];
xr =-a[20] + a[24]; a[20] += a[24]; a[24] = shft9(xr) * wp[-12*27+25];
xr =-a[21] + a[25]; a[21] += a[25]; a[25] = shft9(xr) * wp[-12*27+25];
xr = a[ 4] - a[ 8]; a[ 4] += a[ 8]; a[ 8] = shft9(xr) * wp[-12*27+25];
xr = a[ 5] - a[ 9]; a[ 5] += a[ 9]; a[ 9] = shft9(xr) * wp[-12*27+25];
xr = a[ 0] - a[12]; a[ 0] += a[12]; a[12] = shft9(xr) * wp[ -4*27+25];
xr = a[ 1] - a[13]; a[ 1] += a[13]; a[13] = shft9(xr) * wp[ -4*27+25];
xr = a[16] - a[28]; a[16] += a[28]; a[28] = shft9(xr) * wp[ -4*27+25];
xr =-a[17] + a[29]; a[17] += a[29]; a[29] = shft9(xr) * wp[ -4*27+25];
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;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static void ICODE_ATTR 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;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static void mp3_encoder_reset(void)
{
memset(&cfg.cod_info, 0, sizeof(cfg.cod_info));
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 ));
cfg.slot_lag = 0;
}
static void mp3_encoder_init(unsigned long sample_rate, int num_channels,
unsigned long bitrate)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
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)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
cfg.granules = 2;
cfg.samp_per_frame = 1152;
cfg.flush_frames = 2;
}
else
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
cfg.granules = 1;
cfg.samp_per_frame = 576;
cfg.flush_frames = 3;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
cfg.delay = 576-16;
cfg.padding = 3*576+16;
cfg.samp_buffer = mfbuf + 2*512;
memcpy(scalefac, sfBand[cfg.mpg.smpl_id + 3*cfg.mpg.type], sizeof(scalefac));
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 ));
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
memset(band_scale_f, 0 , sizeof(band_scale_f));
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 */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
cfg.byte_per_frame = calcFrameSize(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));
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
cfg.req_byte_per_frame = ALIGN_UP(cfg.byte_per_frame + 1,
sizeof (uint32_t));
}
static void set_scale_facs(int *mdct_freq)
{
unsigned int i, is, ie, k, s;
int max_freq_val, avrg_freq_val;
/* calc average of first 256 frequency values */
for(avrg_freq_val=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(is=k=0; is<scalefac[21]; k++)
{
max_freq_val = 0;
for(i=is, ie=scalefac[k+1]; i<ie; i++)
if(max_freq_val < mdct_freq[i])
max_freq_val = mdct_freq[i];
for(s=0; s<3; s++)
if((max_freq_val<<s) > avrg_freq_val)
break;
band_scale_f[k] = (unsigned char)s;
for(i=is; s && i<ie; i++)
mdct_freq[i] <<= s;
is = ie;
}
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static size_t ICODE_ATTR mp3_encoder_encode_frame(uint8_t *outbuf)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
int gr, gr_cnt;
uint32_t max;
/* 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;
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.ResvSize = 0;
gr_cnt = cfg.granules * cfg.channels;
CodedData.bitpos = cfg.sideinfo_len; /* leave space for mp3 header */
for(gr=0; gr<cfg.granules; gr++)
{
short *wk = mfbuf + 2*286 + gr*1152;
int ch;
/* 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 ii, k, shift;
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)
{
int band;
for(band=1; band<32; band+=2)
sb_data[ch][1-gr][k][band] *= -1;
}
}
/* Perform imdct of 18 previous + 18 current subband samples */
/* for integer precision do this loop again (if neccessary) */
shift = 14 - (cfg.cod_info[gr][ch].additStep >> 2);
for(k=1,ii=0; ii<3 && 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)
{
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(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(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 = 0;
for(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 */
for(k=0; max<(uint32_t)(0x7800>>k); k++) shift--;
for( ; (max>>k)>=(uint32_t)0x10000; k++) shift++;
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 */
Huffmancodebits(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)
{
memcpy(sb_data[ch][0], sb_data[ch][1],
sizeof(sb_data[ch][0]));
}
}
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* shift out old samples */
memmove(mfbuf, mfbuf + 2*cfg.granules*576, 4*512);
/* finish this chunk by adding sideinfo header data */
CodedData.bitpos = 0;
encodeSideInfo( cfg.cod_info );
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
long size = cfg.byte_per_frame + cfg.mpg.padding;
#ifdef ROCKBOX_LITTLE_ENDIAN
/* convert frame to big endian */
const uint32_t *src = CodedData.bbuf;
uint32_t *dst = (uint32_t *)outbuf;
for(long i = 0; i < size; i += sizeof(uint32_t))
*dst++ = swap32(*src++);
#else
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
memcpy(outbuf, CodedData.bbuf, size);
#endif /* ROCKBOX_LITTLE_ENDIAN */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
return size;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/*======== Codec section ========*/
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* CRC code lovingly ripped from:
* github.com/CFR-maniac/lame/blob/master/libmp3lame/VbrTag.c */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 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
};
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static ssize_t header_size;
static unsigned int mp3_crc16;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 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;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 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;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
return type == 3 ? (mode == 3 ? 21 : 36) : (mode == 3 ? 13 : 21);
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* Write very basic 'Info' header with delay, padding and a bit of
* miscellaneous info. */
static bool write_info_header(bool first_encode)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
ssize_t size = cfg.byte_per_frame;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* By default the MP3 frame header for the info frame is the same as
unpadded audio frames */
uint32_t header = encodeHeader(0, cfg.mpg.bitr_id);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
int i = get_info_offset(header);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
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 = calcFrameSize(j, NULL);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
if (size >= i + 8 + 36)
break;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
if (j >= 15)
{
/* Shouldn't really happen but... */
header_size = -1;
return true;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
header = encodeHeader(0, j);
/* Info offset won't change */
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
uint8_t frame[size];
memset(frame, 0, size);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
frame[0] = header >> 24;
frame[1] = header >> 16;
frame[2] = header >> 8;
frame[3] = header >> 0;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 'Info' header (CBR 'Xing') */
memcpy(&frame[i], "Info", 4);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* flags = 0; Info contains no other sections and is 8 bytes */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* Just mark the LAMEness to indicate header presence; we're not
actually _the_ LAME so 'rbshn' is the version we give */
memcpy(&frame[i + 8], "LAMErbshn", 9);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* Fill-in some info about us
* reference: http://gabriel.mp3-tech.org/mp3infotag.html
*/
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* Revision + VBR method:
* [7:4] = Revision (0 ??)
* [3:0] = VBR method (CBR)
*/
frame[i + 17] = (0 << 4) | (1 << 0);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 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;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 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;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
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);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
if (cfg.channels > 1)
misc |= (1 << 2); /* Stereo */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
frame[i + 32] = misc;
if (ci->enc_stream_write(frame, size) != size)
{
ci->enc_stream_lseek(0, SEEK_SET);
header_size = -1;
return false;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
header_size = size;
return true;
}
static inline int on_stream_data(struct enc_chunk_data *data)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
ssize_t size = data->hdr.size;
if (header_size > 0)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* Header is layed-down; keep running CRC of audio data */
uint8_t *p = data->data;
uint8_t *p_end = p + size;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
while (p < p_end)
mp3_crc16 = crc_update_lookup(*p++, mp3_crc16);
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
if (ci->enc_stream_write(data->data, size) != size)
return -1;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
return 0;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static int on_stream_start(struct enc_chunk_file *file)
{
mp3_crc16 = 0x0000;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
if (!write_info_header(file->hdr.aux0))
return -1;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
return 0;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
static int on_stream_end(union enc_chunk_hdr *hdr)
{
ssize_t size = header_size;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
if (size <= 0)
return 0; /* No header possible/none yet written */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* Update audio CRC and header CRC */
uint8_t frame[size];
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 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;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
uint32_t header = (frame[0] << 24) | (frame[1] << 16) |
(frame[2] << 8) | (frame[3] << 0);
int i = get_info_offset(header); /* Get 'Info' header */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 'Info' header = 8 bytes */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* Fill-in audio data CRC16 */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 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;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* 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);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
frame[i + 42] = hdr_crc16 >> 8;
frame[i + 43] = hdr_crc16;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* Update file */
if (ci->enc_stream_lseek(0, SEEK_SET) == 0)
ci->enc_stream_write(frame, size);
return 0;
}
/* this is the codec entry point */
enum codec_status codec_main(enum codec_entry_call_reason reason)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
#ifdef CPU_COLDFIRE
if (reason == CODEC_LOAD)
asm volatile ("move.l #0, %macsr"); /* integer mode */
#endif
return CODEC_OK;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
(void)reason;
}
/* this is called for each file to process */
enum codec_status codec_run(void)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
mp3_encoder_reset();
uint32_t first = 1;
/* Needs to do stream finishing steps to flush-out all samples */
int frames_rem = -1; /* -1 = indeterminate */
enum { GETBUF_ENC, GETBUF_PCM } getbuf = GETBUF_ENC;
struct enc_chunk_data *data = NULL;
/* main encoding loop */
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
while (frames_rem)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
intptr_t param;
enum codec_command_action action = ci->get_command(&param);
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
if (action != CODEC_ACTION_NULL)
{
if (action != CODEC_ACTION_STREAM_FINISH)
break;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
if (frames_rem < 0)
frames_rem = cfg.flush_frames;
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* Reply with required space */
*(size_t *)param = cfg.req_byte_per_frame*frames_rem;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* First obtain output buffer; when available, get PCM data */
switch (getbuf)
{
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
case GETBUF_ENC:
if (!(data = ci->enc_encbuf_get_buffer(cfg.req_byte_per_frame)))
continue;
getbuf = GETBUF_PCM;
case GETBUF_PCM:
if (LIKELY(frames_rem < 0))
{
/* Encoding audio */
int count = cfg.samp_per_frame;
if (!ci->enc_pcmbuf_read(cfg.samp_buffer, count))
continue;
ci->enc_pcmbuf_advance(cfg.samp_per_frame);
if (cfg.channels == 1)
{
/* Interleave the mono samples to stereo as required by
encoder */
uint16_t *src = cfg.samp_buffer + count;
uint32_t *dst = (uint32_t *)(src + count);
for (int i = count; i > 0; i--)
{ uint32_t s = *--src; *--dst = s | (s << 16); }
}
}
else
{
/* Flushing encoder */
memset(cfg.samp_buffer, 0, cfg.samp_per_frame*4);
frames_rem--;
}
getbuf = GETBUF_ENC;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
data->hdr.aux0 = first;
first = 0;
data->hdr.size = mp3_encoder_encode_frame(data->data);
data->pcm_count = cfg.samp_per_frame;
ci->enc_encbuf_finish_buffer();
}
return CODEC_OK;
}
Update software recording engine to latest codec interface. Basically, just give it a good rewrite. Software codec recording can be implemented in a more straightforward and simple manner and made more robust through the better codec control now available. Encoded audio buffer uses a packed format instead of fixed-size chunks and uses smaller data headers leading to more efficient usage. The greatest benefit is with a VBR format like wavpack which needs to request a maximum size but only actually ends up committing part of that request. No guard buffers are used for either PCM or encoded audio. PCM is read into the codec's provided buffer and mono conversion done at that time in the core if required. Any highly-specialized sample conversion is still done within the codec itself, such as 32-bit (wavpack) or interleaved mono (mp3). There is no longer a separate filename array. All metadata goes onto the main encoded audio buffer, eliminating any predermined file limit on the buffer as well as not wasting the space for unused path queue slots. The core and codec interface is less awkward and a bit more sensible. Some less useful interface features were removed. Threads are kept on narrow code paths ie. the audio thread never calls encoding functions and the codec thread never calls file functions as before. Codecs no longer call file functions directly. Writes are buffered in the core and data written to storage in larger chunks to speed up flushing of data. In fact, codecs are no longer aware of the stream being a file at all and have no access to the fd. SPDIF frequency detection no longer requires a restart of recording or plugging the source before entering the screen. It will poll for changes and update when stopped or prerecording (which does discard now-invalid prerecorded data). I've seen to it that writing a proper header on full disk works when the format makes it reasonably practical to do so. Other cases may have incorrect data sizes but sample info will be in tact. File left that way may play anyway. mp3_enc.codec acquires the ability to write 'Info' headers with LAME tags to make it gapless (bonus). Change-Id: I670685166d5eb32ef58ef317f50b8af766ceb653 Reviewed-on: http://gerrit.rockbox.org/493 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested-by: Michael Sevakis <jethead71@rockbox.org>
2013-06-22 20:41:16 +00:00
/* this is called by recording system */
int ICODE_ATTR 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;
}