Move it to the ATRAC common code, to reuse in the upcoming ATRAC3+ decoder.
Signed-off-by: Diego Biurrun <diego@biurrun.de>
... | ... |
@@ -63,6 +63,67 @@ void ff_atrac_generate_tables(void) |
63 | 63 |
} |
64 | 64 |
} |
65 | 65 |
|
66 |
+av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, |
|
67 |
+ int loc_scale) |
|
68 |
+{ |
|
69 |
+ int i; |
|
70 |
+ |
|
71 |
+ gctx->loc_scale = loc_scale; |
|
72 |
+ gctx->loc_size = 1 << loc_scale; |
|
73 |
+ gctx->id2exp_offset = id2exp_offset; |
|
74 |
+ |
|
75 |
+ /* Generate gain level table. */ |
|
76 |
+ for (i = 0; i < 16; i++) |
|
77 |
+ gctx->gain_tab1[i] = powf(2.0, id2exp_offset - i); |
|
78 |
+ |
|
79 |
+ /* Generate gain interpolation table. */ |
|
80 |
+ for (i = -15; i < 16; i++) |
|
81 |
+ gctx->gain_tab2[i + 15] = powf(2.0, -1.0f / gctx->loc_size * i); |
|
82 |
+} |
|
83 |
+ |
|
84 |
+void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev, |
|
85 |
+ AtracGainInfo *gc_now, AtracGainInfo *gc_next, |
|
86 |
+ int num_samples, float *out) |
|
87 |
+{ |
|
88 |
+ float lev, gc_scale, gain_inc; |
|
89 |
+ int i, pos, lastpos; |
|
90 |
+ |
|
91 |
+ gc_scale = gc_next->num_points ? gctx->gain_tab1[gc_next->lev_code[0]] |
|
92 |
+ : 1.0f; |
|
93 |
+ |
|
94 |
+ if (!gc_now->num_points) { |
|
95 |
+ for (pos = 0; pos < num_samples; pos++) |
|
96 |
+ out[pos] = in[pos] * gc_scale + prev[pos]; |
|
97 |
+ } else { |
|
98 |
+ pos = 0; |
|
99 |
+ |
|
100 |
+ for (i = 0; i < gc_now->num_points; i++) { |
|
101 |
+ lastpos = gc_now->loc_code[i] << gctx->loc_scale; |
|
102 |
+ |
|
103 |
+ lev = gctx->gain_tab1[gc_now->lev_code[i]]; |
|
104 |
+ gain_inc = gctx->gain_tab2[(i + 1 < gc_now->num_points ? gc_now->lev_code[i + 1] |
|
105 |
+ : gctx->id2exp_offset) - |
|
106 |
+ gc_now->lev_code[i] + 15]; |
|
107 |
+ |
|
108 |
+ /* apply constant gain level and overlap */ |
|
109 |
+ for (; pos < lastpos; pos++) |
|
110 |
+ out[pos] = (in[pos] * gc_scale + prev[pos]) * lev; |
|
111 |
+ |
|
112 |
+ /* interpolate between two different gain levels */ |
|
113 |
+ for (; pos < lastpos + gctx->loc_size; pos++) { |
|
114 |
+ out[pos] = (in[pos] * gc_scale + prev[pos]) * lev; |
|
115 |
+ lev *= gain_inc; |
|
116 |
+ } |
|
117 |
+ } |
|
118 |
+ |
|
119 |
+ for (; pos < num_samples; pos++) |
|
120 |
+ out[pos] = in[pos] * gc_scale + prev[pos]; |
|
121 |
+ } |
|
122 |
+ |
|
123 |
+ /* copy the overlapping part into the delay buffer */ |
|
124 |
+ memcpy(prev, &in[num_samples], num_samples * sizeof(float)); |
|
125 |
+} |
|
126 |
+ |
|
66 | 127 |
void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp) |
67 | 128 |
{ |
68 | 129 |
int i, j; |
... | ... |
@@ -29,6 +29,26 @@ |
29 | 29 |
#ifndef AVCODEC_ATRAC_H |
30 | 30 |
#define AVCODEC_ATRAC_H |
31 | 31 |
|
32 |
+/** |
|
33 |
+ * Gain control parameters for one subband. |
|
34 |
+ */ |
|
35 |
+typedef struct AtracGainInfo { |
|
36 |
+ int num_points; ///< number of gain control points |
|
37 |
+ int lev_code[7]; ///< level at corresponding control point |
|
38 |
+ int loc_code[7]; ///< location of gain control points |
|
39 |
+} AtracGainInfo; |
|
40 |
+ |
|
41 |
+/** |
|
42 |
+ * Gain compensation context structure. |
|
43 |
+ */ |
|
44 |
+typedef struct AtracGCContext { |
|
45 |
+ float gain_tab1[16]; ///< gain compensation level table |
|
46 |
+ float gain_tab2[31]; ///< gain compensation interpolation table |
|
47 |
+ int id2exp_offset; ///< offset for converting level index into level exponent |
|
48 |
+ int loc_scale; ///< scale of location code = 2^loc_scale samples |
|
49 |
+ int loc_size; ///< size of location code in samples |
|
50 |
+} AtracGCContext; |
|
51 |
+ |
|
32 | 52 |
extern float ff_atrac_sf_table[64]; |
33 | 53 |
|
34 | 54 |
/** |
... | ... |
@@ -37,6 +57,31 @@ extern float ff_atrac_sf_table[64]; |
37 | 37 |
void ff_atrac_generate_tables(void); |
38 | 38 |
|
39 | 39 |
/** |
40 |
+ * Initialize gain compensation context. |
|
41 |
+ * |
|
42 |
+ * @param gctx pointer to gain compensation context to initialize |
|
43 |
+ * @param id2exp_offset offset for converting level index into level exponent |
|
44 |
+ * @param loc_scale location size factor |
|
45 |
+ */ |
|
46 |
+void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, |
|
47 |
+ int loc_scale); |
|
48 |
+ |
|
49 |
+/** |
|
50 |
+ * Apply gain compensation and perform the MDCT overlapping part. |
|
51 |
+ * |
|
52 |
+ * @param gctx pointer to gain compensation context |
|
53 |
+ * @param in input buffer |
|
54 |
+ * @param prev previous buffer to perform overlap against |
|
55 |
+ * @param gc_now gain control information for current frame |
|
56 |
+ * @param gc_next gain control information for next frame |
|
57 |
+ * @param num_samples number of samples to process |
|
58 |
+ * @param out output data goes here |
|
59 |
+ */ |
|
60 |
+void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev, |
|
61 |
+ AtracGainInfo *gc_now, AtracGainInfo *gc_next, |
|
62 |
+ int num_samples, float *out); |
|
63 |
+ |
|
64 |
+/** |
|
40 | 65 |
* Quadrature mirror synthesis filter. |
41 | 66 |
* |
42 | 67 |
* @param inlo lower part of spectrum |
... | ... |
@@ -54,14 +54,8 @@ |
54 | 54 |
#define SAMPLES_PER_FRAME 1024 |
55 | 55 |
#define MDCT_SIZE 512 |
56 | 56 |
|
57 |
-typedef struct GainInfo { |
|
58 |
- int num_gain_data; |
|
59 |
- int lev_code[8]; |
|
60 |
- int loc_code[8]; |
|
61 |
-} GainInfo; |
|
62 |
- |
|
63 | 57 |
typedef struct GainBlock { |
64 |
- GainInfo g_block[4]; |
|
58 |
+ AtracGainInfo g_block[4]; |
|
65 | 59 |
} GainBlock; |
66 | 60 |
|
67 | 61 |
typedef struct TonalComponent { |
... | ... |
@@ -111,6 +105,7 @@ typedef struct ATRAC3Context { |
111 | 111 |
int scrambled_stream; |
112 | 112 |
//@} |
113 | 113 |
|
114 |
+ AtracGCContext gainc_ctx; |
|
114 | 115 |
FFTContext mdct_ctx; |
115 | 116 |
FmtConvertContext fmt_conv; |
116 | 117 |
AVFloatDSPContext fdsp; |
... | ... |
@@ -417,18 +412,17 @@ static int decode_tonal_components(GetBitContext *gb, |
417 | 417 |
static int decode_gain_control(GetBitContext *gb, GainBlock *block, |
418 | 418 |
int num_bands) |
419 | 419 |
{ |
420 |
- int i, j, num_data; |
|
420 |
+ int i, j; |
|
421 | 421 |
int *level, *loc; |
422 | 422 |
|
423 |
- GainInfo *gain = block->g_block; |
|
423 |
+ AtracGainInfo *gain = block->g_block; |
|
424 | 424 |
|
425 | 425 |
for (i = 0; i <= num_bands; i++) { |
426 |
- num_data = get_bits(gb, 3); |
|
427 |
- gain[i].num_gain_data = num_data; |
|
426 |
+ gain[i].num_points = get_bits(gb, 3); |
|
428 | 427 |
level = gain[i].lev_code; |
429 | 428 |
loc = gain[i].loc_code; |
430 | 429 |
|
431 |
- for (j = 0; j < gain[i].num_gain_data; j++) { |
|
430 |
+ for (j = 0; j < gain[i].num_points; j++) { |
|
432 | 431 |
level[j] = get_bits(gb, 4); |
433 | 432 |
loc[j] = get_bits(gb, 5); |
434 | 433 |
if (j && loc[j] <= loc[j - 1]) |
... | ... |
@@ -438,69 +432,12 @@ static int decode_gain_control(GetBitContext *gb, GainBlock *block, |
438 | 438 |
|
439 | 439 |
/* Clear the unused blocks. */ |
440 | 440 |
for (; i < 4 ; i++) |
441 |
- gain[i].num_gain_data = 0; |
|
441 |
+ gain[i].num_points = 0; |
|
442 | 442 |
|
443 | 443 |
return 0; |
444 | 444 |
} |
445 | 445 |
|
446 | 446 |
/** |
447 |
- * Apply gain parameters and perform the MDCT overlapping part |
|
448 |
- * |
|
449 |
- * @param input input buffer |
|
450 |
- * @param prev previous buffer to perform overlap against |
|
451 |
- * @param output output buffer |
|
452 |
- * @param gain1 current band gain info |
|
453 |
- * @param gain2 next band gain info |
|
454 |
- */ |
|
455 |
-static void gain_compensate_and_overlap(float *input, float *prev, |
|
456 |
- float *output, GainInfo *gain1, |
|
457 |
- GainInfo *gain2) |
|
458 |
-{ |
|
459 |
- float g1, g2, gain_inc; |
|
460 |
- int i, j, num_data, start_loc, end_loc; |
|
461 |
- |
|
462 |
- |
|
463 |
- if (gain2->num_gain_data == 0) |
|
464 |
- g1 = 1.0; |
|
465 |
- else |
|
466 |
- g1 = gain_tab1[gain2->lev_code[0]]; |
|
467 |
- |
|
468 |
- if (gain1->num_gain_data == 0) { |
|
469 |
- for (i = 0; i < 256; i++) |
|
470 |
- output[i] = input[i] * g1 + prev[i]; |
|
471 |
- } else { |
|
472 |
- num_data = gain1->num_gain_data; |
|
473 |
- gain1->loc_code[num_data] = 32; |
|
474 |
- gain1->lev_code[num_data] = 4; |
|
475 |
- |
|
476 |
- for (i = 0, j = 0; i < num_data; i++) { |
|
477 |
- start_loc = gain1->loc_code[i] * 8; |
|
478 |
- end_loc = start_loc + 8; |
|
479 |
- |
|
480 |
- g2 = gain_tab1[gain1->lev_code[i]]; |
|
481 |
- gain_inc = gain_tab2[gain1->lev_code[i + 1] - |
|
482 |
- gain1->lev_code[i ] + 15]; |
|
483 |
- |
|
484 |
- /* interpolate */ |
|
485 |
- for (; j < start_loc; j++) |
|
486 |
- output[j] = (input[j] * g1 + prev[j]) * g2; |
|
487 |
- |
|
488 |
- /* interpolation is done over eight samples */ |
|
489 |
- for (; j < end_loc; j++) { |
|
490 |
- output[j] = (input[j] * g1 + prev[j]) * g2; |
|
491 |
- g2 *= gain_inc; |
|
492 |
- } |
|
493 |
- } |
|
494 |
- |
|
495 |
- for (; j < 256; j++) |
|
496 |
- output[j] = input[j] * g1 + prev[j]; |
|
497 |
- } |
|
498 |
- |
|
499 |
- /* Delay for the overlapping part. */ |
|
500 |
- memcpy(prev, &input[256], 256 * sizeof(*prev)); |
|
501 |
-} |
|
502 |
- |
|
503 |
-/** |
|
504 | 447 |
* Combine the tonal band spectrum and regular band spectrum |
505 | 448 |
* |
506 | 449 |
* @param spectrum output spectrum buffer |
... | ... |
@@ -690,11 +627,10 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, |
690 | 690 |
memset(snd->imdct_buf, 0, 512 * sizeof(*snd->imdct_buf)); |
691 | 691 |
|
692 | 692 |
/* gain compensation and overlapping */ |
693 |
- gain_compensate_and_overlap(snd->imdct_buf, |
|
694 |
- &snd->prev_frame[band * 256], |
|
695 |
- &output[band * 256], |
|
696 |
- &gain1->g_block[band], |
|
697 |
- &gain2->g_block[band]); |
|
693 |
+ ff_atrac_gain_compensation(&q->gainc_ctx, snd->imdct_buf, |
|
694 |
+ &snd->prev_frame[band * 256], |
|
695 |
+ &gain1->g_block[band], &gain2->g_block[band], |
|
696 |
+ 256, &output[band * 256]); |
|
698 | 697 |
} |
699 | 698 |
|
700 | 699 |
/* Swap the gain control buffers for the next frame. */ |
... | ... |
@@ -982,6 +918,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) |
982 | 982 |
q->matrix_coeff_index_next[i] = 3; |
983 | 983 |
} |
984 | 984 |
|
985 |
+ ff_atrac_init_gain_compensation(&q->gainc_ctx, 4, 3); |
|
985 | 986 |
avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); |
986 | 987 |
ff_fmt_convert_init(&q->fmt_conv, avctx); |
987 | 988 |
|