[FFmpeg-soc] [PATCH] AMR-WB Decoder
Rob
robert.swain at gmail.com
Mon Aug 30 15:00:44 CEST 2010
On 30 August 2010 14:31, Vitor Sessak <vitor1001 at gmail.com> wrote:
> On 08/27/2010 11:13 PM, Marcelo Galvão Póvoa wrote:
>> On 26 August 2010 18:55, Vitor Sessak<vitor1001 at gmail.com> wrote:
>>> Marcelo Galvão Póvoa wrote:
[...]
>>>> +/**
>>>> + * Generate the high-band excitation with the same energy from the
>>>> lower
>>>> + * one and scaled by the given gain
>>>> + *
>>>> + * @param[in] ctx The context
>>>> + * @param[out] hb_exc Buffer for the excitation
>>>> + * @param[in] synth_exc Low-band excitation used for
>>>> synthesis
>>>> + * @param[in] hb_gain Wanted excitation gain
>>>> + */
>>>> +static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc,
>>>> + const float *synth_exc, float hb_gain)
>>>> +{
>>>> + int i;
>>>> + float energy = ff_dot_productf(synth_exc, synth_exc,
>>>> AMRWB_SFR_SIZE);
>>>> +
>>>> + /* Generate a white-noise excitation */
>>>> + for (i = 0; i< AMRWB_SFR_SIZE_16k; i++)
>>>> + hb_exc[i] = 32768.0 - (uint16_t) av_lfg_get(&ctx->prng);
>>>> +
>>>> + ff_scale_vector_to_given_sum_of_squares(hb_exc, hb_exc, energy,
>>>> + AMRWB_SFR_SIZE_16k);
>>>> +
>>>> + for (i = 0; i< AMRWB_SFR_SIZE_16k; i++)
>>>> + hb_exc[i] *= hb_gain;
>>>> +}
>>>
>>> Why are you scaling it twice?
>>
>> The first scaling is to match the energy with the lower band part. The
>> second is the high_band gain itself. This can be done in only one loop
>> using ff_scale_vector_to_given_sum_of_squares() ?
>
> I think you will be obliged to duplicate a little of
> ff_scale_vector_to_given_sum_of_squares(), but it will make your code
> faster...
The point is to avoid iterating over the subframe to multiply by some
value twice by merging the two beforehand and then applying to the
vector. Looking at the code:
void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
float sum_of_squares, const int n)
{
int i;
float scalefactor = ff_dot_productf(in, in, n);
if (scalefactor)
scalefactor = sqrt(sum_of_squares / scalefactor);
for (i = 0; i < n; i++)
out[i] = in[i] * scalefactor;
}
We want:
scalefactor * hb_gain =
sqrt(sum_of_squares / ff_dot_productf(in, in, n)) * hb_gain =
sqrt(sum_of_squares * hb_gain * hb_gain / ff_dot_productf())
hb_gain is [0.1, 1.0] according to find_hb_gain() so there's no sign
issue
So you should just be able to pass in energy * hb_gain * hb_gain I
think. Or duplicate the code.
Best regards,
Rob
More information about the FFmpeg-soc
mailing list