Кошмарное программирование для Android - саундпул, аудиотрек?
Мы создали простое приложение для Android музыкального секвенсора, которое воспроизводит несколько аудиофайлов.
Первоначально я использовал SoundPool для воспроизведения mp3-файлов, и он отлично работал на 2.3.4 со старым HTC Droid Incredible. Затем я протестировал его на Galaxy Nexus под управлением 4.3, и производительность была ужасной. Аудио время повсюду и были глюки / щелчки / хлопки.
Поэтому я потратил несколько дней на создание плеера с использованием AudioTrack, включая mp3-декодер, и отлично работал как на Galaxy, так и на HTC. Сейчас я'Мы только что протестировали его на Nexus 4 (работает 4.3), и производительность ужасна - время повсюду. SoundPool даже предлагает лучшую производительность на этом устройстве.
я очень расстроен и неЯ не знаю, что делать, чтобы закончить свое приложение, поэтому я был бы очень признателен, если бы кто-нибудь смог мне помочь. Я'Выложите несколько примеров кода моего аудиоплеера ниже. Я'Я перепробовал все, что мог, включая изменение размера буфера, используяAudioTrack.MODE_STATIC
и т. д. Новые устройства Google имеют низкую задержку звука, поэтомуОчень странно, как все работает лучше на моем старом дроиде!
заранее спасибо
/**
* Play note
*/
public void playNote(String note, float vol)
{
PlayThread oldThread = threadMap.get(note);
if(oldThread != null) {
//Cancel timer
if(oldThread.timer != null) {
oldThread.timer.cancel();
oldThread.timer.purge();
oldThread.timer = null;
}
//Stop
oldThread.requestStop();
threadMap.remove(note);
}
//Play if within Polyphony
if(threadMap.size() < POLYPHONY) {
PlayThread thread = new PlayThread(note, vol);
thread.start();
threadMap.put(note, thread);
}
}
/**
* Stop note
*/
public void stopNote(String note, int fadeDurationInMs)
{
PlayThread thread = threadMap.get(note);
if(thread != null) {
thread.fadeOut(fadeDurationInMs);
threadMap.remove(note);
}
}
/**
* Stop all
*/
public void stopAllPlaying(int fadeDurationInMs)
{
for(PlayThread thread : threadMap.values()) {
if(thread != null) {
thread.fadeOut(fadeDurationInMs);
}
}
threadMap.clear();
}
/**
* PlayThread
*/
private class PlayThread extends Thread
{
String note;
float vol;
float fadeVol;
boolean stop;
AudioTrack audioTrack;
Timer timer;
/**
* Constructor
*/
public PlayThread(String note, float vol)
{
super();
this.note = note;
this.vol = vol;
this.fadeVol = vol;
}
/**
* Run
*/
public void run()
{
try {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
//Create buffer
int bufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, CHANNELS, AudioFormat.ENCODING_PCM_16BIT);
Log.v(Constants.TAG, "min buffersize = " + bufferSize);
bufferSize = bufferSize * 2;
byte[] buffer = new byte[bufferSize];
//AudioTrack
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, CHANNELS, AudioFormat.ENCODING_PCM_16BIT, bufferSize, AudioTrack.MODE_STREAM);
audioTrack.setStereoVolume(vol, vol);
audioTrack.play();
//Get byte data
byte[] byteData = sampleMap.get(note);
//Convert to input stream
InputStream input = new ByteArrayInputStream(byteData);
//Write to audioTrack
int bytesRead = 0;
while(!stop && (bytesRead = input.read(buffer)) != -1) {
audioTrack.write(buffer, 0, bytesRead);
}
//When finished...
audioTrack.stop();
audioTrack.release();
input.close();
killThread(this);
}
catch(Exception e) {}
}
/**
* Set volume
*/
private synchronized void setVol(float newVol)
{
audioTrack.setStereoVolume(newVol, newVol);
}
/**
* Update volume
*/
private synchronized void lowerVol()
{
fadeVol -= 0.01;
if(fadeVol < 0) vol = 0;
audioTrack.setStereoVolume(fadeVol, fadeVol);
}
/**
* Fade out
*/
public synchronized void fadeOut(int fadeDurationInMs)
{
//Start decreasing volume
if(fadeDurationInMs > 0) {
timer = new Timer(true);
TimerTask timerTask = new TimerTask()
{
@Override
public void run()
{
//If thread killed while running
try {
//Lower volume
lowerVol();
}
catch (Exception e) {}
//Stop when volume reaches 0
if(fadeVol