[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