Intereting Posts
Тег метаданных в AndroidManifest.xml вашего приложения не имеет правильного значения Услуги Android: START_STICKY не работает в Kitkat Посредничество AdMob (Android и iOS): как заставить сеть протестировать его? Android.process.acore неожиданно остановился Android OpenGL ES и 2D Eclipse: не позволит мне использовать Android SDK, ошибочно утверждает, что мой ADT устарел Как я могу отправить данные результатов из широковещательного приемника на активность ActionBar Шерлок Пункт меню OnClick Как я могу очистить уведомление при нажатии кнопки Ошибки сборки Gradle после обновления Android Studio Как совместно использовать изображение + текст, используя ACTION_SEND в android? AdMob из Служб Google Play будет выполнять нежелательную автоматическую прокрутку Как сделать наложение при совместном использовании в приложении в Android? Выбор WebView заставляет мягкую клавиатуру временно скрываться, а затем возвращаться NoSuchMethodError com.google.android.gms.internal.gf

Как воспроизводить звуки в точные периоды времени на разных устройствах в 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 аналогичные библиотеки.