1 /*
2 * ATRAC3+ compatible decoder
3 *
4 * Copyright (c) 2010-2013 Maxim Poliakovski
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file
25 * Sony ATRAC3+ compatible decoder.
26 *
27 * Container formats used to store its data:
28 * RIFF WAV (.at3) and Sony OpenMG (.oma, .aa3).
29 *
30 * Technical description of this codec can be found here:
31 * http://wiki.multimedia.cx/index.php?title=ATRAC3plus
32 *
33 * Kudos to Benjamin Larsson and Michael Karcher
34 * for their precious technical help!
35 */
36
37 #include <stdint.h>
38 #include <string.h>
39
47
51
56
60
62
67
69 {
71
74
75 return 0;
76 }
77
80 {
82
84 case 1:
87
90 break;
91 case 2:
95 break;
96 case 3:
101 break;
102 case 4:
108 break;
109 case 6:
116 break;
117 case 7:
125 break;
126 case 8:
134 break;
135 default:
137 "Unsupported channel count: %d!\n", avctx->
channels);
139 }
140
141 return 0;
142 }
143
145 {
148
152 }
153
155
156 /* initialize IPQF */
158
160
162
164
167
169
172
176 }
177
179 for (ch = 0; ch < 2; ch++) {
187 }
188
191 }
192
194
195 return 0;
196 }
197
200 int num_channels,
202 {
203 int i, sb, ch,
qu, nspeclines, RNG_index;
204 float *dst, q;
206 /* calculate RNG table index for each subband */
208
210 for (ch = 0; ch < num_channels; ch++)
211 memset(
out[ch], 0, ATRAC3P_FRAME_SAMPLES *
sizeof(*
out[ch]));
212 return;
213 }
214
218
220 sb_RNG_index[sb] = RNG_index & 0x3FC;
221
222 /* inverse quant and power compensation */
223 for (ch = 0; ch < num_channels; ch++) {
224 /* clear channel's residual spectrum */
225 memset(
out[ch], 0, ATRAC3P_FRAME_SAMPLES *
sizeof(*
out[ch]));
226
230 nspeclines = ff_atrac3p_qu_to_spec_pos[qu + 1] -
231 ff_atrac3p_qu_to_spec_pos[
qu];
232
236 for (i = 0; i < nspeclines; i++)
237 dst[i] = src[i] * q;
238 }
239 }
240
243 sb_RNG_index[sb], sb);
244 }
245
250 FFSWAP(
float,
out[0][sb * ATRAC3P_SUBBAND_SAMPLES + i],
251 out[1][sb * ATRAC3P_SUBBAND_SAMPLES + i]);
252 }
253
254 /* flip coefficients' sign if requested */
257 out[1][sb * ATRAC3P_SUBBAND_SAMPLES + i] = -(
out[1][sb * ATRAC3P_SUBBAND_SAMPLES + i]);
258 }
259 }
260 }
261
264 {
265 int ch, sb;
266
267 for (ch = 0; ch < num_channels; ch++) {
269 /* inverse transform and windowing */
272 &ctx->
mdct_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES],
275
276 /* gain compensation and overlapping */
278 &ctx->
mdct_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES],
279 &ch_unit->
prev_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES],
282 ATRAC3P_SUBBAND_SAMPLES,
283 &ctx->
time_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES]);
284 }
285
286 /* zero unused subbands in both output and overlapping buffers */
288 0,
290 ATRAC3P_SUBBAND_SAMPLES *
293 0,
295 ATRAC3P_SUBBAND_SAMPLES *
297
298 /* resynthesize and add tonal signal */
306 }
307 }
308
309 /* subband synthesis and acoustic signal output */
312 }
313
314 /* swap window shape and gain control buffers. */
315 for (ch = 0; ch < num_channels; ch++) {
322 }
323
325 }
326
328 int *got_frame_ptr,
AVPacket *avpkt)
329 {
332 int i,
ret, ch_unit_id, ch_block = 0, out_ch_index = 0, channels_to_process;
334
337 return ret;
338
340 return ret;
341
345 }
346
352 }
356 "Frame data doesn't match channel configuration!\n");
358 }
359
361 channels_to_process = ch_unit_id + 1;
362
365 channels_to_process,
366 avctx)) < 0)
368
370 channels_to_process, avctx);
372 channels_to_process, avctx);
373
374 for (i = 0; i < channels_to_process; i++)
375 memcpy(samples_p[out_ch_index + i], ctx->
outp_buf[i],
377
378 ch_block++;
379 out_ch_index += channels_to_process;
380 }
381
382 *got_frame_ptr = 1;
383
385 }
386
388 .
name =
"atrac3plus",
396 };