• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

Android sound bug?

SLotman

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jul 3, 2017
Messages
261
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:
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:
    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?
 
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.
 
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.
 
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;
    }
 
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:
            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)
 
I also changed the SoundPool initialization to this: (because 'new SoundPool' is deprecated)

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 );
        }
 
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:
Yeah, hardware drivers can be a bitch that plays tricks on you.
 
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))
 
Back
Top Bottom