/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
******************************************************************************/
package com.badlogic.gdx.backends.android;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import com.badlogic.gdx.Audio;
import com.badlogic.gdx.Files.FileType;
import com.badlogic.gdx.audio.AudioDevice;
import com.badlogic.gdx.audio.AudioRecorder;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.GdxRuntimeException;
/**
* An implementation of the {@link Audio} interface for Android.
*
* @author mzechner
*/
public final class AndroidAudio implements Audio {
private final SoundPool soundPool;
private final AudioManager manager;
protected final List<AndroidMusic> musics = new ArrayList<AndroidMusic>();
public AndroidAudio(Context context, AndroidApplicationConfiguration config) {
soundPool = new SoundPool(config.maxSimultaneousSounds, AudioManager.STREAM_MUSIC, 100);
manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if (context instanceof Activity) {
((Activity) context).setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
}
protected void pause() {
synchronized (musics) {
for (AndroidMusic music : musics) {
if (music.isPlaying()) {
music.wasPlaying = true;
music.pause();
} else
music.wasPlaying = false;
}
}
}
protected void resume() {
synchronized (musics) {
for (int i = 0; i < musics.size(); i++) {
if (musics.get(i).wasPlaying == true)
musics.get(i).play();
}
}
}
/** {@inheritDoc} */
@Override
public AudioDevice newAudioDevice(int samplingRate, boolean isMono) {
return new AndroidAudioDevice(samplingRate, isMono);
}
/** {@inheritDoc} */
@Override
public Music newMusic(FileHandle file) {
AndroidFileHandle aHandle = (AndroidFileHandle) file;
MediaPlayer mediaPlayer = new MediaPlayer();
if (aHandle.type() == FileType.Internal) {
try {
AssetFileDescriptor descriptor = aHandle.assets.openFd(aHandle.path());
mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(),
descriptor.getLength());
descriptor.close();
mediaPlayer.prepare();
AndroidMusic music = new AndroidMusic(this, mediaPlayer);
synchronized (musics) {
musics.add(music);
}
return music;
} catch (Exception ex) {
throw new GdxRuntimeException("Error loading audio file: " + file
+ "\nNote: Internal audio files must be placed in the assets directory.", ex);
}
} else {
try {
mediaPlayer.setDataSource(aHandle.file().getPath());
mediaPlayer.prepare();
AndroidMusic music = new AndroidMusic(this, mediaPlayer);
synchronized (musics) {
musics.add(music);
}
return music;
} catch (Exception ex) {
throw new GdxRuntimeException("Error loading audio file: " + file, ex);
}
}
}
/** {@inheritDoc} */
@Override
public Sound newSound(FileHandle file) {
AndroidFileHandle aHandle = (AndroidFileHandle) file;
if (aHandle.type() == FileType.Internal) {
try {
AssetFileDescriptor descriptor = aHandle.assets.openFd(aHandle.path());
AndroidSound sound = new AndroidSound(soundPool, manager, soundPool.load(descriptor, 1));
descriptor.close();
return sound;
} catch (IOException ex) {
throw new GdxRuntimeException("Error loading audio file: " + file
+ "\nNote: Internal audio files must be placed in the assets directory.", ex);
}
} else {
try {
return new AndroidSound(soundPool, manager, soundPool.load(aHandle.file().getPath(), 1));
} catch (Exception ex) {
throw new GdxRuntimeException("Error loading audio file: " + file, ex);
}
}
}
/** {@inheritDoc} */
@Override
public AudioRecorder newAudioRecorder(int samplingRate, boolean isMono) {
return new AndroidAudioRecorder(samplingRate, isMono);
}
/** Kills the soundpool and all other resources */
public void dispose() {
synchronized (musics) {
// gah i hate myself.... music.dispose() removes the music from the list...
ArrayList<AndroidMusic> musicsCopy = new ArrayList<AndroidMusic>(musics);
for (AndroidMusic music : musicsCopy) {
music.dispose();
}
}
soundPool.release();
}
}