Как синхронизировать анимацию JavaScript с темпом песни, не создавая «аудио-визуализатор»? - PullRequest
4 голосов
/ 01 декабря 2011

Исходя из моего базового понимания, аудио-визуализаторы JavaScript отражают музыку на основе реальных звуковых волн.Я хотел бы построить что-то вроде метронома (http://bl.ocks.org/1399233),, где я анимирую некоторый элемент DOM каждые x удары.

Теперь я делаю это вручную, определяя темп песни,скажем, это 120bpm, затем я преобразую это в миллисекунды для выполнения обратного вызова * 1005. * Но это, похоже, не работает, потому что производительность браузера делает его неточным. Есть ли лучший способ убедиться, что обратный вызов выполняется точно вв том же темпе, в котором находится песня?

Если нет, каковы другие стратегии синхронизации анимации JavaScript с темпом песни, который не является аудио-визуализатором?

Обновление: примерно так это выглядит? https://github.com/bestiejs/benchmark.js/blob/master/benchmark.js#L1606

Ответы [ 2 ]

6 голосов
/ 01 декабря 2011

У меня была похожая проблема, в которой setInterval нельзя было полагаться на то, чтобы "держать время" в течение длительного периода.Моим решением был приведенный ниже фрагмент: (в сценарии кофе скомпилированный js находится в конце ссылки)

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

accurateInterval(1000 * 60 / bpm, callbackFunc);

См. Мой пример использования и пример, который синхронизирует визуалы с предоставленным BPM для видео на YouTube здесь: http://squeegy.github.com/MandalaTron/?bpm=64&vid=EaAzRm5MfY8&vidt=0.5&fullscreen=1

correctInterval code:

# Accurate Interval, guaranteed not to drift!
# (Though each call can still be a few milliseconds late)
window.accurateInterval = (time, fn) ->

  # This value is the next time the the timer should fire.
  nextAt = new Date().getTime() + time

  # Allow arguments to be passed in in either order.
  if typeof time is 'function'
    [fn, time] = [time, fn]

  # Create a function that wraps our function to run.  This is responsible for
  # scheduling the next call and aborting when canceled.
  wrapper = ->
    nextAt += time
    wrapper.timeout = setTimeout wrapper, nextAt - new Date().getTime()
    fn()

  # Clear the next call when canceled.
  wrapper.cancel = -> clearTimeout wrapper.timeout

  # Schedule the first call.
  setTimeout wrapper, nextAt - new Date().getTime()

  # Return the wrapper function so cancel() can later be called on it.
  return wrapper

получите сценарий с кофе и js здесь: https://gist.github.com/1d99b3cd81d610ac7351

2 голосов
/ 01 декабря 2011

Возможно, этот пост актуален:

Суть в том, что вы запускаете функцию в вашем setInterval() немного быстрее, чем ваш темп, например, каждые 100 мс. Если коротко, вы можете отследить, действительно ли пришло время сыграть «удар», проверив значение (new Date()).getMilliseconds() и увидев, прошел ли эквивалент одного удара в миллисекундах, вместо того чтобы полагаться на не очень точный setTimeout или setInterval функции.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...