在Android的下或淡出的声音声音、Android

2023-09-05 07:46:08 作者:像个笑话

我做一个简单的琐事游戏,当用户到达主菜单中运行的循环〜1分钟的MP3文件。声音设置,当用户点击任何按钮,菜单上(即玩游戏)停下来。

I'm making a simple trivia game, and running a looping ~1 min mp3 file when the user arrives at the main menu. The sound is set to stop when user clicks any of the buttons on the menu (i.e. Play Game).

我的问题是,当声音停止,其样的一个不和谐的切断。而不是做.pause()或.stop(),有没有一种方法,使声音的一个按钮后,慢慢淡出是pressed?

My problem is that when the sound stops, its kind of a jarring cut off. Rather than do .pause() or .stop(), is there a way to make the sound slowly fade out after a button is pressed?

感谢

推荐答案

修改(13年3月13日):已更新,新的QA'd code 的

EDIT (3/13/13): Updated with new QA'd code

这是我的整个处理程序类为Android MediaPlayer的。看戏()和暂停()函数。既含有要么褪色或不的能力。所述updateVolume()函数是让声音增加/减少线性的关键。

This is my entire handler class for Android MediaPlayer. Look at the play() and pause() functions. Both contain the ability to either fade or not. The updateVolume() function was the key to let the sound increase/decrease linearly.

public class MusicHandler 
{
private MediaPlayer mediaPlayer;
private Context context;
private int iVolume;

private final static int INT_VOLUME_MAX = 100;
private final static int INT_VOLUME_MIN = 0;
private final static float FLOAT_VOLUME_MAX = 1;
private final static float FLOAT_VOLUME_MIN = 0;

public MusicHandler(Context context)
{
    this.context = context;
}

public void load(String path, boolean looping)
{
    mediaPlayer = MediaPlayer.create(context, Uri.fromFile(new File(path)));
    mediaPlayer.setLooping(looping);
}

public void load(int address, boolean looping)
{
    mediaPlayer = MediaPlayer.create(context, address);
    mediaPlayer.setLooping(looping);
}

public void play(int fadeDuration)
{
    //Set current volume, depending on fade or not
    if (fadeDuration > 0) 
        iVolume = INT_VOLUME_MIN;
    else 
        iVolume = INT_VOLUME_MAX;

    updateVolume(0);

    //Play music
    if(!mediaPlayer.isPlaying()) mediaPlayer.start();

    //Start increasing volume in increments
    if(fadeDuration > 0)
    {
        final Timer timer = new Timer(true);
        TimerTask timerTask = new TimerTask() 
        {
            @Override
            public void run() 
            {
                updateVolume(1);
                if (iVolume == INT_VOLUME_MAX)
                {
                    timer.cancel();
                    timer.purge();
                }
            }
        };

        // calculate delay, cannot be zero, set to 1 if zero
        int delay = fadeDuration/INT_VOLUME_MAX;
        if (delay == 0) delay = 1;

        timer.schedule(timerTask, delay, delay);
    }
}

public void pause(int fadeDuration)
{
    //Set current volume, depending on fade or not
    if (fadeDuration > 0) 
        iVolume = INT_VOLUME_MAX;
    else 
        iVolume = INT_VOLUME_MIN;

    updateVolume(0);

    //Start increasing volume in increments
    if(fadeDuration > 0)
    {
        final Timer timer = new Timer(true);
        TimerTask timerTask = new TimerTask() 
        {
            @Override
            public void run() 
            {   
                updateVolume(-1);
                if (iVolume == INT_VOLUME_MIN)
                {
                    //Pause music
                    if (mediaPlayer.isPlaying()) mediaPlayer.pause();
                    timer.cancel();
                    timer.purge();
                }
            }
        };

        // calculate delay, cannot be zero, set to 1 if zero
        int delay = fadeDuration/INT_VOLUME_MAX;
        if (delay == 0) delay = 1;

        timer.schedule(timerTask, delay, delay);
    }           
}

private void updateVolume(int change)
{
    //increment or decrement depending on type of fade
    iVolume = iVolume + change;

    //ensure iVolume within boundaries
    if (iVolume < INT_VOLUME_MIN)
        iVolume = INT_VOLUME_MIN;
    else if (iVolume > INT_VOLUME_MAX)
        iVolume = INT_VOLUME_MAX;

    //convert to float value
    float fVolume = 1 - ((float) Math.log(INT_VOLUME_MAX - iVolume) / (float) Math.log(INT_VOLUME_MAX));

    //ensure fVolume within boundaries
    if (fVolume < FLOAT_VOLUME_MIN)
        fVolume = FLOAT_VOLUME_MIN;
    else if (fVolume > FLOAT_VOLUME_MAX)
        fVolume = FLOAT_VOLUME_MAX;     

    mediaPlayer.setVolume(fVolume, fVolume);
}
}