blob: dbfc272c5a9f000c8d5d4e6794218a36283a140f [file] [log] [blame]
Dave Chapman2bf9be12005-11-11 19:45:36 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright (C) 2005 Mark Arigo
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "codeclib.h"
21#include <codecs/libffmpegFLAC/shndec.h>
22
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000023CODEC_HEADER
24
Tomasz Malesinski5c54ba42006-11-09 21:59:27 +000025#ifndef IBSS_ATTR_SHORTEN_DECODED0
26#define IBSS_ATTR_SHORTEN_DECODED0 IBSS_ATTR
27#endif
28
Tomasz Malesinski5c54ba42006-11-09 21:59:27 +000029int32_t decoded0[MAX_DECODE_SIZE] IBSS_ATTR_SHORTEN_DECODED0;
Dave Chapman8e46ab82006-02-07 22:16:35 +000030int32_t decoded1[MAX_DECODE_SIZE] IBSS_ATTR;
Dave Chapman2bf9be12005-11-11 19:45:36 +000031
Dave Chapman8e46ab82006-02-07 22:16:35 +000032int32_t offset0[MAX_OFFSET_SIZE] IBSS_ATTR;
33int32_t offset1[MAX_OFFSET_SIZE] IBSS_ATTR;
34
35int8_t ibuf[MAX_BUFFER_SIZE] IBSS_ATTR;
Dave Chapman2bf9be12005-11-11 19:45:36 +000036
37/* this is the codec entry point */
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000038enum codec_status codec_main(void)
Dave Chapman2bf9be12005-11-11 19:45:36 +000039{
40 ShortenContext sc;
41 uint32_t samplesdone;
42 uint32_t elapsedtime;
43 int8_t *buf;
Dave Chapman8e46ab82006-02-07 22:16:35 +000044 int consumed, res, nsamples;
Brandon Lowc76904b2006-03-24 14:02:27 +000045 size_t bytesleft;
Dave Chapman2bf9be12005-11-11 19:45:36 +000046
47 /* Generic codec initialisation */
Michael Sevakis97f369a2007-02-10 16:34:16 +000048 ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
49 ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, 1024*128);
Dave Chapman2bf9be12005-11-11 19:45:36 +000050
Michael Sevakis97f369a2007-02-10 16:34:16 +000051 ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
52 ci->configure(DSP_SET_SAMPLE_DEPTH, SHN_OUTPUT_DEPTH-1);
Dave Chapman2bf9be12005-11-11 19:45:36 +000053
54next_track:
55 /* Codec initialization */
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000056 if (codec_init()) {
Dave Chapman8e46ab82006-02-07 22:16:35 +000057 LOGF("Shorten: codec_init error\n");
58 return CODEC_ERROR;
Dave Chapman2bf9be12005-11-11 19:45:36 +000059 }
60
61 while (!*ci->taginfo_ready)
62 ci->yield();
63
64 /* Shorten decoder initialization */
65 ci->memset(&sc, 0, sizeof(ShortenContext));
66
Dave Chapmanc01775f2005-11-13 11:04:02 +000067 /* Skip id3v2 tags */
68 if (ci->id3->first_frame_offset) {
69 buf = ci->request_buffer(&bytesleft, ci->id3->first_frame_offset);
70 ci->advance_buffer(ci->id3->first_frame_offset);
71 }
72
Dave Chapman2bf9be12005-11-11 19:45:36 +000073 /* Read the shorten & wave headers */
Dave Chapman8e46ab82006-02-07 22:16:35 +000074 buf = ci->request_buffer(&bytesleft, MAX_HEADER_SIZE);
Daniel Stenberg76667e22005-12-02 08:42:48 +000075 res = shorten_init(&sc, (unsigned char *)buf, bytesleft);
Dave Chapman2bf9be12005-11-11 19:45:36 +000076 if (res < 0) {
Dave Chapman8e46ab82006-02-07 22:16:35 +000077 LOGF("Shorten: shorten_init error: %d\n", res);
78 return CODEC_ERROR;
Dave Chapman2bf9be12005-11-11 19:45:36 +000079 }
80
Dave Chapman2bf9be12005-11-11 19:45:36 +000081 ci->id3->frequency = sc.sample_rate;
Michael Sevakis97f369a2007-02-10 16:34:16 +000082 ci->configure(DSP_SWITCH_FREQUENCY, sc.sample_rate);
Dave Chapmanc01775f2005-11-13 11:04:02 +000083
84 if (sc.sample_rate) {
85 ci->id3->length = (sc.totalsamples / sc.sample_rate) * 1000;
86 } else {
87 ci->id3->length = 0;
88 }
89
90 if (ci->id3->length) {
91 ci->id3->bitrate = (ci->id3->filesize * 8) / ci->id3->length;
92 }
Dave Chapman2bf9be12005-11-11 19:45:36 +000093
94 consumed = sc.gb.index/8;
95 ci->advance_buffer(consumed);
96 sc.bitindex = sc.gb.index - 8*consumed;
97
98seek_start:
99 /* The main decoding loop */
Dave Chapman8e46ab82006-02-07 22:16:35 +0000100 ci->memset(&decoded0, 0, sizeof(int32_t)*MAX_DECODE_SIZE);
101 ci->memset(&decoded1, 0, sizeof(int32_t)*MAX_DECODE_SIZE);
102 ci->memset(&offset0, 0, sizeof(int32_t)*MAX_OFFSET_SIZE);
103 ci->memset(&offset1, 0, sizeof(int32_t)*MAX_OFFSET_SIZE);
Dave Chapman2bf9be12005-11-11 19:45:36 +0000104
Dave Chapman2bf9be12005-11-11 19:45:36 +0000105 samplesdone = 0;
Dave Chapman8e46ab82006-02-07 22:16:35 +0000106 buf = ci->request_buffer(&bytesleft, MAX_BUFFER_SIZE);
Dave Chapman2bf9be12005-11-11 19:45:36 +0000107 while (bytesleft) {
108 ci->yield();
Brandon Lowebadcc62006-04-15 02:03:11 +0000109 if (ci->stop_codec || ci->new_track) {
Dave Chapman2bf9be12005-11-11 19:45:36 +0000110 break;
111 }
112
113 /* Seek to start of track */
114 if (ci->seek_time == 1) {
Dave Chapmanc01775f2005-11-13 11:04:02 +0000115 if (ci->seek_buffer(sc.header_bits/8 + ci->id3->first_frame_offset)) {
Dave Chapman2bf9be12005-11-11 19:45:36 +0000116 sc.bitindex = sc.header_bits - 8*(sc.header_bits/8);
117 ci->set_elapsed(0);
118 ci->seek_complete();
119 goto seek_start;
120 }
121 ci->seek_complete();
122 }
123
124 /* Decode a frame */
Dave Chapman8e46ab82006-02-07 22:16:35 +0000125 ci->memcpy(ibuf, buf, bytesleft); /* copy buf to iram */
126 res = shorten_decode_frames(&sc, &nsamples, decoded0, decoded1,
127 offset0, offset1, (unsigned char *)ibuf,
128 bytesleft, ci->yield);
129
130 if (res == FN_ERROR) {
131 LOGF("Shorten: shorten_decode_frames error (%d)\n", samplesdone);
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000132 break;
Dave Chapman2bf9be12005-11-11 19:45:36 +0000133 } else {
Dave Chapman2bf9be12005-11-11 19:45:36 +0000134 /* Insert decoded samples in pcmbuf */
Dave Chapman8e46ab82006-02-07 22:16:35 +0000135 if (nsamples) {
Dave Chapman2bf9be12005-11-11 19:45:36 +0000136 ci->yield();
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000137 ci->pcmbuf_insert(decoded0 + sc.nwrap, decoded1 + sc.nwrap,
138 nsamples);
Dave Chapman8e46ab82006-02-07 22:16:35 +0000139
140 /* Update the elapsed-time indicator */
141 samplesdone += nsamples;
142 elapsedtime = (samplesdone*10) / (sc.sample_rate/100);
143 ci->set_elapsed(elapsedtime);
Dave Chapman2bf9be12005-11-11 19:45:36 +0000144 }
145
Dave Chapman2bf9be12005-11-11 19:45:36 +0000146 /* End of shorten stream...go to next track */
Dave Chapman8e46ab82006-02-07 22:16:35 +0000147 if (res == FN_QUIT)
148 break;
Dave Chapman2bf9be12005-11-11 19:45:36 +0000149 }
150
151 consumed = sc.gb.index/8;
152 ci->advance_buffer(consumed);
Dave Chapman8e46ab82006-02-07 22:16:35 +0000153 buf = ci->request_buffer(&bytesleft, MAX_BUFFER_SIZE);
Dave Chapman2bf9be12005-11-11 19:45:36 +0000154 sc.bitindex = sc.gb.index - 8*consumed;
Dave Chapman2bf9be12005-11-11 19:45:36 +0000155 }
156
Dave Chapman2bf9be12005-11-11 19:45:36 +0000157 if (ci->request_next_track())
158 goto next_track;
159
Dave Chapman8e46ab82006-02-07 22:16:35 +0000160 return CODEC_OK;
Dave Chapman2bf9be12005-11-11 19:45:36 +0000161}