Как работают мидичи в обертоне?
Я пытаюсь добавить некоторую микротональную функциональность к обертону, но у меня возникают проблемы, когда дело доходит до работы с промежуточными функциями, что, кажется, является требованием для работы с миди-вводом.
Это то, что я хочу:
(definst instrument [note 64 amp 0.5 gate 1]
(* amp (lpf (lf-tri (foo note) ) 1100)
(env-gen (adsr 0.1 0.2 2 2 0.3) gate :action FREE)))
foo - это функция, которая принимает значение midi и отображает его в значение в hz (вроде как midicps), однако приведенный выше код работает неправильно.
Для тестирования я определил foo как:
(defn foo [x] (if (= 64 x) 880 440))
Таким образом, (instrument 64)
должен играть ноту на октаву выше, чем любой другой foo, но это не так.
Я верю, что происходит то, что когда я бегу (instrument x)
, он передает что-то еще (событие midi?) в foo вместо целого числа.
Каждый раз, когда я пытаюсь бежать midi->hz
над midicps
Я получаю ошибку:
CompilerException java.lang.ClassCastException: overtone.sc.machinery.ugen.sc_ugen.SCUGen
cannot be cast to java.lang.Number, compiling:(form-init7628662755818333410.clj:1:1)
Вызов midi->hz для заметки без midicps приводит к той же ошибке.
Как мне преобразовать этот ugen (или миди-событие) в целое число, представляющее миди-ноту?
Примечание: я использую midi-poly-player
добавить обработчик MIDI для моего инструмента. Я могу заставить свою функцию отображения высоты тона работать, если я просто создаю обычный обработчик событий, но я бы предпочел использовать midi-poly-player
поэтому мне не нужно повторно реализовывать все его функциональные возможности.
1 ответ
Вы смешиваете scsynth ugens и код Clojure, когда вызываете функцию foo следующим образом. Внутри определенно, это макрос, который берет этот код Clojure и преобразует его в код синтезатора суперколлайдера. Я на самом деле не понимаю, почему код ведет себя так, как он делает, но я думаю, что могу показать вам, как заставить его делать то, что вы хотите. Просто держите код в определенном макросе.
Вот функция midi->hz в Clojure. Midicps делает это как Ugen в суперколлайдере для вас:
(defn midi->hz
"Convert a midi note number to a frequency in hz."
[note]
(* 440.0 (java.lang.Math/pow 2.0 (/ (- note 69.0) 12.0))))
Вы можете просто вставить это примечание-> преобразование частоты в своем определении:
(definst instrument2 [note 64 amp 0.5 gate 1]
(let [freq (* 440.0 (pow 2.0 (/ (- note 69.0) 12.0)))]
(* amp (lpf (lf-tri freq) 1100)
(env-gen (adsr 0.1 0.2 2 2 0.3) gate :action FREE))))
и слушайте стандартные 12 нот на шкалу, например:
(def x (instrument2 69))
(ctl x :gate 0)
(def x (instrument2 70))
(ctl x :gate 0)
(def x (instrument2 71))
(ctl x :gate 0)
например, чтобы настроить больше тонов на октаву, это дает 24...
(definst instrument3 [note 64 amp 0.5 gate 1]
(let [freq (* 440.0 (pow 2.0 (/ (- note 69.0) 24.0)))]
(* amp (lpf (lf-tri freq) 1100)
(env-gen (adsr 0.1 0.2 2 2 0.3) gate :action FREE))))
(def x (instrument3 69))
(ctl x :gate 0)
(def x (instrument3 70))
(ctl x :gate 0)
(def x (instrument3 71))
(ctl x :gate 0)
Я слышу серию маленьких шагов. Я надеюсь, что вы тоже.
Ура,
Роджер