blob: 4e00b9a579ab3dc88c3c56c5730459e6fce039bb [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 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Dave Chapman2bf9be12005-11-11 19:45:36 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "codeclib.h"
23#include <codecs/libffmpegFLAC/shndec.h>
24
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000025CODEC_HEADER
26
Tomasz Malesinski5c54ba42006-11-09 21:59:27 +000027#ifndef IBSS_ATTR_SHORTEN_DECODED0
28#define IBSS_ATTR_SHORTEN_DECODED0 IBSS_ATTR
29#endif
30
Tomasz Malesinski5c54ba42006-11-09 21:59:27 +000031int32_t decoded0[MAX_DECODE_SIZE] IBSS_ATTR_SHORTEN_DECODED0;
Dave Chapman8e46ab82006-02-07 22:16:35 +000032int32_t decoded1[MAX_DECODE_SIZE] IBSS_ATTR;
Dave Chapman2bf9be12005-11-11 19:45:36 +000033
Dave Chapman8e46ab82006-02-07 22:16:35 +000034int32_t offset0[MAX_OFFSET_SIZE] IBSS_ATTR;
35int32_t offset1[MAX_OFFSET_SIZE] IBSS_ATTR;
36
37int8_t ibuf[MAX_BUFFER_SIZE] IBSS_ATTR;
Dave Chapman2bf9be12005-11-11 19:45:36 +000038
39/* this is the codec entry point */
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000040enum codec_status codec_main(void)
Dave Chapman2bf9be12005-11-11 19:45:36 +000041{
42 ShortenContext sc;
43 uint32_t samplesdone;
44 uint32_t elapsedtime;
45 int8_t *buf;
Dave Chapman8e46ab82006-02-07 22:16:35 +000046 int consumed, res, nsamples;
Brandon Lowc76904b2006-03-24 14:02:27 +000047 size_t bytesleft;
Dave Chapman2bf9be12005-11-11 19:45:36 +000048
49 /* Generic codec initialisation */
Michael Sevakis97f369a2007-02-10 16:34:16 +000050 ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
Dave Chapman2bf9be12005-11-11 19:45:36 +000051
Michael Sevakis97f369a2007-02-10 16:34:16 +000052 ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
53 ci->configure(DSP_SET_SAMPLE_DEPTH, SHN_OUTPUT_DEPTH-1);
Dave Chapman2bf9be12005-11-11 19:45:36 +000054
55next_track:
56 /* Codec initialization */
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000057 if (codec_init()) {
Dave Chapman8e46ab82006-02-07 22:16:35 +000058 LOGF("Shorten: codec_init error\n");
59 return CODEC_ERROR;
Dave Chapman2bf9be12005-11-11 19:45:36 +000060 }
61
62 while (!*ci->taginfo_ready)
63 ci->yield();
64
Michael Sevakis9b9e2272007-02-26 17:15:04 +000065 codec_set_replaygain(ci->id3);
66
Dave Chapman2bf9be12005-11-11 19:45:36 +000067 /* Shorten decoder initialization */
68 ci->memset(&sc, 0, sizeof(ShortenContext));
69
Dave Chapmanc01775f2005-11-13 11:04:02 +000070 /* Skip id3v2 tags */
Brandon Lowb46175c2007-11-05 18:16:13 +000071 ci->seek_buffer(ci->id3->first_frame_offset);
Dave Chapmanc01775f2005-11-13 11:04:02 +000072
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) {
Magnus Holmgren01a010f2007-03-18 09:50:53 +0000131 LOGF("Shorten: shorten_decode_frames error (%ld)\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}