|
|
|
@ -54,14 +54,8 @@ |
|
|
|
|
#define SAMPLES_PER_FRAME 1024 |
|
|
|
|
#define MDCT_SIZE 512 |
|
|
|
|
|
|
|
|
|
typedef struct GainInfo { |
|
|
|
|
int num_gain_data; |
|
|
|
|
int lev_code[8]; |
|
|
|
|
int loc_code[8]; |
|
|
|
|
} GainInfo; |
|
|
|
|
|
|
|
|
|
typedef struct GainBlock { |
|
|
|
|
GainInfo g_block[4]; |
|
|
|
|
AtracGainInfo g_block[4]; |
|
|
|
|
} GainBlock; |
|
|
|
|
|
|
|
|
|
typedef struct TonalComponent { |
|
|
|
@ -111,6 +105,7 @@ typedef struct ATRAC3Context { |
|
|
|
|
int scrambled_stream; |
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
AtracGCContext gainc_ctx; |
|
|
|
|
FFTContext mdct_ctx; |
|
|
|
|
FmtConvertContext fmt_conv; |
|
|
|
|
AVFloatDSPContext fdsp; |
|
|
|
@ -417,18 +412,17 @@ static int decode_tonal_components(GetBitContext *gb, |
|
|
|
|
static int decode_gain_control(GetBitContext *gb, GainBlock *block, |
|
|
|
|
int num_bands) |
|
|
|
|
{ |
|
|
|
|
int i, j, num_data; |
|
|
|
|
int i, j; |
|
|
|
|
int *level, *loc; |
|
|
|
|
|
|
|
|
|
GainInfo *gain = block->g_block; |
|
|
|
|
AtracGainInfo *gain = block->g_block; |
|
|
|
|
|
|
|
|
|
for (i = 0; i <= num_bands; i++) { |
|
|
|
|
num_data = get_bits(gb, 3); |
|
|
|
|
gain[i].num_gain_data = num_data; |
|
|
|
|
gain[i].num_points = get_bits(gb, 3); |
|
|
|
|
level = gain[i].lev_code; |
|
|
|
|
loc = gain[i].loc_code; |
|
|
|
|
|
|
|
|
|
for (j = 0; j < gain[i].num_gain_data; j++) { |
|
|
|
|
for (j = 0; j < gain[i].num_points; j++) { |
|
|
|
|
level[j] = get_bits(gb, 4); |
|
|
|
|
loc[j] = get_bits(gb, 5); |
|
|
|
|
if (j && loc[j] <= loc[j - 1]) |
|
|
|
@ -438,68 +432,11 @@ static int decode_gain_control(GetBitContext *gb, GainBlock *block, |
|
|
|
|
|
|
|
|
|
/* Clear the unused blocks. */ |
|
|
|
|
for (; i < 4 ; i++) |
|
|
|
|
gain[i].num_gain_data = 0; |
|
|
|
|
gain[i].num_points = 0; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Apply gain parameters and perform the MDCT overlapping part |
|
|
|
|
* |
|
|
|
|
* @param input input buffer |
|
|
|
|
* @param prev previous buffer to perform overlap against |
|
|
|
|
* @param output output buffer |
|
|
|
|
* @param gain1 current band gain info |
|
|
|
|
* @param gain2 next band gain info |
|
|
|
|
*/ |
|
|
|
|
static void gain_compensate_and_overlap(float *input, float *prev, |
|
|
|
|
float *output, GainInfo *gain1, |
|
|
|
|
GainInfo *gain2) |
|
|
|
|
{ |
|
|
|
|
float g1, g2, gain_inc; |
|
|
|
|
int i, j, num_data, start_loc, end_loc; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (gain2->num_gain_data == 0) |
|
|
|
|
g1 = 1.0; |
|
|
|
|
else |
|
|
|
|
g1 = gain_tab1[gain2->lev_code[0]]; |
|
|
|
|
|
|
|
|
|
if (gain1->num_gain_data == 0) { |
|
|
|
|
for (i = 0; i < 256; i++) |
|
|
|
|
output[i] = input[i] * g1 + prev[i]; |
|
|
|
|
} else { |
|
|
|
|
num_data = gain1->num_gain_data; |
|
|
|
|
gain1->loc_code[num_data] = 32; |
|
|
|
|
gain1->lev_code[num_data] = 4; |
|
|
|
|
|
|
|
|
|
for (i = 0, j = 0; i < num_data; i++) { |
|
|
|
|
start_loc = gain1->loc_code[i] * 8; |
|
|
|
|
end_loc = start_loc + 8; |
|
|
|
|
|
|
|
|
|
g2 = gain_tab1[gain1->lev_code[i]]; |
|
|
|
|
gain_inc = gain_tab2[gain1->lev_code[i + 1] - |
|
|
|
|
gain1->lev_code[i ] + 15]; |
|
|
|
|
|
|
|
|
|
/* interpolate */ |
|
|
|
|
for (; j < start_loc; j++) |
|
|
|
|
output[j] = (input[j] * g1 + prev[j]) * g2; |
|
|
|
|
|
|
|
|
|
/* interpolation is done over eight samples */ |
|
|
|
|
for (; j < end_loc; j++) { |
|
|
|
|
output[j] = (input[j] * g1 + prev[j]) * g2; |
|
|
|
|
g2 *= gain_inc; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (; j < 256; j++) |
|
|
|
|
output[j] = input[j] * g1 + prev[j]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Delay for the overlapping part. */ |
|
|
|
|
memcpy(prev, &input[256], 256 * sizeof(*prev)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Combine the tonal band spectrum and regular band spectrum |
|
|
|
|
* |
|
|
|
@ -690,11 +627,10 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, |
|
|
|
|
memset(snd->imdct_buf, 0, 512 * sizeof(*snd->imdct_buf)); |
|
|
|
|
|
|
|
|
|
/* gain compensation and overlapping */ |
|
|
|
|
gain_compensate_and_overlap(snd->imdct_buf, |
|
|
|
|
ff_atrac_gain_compensation(&q->gainc_ctx, snd->imdct_buf, |
|
|
|
|
&snd->prev_frame[band * 256], |
|
|
|
|
&output[band * 256], |
|
|
|
|
&gain1->g_block[band], |
|
|
|
|
&gain2->g_block[band]); |
|
|
|
|
&gain1->g_block[band], &gain2->g_block[band], |
|
|
|
|
256, &output[band * 256]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Swap the gain control buffers for the next frame. */ |
|
|
|
@ -982,6 +918,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) |
|
|
|
|
q->matrix_coeff_index_next[i] = 3; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ff_atrac_init_gain_compensation(&q->gainc_ctx, 4, 3); |
|
|
|
|
avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); |
|
|
|
|
ff_fmt_convert_init(&q->fmt_conv, avctx); |
|
|
|
|
|
|
|
|
|