views:

184

answers:

2

I'm new to DSP programming, and I'm wondering how best to carry out the seemingly basic operation of level adujustment. Say I have an 8 bit number that represents the amplitude I want a signal to be in 256 steps. I have a set of 16 bit numbers representing the signal data. What's the best way to go about scaling the signal data based on the "volume" parameter so that say 0 is complete attenuation, and 255 leaves the data unchanged?

+1  A: 

How about

out_sample = in_sample * volume / 255;

A straight linear rescaling. This assumes that the computation can be done using higher precision, to capture the result of the multiplication without truncation.

unwind
+4  A: 

What unwind said:

out_sample = in_sample * volume / 255;

If you're working on a real DSP chip or hardware without fast dividers you can use this trick to get the same values without division:

int product = in_sample * volume;
out_sample = (product + (product>>8) + 1)>>8;

On a modern DSP like the C64x+ this code runs about 10 times faster...

Also:

You're talking about volume, and you currently apply a 8 bit volume as a linear gain factor. However, our ears interpret volume as a logarithmic effect. You may want to do a conversion from db (your 8 bits) to linear gain prior to the multiplication. Precalculate them and put them into a table. While you're doing this you can also raise the scale of the value to 2^15 for more precision.

That'll give you a much nicer response and much less clicks of you do volume-fades.

Nils Pipenbrinck