Java Code Examples for android.media.AudioTrack#getPlayState()

The following examples show how to use android.media.AudioTrack#getPlayState() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: BlockingAudioTrack.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
private static int writeToAudioTrack(AudioTrack audioTrack, byte[] bytes) {
    if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
        if (DBG) Log.d(TAG, "AudioTrack not playing, restarting : " + audioTrack.hashCode());
        audioTrack.play();
    }

    int count = 0;
    while (count < bytes.length) {
        // Note that we don't take bufferCopy.mOffset into account because
        // it is guaranteed to be 0.
        int written = audioTrack.write(bytes, count, bytes.length);
        if (written <= 0) {
            break;
        }
        count += written;
    }
    return count;
}
 
Example 2
Source File: AudioTrackPositionTracker.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
/**
 * {@link AudioTrack#getPlaybackHeadPosition()} returns a value intended to be interpreted as an
 * unsigned 32 bit integer, which also wraps around periodically. This method returns the playback
 * head position as a long that will only wrap around if the value exceeds {@link Long#MAX_VALUE}
 * (which in practice will never happen).
 *
 * @return The playback head position, in frames.
 */
private long getPlaybackHeadPosition() {
  AudioTrack audioTrack = Assertions.checkNotNull(this.audioTrack);
  if (stopTimestampUs != C.TIME_UNSET) {
    // Simulate the playback head position up to the total number of frames submitted.
    long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
    long framesSinceStop = (elapsedTimeSinceStopUs * outputSampleRate) / C.MICROS_PER_SECOND;
    return Math.min(endPlaybackHeadPosition, stopPlaybackHeadPosition + framesSinceStop);
  }

  int state = audioTrack.getPlayState();
  if (state == PLAYSTATE_STOPPED) {
    // The audio track hasn't been started.
    return 0;
  }

  long rawPlaybackHeadPosition = 0xFFFFFFFFL & audioTrack.getPlaybackHeadPosition();
  if (needsPassthroughWorkarounds) {
    // Work around an issue with passthrough/direct AudioTracks on platform API versions 21/22
    // where the playback head position jumps back to zero on paused passthrough/direct audio
    // tracks. See [Internal: b/19187573].
    if (state == PLAYSTATE_PAUSED && rawPlaybackHeadPosition == 0) {
      passthroughWorkaroundPauseOffset = lastRawPlaybackHeadPosition;
    }
    rawPlaybackHeadPosition += passthroughWorkaroundPauseOffset;
  }

  if (Util.SDK_INT <= 29) {
    if (rawPlaybackHeadPosition == 0
        && lastRawPlaybackHeadPosition > 0
        && state == PLAYSTATE_PLAYING) {
      // If connecting a Bluetooth audio device fails, the AudioTrack may be left in a state
      // where its Java API is in the playing state, but the native track is stopped. When this
      // happens the playback head position gets stuck at zero. In this case, return the old
      // playback head position and force the track to be reset after
      // {@link #FORCE_RESET_WORKAROUND_TIMEOUT_MS} has elapsed.
      if (forceResetWorkaroundTimeMs == C.TIME_UNSET) {
        forceResetWorkaroundTimeMs = SystemClock.elapsedRealtime();
      }
      return lastRawPlaybackHeadPosition;
    } else {
      forceResetWorkaroundTimeMs = C.TIME_UNSET;
    }
  }

  if (lastRawPlaybackHeadPosition > rawPlaybackHeadPosition) {
    // The value must have wrapped around.
    rawPlaybackHeadWrapCount++;
  }
  lastRawPlaybackHeadPosition = rawPlaybackHeadPosition;
  return rawPlaybackHeadPosition + (rawPlaybackHeadWrapCount << 32);
}
 
Example 3
Source File: BlockingAudioTrack.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
private void blockUntilCompletion(AudioTrack audioTrack) {
    final int lengthInFrames = mBytesWritten / mBytesPerFrame;

    int previousPosition = -1;
    int currentPosition = 0;
    long blockedTimeMs = 0;

    while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames &&
            audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING && !mStopped) {

        final long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
                audioTrack.getSampleRate();
        final long sleepTimeMs = clip(estimatedTimeMs, MIN_SLEEP_TIME_MS, MAX_SLEEP_TIME_MS);

        // Check if the audio track has made progress since the last loop
        // iteration. We should then add in the amount of time that was
        // spent sleeping in the last iteration.
        if (currentPosition == previousPosition) {
            // This works only because the sleep time that would have been calculated
            // would be the same in the previous iteration too.
            blockedTimeMs += sleepTimeMs;
            // If we've taken too long to make progress, bail.
            if (blockedTimeMs > MAX_PROGRESS_WAIT_MS) {
                Log.w(TAG, "Waited unsuccessfully for " + MAX_PROGRESS_WAIT_MS + "ms " +
                        "for AudioTrack to make progress, Aborting");
                break;
            }
        } else {
            blockedTimeMs = 0;
        }
        previousPosition = currentPosition;

        if (DBG) {
            Log.d(TAG, "About to sleep for : " + sleepTimeMs + " ms," +
                    " Playback position : " + currentPosition + ", Length in frames : "
                    + lengthInFrames);
        }
        try {
            Thread.sleep(sleepTimeMs);
        } catch (InterruptedException ie) {
            break;
        }
    }
}
 
Example 4
Source File: AudioTrackPositionTracker.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * {@link AudioTrack#getPlaybackHeadPosition()} returns a value intended to be interpreted as an
 * unsigned 32 bit integer, which also wraps around periodically. This method returns the playback
 * head position as a long that will only wrap around if the value exceeds {@link Long#MAX_VALUE}
 * (which in practice will never happen).
 *
 * @return The playback head position, in frames.
 */
private long getPlaybackHeadPosition() {
  AudioTrack audioTrack = Assertions.checkNotNull(this.audioTrack);
  if (stopTimestampUs != C.TIME_UNSET) {
    // Simulate the playback head position up to the total number of frames submitted.
    long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
    long framesSinceStop = (elapsedTimeSinceStopUs * outputSampleRate) / C.MICROS_PER_SECOND;
    return Math.min(endPlaybackHeadPosition, stopPlaybackHeadPosition + framesSinceStop);
  }

  int state = audioTrack.getPlayState();
  if (state == PLAYSTATE_STOPPED) {
    // The audio track hasn't been started.
    return 0;
  }

  long rawPlaybackHeadPosition = 0xFFFFFFFFL & audioTrack.getPlaybackHeadPosition();
  if (needsPassthroughWorkarounds) {
    // Work around an issue with passthrough/direct AudioTracks on platform API versions 21/22
    // where the playback head position jumps back to zero on paused passthrough/direct audio
    // tracks. See [Internal: b/19187573].
    if (state == PLAYSTATE_PAUSED && rawPlaybackHeadPosition == 0) {
      passthroughWorkaroundPauseOffset = lastRawPlaybackHeadPosition;
    }
    rawPlaybackHeadPosition += passthroughWorkaroundPauseOffset;
  }

  if (Util.SDK_INT <= 28) {
    if (rawPlaybackHeadPosition == 0
        && lastRawPlaybackHeadPosition > 0
        && state == PLAYSTATE_PLAYING) {
      // If connecting a Bluetooth audio device fails, the AudioTrack may be left in a state
      // where its Java API is in the playing state, but the native track is stopped. When this
      // happens the playback head position gets stuck at zero. In this case, return the old
      // playback head position and force the track to be reset after
      // {@link #FORCE_RESET_WORKAROUND_TIMEOUT_MS} has elapsed.
      if (forceResetWorkaroundTimeMs == C.TIME_UNSET) {
        forceResetWorkaroundTimeMs = SystemClock.elapsedRealtime();
      }
      return lastRawPlaybackHeadPosition;
    } else {
      forceResetWorkaroundTimeMs = C.TIME_UNSET;
    }
  }

  if (lastRawPlaybackHeadPosition > rawPlaybackHeadPosition) {
    // The value must have wrapped around.
    rawPlaybackHeadWrapCount++;
  }
  lastRawPlaybackHeadPosition = rawPlaybackHeadPosition;
  return rawPlaybackHeadPosition + (rawPlaybackHeadWrapCount << 32);
}
 
Example 5
Source File: AudioTrackPositionTracker.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * {@link AudioTrack#getPlaybackHeadPosition()} returns a value intended to be interpreted as an
 * unsigned 32 bit integer, which also wraps around periodically. This method returns the playback
 * head position as a long that will only wrap around if the value exceeds {@link Long#MAX_VALUE}
 * (which in practice will never happen).
 *
 * @return The playback head position, in frames.
 */
private long getPlaybackHeadPosition() {
  AudioTrack audioTrack = Assertions.checkNotNull(this.audioTrack);
  if (stopTimestampUs != C.TIME_UNSET) {
    // Simulate the playback head position up to the total number of frames submitted.
    long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
    long framesSinceStop = (elapsedTimeSinceStopUs * outputSampleRate) / C.MICROS_PER_SECOND;
    return Math.min(endPlaybackHeadPosition, stopPlaybackHeadPosition + framesSinceStop);
  }

  int state = audioTrack.getPlayState();
  if (state == PLAYSTATE_STOPPED) {
    // The audio track hasn't been started.
    return 0;
  }

  long rawPlaybackHeadPosition = 0xFFFFFFFFL & audioTrack.getPlaybackHeadPosition();
  if (needsPassthroughWorkarounds) {
    // Work around an issue with passthrough/direct AudioTracks on platform API versions 21/22
    // where the playback head position jumps back to zero on paused passthrough/direct audio
    // tracks. See [Internal: b/19187573].
    if (state == PLAYSTATE_PAUSED && rawPlaybackHeadPosition == 0) {
      passthroughWorkaroundPauseOffset = lastRawPlaybackHeadPosition;
    }
    rawPlaybackHeadPosition += passthroughWorkaroundPauseOffset;
  }

  if (Util.SDK_INT <= 28) {
    if (rawPlaybackHeadPosition == 0
        && lastRawPlaybackHeadPosition > 0
        && state == PLAYSTATE_PLAYING) {
      // If connecting a Bluetooth audio device fails, the AudioTrack may be left in a state
      // where its Java API is in the playing state, but the native track is stopped. When this
      // happens the playback head position gets stuck at zero. In this case, return the old
      // playback head position and force the track to be reset after
      // {@link #FORCE_RESET_WORKAROUND_TIMEOUT_MS} has elapsed.
      if (forceResetWorkaroundTimeMs == C.TIME_UNSET) {
        forceResetWorkaroundTimeMs = SystemClock.elapsedRealtime();
      }
      return lastRawPlaybackHeadPosition;
    } else {
      forceResetWorkaroundTimeMs = C.TIME_UNSET;
    }
  }

  if (lastRawPlaybackHeadPosition > rawPlaybackHeadPosition) {
    // The value must have wrapped around.
    rawPlaybackHeadWrapCount++;
  }
  lastRawPlaybackHeadPosition = rawPlaybackHeadPosition;
  return rawPlaybackHeadPosition + (rawPlaybackHeadWrapCount << 32);
}
 
Example 6
Source File: AudioTrackPositionTracker.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
/**
 * {@link AudioTrack#getPlaybackHeadPosition()} returns a value intended to be interpreted as an
 * unsigned 32 bit integer, which also wraps around periodically. This method returns the playback
 * head position as a long that will only wrap around if the value exceeds {@link Long#MAX_VALUE}
 * (which in practice will never happen).
 *
 * @return The playback head position, in frames.
 */
private long getPlaybackHeadPosition() {
  AudioTrack audioTrack = Assertions.checkNotNull(this.audioTrack);
  if (stopTimestampUs != C.TIME_UNSET) {
    // Simulate the playback head position up to the total number of frames submitted.
    long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
    long framesSinceStop = (elapsedTimeSinceStopUs * outputSampleRate) / C.MICROS_PER_SECOND;
    return Math.min(endPlaybackHeadPosition, stopPlaybackHeadPosition + framesSinceStop);
  }

  int state = audioTrack.getPlayState();
  if (state == PLAYSTATE_STOPPED) {
    // The audio track hasn't been started.
    return 0;
  }

  long rawPlaybackHeadPosition = 0xFFFFFFFFL & audioTrack.getPlaybackHeadPosition();
  if (needsPassthroughWorkarounds) {
    // Work around an issue with passthrough/direct AudioTracks on platform API versions 21/22
    // where the playback head position jumps back to zero on paused passthrough/direct audio
    // tracks. See [Internal: b/19187573].
    if (state == PLAYSTATE_PAUSED && rawPlaybackHeadPosition == 0) {
      passthroughWorkaroundPauseOffset = lastRawPlaybackHeadPosition;
    }
    rawPlaybackHeadPosition += passthroughWorkaroundPauseOffset;
  }

  if (Util.SDK_INT <= 29) {
    if (rawPlaybackHeadPosition == 0
        && lastRawPlaybackHeadPosition > 0
        && state == PLAYSTATE_PLAYING) {
      // If connecting a Bluetooth audio device fails, the AudioTrack may be left in a state
      // where its Java API is in the playing state, but the native track is stopped. When this
      // happens the playback head position gets stuck at zero. In this case, return the old
      // playback head position and force the track to be reset after
      // {@link #FORCE_RESET_WORKAROUND_TIMEOUT_MS} has elapsed.
      if (forceResetWorkaroundTimeMs == C.TIME_UNSET) {
        forceResetWorkaroundTimeMs = SystemClock.elapsedRealtime();
      }
      return lastRawPlaybackHeadPosition;
    } else {
      forceResetWorkaroundTimeMs = C.TIME_UNSET;
    }
  }

  if (lastRawPlaybackHeadPosition > rawPlaybackHeadPosition) {
    // The value must have wrapped around.
    rawPlaybackHeadWrapCount++;
  }
  lastRawPlaybackHeadPosition = rawPlaybackHeadPosition;
  return rawPlaybackHeadPosition + (rawPlaybackHeadWrapCount << 32);
}
 
Example 7
Source File: AudioTrackPositionTracker.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
/**
 * {@link AudioTrack#getPlaybackHeadPosition()} returns a value intended to be interpreted as an
 * unsigned 32 bit integer, which also wraps around periodically. This method returns the playback
 * head position as a long that will only wrap around if the value exceeds {@link Long#MAX_VALUE}
 * (which in practice will never happen).
 *
 * @return The playback head position, in frames.
 */
private long getPlaybackHeadPosition() {
  AudioTrack audioTrack = Assertions.checkNotNull(this.audioTrack);
  if (stopTimestampUs != C.TIME_UNSET) {
    // Simulate the playback head position up to the total number of frames submitted.
    long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
    long framesSinceStop = (elapsedTimeSinceStopUs * outputSampleRate) / C.MICROS_PER_SECOND;
    return Math.min(endPlaybackHeadPosition, stopPlaybackHeadPosition + framesSinceStop);
  }

  int state = audioTrack.getPlayState();
  if (state == PLAYSTATE_STOPPED) {
    // The audio track hasn't been started.
    return 0;
  }

  long rawPlaybackHeadPosition = 0xFFFFFFFFL & audioTrack.getPlaybackHeadPosition();
  if (needsPassthroughWorkarounds) {
    // Work around an issue with passthrough/direct AudioTracks on platform API versions 21/22
    // where the playback head position jumps back to zero on paused passthrough/direct audio
    // tracks. See [Internal: b/19187573].
    if (state == PLAYSTATE_PAUSED && rawPlaybackHeadPosition == 0) {
      passthroughWorkaroundPauseOffset = lastRawPlaybackHeadPosition;
    }
    rawPlaybackHeadPosition += passthroughWorkaroundPauseOffset;
  }

  if (Util.SDK_INT <= 29) {
    if (rawPlaybackHeadPosition == 0
        && lastRawPlaybackHeadPosition > 0
        && state == PLAYSTATE_PLAYING) {
      // If connecting a Bluetooth audio device fails, the AudioTrack may be left in a state
      // where its Java API is in the playing state, but the native track is stopped. When this
      // happens the playback head position gets stuck at zero. In this case, return the old
      // playback head position and force the track to be reset after
      // {@link #FORCE_RESET_WORKAROUND_TIMEOUT_MS} has elapsed.
      if (forceResetWorkaroundTimeMs == C.TIME_UNSET) {
        forceResetWorkaroundTimeMs = SystemClock.elapsedRealtime();
      }
      return lastRawPlaybackHeadPosition;
    } else {
      forceResetWorkaroundTimeMs = C.TIME_UNSET;
    }
  }

  if (lastRawPlaybackHeadPosition > rawPlaybackHeadPosition) {
    // The value must have wrapped around.
    rawPlaybackHeadWrapCount++;
  }
  lastRawPlaybackHeadPosition = rawPlaybackHeadPosition;
  return rawPlaybackHeadPosition + (rawPlaybackHeadWrapCount << 32);
}