Как работают мидичи в обертоне?

Я пытаюсь добавить некоторую микротональную функциональность к обертону, но у меня возникают проблемы, когда дело доходит до работы с промежуточными функциями, что, кажется, является требованием для работы с миди-вводом.

Это то, что я хочу:

(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)

Я слышу серию маленьких шагов. Я надеюсь, что вы тоже.

Ура,

Роджер

Другие вопросы по тегам