# volume change

Started by November 28, 2008
```Does anyone knows how to change the volume by changing the amplitute taken
from a 16bit audio stream.for now i have a byte array which is my sample.i
convert the byte array into an integer array.each element of the integer
array is the amplitude of my sound.then i multuply each element of the
integer array by 2 for example.the sound i get is full of noise.does enyone
know what the problem is?

```
```On nov. 28, 16:41, "christos" <sportline...@hotmail.com> wrote:
> Does anyone knows how to change the volume by changing the amplitute taken
> from a 16bit audio stream.for now i have a byte array which is my sample.i
> convert the byte array into an integer array.each element of the integer
> array is the amplitude of my sound.then i multuply each element of the
> integer array by 2 for example.the sound i get is full of noise.does enyone
> know what the problem is?

In general, you can not increase the volume of a digital audio stream
which consists of fixed-point samples. Multiplying by 2 (i.e., left
shift operation) will most likely result in an overflow. Multiplying
by a number less than 1 should yield correct results (decreased
volume) but it causes loss of precision (the waveform of the same
shape is stored using fewer bits).

Zs
```
```"christos" <sportlineman@hotmail.com> writes:

> Does anyone knows how to change the volume by changing the amplitute taken
> from a 16bit audio stream.for now i have a byte array which is my sample.i
> convert the byte array into an integer array.each element of the integer
> array is the amplitude of my sound.then i multuply each element of the
> integer array by 2 for example.the sound i get is full of noise.does enyone
> know what the problem is?

Hi christos,

You're probably overflowing, which for two's complement integer
arithmetic produces very nasty artifacts.

There are several ways to skin this cat. By far the easiest is to
convert the integer samples into floats, specify your gain coefficient
as a float, and then just multiply the floating-point input data by the
floating-point gain coefficient, producing floating-point output data.

Two problems then arise when you need to convert the resulting floats
back into integers: 1) you must limit the output to a maximum of +32767
(assuming signed, two's complement 16-bit integers) and a minimum of
-32768, and 2) you must "requantize".

The easy way to requantize is just somthing like

int y;
float x;

y = (int)x;

That will probably sound fine as long as you don't care about the sound
quality too much and the gain factor isn't very small (<<1).

Otherwise you'll probably want to dither with noise too, and depending
on the compiler you may want to make sure you round properly. Write
back if you need more input.

PS: Performing a "simple" gain operation is surprisingly difficult to do
well.
--
%  Randy Yates                  % "She has an IQ of 1001, she has a jumpsuit
%% Fuquay-Varina, NC            %            on, and she's also a telephone."
%%% 919-577-9882                %
%%%% <yates@ieee.org>           %        'Yours Truly, 2095', *Time*, ELO
http://www.digitalsignallabs.com
```
```> Does anyone knows how to change the volume by changing the amplitute taken
> from a 16bit audio stream.for now i have a byte array which is my sample.i
> convert the byte array into an integer array.each element of the integer
> array is the amplitude of my sound.then i multuply each element of the
> integer array by 2 for example.the sound i get is full of noise.does
> enyone
> know what the problem is?

You're probably simply going over the 16 bit limits, as already said.
If you're converting your array into 32 bit integers, then you can do volume
changes quickly by something like:
a = (a * v) >> 8
If 'v' is 256 then 'a' would remain the same, and if 'v' is 192 then 'a'
would be 3/4 of its volume.
You can of course use larger fractions for greater accuracy.
Look up 'fixed point arithmetic' for more help.

V.

```
```On Nov 28, 12:13&#2013266080;pm, Randy Yates <ya...@ieee.org> wrote:
> "christos" <sportline...@hotmail.com> writes:
> > Does anyone knows how to change the volume by changing the amplitute taken
> > from a 16bit audio stream.for now i have a byte array which is my sample.i
> > convert the byte array into an integer array.each element of the integer
> > array is the amplitude of my sound.then i multuply each element of the
> > integer array by 2 for example.the sound i get is full of noise.does enyone
> > know what the problem is?
>
> Hi christos,
>
> You're probably overflowing, which for two's complement integer
> arithmetic produces very nasty artifacts.
>
> There are several ways to skin this cat. By far the easiest is to
> convert the integer samples into floats, specify your gain coefficient
> as a float, and then just multiply the floating-point input data by the
> floating-point gain coefficient, producing floating-point output data.
>
> Two problems then arise when you need to convert the resulting floats
> back into integers: 1) you must limit the output to a maximum of +32767
> (assuming signed, two's complement 16-bit integers) and a minimum of
> -32768, and 2) you must "requantize".
>
> The easy way to requantize is just somthing like
>
> int y;
> float x;
>
> y = (int)x;
>
> That will probably sound fine as long as you don't care about the sound
> quality too much and the gain factor isn't very small (<<1).
>
> Otherwise you'll probably want to dither with noise too, and depending
> on the compiler you may want to make sure you round properly. Write
> back if you need more input.
>
> PS: Performing a "simple" gain operation is surprisingly difficult to do
> well.
> --
> % &#2013266080;Randy Yates &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080;% "She has an IQ of 1001, she has a jumpsuit
> %% Fuquay-Varina, NC &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080;% &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080;on, and she's also a telephone."
> %%% 919-577-9882 &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080;%
> %%%% <ya...@ieee.org> &#2013266080; &#2013266080; &#2013266080; &#2013266080; &#2013266080; % &#2013266080; &#2013266080; &#2013266080; &#2013266080;'Yours Truly, 2095', *Time*, ELO &#2013266080;http://www.digitalsignallabs.com

In assembly language, samples can be increased up to 6 dB with
saturation using a signed x unsigned multiply where the unsigned
argument is > 0x7FFF. This is easy using the AD21XX family. For > 6
dB, break it up into more than one multiply, saturating every time.
Another tip is to use a "soft limiter" nonlinearity that is linear
through zero but changes to a flatter slope above and below a defined
threshold.

John
```