Android sound bug?

SLotman

Member
Joined
Jul 3, 2017
I don't think this is a bug from Monkey-x / Cerberus X. But hear me out:

I'm trying to make a game for blind people. On desktop I calculate the distance the enemy is from the camera (using MiniB3D!) and from there I take if the enemy is to the left / right / in front of the player.

This is basically what I do:

Cerberus X:
Local dx:Float = (EntityX(cam) - pos.x) / 10.0
if dx>1 then dx=1
if dx<-1 then dx=-1
SetChannelPan(channel, -dx)
It works really well on desktop. But on Android, it sounds completely wrong!

Enemys right in front of you plays very, very low volume. If I move to any side, the volume practically doubles.

So I tried fixing values. SetChannelPan(channel, 1) < plays both channels, normal volume
So I tried fixing values. SetChannelPan(channel, -1) < plays both channels, normal volume
So I tried fixing values. SetChannelPan(channel, 0) < plays both channels, very low volume

I look at mojo.android.java, and as far as I can tell, setPan looks normal.

Cerberus X:
    int SetPan( int channel,float pan ){
        gxtkChannel chan=channels[channel];
        chan.pan=pan;
        if( chan.stream!=0 ){
            float rv=(chan.pan * .5f + .5f) * chan.volume;
            float lv=chan.volume-rv;   
            pool.setVolume( chan.stream,lv,rv );
        }
        return 0;
    }
I'm lost. I've tried this on 2 different devices, same results. Even using an external headphone (same one I use on desktop for testing) and nothing changes.
Have anyone faced this before? Any clues?
 

MikeHart

Administrator
Joined
Jun 19, 2017
Location
Germany
Just checked it on my Samsung A5 2017 with a modified audio sample that ships with CX. Works fine! I set the pan before playing a channel.
 

MikeHart

Administrator
Joined
Jun 19, 2017
Location
Germany
Btw. with that pan coding above, it is normal that infront you hear only 50% and an the sides 100%. That needs to be recoded.
 

MikeHart

Administrator
Joined
Jun 19, 2017
Location
Germany
Try this version of SetPan:
Java:
    int SetPan( int channel,float pan ){
        gxtkChannel chan=channels[channel];
        chan.pan=pan;
        if( chan.stream!=0 ){
            //float rv=(chan.pan * .5f + .5f) * chan.volume;
            //float lv=chan.volume-rv;
            float rv = chan.volume;
            float lv = chan.volume;
            if (pan > 0.0f) {
                lv *= (1.0f - pan);
            }
            if (pan < 0.0f) {
                rv *= (1.0f + pan);
            }
            pool.setVolume( chan.stream,lv,rv );
        }
        return 0;
    }
 

SLotman

Member
Joined
Jul 3, 2017
Btw. with that pan coding above, it is normal that infront you hear only 50% and an the sides 100%. That needs to be recoded.
Just replaced it with this:

Cerberus X:
            float rv = chan.volume;
            float lv = chan.volume;
            if (chan.pan < 0) {
                rv *= (1 - Math.abs(chan.pan));
             } else if (pan > 0) {
                lv *= (1 - Math.abs(chan.pan));
            }
It improved the sound A LOT. (replaced it everywhere - not only on setpan, but also on setvolume and play)
 

SLotman

Member
Joined
Jul 3, 2017
I also changed the SoundPool initialization to this: (because 'new SoundPool' is deprecated)

Cerberus X:
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
            AudioAttributes attributes = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_GAME)
            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
            .setFlags(64 | 128)

            .build();
                    
            pool = new SoundPool.Builder()
            .setMaxStreams(32)
            .setAudioAttributes(attributes)
            .build();
          } else {
            pool=new SoundPool( 32,AudioManager.STREAM_MUSIC,0 );
        }
 

SLotman

Member
Joined
Jul 3, 2017
Hmmm... using headphones the sound is still *much* lower in the center.

Ok, now I dont understand ANYTHING. I tried another headphone, a bluetooth one. And it sounded fine, BUT... channels were reversed.
The left was playing on the right and vice-versa.

I'm lost. Nevermind, this same headphone plays reversed on my PC as well. Oh, joy.
 
Last edited:

RaspberryDJ

Member
Joined
Jun 3, 2019
There's something called the "pan law" that explains the center loudness phenomena.
Here's the simplest pseudocode example I could think of how to do constant-power-panning (the trigonometry uses radians) :

Constant volume when panning
------------------------------------
'
' input is position (-1 +1)
'
po2 = 4.0 * atan(1.0) * 0.5
ro2 = sqrt(2.0) * 0.5
thispos = position * po2
angle = thispos * 0.5
'
pos.left = ro2 * (cos(angle) - sin(angle))
pos.right = ro2* (cos(angle) + sin(angle))
 
Top Bottom