diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/shorten.c | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/shorten.c')
-rw-r--r-- | lib/rbcodec/codecs/shorten.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/shorten.c b/lib/rbcodec/codecs/shorten.c new file mode 100644 index 0000000000..a8ab3f30a0 --- /dev/null +++ b/lib/rbcodec/codecs/shorten.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: | ||
9 | * | ||
10 | * Copyright (C) 2005 Mark Arigo | ||
11 | * | ||
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. | ||
16 | * | ||
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 | |||
25 | CODEC_HEADER | ||
26 | |||
27 | #ifndef IBSS_ATTR_SHORTEN_DECODED0 | ||
28 | #define IBSS_ATTR_SHORTEN_DECODED0 IBSS_ATTR | ||
29 | #endif | ||
30 | |||
31 | static int32_t decoded0[MAX_DECODE_SIZE] IBSS_ATTR_SHORTEN_DECODED0; | ||
32 | static int32_t decoded1[MAX_DECODE_SIZE] IBSS_ATTR; | ||
33 | |||
34 | static int32_t offset0[MAX_OFFSET_SIZE] IBSS_ATTR; | ||
35 | static int32_t offset1[MAX_OFFSET_SIZE] IBSS_ATTR; | ||
36 | |||
37 | static int8_t ibuf[MAX_BUFFER_SIZE] IBSS_ATTR; | ||
38 | |||
39 | /* this is the codec entry point */ | ||
40 | enum codec_status codec_main(enum codec_entry_call_reason reason) | ||
41 | { | ||
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); | ||
46 | } | ||
47 | |||
48 | return CODEC_OK; | ||
49 | } | ||
50 | |||
51 | /* this is called for each file to process */ | ||
52 | enum codec_status codec_run(void) | ||
53 | { | ||
54 | ShortenContext sc; | ||
55 | uint32_t samplesdone; | ||
56 | uint32_t elapsedtime; | ||
57 | int8_t *buf; | ||
58 | int consumed, res, nsamples; | ||
59 | size_t bytesleft; | ||
60 | intptr_t param; | ||
61 | |||
62 | /* Codec initialization */ | ||
63 | if (codec_init()) { | ||
64 | LOGF("Shorten: codec_init error\n"); | ||
65 | return CODEC_ERROR; | ||
66 | } | ||
67 | |||
68 | codec_set_replaygain(ci->id3); | ||
69 | |||
70 | /* Shorten decoder initialization */ | ||
71 | ci->memset(&sc, 0, sizeof(ShortenContext)); | ||
72 | |||
73 | /* Skip id3v2 tags */ | ||
74 | ci->seek_buffer(ci->id3->first_frame_offset); | ||
75 | |||
76 | /* Read the shorten & wave headers */ | ||
77 | buf = ci->request_buffer(&bytesleft, MAX_HEADER_SIZE); | ||
78 | res = shorten_init(&sc, (unsigned char *)buf, bytesleft); | ||
79 | if (res < 0) { | ||
80 | LOGF("Shorten: shorten_init error: %d\n", res); | ||
81 | return CODEC_ERROR; | ||
82 | } | ||
83 | |||
84 | ci->id3->frequency = sc.sample_rate; | ||
85 | ci->configure(DSP_SWITCH_FREQUENCY, sc.sample_rate); | ||
86 | |||
87 | if (sc.sample_rate) { | ||
88 | ci->id3->length = (sc.totalsamples / sc.sample_rate) * 1000; | ||
89 | } else { | ||
90 | ci->id3->length = 0; | ||
91 | } | ||
92 | |||
93 | if (ci->id3->length) { | ||
94 | ci->id3->bitrate = (ci->id3->filesize * 8) / ci->id3->length; | ||
95 | } | ||
96 | |||
97 | consumed = sc.gb.index/8; | ||
98 | ci->advance_buffer(consumed); | ||
99 | sc.bitindex = sc.gb.index - 8*consumed; | ||
100 | |||
101 | seek_start: | ||
102 | ci->set_elapsed(0); | ||
103 | |||
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); | ||
109 | |||
110 | samplesdone = 0; | ||
111 | buf = ci->request_buffer(&bytesleft, MAX_BUFFER_SIZE); | ||
112 | while (bytesleft) { | ||
113 | enum codec_command_action action = ci->get_command(¶m); | ||
114 | |||
115 | if (action == CODEC_ACTION_HALT) | ||
116 | break; | ||
117 | |||
118 | /* Seek to start of track */ | ||
119 | if (action == CODEC_ACTION_SEEK_TIME) { | ||
120 | if (param == 0 && | ||
121 | ci->seek_buffer(sc.header_bits/8 + ci->id3->first_frame_offset)) { | ||
122 | sc.bitindex = sc.header_bits - 8*(sc.header_bits/8); | ||
123 | ci->seek_complete(); | ||
124 | goto seek_start; | ||
125 | } | ||
126 | ci->seek_complete(); | ||
127 | } | ||
128 | |||
129 | /* Decode a frame */ | ||
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); | ||
134 | |||
135 | if (res == FN_ERROR) { | ||
136 | LOGF("Shorten: shorten_decode_frames error (%lu)\n", | ||
137 | (unsigned long)samplesdone); | ||
138 | return CODEC_ERROR; | ||
139 | } else { | ||
140 | /* Insert decoded samples in pcmbuf */ | ||
141 | if (nsamples) { | ||
142 | ci->yield(); | ||
143 | ci->pcmbuf_insert(decoded0 + sc.nwrap, decoded1 + sc.nwrap, | ||
144 | nsamples); | ||
145 | |||
146 | /* Update the elapsed-time indicator */ | ||
147 | samplesdone += nsamples; | ||
148 | elapsedtime = (samplesdone*10) / (sc.sample_rate/100); | ||
149 | ci->set_elapsed(elapsedtime); | ||
150 | } | ||
151 | |||
152 | /* End of shorten stream...go to next track */ | ||
153 | if (res == FN_QUIT) | ||
154 | break; | ||
155 | } | ||
156 | |||
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; | ||
161 | } | ||
162 | |||
163 | return CODEC_OK; | ||
164 | } | ||