OpenAL convert to mono on the fly?

Started by
17 comments, last by Aressera 12 years, 10 months ago

[quote name='Jansic' timestamp='1309859506' post='4831278']
[quote name='King Joffrey' timestamp='1309859311' post='4831277']
Summing L and R is a simple L + R. The division by 2 is erroneous as it implies that it will gain compensate the output by halving the amplitude, which it wont (for reasons I posted above).


Which is exactly right, though you probably want something that preserves the channel difference too. However, this wasn't a question of halving the volume or making a signal with the correct gain; just one of reducing a stereo stream into a mono one within the bounds of the storage - for which it's a reasonable quick-fix.

Jans.
[/quote]

Ah, I see. Well, assuming that the L and R channels are below 0dbFS then attenuating the summed mono signal by 6dB will ensure the mono signal is below 0dBFS.

@Steve: I had to google this as it's been a long, long time since I dabbled with DSP but this pseudo-code looks about right:

[source]gain = 10 ^ (attenuation_ in_db / 20)[/source]
[/quote]

I'm not sure what you mean but I tried 10 ^ ( (L+R) / 20) and it sounds like hash again...

EDIT: Maybe you mean (L + R ) - (10 ^ (6 / 20))?
Advertisement
By 10 ^ x, he meant 10 to power of x. Not 10 XOR x.
So in C it is written like this: pow(10, x).
Beware also from integer division - 6/20 = 0.

Dividing by 2 will not halve the volume as audio buffers are logarithmic, not linear. Sum the left and right channels and then subtract the result by 3 (or 6) decibels. However, to halve the •perceived• volume, you may want to subtract as much as 10 dB.


actually, he's right:

6dB of attenuation works out to be almost a factor of two:

gain = 10^(-6dB / 20) = 0.5012

[quote name='King Joffrey' timestamp='1309857655' post='4831269']
Dividing by 2 will not halve the volume as audio buffers are logarithmic, not linear. Sum the left and right channels and then subtract the result by 3 (or 6) decibels. However, to halve the •perceived• volume, you may want to subtract as much as 10 dB.


actually, he's right:

6dB of attenuation works out to be almost a factor of two:

gain = 10^(-6dB / 20) = 0.5012
[/quote]

I still don't know what I am suppose to do...

float gain = pow(10.0f,(-6.0f / 20.0f));
std::vector<int> mono(buffer->data.size() / 2);
for (UINT i = 0; i < mono.size(); i++)
{
mono = (buffer->data[2*i] + buffer->data[2*i+1])*gain;
}



When I do this all I hear is hash.

When I do this all I hear is hash.

Have you checked that your OpenAL setup is correct. This code generates a mono 32-bit signed integer buffer, but I believe OpenAL only offers 8 and 16 bit integer formats.

Are you giving OpenAL data in a format it understands?

Jans.


std::vector<int> mono(buffer->data.size() / 2);
for (UINT i = 0; i < mono.size(); i++)
{
float gain = pow(10.0f,(-6.0f / 20.0f));
mono = (buffer->data[2*i] + buffer->data[2*i+1])*gain;
}



When I do this all I hear is hash.


What is the data type of 'data'? Where did it come from? Are stereo audio streams actually interleaved in that buffer? Is OpenAL expecting your mono buffer to be 16-bit or 32-bit?

[quote name='SteveDeFacto' timestamp='1309917993' post='4831594']
When I do this all I hear is hash.

Have you checked that your OpenAL setup is correct. This code generates a mono 32-bit signed integer buffer, but I believe OpenAL only offers 8 and 16 bit integer formats.

Are you giving OpenAL data in a format it understands?

Jans.
[/quote]

For some reason I thought an int was a signed short but I guess not. It's working now! =D

Anyway, now that it's working right which should I use (Left+Right) /2 or [font="CourierNew, monospace"]the other way?[/font]
I would personally use (left+right)/2. I think that the 6dB figure that most people throw around exists because it is about a factor of two. I'd rather preserve amplitude exactly when combining two identical channels. You might want to upsample to 32 bit integers or floating point when doing the calculations in order to prevent overflow for samples near 0dBFS.

But really, it depends on the contents of the source audio buffers. If you were downmixing a surround sound stream you couldn't expect to divide the sum of the channels by the number of channels and get a reasonable result because surround mixes are often front-heavy.

This topic is closed to new replies.

Advertisement