defaultxr / cl-patterns

Library for writing patterns to generate or process (a)musical sequences of mathematically (un)related (non-)compound values in Lisp.
https://w.struct.ws/cl-patterns
MIT License
76 stars 10 forks source link

midi backend: add pitchbend #42

Closed ntrocado closed 9 months ago

ntrocado commented 9 months ago

Adds the :bend key in the context of the alsa-midi backend. :bend accepts values from -1 to +1. How these values translate into semitones varies widely according to each specific midi device.

This PR depends on this cl-alsaseq update.

To test:

;; Simultaneous note and pitchbend
(pb :detune/microtones
  :instrument 0
  :midinote 60
  :bend (pseq (list (pseries 0 -.1 10) (pseries 0 .1 10)))
  :dur 1/4)

(play :detune/microtones)

;; Play a key and adjust the pitch wheel afterwards
(pb :c
  :type :note
  :instrument 0
  :midinote 60
  :dur 2)

(pb :pitchbend
  :type :set
  :instrument 0
  :dur 1
  :bend (pseq (list 0 (pwhite -1.0 1.0 1))))

(play (ppar '(:c :pitchbend)))
ntrocado commented 9 months ago

To test the latest commit:

Set *alsa-midi-pitchbend-range* for the pitchbend range of the midi device (the default is 2, which is a common value).

(play
 (pb :foo
   :instrument 0
   :freq (pseries 440 -10 10)))
defaultxr commented 9 months ago

Thanks for this! Good to have a few of the todo items crossed off. :)

Before I merge, could you please make these changes:

Thanks again for your patches! :pray:

ntrocado commented 9 months ago
  • Add pitchbend-range as an optional argument to bipolar-1-to-midi-pitchbend (with *alsa-midi-pitchbend-range* as the default)

I'm not sure if I understand this point... I was conceptualizing bipolar-1-to-midi-pitchbend as a conversion from -1..1 to the midi spec range of -8192..8191. This way you would specify :bend as the position of the pitchbend wheel found on most synths: 0 is neutral, 1 full up, -1 full down. The consideration of the pitchbend range is more high-level, and in this scheme it only matters for freq->bend conversion or for translating fractional midinote numbers (e.g. 60.5 for a half-sharp C). This is taken care of by the pitchbend-midi function.

If I'm not mistaken it would only make sense to add pitchbend-range as an argument to bipolar-1-to-midi-pitchbend if we wanted to convert pitchbend semitones to midi. I can create a new function like this in conversions.lisp. It does seem cleaner than to have the calculation inside pitchbend-midi.

Another way is to always represent pitchbend in semitones, so one would write e.g. bend:-12 for octave down instead of bipolar values. Do you prefer this?

defaultxr commented 9 months ago

If I'm not mistaken it would only make sense to add pitchbend-range as an argument to bipolar-1-to-midi-pitchbend if we wanted to convert pitchbend semitones to midi. I can create a new function like this in conversions.lisp. It does seem cleaner than to have the calculation inside pitchbend-midi.

Ahh, okay, yeah, that makes sense. Yes, the current function should be fine as is.

defaultxr commented 9 months ago

Merged, thanks again! :)