mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add support for AudioTrack pitch/speed alteration on API 23.
Issue #26 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=108958826
This commit is contained in:
parent
33506adab5
commit
6570ef0e48
2 changed files with 87 additions and 7 deletions
|
|
@ -24,6 +24,7 @@ import com.google.android.exoplayer.util.MimeTypes;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
|
import android.media.PlaybackParams;
|
||||||
import android.media.audiofx.Virtualizer;
|
import android.media.audiofx.Virtualizer;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
@ -76,6 +77,14 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
|
||||||
*/
|
*/
|
||||||
public static final int MSG_SET_VOLUME = 1;
|
public static final int MSG_SET_VOLUME = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of a message that can be passed to an instance of this class via
|
||||||
|
* {@link ExoPlayer#sendMessage} or {@link ExoPlayer#blockingSendMessage}. The message object
|
||||||
|
* should be a {@link android.media.PlaybackParams}. This will be used to configure the
|
||||||
|
* underlying {@link android.media.AudioTrack}.
|
||||||
|
*/
|
||||||
|
public static final int MSG_SET_PLAYBACK_PARAMS = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name for the raw (passthrough) decoder OMX component.
|
* The name for the raw (passthrough) decoder OMX component.
|
||||||
*/
|
*/
|
||||||
|
|
@ -401,10 +410,16 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
|
public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
|
||||||
if (messageType == MSG_SET_VOLUME) {
|
switch (messageType) {
|
||||||
audioTrack.setVolume((Float) message);
|
case MSG_SET_VOLUME:
|
||||||
} else {
|
audioTrack.setVolume((Float) message);
|
||||||
super.handleMessage(messageType, message);
|
break;
|
||||||
|
case MSG_SET_PLAYBACK_PARAMS:
|
||||||
|
audioTrack.setPlaybackParams((PlaybackParams) message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
super.handleMessage(messageType, message);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import android.media.AudioFormat;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.AudioTimestamp;
|
import android.media.AudioTimestamp;
|
||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
|
import android.media.PlaybackParams;
|
||||||
import android.os.ConditionVariable;
|
import android.os.ConditionVariable;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
@ -248,7 +249,9 @@ public final class AudioTrack {
|
||||||
// There's no guarantee this method exists. Do nothing.
|
// There's no guarantee this method exists. Do nothing.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Util.SDK_INT >= 19) {
|
if (Util.SDK_INT >= 23) {
|
||||||
|
audioTrackUtil = new AudioTrackUtilV23();
|
||||||
|
} else if (Util.SDK_INT >= 19) {
|
||||||
audioTrackUtil = new AudioTrackUtilV19();
|
audioTrackUtil = new AudioTrackUtilV19();
|
||||||
} else {
|
} else {
|
||||||
audioTrackUtil = new AudioTrackUtil();
|
audioTrackUtil = new AudioTrackUtil();
|
||||||
|
|
@ -300,7 +303,10 @@ public final class AudioTrack {
|
||||||
if (audioTimestampSet) {
|
if (audioTimestampSet) {
|
||||||
// How long ago in the past the audio timestamp is (negative if it's in the future).
|
// How long ago in the past the audio timestamp is (negative if it's in the future).
|
||||||
long presentationDiff = systemClockUs - (audioTrackUtil.getTimestampNanoTime() / 1000);
|
long presentationDiff = systemClockUs - (audioTrackUtil.getTimestampNanoTime() / 1000);
|
||||||
long framesDiff = durationUsToFrames(presentationDiff);
|
// Fixes such difference if the playback speed is not real time speed.
|
||||||
|
long actualSpeedPresentationDiff = (long) (presentationDiff
|
||||||
|
* audioTrackUtil.getPlaybackSpeed());
|
||||||
|
long framesDiff = durationUsToFrames(actualSpeedPresentationDiff);
|
||||||
// The position of the frame that's currently being presented.
|
// The position of the frame that's currently being presented.
|
||||||
long currentFramePosition = audioTrackUtil.getTimestampFramePosition() + framesDiff;
|
long currentFramePosition = audioTrackUtil.getTimestampFramePosition() + framesDiff;
|
||||||
currentPositionUs = framesToDurationUs(currentFramePosition) + startMediaTimeUs;
|
currentPositionUs = framesToDurationUs(currentFramePosition) + startMediaTimeUs;
|
||||||
|
|
@ -652,9 +658,20 @@ public final class AudioTrack {
|
||||||
public boolean hasPendingData() {
|
public boolean hasPendingData() {
|
||||||
return isInitialized()
|
return isInitialized()
|
||||||
&& (getSubmittedFrames() > audioTrackUtil.getPlaybackHeadPosition()
|
&& (getSubmittedFrames() > audioTrackUtil.getPlaybackHeadPosition()
|
||||||
|| overrideHasPendingData());
|
|| overrideHasPendingData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the playback parameters. Only available for SDK_INT >= 23
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException if the Playback Parameters are not supported. That is,
|
||||||
|
* SDK_INT < 23.
|
||||||
|
*/
|
||||||
|
public void setPlaybackParams(PlaybackParams playbackParams) {
|
||||||
|
audioTrackUtil.setPlaybackParameters(playbackParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the playback volume.
|
* Sets the playback volume.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1100,6 +1117,27 @@ public final class AudioTrack {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Playback Parameters to be used by the underlying {@link android.media.AudioTrack}.
|
||||||
|
*
|
||||||
|
* @param playbackParams to be used by the {@link android.media.AudioTrack}.
|
||||||
|
* @throws UnsupportedOperationException If Playback Parameters are not supported
|
||||||
|
* (i.e. SDK_INT < 23).
|
||||||
|
*/
|
||||||
|
public void setPlaybackParameters(PlaybackParams playbackParams) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configured playback speed according to the used Playback Parameters. If these are
|
||||||
|
* not supported, 1.0f(normal speed) is returned.
|
||||||
|
*
|
||||||
|
* @return The speed factor used by the underlying {@link android.media.AudioTrack}.
|
||||||
|
*/
|
||||||
|
public float getPlaybackSpeed() {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(19)
|
@TargetApi(19)
|
||||||
|
|
@ -1151,4 +1189,31 @@ public final class AudioTrack {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TargetApi(23)
|
||||||
|
private static class AudioTrackUtilV23 extends AudioTrackUtilV19 {
|
||||||
|
|
||||||
|
private PlaybackParams playbackParams;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reconfigure(android.media.AudioTrack audioTrack,
|
||||||
|
boolean needsPassthroughWorkaround) {
|
||||||
|
super.reconfigure(audioTrack, needsPassthroughWorkaround);
|
||||||
|
setPlaybackParameters(playbackParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaybackParameters(PlaybackParams playbackParams) {
|
||||||
|
this.playbackParams = playbackParams;
|
||||||
|
if (audioTrack != null && playbackParams != null) {
|
||||||
|
audioTrack.setPlaybackParams(playbackParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPlaybackSpeed() {
|
||||||
|
if (playbackParams != null) {
|
||||||
|
return playbackParams.getSpeed();
|
||||||
|
} else {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue