# [FFmpeg-devel] [PATCH] WMA Voice decoder

Ronald S. Bultje rsbultje
Thu Jan 21 19:01:16 CET 2010

```Hi,

On Wed, Jan 20, 2010 at 7:53 PM, Michael Niedermayer <michaelni at gmx.at> wrote:
> On Wed, Jan 20, 2010 at 04:56:25PM -0500, Ronald S. Bultje wrote:
>> +static int pRNG(int frame_cntr, int block_num, int block_size)
>> +{
>
>> + ? ?int x = (block_num * 1877 + frame_cntr) % 0xFFFF;
>
> can this be >= 2 * 0xFFFF ?
> if not
> int x = block_num * 1877 + frame_cntr;
> if(x>=0xFFFF) x-=0xFFFF could be used

Max value is 0x13AA6, so changed (locally).

> modulo is slow and i assume this silly function must be like that exactly

For now... Once this is committed, I want to see if I can use LFG or
something and see if the different output is quality-wise comparable
(i.e. don't look at stddev, which will of course change, but look at
audible quality and see what happens).

>> + ? ?int y = (x % 9) * 5 + 6;
>
> you can probably multiply x by some constant and >> (see FAST_DIV also)
> to find x/9 and x - x/9*9 = x%9

Using FASTDIV appears to give identical output, so changed also. Or
did you mean you always want me to use the multiply/shift, even
without CONFIG_FASTDIV?

>> + ? ?int z = (uint16_t) (x * 49995 / y);
>
> I wonder if the 9 possible values for y could with a table ?9 entries
> and multiply + >> be used to simplify this

So x%9=[0,8], so y is then 6, 11, 16, 21, ..., 46. Since 49995 uses 16
bits and x itself is 16 bits also, we'd either have to guarantee that
x*49995/y == x*(49995/y), which I think is not possible I think, or
use 64 bits. Couldn't I just use FASTDIV here also? I suppose a more
optimal solution would be:

static const uint32_t tbl = {
(49995U << 16) / 6,
(49996U << 16) / 11,
[etc]
};
x = ..;
z = (uint16_t) MULL(x, tbl[x - FASTDIV(x, 9) / 9], 16);

? (I use 16 and not 32 because otherwise tbl itself would need to be
64 bit also, which is silly.) should I use MULL()? Is there a faster
way to multiply 2 32 bit ints and have them become 64?

Note that with this implementation, stddev changes by 0.01-0.07
depending on which sample I test with, so it's not ideal... The weird
thing is that that happens even when I use 32 instead of 16 (64-bit
table) and then directly using ((uint64)x * tbl[..]) >> 32, so maybe
my code is buggy?

>> +static const uint8_t ff_wmavoice_dq_lsp16r2[0x500] = {
>> + ? ? 98, ?98, 119, 121, 109, 112, 128, 135, 115, 121,
[..]
> If you want to reuduce the size of these tables, i suspect it
> might be possible, first convert them to deltas that is
> new_table= oldtable[i] - oldtable[i-1]
> then store using a wisely choosen vlc code
> That might or might not be a good idea but as someone seemed
> to dislike their size this might be able to cut them in half

Uh, I have no idea how to do that, can I do that after committing? :-).

Ronald

```