[FFmpeg-devel] [PATCH] QCELP decoder

Kenan Gillet kenan.gillet
Wed Nov 12 23:22:40 CET 2008


On Nov 12, 2008, at 11:57 AM, Michael Niedermayer wrote:

> On Wed, Nov 12, 2008 at 09:05:02AM -0800, Kenan Gillet wrote:
>>
>> On Nov 11, 2008, at 10:00 AM, Michael Niedermayer wrote:
>>
>>> On Sun, Nov 09, 2008 at 09:49:20PM -0800, Kenan Gillet wrote:
> [...]
>>>> +        const float *predictors = (q->prev_framerate !=
>>>> RATE_OCTAVE ||
>>>> +                                   q->prev_framerate != I_F_Q ? q-
>>>>> prev_lspf
>>>> +                                                              : q-
>>>>> predictor_lspf);
>>>
>>> hmmmmmmm
>>> hmm
>>>
>>> Which value is not unequal to either RATE_OCTAVE or I_F_Q ?
>>
>> q->prev_framerate : framerate of the previous frame
>> q->framerate: framerate of the current frame
>> :)
>
> there is no q->framerate in there :)
>
>
>>
>>
>> The predictor changes based on the rate of the previous frame.
>>
>>
>>>
>>>
>>> Are you testing the code in each patch iteration?
>>
>> I do check the output to wav of all the test files I have for every
>> commit in my svn.
>
> great, now i feel better, this is a good strategy
>
> [...]
>>>> +        break;
>>>> +    case RATE_OCTAVE:
>>>> +        cbseed = q->first16bits;
>>>> +        for (i = 0; i < 8; i++) {
>>>> +            tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0);
>>>> +            for (j = 0; j < 20; j++) {
>>>> +                cbseed = 521 * cbseed + 259;
>>>> +                *cdn_vector++ = tmp_gain * (int16_t)cbseed;
>>>> +            }
>>>> +        }
>>>> +        break;
>>>> +    case I_F_Q:
>>>> +        cbseed = -44; // random codebook index
>>>> +        for (i = 0; i < 4; i++) {
>>>> +            tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
>>>> +            for (j = 0; j < 40; j++)
>>>> +                *cdn_vector++ = tmp_gain *
>>>> qcelp_rate_full_codebook[cbseed++ & 127];
>>>> +        }
>>>> +        break;
>>>> +    }
>>>> +}
>>>> +
>>>
>>>> +/**
>>>> + * Apply generic gain control.
>>>> + *
>>>> + * @param v_out output vector
>>>> + * @param v_in gain-controlled vector
>>>> + * @param v_ref vector to control gain of
>>>> + *
>>>> + * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6
>>>> + */
>>>> +static void apply_gain_ctrl(float *v_out,
>>>> +                            const float *v_ref,
>>>> +                            const float *v_in) {
>>>> +    int   i, j, len;
>>>> +    float scalefactor;
>>>> +
>>>> +    for (i = 0, j = 0; i < 4; i++) {
>>>> +        scalefactor = ff_dot_productf(v_in + j, v_in + j, 40);
>>>
>>>> +        if (scalefactor) {
>>>> +            scalefactor = sqrt(ff_dot_productf(v_ref + j, v_ref +
>>>> j, 40) / scalefactor);
>>>> +            for (len = j + 40; j < len; j++)
>>>> +                v_out[j] = scalefactor * v_in[j];
>>>> +        } else {
>>>> +            memset(v_out + j, 0,  40 * sizeof(float));
>>>> +            j += 40;
>>>> +        }
>>>
>>> assuming this is correct
>>
>> it is undefined in the specs and the reference code is setting
>> scalefactor
>>  only if both dot product are not zero but sill assign
>> v_out[j] = v_in[j] * scalefactor
>>  with the unassigned scalefactor :(
>
> interresting, i guess then a  if() av_log_missing_feature() would be
> a good idea, so we will get a sample that triggers this

 From my investigation, an initial SILENCE frame could trigger it,
and on this particular case, v_in & v_out would be 0 vectors. I don't
think another case could trigger it but i have not investigate enough
to be sure, maybe a very long succession of SILENCE might trigger it
too.

I am not sure that carrying the AVCodecContext into this function to add
an av_log_missing_feature would be worth it.

But again it is up to you and Reynaldo.

Kenan






More information about the ffmpeg-devel mailing list