summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/demac/libdemac/decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/demac/libdemac/decoder.c')
-rw-r--r--lib/rbcodec/codecs/demac/libdemac/decoder.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/demac/libdemac/decoder.c b/lib/rbcodec/codecs/demac/libdemac/decoder.c
new file mode 100644
index 0000000000..b0339a75d9
--- /dev/null
+++ b/lib/rbcodec/codecs/demac/libdemac/decoder.c
@@ -0,0 +1,216 @@
1/*
2
3libdemac - A Monkey's Audio decoder
4
5$Id$
6
7Copyright (C) Dave Chapman 2007
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
22
23*/
24
25#include <inttypes.h>
26#include <string.h>
27
28#include "demac.h"
29#include "predictor.h"
30#include "entropy.h"
31#include "filter.h"
32#include "demac_config.h"
33
34/* Statically allocate the filter buffers */
35
36#ifdef FILTER256_IRAM
37static filter_int filterbuf32[(32*3 + FILTER_HISTORY_SIZE) * 2]
38 IBSS_ATTR_DEMAC MEM_ALIGN_ATTR;
39 /* 2432 or 4864 bytes */
40static filter_int filterbuf256[(256*3 + FILTER_HISTORY_SIZE) * 2]
41 IBSS_ATTR_DEMAC MEM_ALIGN_ATTR;
42 /* 5120 or 10240 bytes */
43#define FILTERBUF64 filterbuf256
44#define FILTERBUF32 filterbuf32
45#define FILTERBUF16 filterbuf32
46#else
47static filter_int filterbuf64[(64*3 + FILTER_HISTORY_SIZE) * 2]
48 IBSS_ATTR_DEMAC MEM_ALIGN_ATTR;
49 /* 2432 or 4864 bytes */
50static filter_int filterbuf256[(256*3 + FILTER_HISTORY_SIZE) * 2]
51 MEM_ALIGN_ATTR; /* 5120 or 10240 bytes */
52#define FILTERBUF64 filterbuf64
53#define FILTERBUF32 filterbuf64
54#define FILTERBUF16 filterbuf64
55#endif
56
57/* This is only needed for "insane" files, and no current Rockbox targets
58 can hope to decode them in realtime, except the Gigabeat S (at 528MHz). */
59static filter_int filterbuf1280[(1280*3 + FILTER_HISTORY_SIZE) * 2]
60 IBSS_ATTR_DEMAC_INSANEBUF MEM_ALIGN_ATTR;
61 /* 17408 or 34816 bytes */
62
63void init_frame_decoder(struct ape_ctx_t* ape_ctx,
64 unsigned char* inbuffer, int* firstbyte,
65 int* bytesconsumed)
66{
67 init_entropy_decoder(ape_ctx, inbuffer, firstbyte, bytesconsumed);
68 //printf("CRC=0x%08x\n",ape_ctx->CRC);
69 //printf("Flags=0x%08x\n",ape_ctx->frameflags);
70
71 init_predictor_decoder(&ape_ctx->predictor);
72
73 switch (ape_ctx->compressiontype)
74 {
75 case 2000:
76 init_filter_16_11(FILTERBUF16);
77 break;
78
79 case 3000:
80 init_filter_64_11(FILTERBUF64);
81 break;
82
83 case 4000:
84 init_filter_256_13(filterbuf256);
85 init_filter_32_10(FILTERBUF32);
86 break;
87
88 case 5000:
89 init_filter_1280_15(filterbuf1280);
90 init_filter_256_13(filterbuf256);
91 init_filter_16_11(FILTERBUF32);
92 }
93}
94
95int ICODE_ATTR_DEMAC decode_chunk(struct ape_ctx_t* ape_ctx,
96 unsigned char* inbuffer, int* firstbyte,
97 int* bytesconsumed,
98 int32_t* decoded0, int32_t* decoded1,
99 int count)
100{
101 int32_t left, right;
102#ifdef ROCKBOX
103 int scale = (APE_OUTPUT_DEPTH - ape_ctx->bps);
104 #define SCALE(x) ((x) << scale)
105#else
106 #define SCALE(x) (x)
107#endif
108
109 if ((ape_ctx->channels==1) || ((ape_ctx->frameflags
110 & (APE_FRAMECODE_PSEUDO_STEREO|APE_FRAMECODE_STEREO_SILENCE))
111 == APE_FRAMECODE_PSEUDO_STEREO)) {
112
113 entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed,
114 decoded0, NULL, count);
115
116 if (ape_ctx->frameflags & APE_FRAMECODE_MONO_SILENCE) {
117 /* We are pure silence, so we're done. */
118 return 0;
119 }
120
121 switch (ape_ctx->compressiontype)
122 {
123 case 2000:
124 apply_filter_16_11(ape_ctx->fileversion,0,decoded0,count);
125 break;
126
127 case 3000:
128 apply_filter_64_11(ape_ctx->fileversion,0,decoded0,count);
129 break;
130
131 case 4000:
132 apply_filter_32_10(ape_ctx->fileversion,0,decoded0,count);
133 apply_filter_256_13(ape_ctx->fileversion,0,decoded0,count);
134 break;
135
136 case 5000:
137 apply_filter_16_11(ape_ctx->fileversion,0,decoded0,count);
138 apply_filter_256_13(ape_ctx->fileversion,0,decoded0,count);
139 apply_filter_1280_15(ape_ctx->fileversion,0,decoded0,count);
140 }
141
142 /* Now apply the predictor decoding */
143 predictor_decode_mono(&ape_ctx->predictor,decoded0,count);
144
145 if (ape_ctx->channels==2) {
146 /* Pseudo-stereo - copy left channel to right channel */
147 while (count--)
148 {
149 left = *decoded0;
150 *(decoded1++) = *(decoded0++) = SCALE(left);
151 }
152 }
153#ifdef ROCKBOX
154 else {
155 /* Scale to output depth */
156 while (count--)
157 {
158 left = *decoded0;
159 *(decoded0++) = SCALE(left);
160 }
161 }
162#endif
163 } else { /* Stereo */
164 entropy_decode(ape_ctx, inbuffer, firstbyte, bytesconsumed,
165 decoded0, decoded1, count);
166
167 if ((ape_ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE)
168 == APE_FRAMECODE_STEREO_SILENCE) {
169 /* We are pure silence, so we're done. */
170 return 0;
171 }
172
173 /* Apply filters - compression type 1000 doesn't have any */
174 switch (ape_ctx->compressiontype)
175 {
176 case 2000:
177 apply_filter_16_11(ape_ctx->fileversion,0,decoded0,count);
178 apply_filter_16_11(ape_ctx->fileversion,1,decoded1,count);
179 break;
180
181 case 3000:
182 apply_filter_64_11(ape_ctx->fileversion,0,decoded0,count);
183 apply_filter_64_11(ape_ctx->fileversion,1,decoded1,count);
184 break;
185
186 case 4000:
187 apply_filter_32_10(ape_ctx->fileversion,0,decoded0,count);
188 apply_filter_32_10(ape_ctx->fileversion,1,decoded1,count);
189 apply_filter_256_13(ape_ctx->fileversion,0,decoded0,count);
190 apply_filter_256_13(ape_ctx->fileversion,1,decoded1,count);
191 break;
192
193 case 5000:
194 apply_filter_16_11(ape_ctx->fileversion,0,decoded0,count);
195 apply_filter_16_11(ape_ctx->fileversion,1,decoded1,count);
196 apply_filter_256_13(ape_ctx->fileversion,0,decoded0,count);
197 apply_filter_256_13(ape_ctx->fileversion,1,decoded1,count);
198 apply_filter_1280_15(ape_ctx->fileversion,0,decoded0,count);
199 apply_filter_1280_15(ape_ctx->fileversion,1,decoded1,count);
200 }
201
202 /* Now apply the predictor decoding */
203 predictor_decode_stereo(&ape_ctx->predictor,decoded0,decoded1,count);
204
205 /* Decorrelate and scale to output depth */
206 while (count--)
207 {
208 left = *decoded1 - (*decoded0 / 2);
209 right = left + *decoded0;
210
211 *(decoded0++) = SCALE(left);
212 *(decoded1++) = SCALE(right);
213 }
214 }
215 return 0;
216}