[FFmpeg-devel] [PATCH] QCELP decoder
Vitor Sessak
vitor1001
Tue Dec 2 17:52:27 CET 2008
Michael Niedermayer wrote:
> On Mon, Dec 01, 2008 at 03:15:40PM -0800, Kenan Gillet wrote:
>> 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,
Commited the last remaining parts. The following chunk
> + st->codec->frame_size= 160;
> st->codec->channels= 1; /* really needed */
> + break;
>
was never ok'ed but I considered it harmless enough.
-Vitor
PS @Kenan: missing patch to
svn://svn.ffmpeg.org/ffmpeg.org/trunk/src/index =)
More information about the ffmpeg-devel
mailing list