1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Dave Chapman
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
21 #include <inttypes.h> /* Needed by a52.h */
22 #include <codecs/liba52/config-a52.h>
23 #include <codecs/liba52/a52.h>
27 #define BUFFER_SIZE 4096
29 #define A52_SAMPLESPERFRAME (6*256)
31 static a52_state_t
*state
;
32 unsigned long samplesdone
;
33 unsigned long frequency
;
35 /* used outside liba52 */
36 static uint8_t buf
[3840] IBSS_ATTR
;
38 static inline void output_audio(sample_t
*samples
)
41 ci
->pcmbuf_insert(&samples
[0], &samples
[256], 256);
44 void a52_decode_data(uint8_t *start
, uint8_t *end
)
46 static uint8_t *bufptr
= buf
;
47 static uint8_t *bufpos
= buf
+ 7;
49 * sample_rate and flags are static because this routine could
50 * exit between the a52_syncinfo() and the ao_setup(), and we want
51 * to have the same values when we get back !
53 static int sample_rate
;
62 if (len
> bufpos
- bufptr
)
63 len
= bufpos
- bufptr
;
64 memcpy(bufptr
, start
, len
);
67 if (bufptr
== bufpos
) {
68 if (bufpos
== buf
+ 7) {
71 length
= a52_syncinfo(buf
, &flags
, &sample_rate
, &bit_rate
);
74 for (bufptr
= buf
; bufptr
< buf
+ 6; bufptr
++)
75 bufptr
[0] = bufptr
[1];
78 bufpos
= buf
+ length
;
80 /* Unity gain is 1 << 26, and we want to end up on 28 bits
81 of precision instead of the default 30.
83 level_t level
= 1 << 24;
87 /* This is the configuration for the downmixing: */
88 flags
= A52_STEREO
| A52_ADJUST_LEVEL
;
90 if (a52_frame(state
, buf
, &flags
, &level
, bias
))
92 a52_dynrng(state
, NULL
, NULL
);
93 frequency
= sample_rate
;
95 /* An A52 frame consists of 6 blocks of 256 samples
96 So we decode and output them one block at a time */
97 for (i
= 0; i
< 6; i
++) {
100 output_audio(a52_samples(state
));
103 ci
->set_elapsed(samplesdone
/(frequency
/1000));
108 //logf("Error decoding A52 stream\n");
116 /* this is the codec entry point */
117 enum codec_status
codec_main(void)
120 unsigned char *filebuf
;
124 /* Generic codec initialisation */
125 ci
->configure(DSP_SET_STEREO_MODE
, STEREO_NONINTERLEAVED
);
126 ci
->configure(DSP_SET_SAMPLE_DEPTH
, 28);
130 retval
= CODEC_ERROR
;
134 while (!ci
->taginfo_ready
)
137 ci
->configure(DSP_SWITCH_FREQUENCY
, ci
->id3
->frequency
);
138 codec_set_replaygain(ci
->id3
);
140 /* Intialise the A52 decoder and check for success */
143 /* The main decoding loop */
144 if (ci
->id3
->offset
) {
145 if (ci
->seek_buffer(ci
->id3
->offset
)) {
146 samplesdone
= (ci
->id3
->offset
/ ci
->id3
->bytesperframe
) *
148 ci
->set_elapsed(samplesdone
/(ci
->id3
->frequency
/ 1000));
156 if (ci
->stop_codec
|| ci
->new_track
)
160 sample_loc
= (ci
->seek_time
- 1)/1000 * ci
->id3
->frequency
;
162 if (ci
->seek_buffer((sample_loc
/A52_SAMPLESPERFRAME
)*ci
->id3
->bytesperframe
)) {
163 samplesdone
= sample_loc
;
164 ci
->set_elapsed(samplesdone
/(ci
->id3
->frequency
/1000));
169 filebuf
= ci
->request_buffer(&n
, BUFFER_SIZE
);
171 if (n
== 0) /* End of Stream */
174 a52_decode_data(filebuf
, filebuf
+ n
);
175 ci
->advance_buffer(n
);
179 if (ci
->request_next_track())