h6ah4i / android-openslmediaplayer

Re-implementation of Android's MediaPlayer and audio effect classes based on OpenSL ES APIs.
https://openslmediaplayer.h6ah4i.com
Apache License 2.0
418 stars 97 forks source link

HQ Equalizer does not always works #23

Closed fgnm closed 7 years ago

fgnm commented 7 years ago

Hello , very great job, unique and very inspiring :) I've an issue with HQ Equalizer. I set the 10 bands with the method mEqualizer.setBandLevel(band, (short) value); and it works well before starting playing a track. After some seconds happens that changes does not have any effects, I've to release the player and recreate it again, any solutions? I'm wrong something? Thank you!

h6ah4i commented 7 years ago

Hi. Thanks for the issue report! Could you share me your code that can reproduce the issue? At least, I cannot reproduce it with the official demo app...

fgnm commented 7 years ago

Sure, the code is sparse across the app so I'll put only relevant part. First create the PlayerFactory: mFactory = new HybridMediaPlayerFactory(App.applicationContext);

This is the player:

audioPlayer = mFactory.createMediaPlayer();
            audioPlayer.setWakeMode(App.applicationContext, PowerManager.PARTIAL_WAKE_LOCK);
            audioPlayer
                    .setAudioStreamType(useFrontSpeaker ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC);
            Uri songUri = ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    mSongDetail.getId());

            audioPlayer.setDataSource(App.applicationContext, songUri);
            audioPlayer.prepare();
            audioPlayer.start();

Then attach the effects and visualizer:

mVisualizer = mFactory.createVisualizer(getMediaPlayer());
        mVisualizer.setEnabled(false);
        mVisualizer.setCaptureSize(66);
        mVisualizer.setDataCaptureListener(mVisualizerListener, mVisualizer.getMaxCaptureRate(), false, true);
        mVisualizer.setEnabled(true);

        mPreAmp = mFactory.createPreAmp();
        mPreAmp.setEnabled(true);
        mPreAmp.setLevel(2);
        getMediaPlayer().setAuxEffectSendLevel(1.0f);

        try{
            mEqualizer = mFactory.createHQEqualizer();  
        }catch (Exception e) {
            mEqualizer = mFactory.createEqualizer(getMediaPlayer());
        }
        mEqualizer.setEnabled(true);

        equalizerBands = new int[mEqualizer.getNumberOfBands()];
        for(int i = 0; i < equalizerBands.length; i++){
            equalizerBands[i] = mEqualizer.getCenterFreq((short) i);
        }

        getMediaPlayer().setAuxEffectSendLevel(1.0f);

        bassBoost = mFactory.createBassBoost(getMediaPlayer());
        bassBoost.setEnabled(true);

        try {
            if (bassStrength == -1) {
                bassBoost.setStrength((short) 0);
            } else {
                bassBoost.setStrength((short) (bassStrength * ((float) 1000 / 19)));
            }
        } catch (Exception e) {
            System.out.println("SetupFX(): " + e.getMessage());
            mEQAvailable = false;
        }
        getMediaPlayer().setAuxEffectSendLevel(1.0f);

        virtualizer = mFactory.createVirtualizer(getMediaPlayer());
        virtualizer.setEnabled(true);

        try {
            if (virtStrength == -1) {
                virtualizer.setStrength((short) 0);
            } else {
                virtualizer.setStrength((short) (virtStrength * ((float) 1000 / 19)));
            }
        } catch (Exception e) {
            System.out.println("SetupFX(): " + e.getMessage());
            mEQAvailable = false;
        }
        getMediaPlayer().setAuxEffectSendLevel(1.0f);

//Setting the band level at this moment always works well
        int pos = presetPos;
        try {
            if (pos != 0) {
                mEqualizer.usePreset((short) (pos - 1));
            } else {
                short band;
                for(int i = 0; i < equalizerBands.length; i++){
                    band = mEqualizer.getBand(equalizerBands[i]);
                    mEqualizer.setBandLevel(band, (short) seekbarpos[i]);
                }
            }
        } catch (Exception e) {
            System.out.println("SetupFX(): " + e.getMessage());
            mEQAvailable = false;
        }

Later in equalizer screen I change band level in this way, but here setBandLevel() has no effect:

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {    
                    short band = MediaController.getInstance().getEqualizer().getBand(MediaController.getInstance().equalizerBands[equalizerBandIndex]);
                    MediaController.getInstance().getEqualizer().setBandLevel(band, (short) (progress + lowerEqualizerBandLevel));

                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
//A very dirty workaround is to disable equalizer here and reaneble in onStopTrackingTouch()
                    //MediaController.getInstance().getEqualizer().setEnabled(false);
                //MediaController.getInstance().getMediaPlayer().setAuxEffectSendLevel(0.0f);
                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                    MediaController.getInstance().getEqualizer().setEnabled(true);
                    MediaController.getInstance().getMediaPlayer().setAuxEffectSendLevel(1.0f);
                }
            });

Instead BassBoost and Virtualizer works as expected. I'm worried about band level range, actually the seekbar range is [-1500;1500] but I'm unsure, too much?

As you can see it's a pretty basic implementation and standard media player (android.media.MediaPlayer) works without any issue.

The same behaviour happens with OpenSLMediaPlayerFactory (Tested with a OnePlus One and OnePlus 3). Thank you so much for your help, and again congratulations for this work. I've started studying the code, just a little question, theoretically with this player I could filter every frequency, right?

fgnm commented 7 years ago

Sorry, It was my bad, found the reason. There was a mistake in my code, setBandLevel() was called twice at same time. Removing the second call it works now as expected.