1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Mark Arigo
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #include <codecs/libffmpegFLAC/shndec.h>
27 #ifndef IBSS_ATTR_SHORTEN_DECODED0
28 #define IBSS_ATTR_SHORTEN_DECODED0 IBSS_ATTR
31 static int32_t decoded0
[MAX_DECODE_SIZE
] IBSS_ATTR_SHORTEN_DECODED0
;
32 static int32_t decoded1
[MAX_DECODE_SIZE
] IBSS_ATTR
;
34 static int32_t offset0
[MAX_OFFSET_SIZE
] IBSS_ATTR
;
35 static int32_t offset1
[MAX_OFFSET_SIZE
] IBSS_ATTR
;
37 static int8_t ibuf
[MAX_BUFFER_SIZE
] IBSS_ATTR
;
39 /* this is the codec entry point */
40 enum codec_status
codec_main(enum codec_entry_call_reason reason
)
42 if (reason
== CODEC_LOAD
) {
43 /* Generic codec initialisation */
44 ci
->configure(DSP_SET_STEREO_MODE
, STEREO_NONINTERLEAVED
);
45 ci
->configure(DSP_SET_SAMPLE_DEPTH
, SHN_OUTPUT_DEPTH
-1);
51 /* this is called for each file to process */
52 enum codec_status
codec_run(void)
58 int consumed
, res
, nsamples
;
62 /* Codec initialization */
64 LOGF("Shorten: codec_init error\n");
68 codec_set_replaygain(ci
->id3
);
70 /* Shorten decoder initialization */
71 ci
->memset(&sc
, 0, sizeof(ShortenContext
));
74 ci
->seek_buffer(ci
->id3
->first_frame_offset
);
76 /* Read the shorten & wave headers */
77 buf
= ci
->request_buffer(&bytesleft
, MAX_HEADER_SIZE
);
78 res
= shorten_init(&sc
, (unsigned char *)buf
, bytesleft
);
80 LOGF("Shorten: shorten_init error: %d\n", res
);
84 ci
->id3
->frequency
= sc
.sample_rate
;
85 ci
->configure(DSP_SWITCH_FREQUENCY
, sc
.sample_rate
);
88 ci
->id3
->length
= (sc
.totalsamples
/ sc
.sample_rate
) * 1000;
93 if (ci
->id3
->length
) {
94 ci
->id3
->bitrate
= (ci
->id3
->filesize
* 8) / ci
->id3
->length
;
97 consumed
= sc
.gb
.index
/8;
98 ci
->advance_buffer(consumed
);
99 sc
.bitindex
= sc
.gb
.index
- 8*consumed
;
104 /* The main decoding loop */
105 ci
->memset(&decoded0
, 0, sizeof(int32_t)*MAX_DECODE_SIZE
);
106 ci
->memset(&decoded1
, 0, sizeof(int32_t)*MAX_DECODE_SIZE
);
107 ci
->memset(&offset0
, 0, sizeof(int32_t)*MAX_OFFSET_SIZE
);
108 ci
->memset(&offset1
, 0, sizeof(int32_t)*MAX_OFFSET_SIZE
);
111 buf
= ci
->request_buffer(&bytesleft
, MAX_BUFFER_SIZE
);
113 enum codec_command_action action
= ci
->get_command(¶m
);
115 if (action
== CODEC_ACTION_HALT
)
118 /* Seek to start of track */
119 if (action
== CODEC_ACTION_SEEK_TIME
) {
121 ci
->seek_buffer(sc
.header_bits
/8 + ci
->id3
->first_frame_offset
)) {
122 sc
.bitindex
= sc
.header_bits
- 8*(sc
.header_bits
/8);
130 ci
->memcpy(ibuf
, buf
, bytesleft
); /* copy buf to iram */
131 res
= shorten_decode_frames(&sc
, &nsamples
, decoded0
, decoded1
,
132 offset0
, offset1
, (unsigned char *)ibuf
,
133 bytesleft
, ci
->yield
);
135 if (res
== FN_ERROR
) {
136 LOGF("Shorten: shorten_decode_frames error (%lu)\n",
137 (unsigned long)samplesdone
);
140 /* Insert decoded samples in pcmbuf */
143 ci
->pcmbuf_insert(decoded0
+ sc
.nwrap
, decoded1
+ sc
.nwrap
,
146 /* Update the elapsed-time indicator */
147 samplesdone
+= nsamples
;
148 elapsedtime
= (samplesdone
*10) / (sc
.sample_rate
/100);
149 ci
->set_elapsed(elapsedtime
);
152 /* End of shorten stream...go to next track */
157 consumed
= sc
.gb
.index
/8;
158 ci
->advance_buffer(consumed
);
159 buf
= ci
->request_buffer(&bytesleft
, MAX_BUFFER_SIZE
);
160 sc
.bitindex
= sc
.gb
.index
- 8*consumed
;