Added support for ducking (#45)

This commit is contained in:
Xiao Bao Clark 2015-08-22 12:23:22 +10:00
parent 107cce708a
commit 2c7a9d53cd
2 changed files with 52 additions and 5 deletions

View File

@ -233,12 +233,18 @@ public final class PlaybackService extends Service
* These three bits will be one of SongTimeline.SHUFFLE_*.
*/
public static final int MASK_SHUFFLE = 0x7 << SHIFT_SHUFFLE;
public static final int SHIFT_DUCKING = 10;
/**
* Whether we're 'ducking' (lowering the playback volume temporarily due to a transient system
* sound, such as a notification) or not
*/
public static final int FLAG_DUCKING = 0x1 << SHIFT_DUCKING;
/**
* The PlaybackService state, indicating if the service is playing,
* repeating, etc.
*
* The format of this is 0b00000000_00000000_0000000ff_feeedcba,
* The format of this is 0b00000000_00000000_000000gff_feeedcba,
* where each bit is:
* a: {@link PlaybackService#FLAG_PLAYING}
* b: {@link PlaybackService#FLAG_NO_MEDIA}
@ -246,6 +252,7 @@ public final class PlaybackService extends Service
* d: {@link PlaybackService#FLAG_EMPTY_QUEUE}
* eee: {@link PlaybackService#MASK_FINISH}
* fff: {@link PlaybackService#MASK_SHUFFLE}
* g: {@link PlaybackService#FLAG_DUCKING}
*/
int mState;
@ -661,7 +668,7 @@ public final class PlaybackService extends Service
} else if (rg_result < 0.0f) {
rg_result = 0.0f;
}
mp.setVolume(rg_result, rg_result);
mp.setReplayGain(rg_result);
}
/**
@ -979,6 +986,10 @@ public final class PlaybackService extends Service
mTimeline.setShuffleMode(shuffleMode(state));
if ((toggled & MASK_FINISH) != 0)
mTimeline.setFinishAction(finishAction(state));
if((toggled & FLAG_DUCKING) != 0) {
mMediaPlayer.setIsDucking((state & FLAG_DUCKING) != 0);
}
}
private void broadcastChange(int state, Song song, long uptime)
@ -2010,8 +2021,8 @@ public final class PlaybackService extends Service
Log.d("VanillaMusic", "audio focus change: " + type);
switch (type) {
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
mDuckedLoss = (mState & FLAG_PLAYING) != 0;
unsetFlag(FLAG_PLAYING);
mDuckedLoss = true;
setFlag(FLAG_DUCKING);
break;
case AudioManager.AUDIOFOCUS_LOSS:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
@ -2022,7 +2033,7 @@ public final class PlaybackService extends Service
case AudioManager.AUDIOFOCUS_GAIN:
if (mDuckedLoss) {
mDuckedLoss = false;
setFlag(FLAG_PLAYING);
unsetFlag(FLAG_DUCKING);
}
break;
}

View File

@ -29,6 +29,8 @@ public class VanillaMediaPlayer extends MediaPlayer {
private Context mContext;
private String mDataSource;
private boolean mHasNextMediaPlayer;
private float mReplayGain = Float.NaN;
private float mDuckingFactor = Float.NaN;
/**
* Constructs a new VanillaMediaPlayer class
@ -107,4 +109,38 @@ public class VanillaMediaPlayer extends MediaPlayer {
mContext.sendBroadcast(i);
}
/**
* Sets the desired scaling due to replay gain.
* @param mReplayGain the factor to adjust the volume by. Must be between 0 and 1 (inclusive)
* or {@link Float#NaN} to disable replay gain scaling
*/
public void setReplayGain(float mReplayGain) {
this.mReplayGain = mReplayGain;
updateVolume();
}
/**
* Sets whether we are ducking or not. Ducking is when we temporarily decrease the volume for
* a transient sound to play from another application, such as a notification's beep.
* @param isDucking true if we are ducking, false if we are not
*/
public void setIsDucking(boolean isDucking) {
mDuckingFactor = (isDucking ? 0.2f : Float.NaN);
updateVolume();
}
/**
* Sets the volume. Ducking takes precedence over replay gain. If neither ducking nor replay
* gain is set, uses the default value of 1.0f
*/
private void updateVolume() {
float volume = 1.0f;
if(!Float.isNaN(mDuckingFactor)) {
volume = mDuckingFactor;
} else if (!Float.isNaN(mReplayGain)) {
volume = mReplayGain;
}
setVolume(volume, volume);
}
}