"Play" звучит в формате.wav
Я пытаюсь сделать программу, которая может конвертировать файлы ORG в файлы WAV напрямую. Формат ORG похож на MIDI в том смысле, что он представляет собой список "инструкций" о том, когда и как следует играть на определенных инструментах, и программа воспроизводит эти инструменты для создания песни.
Однако, как я уже сказал, я хочу генерировать WAV напрямую, а не просто играть в ORG. Так что, в некотором смысле, я хочу "воспроизвести" звуки в формате WAV. Я знаю формат WAV и создал несколько файлов из необработанных образцов PCM, но это не так просто.
Звуки, генерируемые ORG, исходят из группы файлов, содержащих сэмплы WAV, которые у меня есть. Они моно, 8-битные сэмплы должны воспроизводиться на частоте 22050 Гц. Они все менее чем за секунду, а самые большие не более 11 КБ. Я бы предположил, что для воспроизведения их всех друг за другом, я просто поместил бы сэмплы в WAV один за другим. Однако это не так просто, поскольку в ORG может одновременно играть до 16 различных инструментов, и каждая нота каждого инструмента также имеет панораму (то есть баланс, позволяющий воспроизводить стереозвук). Более того, каждый ORG имеет свой собственный темп (т. Е. Миллисекунды между каждой точкой, в которой может воспроизводиться звук), и некоторые звуки могут быть длиннее этого темпа, что означает, что два звука на одном инструменте могут перекрываться. Например, нота играет на инструменте, спустя 90 миллисекунд такая же нота играет на том же инструменте, но первая еще не закончена, поэтому первая нота играет во вторую.
Я просто подумал объяснить все это, чтобы быть уверенным, что ситуация ясна. В любом случае, мне бы хотелось узнать, как бы я конвертировал или "проигрывал" ORG (или, если хотите, MIDI (поскольку они по сути одинаковые)) в WAV. Как я уже упоминал, каждая нота имеет панорамирование / баланс, поэтому WAV также должен быть стереофоническим.
Если это вообще имеет значение, я буду делать это в ActionScript 3.0 во FlashDevelop. Мне не нужен какой-либо код (так как это потребовало бы, чтобы кто-то сделал работу за меня), но я просто хочу знать, как бы я поступил правильно. Алгоритм или два могут быть также полезны.
1 ответ
Прежде всего позвольте мне сказать, что AS3 не лучший язык для подобных вещей. Супер коллайдер будет лучшим и более легким выбором.
Но если вы хотите сделать это в AS3, вот общий подход. Я не проверял ничего из этого, это чистая теория.
Сначала поместите все свои звуки в массив, а затем найдите способ сопоставления нот из вашего файла midi с позицией в массиве.
Я не знаю формат midi подробно, но я знаю, что наименьшее значение - это тик, и длина тика зависит от BPM. Вот формула для вычисления миди-тика: Миди- тики до фактических секунд PlayBack!!! (Midi Music)
Допустим, ваш тик имеет длину 2 мс. Так что теперь у вас есть базовое значение. Вы можете заполнить Vector
(как Array
но быстрее) с тем, что происходит на каждом тике. Если ничего не происходит на определенном тике, вставьте нулевое значение.
Теперь большая проблема заключается в чтении этого Vector
, Это проблема, потому что Timer
класс не работает при небольших значениях, таких как 2 мс. Но то, что вы можете сделать, это проверить прошедшее время в мс, так как приложение начало использовать getTimer()
, У вас может быть какой-то цикл, который будет проверять истекшее время, и когда у вас есть еще 2 мс, вы читаете следующий индекс в Vector
, Если на этом указателе есть примечания, вы воспроизводите звуки. Если нет, то ждите следующего тика.
Проблема заключается в том, что если цикл продолжается более 15 секунд (я не уверен в этом значении), Flash будет считать, что программа не отвечает, и уничтожит ее. Таким образом, вы должны позаботиться об этом, заканчивая цикл и открывая новый, прежде чем Flash убьет вашу программу.
Хорошо, теперь у вас есть играющие звуки. Вы можете записывать звуки, которые издает флеш (wavs, mp3, mic) с библиотекой Standing Wave 3.
https://github.com/maxl0rd/standingwave3
Это очень теоретически... и я вполне уверен, что в зависимости от количества звуков, которые вы хотите воспроизвести, вы можете заморозить вашу программу... но я надеюсь, что это поможет вам начать работу.