Intereting Posts
Handle touch event для элементов внутри Recyclerview – андроид Измените имя пакета для Android в React Native Ошибка «adb not installed» при попытке сделать снимок с помощью uiautomatorviewer Как установить несколько тегов на кнопку? Плавающий видеопроигрыватель в Android? Выравнивание текста в стиле андроид Каков наилучший способ создания и тестирования проекта библиотеки в Android Studio для участия в любом проекте? Как использовать наборщик номеров с диалогом Как включить эмулятор Genymotion для использования Интернета WIFI, который использует хост Как определить правильную ориентацию устройства в многоэкранном режиме Android N? Камера всегда возвращает resultCode как 0 Перевод идентификатора метки телефона телефона Android в строку Переполнение Webview iframe Как реализовать двойной щелчок мышью в Android? Чистое Blank Android-приложение не удается построить – «не удалось найти версию средств для сборки 23.0.0 rc1»

Как воспроизводить звуки в точные периоды времени на разных устройствах в Android

Я разрабатываю игру на Android, и я наткнулся на очень раздражающую, труднодоступную ошибку. Проблема в том, что когда вы используете SoundPool для воспроизведения ваших звуков, вы можете на самом деле зацикливать любой звук, который вы играете. В этом случае проблема заключается в звуке «бегущих шагов»; Этот звук выполняется довольно быстро и непрерывно (примерно каждые 400ms ) при запуске главного героя.

Теперь, когда вы воспроизводите звук на обычном (не очень мощном) устройстве, например Samsung SII, звук воспроизводится каждые 500ms однако, если я запускаю тот же код на другом устройстве (скажем, Samsung SIV, Samsung SIII), звук Играет в два или даже три раза быстрее.

Похоже, что чем мощнее аппаратные спецификации устройства, тем быстрее он играет. На некоторых устройствах он работает так быстро, что вы почти слышите один сплошной непрерывный звук. Я искал методы, чтобы установить определенный коэффициент в промежуток времени между звуковыми играми, но он не работает должным образом, и проблема остается. Кто-нибудь знает, как исправить это, используя SoundPool , MediaPlayer или любой другой управляющий звуком API на Android?

Solutions Collecting From Web of "Как воспроизводить звуки в точные периоды времени на разных устройствах в Android"

Проблема с простой петлей или использованием регулярного интервала для чего-то вроде шагов – это то, что у вас есть возможная развязка звука и визуальных эффектов. Если ваш звук задерживается или ускоряется, или ваши визуальные эффекты задерживаются или ускоряются, вам придется настраивать эту задержку динамически и автоматически. Вы уже имеете эту проблему прямо здесь

Лучшим решением было бы поставить триггер на точное событие, которое должно вызывать звук (в этом случае нога будет помещена вниз), который затем воспроизводит звук. Это также означает, что если у вас есть несколько источников звука (например, несколько шагов), вам не нужно вручную запускать звук с правильным интервалом.

Вы можете использовать AudioTrack для воспроизведения непрерывного потока данных PCM, так как вы передадите поток, вы можете быть уверены в интервалах между звуками. Недостатком может быть небольшая задержка при первом запуске звука, но это зависит от минимального размера буфера, и это зависит, на мой взгляд, от версии и устройства Android. На моей галактике s2 android 4.1 было около 20 мс.
Если вы считаете, что это может быть вариант, я могу опубликовать код

Я не могу воспроизвести проблему на Galaxy Nexus и Nexus S, значит ли это, что я ее исправил? Или, может быть, вы могли бы показать, что вы делаете иначе:

 SoundPool soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100); Integer sound1 = soundPool.load(this, R.raw.file1, 1); Integer sound2 = soundPool.load(this, R.raw.file2, 1); playSound(sound1); public void playSound(int sound) { AudioManager mgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE); float volume = mgr.getStreamVolume(AudioManager.STREAM_MUSIC) / mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC); soundPool.play(sound, volume, volume, 1, -1, 1.0f); } 

Если проблема в том, что вы хотите контролировать интервал между дискретными звуками, самый простой способ сделать это с помощью обработчика.

В основном вы начинаете звуковое воспроизведение, которое является асинхронным процессом. Затем вы используете обработчик для планирования сообщения для воспроизведения следующего звука в будущем. Для правильной работы потребуется проб и ошибок, но вам гарантируется, что звук начнется с того же интервала после предыдущего звука на каждом устройстве.

Вот какой код, чтобы проиллюстрировать то, о чем я говорю.

Вот реализация обработчика, которую вы могли бы использовать:

  handler = new Handler() { /* (non-Javadoc) * @see android.os.Handler#handleMessage(android.os.Message) */ @Override public void handleMessage(Message msg) { if (msg.what == NEXT_ITEM_MSG) { playNextSound(); } else if (msg.what == SEQUENCE_COMPLETE_MSG) { // notify a listener listener.onSoundComplete() } } }; 

Тогда вы можете написать playNextSound следующим образом:

 private void playNextSound() { if (mRunning) { // Get the first item SoundSequenceItem item = currentSequence.getNextSequenceItem(); if (item == null) { Message msg = handler.obtainMessage(SEQUENCE_COMPLETE_MSG); handler.sendMessage(msg); return; } // Play the sound int iSoundResId = item.getSoundResId(); if (iSoundResId != -1) { player.playSoundNow(soundResId); } // schedule a message to advance to next item after duration Message msg = handler.obtainMessage(NEXT_ITEM_MSG); handler.sendMessageDelayed(msg, item.getDuration()); } } 

И ваш SoundSequenceItem может быть просто классом, который имеет идентификатор файла звукового файла и продолжительность. Если вы хотите продолжать воспроизведение звука во время движения персонажа, вы можете сделать что-то вроде этого:

 public void onSoundComplete() { if (character.isRunning()) { currentSequence.addSequenceItem(new SoundSequenceItem(R.id.footsteps,500); playNextSound(); } } 

Или вы можете изменить playNextSound, чтобы постоянно воспроизводить тот же звук. Mine написано таким образом, чтобы иметь возможность воспроизводить разные звуки в последовательности.

У меня было много проблем с разработкой приложений, которые использовали звуки и тому подобное. Я не предлагаю вам использовать SoundPool, так как он поврежден, и также помните, что звуки цикла с SoundPool не будут работать на устройствах с 4.3 и выше, см. Эту открытую проблему в AOSP – Issue tracker . Я думаю, что решение состоит в том, чтобы пойти на родной язык и использовать OpenSL ES o аналогичные библиотеки.