OpenAL convert to mono on the fly?

Started by
17 comments, last by Aressera 12 years, 9 months ago
I can't convert every file I want to use for 3D audio to mono. Seems like they would just have a command in OpenAL to turn on and off 3d audio for a source. That way they can read the audio based on if it were stereo or mono and output the audio properly. Is there a way I can convert my stereo audio buffer into mono without having to edit the audio file?
Advertisement
Yes, there is a way:
for (int i=0; i<sample_count; i++)
{
mono = (stereo[2*i] + stereo[2*i+1]) / 2;
}

Yes, there is a way:
for (int i=0; i<sample_count; i++)
{
mono = (stereo[2*i] + stereo[2*i+1]) / 2;
}



Should I store a stereo and mono buffer in my audio buffer class or should I create the mono buffer each time audio plays?

Yes, there is a way:
for (int i=0; i<sample_count; i++)
{
mono = (stereo[2*i] + stereo[2*i+1]) / 2;
}


For some reason it sounds like hash when I mix them like that. However, I can play either channel alone without a problem...
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.

For some reason it sounds like hash when I mix them like that. However, I can play either channel alone without a problem...


The algorithm posted will generally do the right thing; as long as the summation of the two channels doesn't overflow - you might need to cast the samples to larger types first.

However doing stereo-to-mono dowmixing like this will reduce overall signal energy and pathalogical audio streams can produce either very quiet or very strange results when mixed. You might get better results by choosing the loudest of the two channels.

Jans.

[quote name='SteveDeFacto' timestamp='1309850732' post='4831239']
For some reason it sounds like hash when I mix them like that. However, I can play either channel alone without a problem...


The algorithm posted will generally do the right thing; as long as the summation of the two channels doesn't overflow - you might need to cast the samples to larger types first.

However doing stereo-to-mono dowmixing like this will reduce overall signal energy and pathalogical audio streams can produce either very quiet or very strange results when mixed. You might get better results by choosing the loudest of the two channels.

Jans.
[/quote]

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

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.

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.


How do I subtract 6 dB? L + R - 6?

[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]

This topic is closed to new replies.

Advertisement