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?

# volume change

Started by ●November 28, 2008

Reply by ●November 28, 20082008-11-28

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

Reply by ●November 28, 20082008-11-28

"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

Reply by ●November 29, 20082008-11-29

> 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.

Reply by ●November 29, 20082008-11-29

On Nov 28, 12:13�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. > -- > % �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 � � � � � � � �% > %%%% <ya...@ieee.org> � � � � � % � � � �'Yours Truly, 2095', *Time*, ELO �http://www.digitalsignallabs.comIn 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