103 lines
3.1 KiB
Java
103 lines
3.1 KiB
Java
package com.limelight.binding.audio;
|
|
|
|
import android.media.AudioFormat;
|
|
import android.media.AudioManager;
|
|
import android.media.AudioTrack;
|
|
|
|
import com.limelight.LimeLog;
|
|
import com.limelight.nvstream.av.audio.AudioRenderer;
|
|
|
|
public class AndroidAudioRenderer implements AudioRenderer {
|
|
|
|
private AudioTrack track;
|
|
|
|
@Override
|
|
public boolean streamInitialized(int channelCount, int channelMask, int samplesPerFrame, int sampleRate) {
|
|
int channelConfig;
|
|
int bufferSize;
|
|
int bytesPerFrame = (samplesPerFrame * 2);
|
|
|
|
switch (channelCount)
|
|
{
|
|
case 1:
|
|
channelConfig = AudioFormat.CHANNEL_OUT_MONO;
|
|
break;
|
|
case 2:
|
|
channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
|
|
break;
|
|
case 4:
|
|
channelConfig = AudioFormat.CHANNEL_OUT_QUAD;
|
|
break;
|
|
case 6:
|
|
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
|
|
break;
|
|
default:
|
|
LimeLog.severe("Decoder returned unhandled channel count");
|
|
return false;
|
|
}
|
|
|
|
// We're not supposed to request less than the minimum
|
|
// buffer size for our buffer, but it appears that we can
|
|
// do this on many devices and it lowers audio latency.
|
|
// We'll try the small buffer size first and if it fails,
|
|
// use the recommended larger buffer size.
|
|
try {
|
|
// Buffer two frames of audio if possible
|
|
bufferSize = bytesPerFrame * 2;
|
|
|
|
track = new AudioTrack(AudioManager.STREAM_MUSIC,
|
|
sampleRate,
|
|
channelConfig,
|
|
AudioFormat.ENCODING_PCM_16BIT,
|
|
bufferSize,
|
|
AudioTrack.MODE_STREAM);
|
|
track.play();
|
|
} catch (Exception e) {
|
|
// Try to release the AudioTrack if we got far enough
|
|
try {
|
|
if (track != null) {
|
|
track.release();
|
|
}
|
|
} catch (Exception ignored) {}
|
|
|
|
// Now try the larger buffer size
|
|
bufferSize = Math.max(AudioTrack.getMinBufferSize(sampleRate,
|
|
channelConfig,
|
|
AudioFormat.ENCODING_PCM_16BIT),
|
|
bytesPerFrame * 2);
|
|
|
|
// Round to next frame
|
|
bufferSize = (((bufferSize + (bytesPerFrame - 1)) / bytesPerFrame) * bytesPerFrame);
|
|
|
|
track = new AudioTrack(AudioManager.STREAM_MUSIC,
|
|
sampleRate,
|
|
channelConfig,
|
|
AudioFormat.ENCODING_PCM_16BIT,
|
|
bufferSize,
|
|
AudioTrack.MODE_STREAM);
|
|
track.play();
|
|
}
|
|
|
|
LimeLog.info("Audio track buffer size: "+bufferSize);
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void playDecodedAudio(byte[] audioData, int offset, int length) {
|
|
track.write(audioData, offset, length);
|
|
}
|
|
|
|
@Override
|
|
public void streamClosing() {
|
|
if (track != null) {
|
|
track.release();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getCapabilities() {
|
|
return 0;
|
|
}
|
|
}
|