1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.backends.android; 18 19 import android.media.AudioFormat; 20 import android.media.AudioManager; 21 import android.media.AudioTrack; 22 23 import com.badlogic.gdx.audio.AudioDevice; 24 25 /** Implementation of the {@link AudioDevice} interface for Android using the AudioTrack class. You will need to set the permission 26 * android.permission.RECORD_AUDIO in your manifest file. 27 * @author mzechner */ 28 class AndroidAudioDevice implements AudioDevice { 29 /** the audio track **/ 30 private final AudioTrack track; 31 32 /** the mighty buffer **/ 33 private short[] buffer = new short[1024]; 34 35 /** whether this device is in mono or stereo mode **/ 36 private final boolean isMono; 37 38 /** the latency in samples **/ 39 private final int latency; 40 41 AndroidAudioDevice (int samplingRate, boolean isMono) { 42 this.isMono = isMono; 43 int minSize = AudioTrack.getMinBufferSize(samplingRate, isMono ? AudioFormat.CHANNEL_OUT_MONO 44 : AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT); 45 track = new AudioTrack(AudioManager.STREAM_MUSIC, samplingRate, isMono ? AudioFormat.CHANNEL_OUT_MONO 46 : AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, minSize, AudioTrack.MODE_STREAM); 47 track.play(); 48 latency = minSize / (isMono ? 1 : 2); 49 } 50 51 @Override 52 public void dispose () { 53 track.stop(); 54 track.release(); 55 } 56 57 @Override 58 public boolean isMono () { 59 return isMono; 60 } 61 62 @Override 63 public void writeSamples (short[] samples, int offset, int numSamples) { 64 int writtenSamples = track.write(samples, offset, numSamples); 65 while (writtenSamples != numSamples) 66 writtenSamples += track.write(samples, offset + writtenSamples, numSamples - writtenSamples); 67 } 68 69 @Override 70 public void writeSamples (float[] samples, int offset, int numSamples) { 71 if (buffer.length < samples.length) buffer = new short[samples.length]; 72 73 int bound = offset + numSamples; 74 for (int i = offset, j = 0; i < bound; i++, j++) { 75 float fValue = samples[i]; 76 if (fValue > 1) fValue = 1; 77 if (fValue < -1) fValue = -1; 78 short value = (short)(fValue * Short.MAX_VALUE); 79 buffer[j] = value; 80 } 81 82 int writtenSamples = track.write(buffer, 0, numSamples); 83 while (writtenSamples != numSamples) 84 writtenSamples += track.write(buffer, writtenSamples, numSamples - writtenSamples); 85 } 86 87 @Override 88 public int getLatency () { 89 return latency; 90 } 91 92 @Override 93 public void setVolume (float volume) { 94 track.setStereoVolume(volume, volume); 95 } 96 } 97