Updated our source code header to explicitly mention that we are GPL v2 or
[Rockbox.git] / apps / codecs / shorten.c
blob4e00b9a579ab3dc88c3c56c5730459e6fce039bb
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
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 ****************************************************************************/
22 #include "codeclib.h"
23 #include <codecs/libffmpegFLAC/shndec.h>
25 CODEC_HEADER
27 #ifndef IBSS_ATTR_SHORTEN_DECODED0
28 #define IBSS_ATTR_SHORTEN_DECODED0 IBSS_ATTR
29 #endif
31 int32_t decoded0[MAX_DECODE_SIZE] IBSS_ATTR_SHORTEN_DECODED0;
32 int32_t decoded1[MAX_DECODE_SIZE] IBSS_ATTR;
34 int32_t offset0[MAX_OFFSET_SIZE] IBSS_ATTR;
35 int32_t offset1[MAX_OFFSET_SIZE] IBSS_ATTR;
37 int8_t ibuf[MAX_BUFFER_SIZE] IBSS_ATTR;
39 /* this is the codec entry point */
40 enum codec_status codec_main(void)
42 ShortenContext sc;
43 uint32_t samplesdone;
44 uint32_t elapsedtime;
45 int8_t *buf;
46 int consumed, res, nsamples;
47 size_t bytesleft;
49 /* Generic codec initialisation */
50 ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
52 ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
53 ci->configure(DSP_SET_SAMPLE_DEPTH, SHN_OUTPUT_DEPTH-1);
55 next_track:
56 /* Codec initialization */
57 if (codec_init()) {
58 LOGF("Shorten: codec_init error\n");
59 return CODEC_ERROR;
62 while (!*ci->taginfo_ready)
63 ci->yield();
65 codec_set_replaygain(ci->id3);
67 /* Shorten decoder initialization */
68 ci->memset(&sc, 0, sizeof(ShortenContext));
70 /* Skip id3v2 tags */
71 ci->seek_buffer(ci->id3->first_frame_offset);
73 /* Read the shorten & wave headers */
74 buf = ci->request_buffer(&bytesleft, MAX_HEADER_SIZE);
75 res = shorten_init(&sc, (unsigned char *)buf, bytesleft);
76 if (res < 0) {
77 LOGF("Shorten: shorten_init error: %d\n", res);
78 return CODEC_ERROR;
81 ci->id3->frequency = sc.sample_rate;
82 ci->configure(DSP_SWITCH_FREQUENCY, sc.sample_rate);
84 if (sc.sample_rate) {
85 ci->id3->length = (sc.totalsamples / sc.sample_rate) * 1000;
86 } else {
87 ci->id3->length = 0;
90 if (ci->id3->length) {
91 ci->id3->bitrate = (ci->id3->filesize * 8) / ci->id3->length;
94 consumed = sc.gb.index/8;
95 ci->advance_buffer(consumed);
96 sc.bitindex = sc.gb.index - 8*consumed;
98 seek_start:
99 /* The main decoding loop */
100 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);
105 samplesdone = 0;
106 buf = ci->request_buffer(&bytesleft, MAX_BUFFER_SIZE);
107 while (bytesleft) {
108 ci->yield();
109 if (ci->stop_codec || ci->new_track) {
110 break;
113 /* Seek to start of track */
114 if (ci->seek_time == 1) {
115 if (ci->seek_buffer(sc.header_bits/8 + ci->id3->first_frame_offset)) {
116 sc.bitindex = sc.header_bits - 8*(sc.header_bits/8);
117 ci->set_elapsed(0);
118 ci->seek_complete();
119 goto seek_start;
121 ci->seek_complete();
124 /* Decode a frame */
125 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);
130 if (res == FN_ERROR) {
131 LOGF("Shorten: shorten_decode_frames error (%ld)\n", samplesdone);
132 break;
133 } else {
134 /* Insert decoded samples in pcmbuf */
135 if (nsamples) {
136 ci->yield();
137 ci->pcmbuf_insert(decoded0 + sc.nwrap, decoded1 + sc.nwrap,
138 nsamples);
140 /* Update the elapsed-time indicator */
141 samplesdone += nsamples;
142 elapsedtime = (samplesdone*10) / (sc.sample_rate/100);
143 ci->set_elapsed(elapsedtime);
146 /* End of shorten stream...go to next track */
147 if (res == FN_QUIT)
148 break;
151 consumed = sc.gb.index/8;
152 ci->advance_buffer(consumed);
153 buf = ci->request_buffer(&bytesleft, MAX_BUFFER_SIZE);
154 sc.bitindex = sc.gb.index - 8*consumed;
157 if (ci->request_next_track())
158 goto next_track;
160 return CODEC_OK;