Android sound bug?

SLotman

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
149
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:

code_language.cerberus:
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.

code_language.cerberus:
    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
Messages
2,815
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
Messages
2,815
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
Messages
2,815
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

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
149
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:

code_language.cerberus:
            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

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
149
I also changed the SoundPool initialization to this: (because 'new SoundPool' is deprecated)

code_language.cerberus:
        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

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
149
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:

MikeHart

Administrator
Joined
Jun 19, 2017
Messages
2,815
Yeah, hardware drivers can be a bitch that plays tricks on you.
 

RaspberryDJ

New member
Joined
Jun 3, 2019
Messages
122
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