2010-05-01 3 views
3

Я хотел бы знать, знает ли кто-нибудь библиотеку об изменении скорости воспроизведения трека в реальном времени. Моя идея - загрузить трек и изменить его скорость воспроизведения до половины или в два раза. Во-первых, я попробовал с MusicPlayer, но это было невозможно, а затем я попытался с SoundPool. Проблема в том, что с SoundPool я не могу изменить скорость после загрузки трека. Вот код, я использую (доказательство концепции):Изменение скорости воспроизведения дорожки в реальном времени на Android

float j = 1; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    Button b = (Button)findViewById(R.id.Button01); 
    b.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      j = (float) (j +.5); 

     } 
    }); 

    AssetFileDescriptor afd; 
    try { 

     SoundPool sp = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); 

     afd = getAssets().openFd("wav/sample.wav"); 
     int id = sp.load(afd, 1); 
     sp.play(id, 1, 1, 1, 0, j); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

При нажатии на кнопку, скорость воспроизведения должна увеличиться, но этого не происходит. Любая идея о том, как изменить скорость в реальном времени?

Заранее спасибо.

ответ

1

Вы вызываете sp.play один раз, когда функция называется значением j, копируется в эту функцию.

Изменение J после не изменяет значение J в функции (это называется передача по значению)

Чтобы изменить скорость воспроизведения после вам нужно вызвать sp.setRate (StreamID, J) в нажмите кнопку прослушивания кнопки.

Обратите внимание, что StreamID возвращается функцией sp.play, поэтому сохраните это как переменную в классе.

Этот код должен работать (я не проверял):

float j = 1.0f; 
SoundPool sp = null; 
int sID = 0; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    Button b = (Button)findViewById(R.id.Button01); 
    b.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      j = (float) (j +.5f); 
      sp.setRate(sID,j); 

     } 
    }); 

    AssetFileDescriptor afd; 
    try { 

     sp = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); 

     afd = getAssets().openFd("wav/sample.wav"); 
     int id = sp.load(afd, 1); 
     sID = sp.play(id, 1, 1, 1, 0, j); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

хотя это, вероятно, крах после того, как кнопка пары пресс, Soundpool поддерживает только ставки от 0,5 до 2,0. Вы должны добавить проверку, чтобы убедиться, что j остается в пределах этих границ.

+0

Hi Mark! Спасибо за ваш ответ, я пробовал это, и вы правы. Теперь у меня другая проблема, возможно, вы знаете, как ее решить: когда я запускаю программу, иногда я получаю эту ошибку: ERROR/AudioCache (31): Переполнение массива кучи! req size: 1058400, max size: 1048576 . Моя идея - загрузить песни размером в два раза (по крайней мере) размером загруженного файла, поэтому я думаю, что я не смогу использовать SoundPool для этого. Как вы думаете? Спасибо – ahmontero

+0

TBH SoundPool - это сложная штука ****, одна из ошибок, с которой вы столкнетесь, заключается в том, что каждый звуковой пул должен иметь не более 1 МБ звуковых данных, связанных с ним, будь то в 1 файле или 10. Его действительно сделанный для воспроизведения небольших звуковых эффектов. Если вы используете Google Googling для звуков SoundPool, то вам придется быть осторожным. Если вам нужно работать с большими дорожками, я рекомендую вам создать собственный звуковой движок и выгрузить необработанные образцы в экземпляр AudioTrack. – Mark

+0

Что-то я забыл упомянуть, ограничение 1 МБ находится на необработанном размере файла, поэтому вы можете сжать ваши файлы wav в ogg и, возможно, обойти ограничения SoundPool – Mark

 Смежные вопросы

  • Нет связанных вопросов^_^