Flyspray: FS#10326
[kugel-rb.git] / apps / codecs / shorten.c
blob9b5c2e2f1762f397fb8f3c1a530bdfe1c12b25d3
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(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
51 ci->configure(DSP_SET_SAMPLE_DEPTH, SHN_OUTPUT_DEPTH-1);
53 next_track:
54 /* Codec initialization */
55 if (codec_init()) {
56 LOGF("Shorten: codec_init error\n");
57 return CODEC_ERROR;
60 while (!*ci->taginfo_ready)
61 ci->yield();
63 codec_set_replaygain(ci->id3);
65 /* Shorten decoder initialization */
66 ci->memset(&sc, 0, sizeof(ShortenContext));
68 /* Skip id3v2 tags */
69 ci->seek_buffer(ci->id3->first_frame_offset);
71 /* Read the shorten & wave headers */
72 buf = ci->request_buffer(&bytesleft, MAX_HEADER_SIZE);
73 res = shorten_init(&sc, (unsigned char *)buf, bytesleft);
74 if (res < 0) {
75 LOGF("Shorten: shorten_init error: %d\n", res);
76 return CODEC_ERROR;
79 ci->id3->frequency = sc.sample_rate;
80 ci->configure(DSP_SWITCH_FREQUENCY, sc.sample_rate);
82 if (sc.sample_rate) {
83 ci->id3->length = (sc.totalsamples / sc.sample_rate) * 1000;
84 } else {
85 ci->id3->length = 0;
88 if (ci->id3->length) {
89 ci->id3->bitrate = (ci->id3->filesize * 8) / ci->id3->length;
92 consumed = sc.gb.index/8;
93 ci->advance_buffer(consumed);
94 sc.bitindex = sc.gb.index - 8*consumed;
96 seek_start:
97 /* The main decoding loop */
98 ci->memset(&decoded0, 0, sizeof(int32_t)*MAX_DECODE_SIZE);
99 ci->memset(&decoded1, 0, sizeof(int32_t)*MAX_DECODE_SIZE);
100 ci->memset(&offset0, 0, sizeof(int32_t)*MAX_OFFSET_SIZE);
101 ci->memset(&offset1, 0, sizeof(int32_t)*MAX_OFFSET_SIZE);
103 samplesdone = 0;
104 buf = ci->request_buffer(&bytesleft, MAX_BUFFER_SIZE);
105 while (bytesleft) {
106 ci->yield();
107 if (ci->stop_codec || ci->new_track) {
108 break;
111 /* Seek to start of track */
112 if (ci->seek_time == 1) {
113 if (ci->seek_buffer(sc.header_bits/8 + ci->id3->first_frame_offset)) {
114 sc.bitindex = sc.header_bits - 8*(sc.header_bits/8);
115 ci->set_elapsed(0);
116 ci->seek_complete();
117 goto seek_start;
119 ci->seek_complete();
122 /* Decode a frame */
123 ci->memcpy(ibuf, buf, bytesleft); /* copy buf to iram */
124 res = shorten_decode_frames(&sc, &nsamples, decoded0, decoded1,
125 offset0, offset1, (unsigned char *)ibuf,
126 bytesleft, ci->yield);
128 if (res == FN_ERROR) {
129 LOGF("Shorten: shorten_decode_frames error (%ld)\n", samplesdone);
130 break;
131 } else {
132 /* Insert decoded samples in pcmbuf */
133 if (nsamples) {
134 ci->yield();
135 ci->pcmbuf_insert(decoded0 + sc.nwrap, decoded1 + sc.nwrap,
136 nsamples);
138 /* Update the elapsed-time indicator */
139 samplesdone += nsamples;
140 elapsedtime = (samplesdone*10) / (sc.sample_rate/100);
141 ci->set_elapsed(elapsedtime);
144 /* End of shorten stream...go to next track */
145 if (res == FN_QUIT)
146 break;
149 consumed = sc.gb.index/8;
150 ci->advance_buffer(consumed);
151 buf = ci->request_buffer(&bytesleft, MAX_BUFFER_SIZE);
152 sc.bitindex = sc.gb.index - 8*consumed;
155 if (ci->request_next_track())
156 goto next_track;
158 return CODEC_OK;