<commit_before>(in-package :cl-patterns)

(midihelper:start-midihelper)

(defparameter *midi-channels-instruments* (make-list 16 :initial-element 0))

;; backend functions

(defun is-midi-event-p (event)
  (or (eq (event-value event :type) :midi)
      (typep (event-value event :instrument) 'number)))

(defun play-midi (event &optional task)
  (declare (ignore task))
  (let* ((channel (or (event-value event :channel)
                      0))
         (pgm (and (typep (event-value event :instrument) 'number)
                   (truncate (event-value event :instrument))))
         (note (truncate (event-value event :midinote)))
         (velocity (round (* 127 (event-value event :amp)))) ;; FIX: maybe this shouldn't be linear
         (time (local-time:timestamp+ (or (raw-event-value event :timestamp-at-start) (local-time:now))
                                      (truncate (* (or (raw-event-value event :latency) *latency*) 1000000000))
                                      :nsec)))
    (bt:make-thread (lambda ()
                      (sleep (local-time:timestamp-difference time (local-time:now)))
                      (when (and pgm
                                 (not (= pgm (nth channel *midi-channels-instruments*))))
                        (midihelper:send-event (midihelper:ev-pgmchange channel pgm)))
                      (midihelper:send-event (midihelper:ev-noteon channel note velocity))
                      (sleep (dur-time (sustain event)))
                      (midihelper:send-event (midihelper:ev-noteoff channel note velocity)))
                    :name "cl-patterns temporary midi note thread")))

(defun release-midi (&rest foo)
  (declare (ignore foo))
  ;; FIX
  nil
  )

(defun release-midi-at (&rest foo)
  (declare (ignore foo))
  ;; FIX
  nil
  )

(defun timestamp-to-midi (timestamp)
  (declare (ignore timestamp))
  ;; FIX
  nil
  )

(register-backend :midi<commit_msg>add :pan support via CC; clamp values within acceptable ranges<commit_after>(in-package :cl-patterns)

(midihelper:start-midihelper)

(defparameter *midi-channels-instruments* (make-list 16 :initial-element 0))

;;; backend functions

(defun is-midi-event-p (event)
  (or (eq (event-value event :type) :midi)
      (typep (event-value event :instrument) 'number)))

(defun play-midi (event &optional task)
  (declare (ignore task))
  (let* ((channel (alexandria:clamp (or (event-value event :channel)
                                        0)
                                    0 15))
         (pgm (alexandria:clamp (and (typep (event-value event :instrument) 'number)
                                     (truncate (event-value event :instrument)))
                                0 127))
         (pan (alexandria:clamp (ceiling (* 63.5 (1+ (event-value event :pan)))) 0 127))
         (note (alexandria:clamp (truncate (event-value event :midinote)) 0 127))
         (velocity (alexandria:clamp (round (* 127 (event-value event :amp))) 0 127)) ;; FIX: maybe this shouldn't be linear?
         (time (local-time:timestamp+ (or (raw-event-value event :timestamp-at-start) (local-time:now))
                                      (truncate (* (or (raw-event-value event :latency) *latency*) 1000000000))
                                      :nsec)))
    (bt:make-thread (lambda ()
                      (sleep (local-time:timestamp-difference time (local-time:now)))
                      (when (and pgm
                                 (not (= pgm (nth channel *midi-channels-instruments*))))
                        (midihelper:send-event (midihelper:ev-pgmchange channel pgm)))
                      (midihelper:send-event (midihelper:ev-cc channel 10 pan))
                      (midihelper:send-event (midihelper:ev-noteon channel note velocity))
                      (sleep (dur-time (sustain event)))
                      (midihelper:send-event (midihelper:ev-noteoff channel note velocity)))
                    :name "cl-patterns temporary midi note thread")))

(defun release-midi (&rest foo)
  (declare (ignore foo))
  ;; FIX
  nil
  )

(defun release-midi-at (&rest foo)
  (declare (ignore foo))
  ;; FIX
  nil
  )

(defun timestamp-to-midi (timestamp)
  (declare (ignore timestamp))
  ;; FIX
  nil
  )

(register-backend :midi
{'fraction_non_alphanumeric': 0.12942555685814772, 'fraction_numerical': 0.013833528722157092, 'mean_word_length': 2.120702267739576, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4083567', 'n_tokens_mistral': 1359, 'n_tokens_neox': 1247, 'n_words': 333}