[FFmpeg-soc] [PATCH] AMR-WB Decoder

Marcelo Galvão Póvoa marspeoplester at gmail.com
Sat Sep 11 16:47:40 CEST 2010


On 9 September 2010 16:11, Vitor Sessak <vitor1001 at gmail.com> wrote:
> On 09/07/2010 02:05 AM, Marcelo Galvão Póvoa wrote:
>>
>> On 6 September 2010 11:31, Vitor Sessak<vitor1001 at gmail.com>  wrote:
>>>
>>> On 09/06/2010 02:46 AM, Marcelo Galvăo Póvoa wrote:
>>>>
[...]
>>>> +
>>>> +/**
>>>> + * Find the pitch vector by interpolating the past excitation at the
>>>> + * pitch delay, which is obtained in this function
>>>> + *
>>>> + * @param[in,out] ctx              The context
>>>> + * @param[in] amr_subframe         Current subframe data
>>>> + * @param[in] subframe             Current subframe index (0 to 3)
>>>> + */
>>>> +static void decode_pitch_vector(AMRWBContext *ctx,
>>>> +                                const AMRWBSubFrame *amr_subframe,
>>>> +                                const int subframe)
>>>> +{
>>>> +    int pitch_lag_int, pitch_lag_frac;
>>>> +    int i;
>>>> +    float *exc     = ctx->excitation;
>>>> +    enum Mode mode = ctx->fr_cur_mode;
>>>> +
>>>> +    if (mode<= MODE_8k85) {
>>>> +        decode_pitch_lag_low(&pitch_lag_int,&pitch_lag_frac,
>>>> amr_subframe->adap,
>>>> +&ctx->base_pitch_lag, subframe, mode);
>>>> +    } else
>>>> +        decode_pitch_lag_high(&pitch_lag_int,&pitch_lag_frac,
>>>> amr_subframe->adap,
>>>> +&ctx->base_pitch_lag, subframe);
>>>> +
>>>> +    ctx->pitch_lag_int = pitch_lag_int;
>>>>
>>>
>>>> +    pitch_lag_int     += (pitch_lag_frac<    0 ? -1 : 0) +
>>>> (pitch_lag_frac ? 1 : 0);
>>>>
>>>
>>> pitch_lag_int     += pitch_lag_frac ? FFSIGN(pitch_lag_frac) : 0;
>>>
>>
>> I don't see if I understand this correctly, see my "truth table" below:
>> pitch_lag_frac | mine_RHS | your_RHS
>> <0 | 0 | -1
>> =0 | 0 | 0
>>>
>>> 0 | 1 | 1
>>
>> So, the simplified form would be this?
>>
>> pitch_lag_int += pitch_lag_frac>  0 ? 1 : 0;
>
> or, as Michael suggested
>
> pitch_lag_int += pitch_lag_frac > 0;
>

Fixed and removed "? 1 : 0" everywhere.

>>>> +/**
>>>> + * Reduce fixed vector sparseness by smoothing with one of three IR
>>>> filters
>>>> + * Also known as "adaptive phase dispersion"
>>>> + *
>>>> + * @param[in] ctx                  The context
>>>> + * @param[in,out] fixed_vector     Unfiltered fixed vector
>>>> + * @param[out] buf                 Space for modified vector if
>>>> necessary
>>>> + *
>>>> + * @return The potentially overwritten filtered fixed vector address
>>>> + */
>>>> +static float *anti_sparseness(AMRWBContext *ctx,
>>>> +                              float *fixed_vector, float *buf)
>>>> +{
>>>> +    int ir_filter_nr;
>>>> +
>>>> +    if (ctx->fr_cur_mode>    MODE_8k85) // no filtering in higher modes
>>>> +        return fixed_vector;
>>>> +
>>>> +    if (ctx->pitch_gain[0]<    0.6) {
>>>> +        ir_filter_nr = 0;      // strong filtering
>>>> +    } else if (ctx->pitch_gain[0]<    0.9) {
>>>> +        ir_filter_nr = 1;      // medium filtering
>>>> +    } else
>>>> +        ir_filter_nr = 2;      // no filtering
>>>> +
>>>> +    /* detect 'onset' */
>>>> +    if (ctx->fixed_gain[0]>    3.0 * ctx->fixed_gain[1]) {
>>>> +        if (ir_filter_nr<    2)
>>>> +            ir_filter_nr++;
>>>> +    } else {
>>>> +        int i, count = 0;
>>>> +
>>>> +        for (i = 0; i<    6; i++)
>>>> +            if (ctx->pitch_gain[i]<    0.6)
>>>> +                count++;
>>>> +
>>>> +        if (count>    2)
>>>> +            ir_filter_nr = 0;
>>>> +
>>>> +        if (ir_filter_nr>    ctx->prev_ir_filter_nr + 1)
>>>> +            ir_filter_nr--;
>>>> +    }
>>>> +
>>>> +    /* update ir filter strength history */
>>>> +    ctx->prev_ir_filter_nr = ir_filter_nr;
>>>> +
>>>> +    ir_filter_nr += (ctx->fr_cur_mode == MODE_8k85 ? 1 : 0);
>>>> +
>>>> +    if (ir_filter_nr<    2) {
>>>> +        int i, j;
>>>> +        const float *coef = ir_filters_lookup[ir_filter_nr];
>>>> +
>>>> +        /* Circular convolution code in the reference
>>>> +         * decoder was modified to avoid using one
>>>> +         * extra array. The filtered vector is given by:
>>>> +         *
>>>> +         * c2(n) = sum(i,0,len-1){ c(i) * coef( (n - i + len) % len ) }
>>>> +         */
>>>> +
>>>> +        memset(buf, 0, sizeof(float) * AMRWB_SFR_SIZE);
>>>> +        for (i = 0; i<    AMRWB_SFR_SIZE; i++)
>>>
>>>> +            if (fixed_vector[i]) {
>>>> +                int li = AMRWB_SFR_SIZE - i;
>>>> +
>>>> +                for (j = 0; j<    li; j++)
>>>> +                    buf[i + j] += fixed_vector[i] * coef[j];
>>>> +
>>>> +                for (j = 0; j<    i; j++)
>>>> +                    buf[j] += fixed_vector[i] * coef[j + li];
>>>> +            }
>>>
>>> Can celp_filters.c:ff_celp_circ_addf() simplify this?
>>>
>>
>> I already gave some thought to that but I couldn't figure out how to
>> use ff_celp_circ_addf() there. I wrote the algorithm the simplest way
>> I could think of.
>
> Try
>
>        for (i = 0; i < AMRWB_SFR_SIZE; i++)
>            if (fixed_vector[i])
>                ff_celp_circ_addf(buf, buf, coef, i, fixed_vector[i],
>                                  AMRWB_SFR_SIZE);
>
>

That's right indeed, thanks!

[...]

-- 
Marcelo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: amrwb.patch
Type: application/octet-stream
Size: 152592 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-soc/attachments/20100911/2a0d374a/attachment.obj>


More information about the FFmpeg-soc mailing list