[FFmpeg-devel] [PATCH] QCELP decoder

Kenan Gillet kenan.gillet
Tue Dec 2 00:15:40 CET 2008


Hi,

On Mon, Dec 1, 2008 at 1:39 PM, Michael Niedermayer <michaelni at gmx.at> wrote:
> On Mon, Dec 01, 2008 at 12:45:09PM -0800, Kenan Gillet wrote:
>> Hi,
>> On Mon, Dec 1, 2008 at 8:24 AM, Michael Niedermayer <michaelni at gmx.at> wrote:

[...]


>> Index: libavcodec/qcelpdec.c
>> ===================================================================
>> --- libavcodec/qcelpdec.c     (revision 15972)
>> +++ libavcodec/qcelpdec.c     (working copy)

[...]


>> @@ -476,6 +495,64 @@
>>  }
>>
>>  /**
>> + * Apply pitch synthesis filter and pitch prefilter to the scaled codebook vector.
>> + * TIA/EIA/IS-733 2.4.5.2
>> + *
>> + * @param q the context
>> + * @param cdn_vector the scaled codebook vector
>> + */
>> +static void apply_pitch_filters(QCELPContext *q,
>> +                                float *cdn_vector) {
>> +    int         i;
>> +    float       gain[4];
>> +    const float *v_synthesis_filtered, *v_pre_filtered;
>> +
>> +    if (q->bitrate >= RATE_HALF ||
>> +       (q->bitrate == I_F_Q && (q->prev_bitrate >= RATE_HALF))) {
>> +
>> +        if (q->bitrate >= RATE_HALF) {
>> +
>> +            // Compute gain & lag for the whole frame.
>> +            for (i = 0; i < 4; i++) {
>> +                gain[i] = q->frame.plag[i] ? (q->frame.pgain[i] + 1) * 0.25 : 0.0;
>> +
>> +                q->frame.plag[i] += 16;
>> +            }
>> +            memcpy(q->prev_pitch_lag, q->frame.plag, sizeof(q->frame.plag));
>> +        } else {
>> +            gain[3] = q->erasure_count < 3 ? 0.9 - 0.3 * (q->erasure_count - 1)
>> +                                           : 0.0;
>> +            for (i = 0; i < 4; i++)
>> +                gain[i] = FFMIN(q->prev_pitch_gain[i], gain[3]);
>> +
>> +            memset(q->frame.pfrac, 0, sizeof(q->frame.pfrac));
>
>> +            memcpy(q->frame.plag, q->prev_pitch_lag, sizeof(q->frame.plag));
>
> i think if prev_pitch_lag was used in the surrounding code then this memcpy
> would be unneeded

done, and var renamed to pitch_lag


>> +        }
>> +
>> +        // pitch synthesis filter
>> +        v_synthesis_filtered = do_pitchfilter(q->pitch_synthesis_filter_mem, cdn_vector,
>> +                                              gain, q->frame.plag, q->frame.pfrac);
>> +
>> +        // pitch prefilter update
>> +        for (i = 0; i < 4; i++)
>> +            gain[i] = 0.5 * FFMIN(gain[i], 1.0);
>> +
>> +        v_pre_filtered = do_pitchfilter(q->pitch_pre_filter_mem, v_synthesis_filtered,
>> +                                        gain, q->frame.plag, q->frame.pfrac);
>> +
>> +        apply_gain_ctrl(cdn_vector, v_synthesis_filtered, v_pre_filtered);
>> +
>
>> +        memcpy(q->prev_pitch_gain, gain, sizeof(q->prev_pitch_gain));
>
> cant prev_pitch_gain be directly used instead of gain that then is copied
> back?
> (possibly with a better var name than prev_pitch_gain)

done, and var renamed to pitch_gain


>
>
>> +
>> +    } else {
>> +        memcpy(q->pitch_synthesis_filter_mem, cdn_vector + 17, 143 * sizeof(float));
>> +        memcpy(q->pitch_pre_filter_mem,       cdn_vector + 17, 143 * sizeof(float));
>> +        memset(q->prev_pitch_gain, 0, sizeof(q->prev_pitch_gain));
>> +        memset(q->prev_pitch_lag,  0, sizeof(q->prev_pitch_lag));
>> +    }
>> +}
>> +
>> +/**
>>   * Interpolates LSP frequencies and computes LPC coefficients
>>   * for a given bitrate & pitch subframe.
>>   *
>

[...]


>
> [...]
>> Index: libavformat/mov.c
>> ===================================================================
>> --- libavformat/mov.c (revision 15972)
>> +++ libavformat/mov.c (working copy)
>> @@ -988,6 +988,10 @@
>>  #endif
>>      /* no ifdef since parameters are always those */
>>      case CODEC_ID_QCELP:
>> +        st->need_parsing = AVSTREAM_PARSE_FULL;
>> +        st->codec->frame_size= 160;
>
>
>> +        st->codec->channels= 1; /* really needed */
>
> if this is really needed then its ok

when removed, some samples wav output changes,
plus QCELP only handles mono.

>
>
>> +        break;
>>      case CODEC_ID_AMR_NB:
>>      case CODEC_ID_AMR_WB:
>>          st->codec->frame_size= sc->samples_per_frame;
> [...]
>

round 15 attached.

note: there is a small update to the glue code in libavformat/mov.c
so I repost the doc-glue patch for this particular round but it has not
changed otherwise.

thanks for all your help,

Kenan
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qcelp-round15-decoder.patch.txt
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20081201/fc370848/attachment.txt>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qcelp-round15-doc-glue.patch.txt
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20081201/fc370848/attachment-0001.txt>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qcelp-round15-lsp.patch.txt
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20081201/fc370848/attachment-0002.txt>



More information about the ffmpeg-devel mailing list