aboutsummaryrefslogtreecommitdiff
path: root/libavcodec/atrac3plus.h
blob: a33c38a3ee21a374a61f9b63f7d403ef9c880660 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/*
 * ATRAC3+ compatible decoder
 *
 * Copyright (c) 2010-2013 Maxim Poliakovski
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Global structures, constants and data for ATRAC3+ decoder.
 */

#ifndef AVCODEC_ATRAC3PLUS_H
#define AVCODEC_ATRAC3PLUS_H

#include <stdint.h>

#include "libavutil/float_dsp.h"
#include "atrac.h"
#include "avcodec.h"
#include "fft.h"
#include "get_bits.h"

/** Global unit sizes */
#define ATRAC3P_SUBBANDS        16  ///< number of PQF subbands
#define ATRAC3P_SUBBAND_SAMPLES 128 ///< number of samples per subband
#define ATRAC3P_FRAME_SAMPLES   (ATRAC3P_SUBBAND_SAMPLES * ATRAC3P_SUBBANDS)

#define ATRAC3P_PQF_FIR_LEN     12  ///< length of the prototype FIR of the PQF

/** Global constants */
#define ATRAC3P_POWER_COMP_OFF  15  ///< disable power compensation

/** ATRAC3+ channel unit types */
enum Atrac3pChannelUnitTypes {
    CH_UNIT_MONO       = 0, ///< unit containing one coded channel
    CH_UNIT_STEREO     = 1, ///< unit containing two jointly-coded channels
    CH_UNIT_EXTENSION  = 2, ///< unit containing extension information
    CH_UNIT_TERMINATOR = 3  ///< unit sequence terminator
};

/** Per-channel IPQF history */
typedef struct Atrac3pIPQFChannelCtx {
    DECLARE_ALIGNED(32, float, buf1)[ATRAC3P_PQF_FIR_LEN * 2][8];
    DECLARE_ALIGNED(32, float, buf2)[ATRAC3P_PQF_FIR_LEN * 2][8];
    int pos;
} Atrac3pIPQFChannelCtx;

/** Amplitude envelope of a group of sine waves */
typedef struct Atrac3pWaveEnvelope {
    int has_start_point;    ///< indicates start point within the GHA window
    int has_stop_point;     ///< indicates stop point within the GHA window
    int start_pos;          ///< start position expressed in n*4 samples
    int stop_pos;           ///< stop  position expressed in n*4 samples
} Atrac3pWaveEnvelope;

/** Parameters of a group of sine waves */
typedef struct Atrac3pWavesData {
    Atrac3pWaveEnvelope pend_env;   ///< pending envelope from the previous frame
    Atrac3pWaveEnvelope curr_env;   ///< group envelope from the current frame
    int num_wavs;           ///< number of sine waves in the group
    int start_index;        ///< start index into global tones table for that subband
} Atrac3pWavesData;

/** Parameters of a single sine wave */
typedef struct Atrac3pWaveParam {
    int   freq_index;   ///< wave frequency index
    int   amp_sf;       ///< quantized amplitude scale factor
    int   amp_index;    ///< quantized amplitude index
    int   phase_index;  ///< quantized phase index
} Atrac3pWaveParam;

/** Sound channel parameters */
typedef struct Atrac3pChanParams {
    int ch_num;
    int num_coded_vals;         ///< number of transmitted quant unit values
    int fill_mode;
    int split_point;
    int table_type;             ///< table type: 0 - tone?, 1- noise?
    int qu_wordlen[32];         ///< array of word lengths for each quant unit
    int qu_sf_idx[32];          ///< array of scale factor indexes for each quant unit
    int qu_tab_idx[32];         ///< array of code table indexes for each quant unit
    int16_t spectrum[2048];     ///< decoded IMDCT spectrum
    uint8_t power_levs[5];      ///< power compensation levels

    /* imdct window shape history (2 frames) for overlapping. */
    uint8_t wnd_shape_hist[2][ATRAC3P_SUBBANDS];    ///< IMDCT window shape, 0=sine/1=steep
    uint8_t *wnd_shape;         ///< IMDCT window shape for current frame
    uint8_t *wnd_shape_prev;    ///< IMDCT window shape for previous frame

    /* gain control data history (2 frames) for overlapping. */
    AtracGainInfo gain_data_hist[2][ATRAC3P_SUBBANDS];  ///< gain control data for all subbands
    AtracGainInfo *gain_data;       ///< gain control data for next frame
    AtracGainInfo *gain_data_prev;  ///< gain control data for previous frame
    int num_gain_subbands;      ///< number of subbands with gain control data

    /* tones data history (2 frames) for overlapping. */
    Atrac3pWavesData tones_info_hist[2][ATRAC3P_SUBBANDS];
    Atrac3pWavesData *tones_info;
    Atrac3pWavesData *tones_info_prev;
} Atrac3pChanParams;

/* Per-unit sine wave parameters */
typedef struct Atrac3pWaveSynthParams {
    int tones_present;                      ///< 1 - tones info present
    int amplitude_mode;                     ///< 1 - low range, 0 - high range
    int num_tone_bands;                     ///< number of PQF bands with tones
    uint8_t tone_sharing[ATRAC3P_SUBBANDS]; ///< 1 - subband-wise tone sharing flags
    uint8_t tone_master[ATRAC3P_SUBBANDS];  ///< 1 - subband-wise tone channel swapping
    uint8_t invert_phase[ATRAC3P_SUBBANDS]; ///< 1 - subband-wise phase inversion
    int tones_index;                        ///< total sum of tones in this unit
    Atrac3pWaveParam waves[48];
} Atrac3pWaveSynthParams;

/** Channel unit parameters */
typedef struct Atrac3pChanUnitCtx {
    /* channel unit variables */
    int unit_type;                          ///< unit type (mono/stereo)
    int num_quant_units;
    int num_subbands;
    int used_quant_units;                   ///< number of quant units with coded spectrum
    int num_coded_subbands;                 ///< number of subbands with coded spectrum
    int mute_flag;                          ///< mute flag
    int use_full_table;                     ///< 1 - full table list, 0 - restricted one
    int noise_present;                      ///< 1 - global noise info present
    int noise_level_index;                  ///< global noise level index
    int noise_table_index;                  ///< global noise RNG table index
    uint8_t swap_channels[ATRAC3P_SUBBANDS];    ///< 1 - perform subband-wise channel swapping
    uint8_t negate_coeffs[ATRAC3P_SUBBANDS];    ///< 1 - subband-wise IMDCT coefficients negation
    Atrac3pChanParams channels[2];

    /* Variables related to GHA tones */
    Atrac3pWaveSynthParams wave_synth_hist[2];     ///< waves synth history for two frames
    Atrac3pWaveSynthParams *waves_info;
    Atrac3pWaveSynthParams *waves_info_prev;

    Atrac3pIPQFChannelCtx ipqf_ctx[2];
    DECLARE_ALIGNED(32, float, prev_buf)[2][ATRAC3P_FRAME_SAMPLES]; ///< overlapping buffer
} Atrac3pChanUnitCtx;

/**
 * Initialize VLC tables for bitstream parsing.
 */
void ff_atrac3p_init_vlcs(void);

/**
 * Decode bitstream data of a channel unit.
 *
 * @param[in]     gb            the GetBit context
 * @param[in,out] ctx           ptr to the channel unit context
 * @param[in]     num_channels  number of channels to process
 * @param[in]     avctx         ptr to the AVCodecContext
 * @return result code: 0 = OK, otherwise - error code
 */
int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx,
                                   int num_channels, AVCodecContext *avctx);

/**
 * Initialize IMDCT transform.
 *
 * @param[in]   avctx      ptr to the AVCodecContext
 * @param[in]   mdct_ctx   pointer to MDCT transform context
 */
void ff_atrac3p_init_imdct(AVCodecContext *avctx, FFTContext *mdct_ctx);

/**
 * Initialize sine waves synthesizer.
 */
void ff_atrac3p_init_wave_synth(void);

/**
 * Synthesize sine waves for a particular subband.
 *
 * @param[in]   ch_unit   pointer to the channel unit context
 * @param[in]   fdsp      pointer to float DSP context
 * @param[in]   ch_num    which channel to process
 * @param[in]   sb        which subband to process
 * @param[out]  out       receives processed data
 */
void ff_atrac3p_generate_tones(Atrac3pChanUnitCtx *ch_unit, AVFloatDSPContext *fdsp,
                               int ch_num, int sb, float *out);

/**
 * Perform power compensation aka noise dithering.
 *
 * @param[in]      ctx         ptr to the channel context
 * @param[in]      ch_index    which channel to process
 * @param[in,out]  sp          ptr to channel spectrum to process
 * @param[in]      rng_index   indicates which RNG table to use
 * @param[in]      sb_num      which subband to process
 */
void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, int ch_index,
                                   float *sp, int rng_index, int sb_num);

/**
 * Regular IMDCT and windowing without overlapping,
 * with spectrum reversal in the odd subbands.
 *
 * @param[in]   fdsp       pointer to float DSP context
 * @param[in]   mdct_ctx   pointer to MDCT transform context
 * @param[in]   pIn        float input
 * @param[out]  pOut       float output
 * @param[in]   wind_id    which MDCT window to apply
 * @param[in]   sb         subband number
 */
void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, FFTContext *mdct_ctx, float *pIn,
                      float *pOut, int wind_id, int sb);

/**
 * Subband synthesis filter based on the polyphase quadrature (pseudo-QMF)
 * filter bank.
 *
 * @param[in]      dct_ctx   ptr to the pre-initialized IDCT context
 * @param[in,out]  hist      ptr to the filter history
 * @param[in]      in        input data to process
 * @param[out]     out       receives processed data
 */
void ff_atrac3p_ipqf(FFTContext *dct_ctx, Atrac3pIPQFChannelCtx *hist,
                     const float *in, float *out);

extern const uint16_t ff_atrac3p_qu_to_spec_pos[33];
extern const float ff_atrac3p_sf_tab[64];
extern const float ff_atrac3p_mant_tab[8];

#endif /* AVCODEC_ATRAC3PLUS_H */