From 6cbfcca39cab51d8b404f632947565afb2df5e45 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Sun, 17 Dec 2023 21:00:26 -0500 Subject: [PATCH 01/11] Initial split of music ops out of maths, and setup out of hardware --- .gitignore | 2 +- docs/Makefile | 14 +- .../{cheatsheet.tex => cheatsheet-common.tex} | 0 docs/ops/hardware.toml | 95 +------ docs/ops/hardware_setup.md | 1 + docs/ops/hardware_setup.toml | 91 ++++++ docs/ops/maths.toml | 259 +----------------- docs/ops/music.md | 3 + docs/ops/music.toml | 257 +++++++++++++++++ docs/ops/variables.toml | 40 ++- utils/cheatsheet.py | 89 +++--- utils/docs.py | 2 + 12 files changed, 434 insertions(+), 419 deletions(-) rename docs/cheatsheet/{cheatsheet.tex => cheatsheet-common.tex} (100%) create mode 100644 docs/ops/hardware_setup.md create mode 100644 docs/ops/hardware_setup.toml create mode 100644 docs/ops/music.md create mode 100644 docs/ops/music.toml diff --git a/.gitignore b/.gitignore index 1e3381d2..ac9b6a4c 100644 --- a/.gitignore +++ b/.gitignore @@ -53,5 +53,5 @@ __pycache__/ /docs/teletype.pdf /docs/teletype.html /docs/cheatsheet/* -!/docs/cheatsheet/cheatsheet.tex +!/docs/cheatsheet/cheatsheet-common.tex /docs/testServe/ diff --git a/docs/Makefile b/docs/Makefile index ccecdb26..4e0e175f 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,6 +1,6 @@ .PHONY: build clean -build: teletype.pdf teletype.html cheatsheet/cheatsheet.pdf +build: teletype.pdf teletype.html cheatsheet/cheatsheet-core.pdf cheatsheet/cheatsheet-i2c.pdf clean: rm -f teletype.pdf && \ @@ -18,8 +18,12 @@ teletype.html: $(wildcard *.md ops/*.md ops/*.toml) \ ../utils/docs.py ../CHANGELOG.md $(wildcard ../utils/templates/*) ../utils/docs.py teletype.html -cheatsheet/include.tex: $(wildcard ops/*.toml) ../utils/cheatsheet.py - ../utils/cheatsheet.py "cheatsheet/include.tex" +cheatsheet/cheatsheet-%.pdf: $(wildcard ops/*.toml) ../utils/cheatsheet.py cheatsheet/cheatsheet.tex + ../utils/cheatsheet.py $* "cheatsheet/include.tex" + cd cheatsheet && latexmk -xelatex cheatsheet.tex -jobname=cheatsheet-$* -cheatsheet/cheatsheet.pdf: cheatsheet/cheatsheet.tex cheatsheet/include.tex - cd cheatsheet && latexmk -xelatex cheatsheet.tex +cheatsheet/%.tex: $(wildcard ops/*.toml) ../utils/cheatsheet.py + ../utils/cheatsheet.py $* "cheatsheet/$*.tex" + +cheatsheet/%.pdf: cheatsheet/cheatsheet.tex cheatsheet/include.tex + cd cheatsheet && latexmk -xelatex cheatsheet-common.tex -jobname=$* \ No newline at end of file diff --git a/docs/cheatsheet/cheatsheet.tex b/docs/cheatsheet/cheatsheet-common.tex similarity index 100% rename from docs/cheatsheet/cheatsheet.tex rename to docs/cheatsheet/cheatsheet-common.tex diff --git a/docs/ops/hardware.toml b/docs/ops/hardware.toml index f5a34e6f..3c40c0ff 100644 --- a/docs/ops/hardware.toml +++ b/docs/ops/hardware.toml @@ -6,6 +6,7 @@ description = """ Get the value of CV associated with output `x`, or set the CV output of `x` to `y`. """ +see_also = "`V` and `VV` in Maths, `N` in Musical Maths, `CV.CAL` in Hardware Setup" ["CV.OFF"] prototype = "CV.OFF x" @@ -40,51 +41,13 @@ Get the slew time in ms associated with CV output `x`. Set the slew time associated with CV output `x` to `y` ms. """ -["CV.CAL"] -prototype = "CV.CAL n mv1v mv3v" -short = "Calibrate CV output `n`" -description = """ -Following a short calibration procedure, you can use `CV.CAL` to more -precisely match your CV outputs to each other or to an external reference. A -digital multimeter (or other voltage measuring device) is required. - -To calibrate CV 1, first set it to output one volt with `CV 1 V 1`. Using -a digital multimeter with at least millivolt precision (three digits after -the decimal point), record the measured output of CV 1 between tip and sleeve -on a patch cable. Then set CV 1 to three volts with `CV 1 V 3` and measure -again. - -Once you have both measurements, use the observed 1V and 3V values in -millivolts as the second and third arguments to `CV.CAL`. For example, if you -measured 0.990V and 2.984V, enter `CV.CAL 1 990 2984`. (If both your -measurements are within 1 or 2 millivolts already, there's no need to run -`CV.CAL`.) - -Measure the output with `CV 1 V 1` and `CV 1 V 3` again and confirm the values -are closer to the expected 1.000V and 3.000V. - -Repeat the above steps for CV 2-4, if desired. The calibration data is stored -in flash memory so you only need to go through this process once. - -Note: The calibration adjustment is made after `CV.SLEW` and `CV.OFF` are -applied, and does not affect `CV.GET` or any other scene-visible values. It -only affects the levels coming out of the DAC. -""" - -["CV.CAL.RESET"] -prototype = "CV.CAL.RESET n" -short = "Reset calibration data for CV output `n`" -description = """ -Clear the calibration data for CV output `n` and return it to its default -behavior, with no calibration adjustment. -""" - ["IN"] prototype = "IN" short = "Get the value of IN jack (0-16383)" description = """ Get the value of the IN jack. This returns a valuue in the range 0-16383. """ +see_also = "`IN.CAL` ops in Hardware Setup" ["IN.SCALE"] prototype = "IN.SCALE min max" @@ -97,56 +60,12 @@ short = "Get the value of PARAM knob (0-16383)" description = """ Get the value of the PARAM knob. This returns a valuue in the range 0-16383. """ +see_also = "`PARAM.CAL` ops in Hardware Setup" ["PARAM.SCALE"] prototype = "PARAM.SCALE min max" short = "Set static scaling of the PARAM knob to between `min` and `max`." -["IN.CAL.MIN"] -prototype = "IN.CAL.MIN" -short = "Reads the input CV and assigns the voltage to the zero point" -description = """ - 1. Connect a patch cable from a calibrated voltage source - 2. Set the voltage source to 0 volts - 3. Execute IN.CAL.MIN from the live terminal - 4. Call IN and confirm the 0 result -""" - -["IN.CAL.MAX"] -prototype = "IN.CAL.MAX" -short = "Reads the input CV and assigns the voltage to the max point" -description = """ - 5. Set the voltage source to target maximum voltage (10V) - 6. Execute IN.CAL.MAX from the live terminal - 7. Call IN and confirm that the result is 16383 -""" - -["IN.CAL.RESET"] -prototype = "IN.CAL.RESET" -short = "Resets the input CV calibration" - -["PARAM.CAL.MIN"] -prototype = "PARAM.CAL.MIN" -short = "Reads the Parameter Knob minimum position and assigns a zero value" -description = """ - 1. Turn the PARAM knob all the way to the left - 2. Execute PARAM.CAL.MIN from the live terminal - 3. Call PARAM and confirm the 0 result -""" - -["PARAM.CAL.MAX"] -prototype = "PARAM.CAL.MAX" -short = "Reads the Parameter Knob maximum position and assigns the maximum point" -description = """ - 4. Turn the knob all the way to the right - 5. Execute PARAM.CAL.MAX from the live terminal - 6. Call PARAM and verify that the result is 16383 -""" - -["PARAM.CAL.RESET"] -prototype = "PARAM.CAL.RESET" -short = "Resets the Parameter Knob calibration" - ["TR"] prototype = "TR x" prototype_set = "TR x y" @@ -205,14 +124,6 @@ description = """ Read the current state of trigger input `x` (0=low, 1=high). """ -["DEVICE.FLIP"] -prototype = "DEVICE.FLIP" -short = "Flip the screen/inputs/outputs" -description = """ -Flip the screen, the inputs and the outputs. This op is useful if you want to mount your Teletype upside down. -The new state will be saved to flash. -""" - ["LIVE.OFF"] prototype = "LIVE.OFF" aliases = ["LIVE.O"] diff --git a/docs/ops/hardware_setup.md b/docs/ops/hardware_setup.md new file mode 100644 index 00000000..8faf9fa0 --- /dev/null +++ b/docs/ops/hardware_setup.md @@ -0,0 +1 @@ +# Hardware Setup \ No newline at end of file diff --git a/docs/ops/hardware_setup.toml b/docs/ops/hardware_setup.toml new file mode 100644 index 00000000..261113c1 --- /dev/null +++ b/docs/ops/hardware_setup.toml @@ -0,0 +1,91 @@ +["DEVICE.FLIP"] +prototype = "DEVICE.FLIP" +short = "Flip the screen/inputs/outputs" +description = """ +Flip the screen, the inputs and the outputs. This op is useful if you want to mount your Teletype upside down. +The new state will be saved to flash. +""" + +["IN.CAL.MIN"] +prototype = "IN.CAL.MIN" +short = "Reads the input CV and assigns the voltage to the zero point" +description = """ + 1. Connect a patch cable from a calibrated voltage source + 2. Set the voltage source to 0 volts + 3. Execute IN.CAL.MIN from the live terminal + 4. Call IN and confirm the 0 result +""" + +["IN.CAL.MAX"] +prototype = "IN.CAL.MAX" +short = "Reads the input CV and assigns the voltage to the max point" +description = """ + 5. Set the voltage source to target maximum voltage (10V) + 6. Execute IN.CAL.MAX from the live terminal + 7. Call IN and confirm that the result is 16383 +""" + +["IN.CAL.RESET"] +prototype = "IN.CAL.RESET" +short = "Resets the input CV calibration" + +["PARAM.CAL.MIN"] +prototype = "PARAM.CAL.MIN" +short = "Reads the Parameter Knob minimum position and assigns a zero value" +description = """ + 1. Turn the PARAM knob all the way to the left + 2. Execute PARAM.CAL.MIN from the live terminal + 3. Call PARAM and confirm the 0 result +""" + +["PARAM.CAL.MAX"] +prototype = "PARAM.CAL.MAX" +short = "Reads the Parameter Knob maximum position and assigns the maximum point" +description = """ + 4. Turn the knob all the way to the right + 5. Execute PARAM.CAL.MAX from the live terminal + 6. Call PARAM and verify that the result is 16383 +""" + +["PARAM.CAL.RESET"] +prototype = "PARAM.CAL.RESET" +short = "Resets the Parameter Knob calibration" + +["CV.CAL"] +prototype = "CV.CAL n mv1v mv3v" +short = "Calibrate CV output `n`" +description = """ +Following a short calibration procedure, you can use `CV.CAL` to more +precisely match your CV outputs to each other or to an external reference. A +digital multimeter (or other voltage measuring device) is required. + +To calibrate CV 1, first set it to output one volt with `CV 1 V 1`. Using +a digital multimeter with at least millivolt precision (three digits after +the decimal point), record the measured output of CV 1 between tip and sleeve +on a patch cable. Then set CV 1 to three volts with `CV 1 V 3` and measure +again. + +Once you have both measurements, use the observed 1V and 3V values in +millivolts as the second and third arguments to `CV.CAL`. For example, if you +measured 0.990V and 2.984V, enter `CV.CAL 1 990 2984`. (If both your +measurements are within 1 or 2 millivolts already, there's no need to run +`CV.CAL`.) + +Measure the output with `CV 1 V 1` and `CV 1 V 3` again and confirm the values +are closer to the expected 1.000V and 3.000V. + +Repeat the above steps for CV 2-4, if desired. The calibration data is stored +in flash memory so you only need to go through this process once. + +Note: The calibration adjustment is made after `CV.SLEW` and `CV.OFF` are +applied, and does not affect `CV.GET` or any other scene-visible values. It +only affects the levels coming out of the DAC. +""" + +["CV.CAL.RESET"] +prototype = "CV.CAL.RESET n" +short = "Reset calibration data for CV output `n`" +description = """ +Clear the calibration data for CV output `n` and return it to its default +behavior, with no calibration adjustment. +""" \ No newline at end of file diff --git a/docs/ops/maths.toml b/docs/ops/maths.toml index 1fd8e50a..8a928f91 100644 --- a/docs/ops/maths.toml +++ b/docs/ops/maths.toml @@ -62,32 +62,7 @@ short = "limit the value `x` to the range `y` to `z` inclusive, but with wrappin [QT] prototype = "QT x y" short = "round `x` to the closest multiple of `y` (quantise)" - -["QT.S"] -prototype = "QT.S x r s" -short = "quantize 1V/OCT signal `x` to scale `s` (0-8, reference N.S scales) with root 1V/OCT pitch `r`" - -["QT.CS"] -prototype = "QT.CS x r s d c" -short = "quantize 1V/OCT signal `x` to chord `c` (1-7) from scale `s` (0-8, reference N.S scales) at degree `d` (1-7) with root 1V/OCT pitch `r`" -description = """ -Quantize 1V/OCT signal `x` to chord `c` (1-7) from scale `s` (0-8, reference N.S scales) at degree `d` (1-7) with root 1V/OCT pitch `r`. - -Chords (1-7) - - `1` = Tonic - - `2` = Third - - `3` = Triad - - `4` = Seventh - - etc. -""" - -["QT.B"] -prototype = "QT.B x" -short = "quantize 1V/OCT signal `x` to scale defined by `N.B`" - -["QT.BX"] -prototype = "QT.BX i x" -short = "quantize 1V/OCT signal `x` to scale defined by `N.BX` in scale index `i`" +see_also = "`QT.S`, `QT.CS`, `QT.B`, `QT.BX` in Musical Maths" [AVG] prototype = "AVG x y" @@ -260,10 +235,6 @@ description = """ Logical OR of `x`, `y`, `z` and `a`. Returns `1` if either `x`, `y`, `z` or `a` are greater than `0`, otherwise it returns `0`. """ -[JI] -prototype = "JI x y" -short = "just intonation helper, precision ratio divider normalised to 1V" - [SCALE] prototype = "SCALE a b x y i" aliases = ["SCL"] @@ -274,234 +245,6 @@ prototype = "SCALE a b i" aliases = ["SCL0"] short = "scale `i` from range `0` to `a` to range `0` to `b`" -[ER] -prototype = "ER f l i" -short = "Euclidean rhythm, `f` is fill (`1-32`), `l` is length (`1-32`) and `i` is step (any value), returns `0` or `1`" -description=""" -Euclidean rhythm helper, as described by Godfried Toussaint in his 2005 paper ["The Euclidean Algorithm Generates Traditional Musical Rhythms"][euclidean_rhythm_paper][^euclidean_rhythm_citation]. From the abstract: - - - `f` is fill (`1-32`) and should be less then or equal to length - - `l` is length (`1-32`) - - `i` is the step index, and will work with negative as well as positive numbers - -If you wish to add rotation as well, use the following form: - -``` -ER f l SUB i r -``` - -where `r` is the number of step of _forward_ rotation you want. - -For more info, see the post on [samdoshi.com][samdoshi_com_euclidean] - -[samdoshi_com_euclidean]: http://samdoshi.com/post/2016/03/teletype-euclidean/ -[euclidean_rhythm_paper]: http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf -[^euclidean_rhythm_citation]: Toussaint, G. T. (2005, July). The Euclidean algorithm generates traditional musical rhythms. _In Proceedings of BRIDGES: Mathematical Connections in Art, Music and Science_ (pp. 47-56). -""" - -[NR] -prototype = "NR p m f s" -short = "Numeric Repeater, `p` is prime pattern (`0-31`), `m` is & mask (`0-3`), `f` is variation factor (`0-16`) and `s` is step (`0-15`), returns `0` or `1`" -description = """ -Numeric Repeater is similar to ER, except it generates patterns using the binary arithmetic process found in ["Noise Engineering's Numeric Repetitor"][numeric_repetitor]. From the description: - -Numeric Repetitor is a rhythmic gate generator based on binary arithmetic. A core pattern forms the basis and variation is achieved by treating this pattern as a binary number and multiplying it by another. NR contains 32 prime rhythms derived by examining all possible rhythms and weeding out bad ones via heuristic. - -All parameters wrap around their specified ranges automatically and support negative indexing. - -Masks - - `0` is no mask - - `1` is `0x0F0F` - - `2` is `0xF003` - - `3` is `0x1F0` - -For further detail ["see the manual"][nr_manual]. - -[numeric_repetitor]: https://www.noiseengineering.us/shop/numeric-repetitor -[nr_manual]: https://static1.squarespace.com/static/58c709192e69cf2422026fa6/t/5e6041ad4cbc0979d6d793f2/1583366574430/NR_manual.pdf -""" - -["DR.T"] -prototype = "DR.T b p q l s" -short = "Tresillo helper, `b` is the drum bank (`0-4`), `p` is first pattern (0-215), `q` is the second pattern (0-215), `l` is length (`1-64`), and step is the step number (0-length-1), returns `0` or `1`" -description = """ -The Tresillo helper uses the preset drum patterns described in the drum pattern help function in a 3, 3, 2 rythmic formation. In the tresillo, pattern 1 will be repeated twice for a number of steps determined by the overall length of the pattern. A pattern of length 8 will play the first three steps of your selected pattern 1 twice, and -the first two steps of pattern 2 once. A pattern length of 16 will play the first six steps of selected pattern 1 twice, and the first four steps of pattern 2 once. And so on. The max length is 64. Length will be rounded down to the nearest multiple of 8. The step number wraps at the given length. -""" - -["DR.P"] -prototype = "DR.P b p s" -short = "Drum pattern helper, `b` is the drum bank (`0-4`), `p` is the pattern (0-215) and step is the step number (0-15), returns `0` or `1`" -description = """ -The drum helper uses preset drum patterns to give 16-step gate patterns. Gates wrap after step 16. Bank 0 is a set of pseudo random gates increasing in density at higher numbered patterns, where pattern 0 is empty, -and pattern 215 is 1s. Bank 1 is bass drum patterns. Bank 2 is snare drum patterns. Bank 3 is closed hi-hats. Bank 4 is open hi-hits and in some cases cymbals. Bank 1-4 patterns are related to each other (bank 1 pattern 1's bass drum pattern fits bank 2 pattern 1's snare drum pattern). -The patterns are from [Paul Wenzel's "Pocket Operations" book](https://shittyrecording.studio/). -""" - -["DR.V"] -prototype = "DR.V p s" -short = "Velocity helper. `p` is the pattern (0-19). `s` is the step number (0-15)" -description = """ -The velocity helper gives velocity values (0-16383) at each step. The values are intended to be used for drum hit velocities. There are 16 steps, which wrap around. Divide by 129 to convert to midi cc values. -""" - -[BPM] -prototype = "BPM x" -short = "milliseconds per beat in BPM `x`" - -[N] -prototype = "N x" -short = "converts an equal temperament note number to a value usable by the CV outputs (`x` in the range `-127` to `127`)" -description = """ -The `N` OP converts an equal temperament note number to a value usable by the CV outputs. - -Examples: - -``` -CV 1 N 60 => set CV 1 to middle C, i.e. 5V -CV 1 N RAND 24 => set CV 1 to a random note from the lowest 2 octaves -``` -""" - -[VN] -prototype = "VN x" -short = "converts 1V/OCT value `x` to an equal temperament note number" - -[HZ] -prototype = "HZ x" -short = "converts 1V/OCT value `x` to Hz/Volt value, useful for controlling non-euro synths like Korg MS-20" - -["N.B"] -prototype = "N.B d" -prototype_set = "N.B r s" -short = "get degree `d` of scale/set scale root to `r`, scale to `s`, `s` is either bit mask (`s` >= 1) or scale preset (`s` < 1)" -description = """ -Converts a degree in a user-defined equal temperament scale to a value usable by the CV outputs. Default values of `r` and `s` are 0 and R101011010101, corresponding to C-major. -To make it easier to generate bit-masks in code, LSB (bit 0) represent the first note in the octave. To avoid having to mirror scales in our heads when entering them by hand, we use `R...` (reverse binary) instead of `B...` (binary ). - -The bit-masks uses the 12 lower bits. - -Note that N.B is using scale at index 0 as used by N.BX ,so N.B and N.BX 0 are equivalent. - -Examples: -``` -CV 1 N.B 1 ==> set CV 1 to 1st degree of default scale - (C, value corresponding to N 0) -N.B 0 R101011010101 ==> set scale to C-major (default) -CV 1 N.B 1 ==> set CV 1 get 1st degree of scale - (C, value corresponding to N 0) -N.B 2 R101011010101 ==> set scale to D-major -CV 1 N.B 3 ==> set CV 1 to 3rd degree of scale - (F#, value corresponding to N 6) -N.B 3 R100101010010 ==> set scale to Eb-minor pentatonic -CV 1 N.B 2 ==> set CV 1 to 2nd degree of scale - (Gb, value corresponding to N 6) -N.B 5 -3 ==> set scale to F-lydian using preset -``` -Values of `s` less than 1 sets the bit mask to a preset scale: -``` -0: Ionian (major) --1: Dorian --2: Phrygian --3: Lydian --4: Mixolydian --5: Aeolean (natural minor) --6: Locrian --7: Melodic minor --8: Harmonic minor --9: Major pentatonic --10: Minor pentatonic --11 Whole note (1st Messiaen mode) --12 Octatonic (half-whole, 2nd Messiaen mode) --13 Octatonic (whole-half) --14 3rd Messiaen mode --15 4th Messiaen mode --16 5th Messiaen mode --17 6th Messiaen mode --18 7th Messiaen mode --19 Augmented -``` -""" - -["N.BX"] -prototype = "N.BX i d" -prototype_set = "N.BX i r s" -short = "multi-index version of N.B, scale at `i` (index) 0 is shared with N.B" -description = """ -Multi-index version of N.B. Index `i` in the range 0-15, allows working with 16 independent scales. Scale at `i` 0 is shared with N.B. - -Examples: -``` -N.BX 0 0 R101011010101 ==> set scale at index 0 to C-major (default) -CV 1 N.BX 0 1 ==> set CV 1 to 1st degree of scale - (C, value corresponding to N 0) -N.BX 1 3 R100101010010 ==> set scale at index 1 to Eb-minor pentatonic -CV 1 N.BX 1 2 ==> set CV 1 to 2nd degree of scale - (Gb, value corresponding to N 6) -N.BX 2 5 -3 ==> set scale at index 2 to F-lydian using preset -``` - -""" - - -["N.S"] -prototype = "N.S r s d" -short = "Note Scale operator, `r` is the root note (`0-127`), `s` is the scale (`0-8`) and `d` is the degree (`1-7`), returns a value from the `N` table." -description = """ -The `N.S` OP lets you retrieve `N` table values according to traditional western scales. `s` and `d` wrap to their ranges automatically and support negative indexing. - -Scales - - `0` = Major - - `1` = Natural Minor - - `2` = Harmonic Minor - - `3` = Melodic Minor - - `4` = Dorian - - `5` = Phrygian - - `6` = Lydian - - `7` = Mixolydian - - `8` = Locrian -""" - -["N.C"] -prototype = "N.C r c d" -short = "Note Chord operator, `r` is the root note (`0-127`), `c` is the chord (`0-12`) and `d` is the degree (`0-3`), returns a value from the `N` table." -description = """ -The `N.C` OP lets you retrieve `N` table values according to traditional western chords. `c` and `d` wrap to their ranges automatically and support negative indexing. - -Chords - - `0` = Major 7th `{0, 4, 7, 11}` - - `1` = Minor 7th `{0, 3, 7, 10}` - - `2` = Dominant 7th `{0, 4, 7, 10}` - - `3` = Diminished 7th `{0, 3, 6, 9}` - - `4` = Augmented 7th `{0, 4, 8, 10}` - - `5` = Dominant 7b5 `{0, 4, 6, 10}` - - `6` = Minor 7b5 `{0, 3, 6, 10}` - - `7` = Major 7#5 `{0, 4, 8, 11}` - - `8` = Minor Major 7th `{0, 3, 7, 11}` - - `9` = Diminished Major 7th `{0, 3, 6, 11}` - - `10` = Major 6th `{0, 4, 7, 9}` - - `11` = Minor 6th `{0, 3, 7, 9}` - - `12` = 7sus4 `{0, 5, 7, 10}` - """ - -["N.CS"] -prototype = "N.CS r s d c" -short = "Note Chord Scale operator, `r` is the root note (`0-127`), `s` is the scale (`0-8`), `d` is the scale degree (`1-7`) and `c` is the chord component (`0-3`), returns a value from the `N` table." -description = """ -The `N.CS` OP lets you retrieve `N` table values according to traditional western scales and chords. `s`, `c` and `d` wrap to their ranges automatically and support negative indexing. - -Chord Scales - Refer to chord indices in `N.C` OP - - `0` = Major `{0, 1, 1, 0, 2, 1, 6}` - - `1` = Natural Minor `{1, 6, 0, 1, 1, 0, 2}` - - `2` = Harmonic Minor `{8, 6, 7, 1, 2, 0, 3}` - - `3` = Melodic Minor `{8, 1, 7, 2, 2, 6, 6}` - - `4` = Dorian `{1, 1, 0, 2, 1, 6, 0}` - - `5` = Phrygian `{1, 0, 2, 1, 6, 0, 1}` - - `6` = Lydian `{0, 2, 1, 6, 0, 1, 1}` - - `7` = Mixolydian `{2, 1, 6, 0, 1, 1, 0}` - - `8` = Locrian `{6, 0, 1, 1, 0, 2, 1}` - """ - [V] prototype = "V x" short = "converts a voltage to a value usable by the CV outputs (`x` between `0` and `10`)" diff --git a/docs/ops/music.md b/docs/ops/music.md new file mode 100644 index 00000000..7337adb4 --- /dev/null +++ b/docs/ops/music.md @@ -0,0 +1,3 @@ +## Musical Maths + +Mathematical calcuations and tables helpful in specific musical contexts. diff --git a/docs/ops/music.toml b/docs/ops/music.toml new file mode 100644 index 00000000..53558ff5 --- /dev/null +++ b/docs/ops/music.toml @@ -0,0 +1,257 @@ + +[N] +prototype = "N x" +short = "converts an equal temperament note number to a value usable by the CV outputs (`x` in the range `-127` to `127`)" +description = """ +The `N` OP converts an equal temperament note number to a value usable by the CV outputs. + +Examples: + +``` +CV 1 N 60 => set CV 1 to middle C, i.e. 5V +CV 1 N RAND 24 => set CV 1 to a random note from the lowest 2 octaves +``` +""" + +[VN] +prototype = "VN x" +short = "converts 1V/OCT value `x` to an equal temperament note number" + +[HZ] +prototype = "HZ x" +short = "converts 1V/OCT value `x` to Hz/Volt value, useful for controlling non-euro synths like Korg MS-20" + +[JI] +prototype = "JI x y" +short = "just intonation helper, precision ratio divider normalised to 1V" + +[BPM] +prototype = "BPM x" +short = "milliseconds per beat in BPM `x`" + +["N.S"] +prototype = "N.S r s d" +short = "Note Scale operator, `r` is the root note (`0-127`), `s` is the scale (`0-8`) and `d` is the degree (`1-7`), returns a value from the `N` table." +description = """ +The `N.S` OP lets you retrieve `N` table values according to traditional western scales. `s` and `d` wrap to their ranges automatically and support negative indexing. + +Scales + - `0` = Major + - `1` = Natural Minor + - `2` = Harmonic Minor + - `3` = Melodic Minor + - `4` = Dorian + - `5` = Phrygian + - `6` = Lydian + - `7` = Mixolydian + - `8` = Locrian +""" + +["QT.S"] +prototype = "QT.S x r s" +short = "quantize 1V/OCT signal `x` to scale `s` (0-8, reference N.S scales) with root 1V/OCT pitch `r`" + +["QT.CS"] +prototype = "QT.CS x r s d c" +short = "quantize 1V/OCT signal `x` to chord `c` (1-7) from scale `s` (0-8, reference N.S scales) at degree `d` (1-7) with root 1V/OCT pitch `r`" +description = """ +Quantize 1V/OCT signal `x` to chord `c` (1-7) from scale `s` (0-8, reference N.S scales) at degree `d` (1-7) with root 1V/OCT pitch `r`. + +Chords (1-7) + - `1` = Tonic + - `2` = Third + - `3` = Triad + - `4` = Seventh + - etc. +""" + +["N.C"] +prototype = "N.C r c d" +short = "Note Chord operator, `r` is the root note (`0-127`), `c` is the chord (`0-12`) and `d` is the degree (`0-3`), returns a value from the `N` table." +description = """ +The `N.C` OP lets you retrieve `N` table values according to traditional western chords. `c` and `d` wrap to their ranges automatically and support negative indexing. + +Chords + - `0` = Major 7th `{0, 4, 7, 11}` + - `1` = Minor 7th `{0, 3, 7, 10}` + - `2` = Dominant 7th `{0, 4, 7, 10}` + - `3` = Diminished 7th `{0, 3, 6, 9}` + - `4` = Augmented 7th `{0, 4, 8, 10}` + - `5` = Dominant 7b5 `{0, 4, 6, 10}` + - `6` = Minor 7b5 `{0, 3, 6, 10}` + - `7` = Major 7#5 `{0, 4, 8, 11}` + - `8` = Minor Major 7th `{0, 3, 7, 11}` + - `9` = Diminished Major 7th `{0, 3, 6, 11}` + - `10` = Major 6th `{0, 4, 7, 9}` + - `11` = Minor 6th `{0, 3, 7, 9}` + - `12` = 7sus4 `{0, 5, 7, 10}` + """ + +["N.CS"] +prototype = "N.CS r s d c" +short = "Note Chord Scale operator, `r` is the root note (`0-127`), `s` is the scale (`0-8`), `d` is the scale degree (`1-7`) and `c` is the chord component (`0-3`), returns a value from the `N` table." +description = """ +The `N.CS` OP lets you retrieve `N` table values according to traditional western scales and chords. `s`, `c` and `d` wrap to their ranges automatically and support negative indexing. + +Chord Scales - Refer to chord indices in `N.C` OP + - `0` = Major `{0, 1, 1, 0, 2, 1, 6}` + - `1` = Natural Minor `{1, 6, 0, 1, 1, 0, 2}` + - `2` = Harmonic Minor `{8, 6, 7, 1, 2, 0, 3}` + - `3` = Melodic Minor `{8, 1, 7, 2, 2, 6, 6}` + - `4` = Dorian `{1, 1, 0, 2, 1, 6, 0}` + - `5` = Phrygian `{1, 0, 2, 1, 6, 0, 1}` + - `6` = Lydian `{0, 2, 1, 6, 0, 1, 1}` + - `7` = Mixolydian `{2, 1, 6, 0, 1, 1, 0}` + - `8` = Locrian `{6, 0, 1, 1, 0, 2, 1}` + """ + +["N.B"] +prototype = "N.B d" +prototype_set = "N.B r s" +short = "get degree `d` of scale/set scale root to `r`, scale to `s`, `s` is either bit mask (`s` >= 1) or scale preset (`s` < 1)" +description = """ +Converts a degree in a user-defined equal temperament scale to a value usable by the CV outputs. Default values of `r` and `s` are 0 and R101011010101, corresponding to C-major. +To make it easier to generate bit-masks in code, LSB (bit 0) represent the first note in the octave. To avoid having to mirror scales in our heads when entering them by hand, we use `R...` (reverse binary) instead of `B...` (binary ). + +The bit-masks uses the 12 lower bits. + +Note that N.B is using scale at index 0 as used by N.BX ,so N.B and N.BX 0 are equivalent. + +Examples: +``` +CV 1 N.B 1 ==> set CV 1 to 1st degree of default scale + (C, value corresponding to N 0) +N.B 0 R101011010101 ==> set scale to C-major (default) +CV 1 N.B 1 ==> set CV 1 get 1st degree of scale + (C, value corresponding to N 0) +N.B 2 R101011010101 ==> set scale to D-major +CV 1 N.B 3 ==> set CV 1 to 3rd degree of scale + (F#, value corresponding to N 6) +N.B 3 R100101010010 ==> set scale to Eb-minor pentatonic +CV 1 N.B 2 ==> set CV 1 to 2nd degree of scale + (Gb, value corresponding to N 6) +N.B 5 -3 ==> set scale to F-lydian using preset +``` +Values of `s` less than 1 sets the bit mask to a preset scale: +``` +0: Ionian (major) +-1: Dorian +-2: Phrygian +-3: Lydian +-4: Mixolydian +-5: Aeolean (natural minor) +-6: Locrian +-7: Melodic minor +-8: Harmonic minor +-9: Major pentatonic +-10: Minor pentatonic +-11 Whole note (1st Messiaen mode) +-12 Octatonic (half-whole, 2nd Messiaen mode) +-13 Octatonic (whole-half) +-14 3rd Messiaen mode +-15 4th Messiaen mode +-16 5th Messiaen mode +-17 6th Messiaen mode +-18 7th Messiaen mode +-19 Augmented +``` +""" + +["N.BX"] +prototype = "N.BX i d" +prototype_set = "N.BX i r s" +short = "multi-index version of N.B, scale at `i` (index) 0 is shared with N.B" +description = """ +Multi-index version of N.B. Index `i` in the range 0-15, allows working with 16 independent scales. Scale at `i` 0 is shared with N.B. + +Examples: +``` +N.BX 0 0 R101011010101 ==> set scale at index 0 to C-major (default) +CV 1 N.BX 0 1 ==> set CV 1 to 1st degree of scale + (C, value corresponding to N 0) +N.BX 1 3 R100101010010 ==> set scale at index 1 to Eb-minor pentatonic +CV 1 N.BX 1 2 ==> set CV 1 to 2nd degree of scale + (Gb, value corresponding to N 6) +N.BX 2 5 -3 ==> set scale at index 2 to F-lydian using preset +``` + +""" + +["QT.B"] +prototype = "QT.B x" +short = "quantize 1V/OCT signal `x` to scale defined by `N.B`" + +["QT.BX"] +prototype = "QT.BX i x" +short = "quantize 1V/OCT signal `x` to scale defined by `N.BX` in scale index `i`" + +[ER] +prototype = "ER f l i" +short = "Euclidean rhythm, `f` is fill (`1-32`), `l` is length (`1-32`) and `i` is step (any value), returns `0` or `1`" +description=""" +Euclidean rhythm helper, as described by Godfried Toussaint in his 2005 paper ["The Euclidean Algorithm Generates Traditional Musical Rhythms"][euclidean_rhythm_paper][^euclidean_rhythm_citation]. From the abstract: + + - `f` is fill (`1-32`) and should be less then or equal to length + - `l` is length (`1-32`) + - `i` is the step index, and will work with negative as well as positive numbers + +If you wish to add rotation as well, use the following form: + +``` +ER f l SUB i r +``` + +where `r` is the number of step of _forward_ rotation you want. + +For more info, see the post on [samdoshi.com][samdoshi_com_euclidean] + +[samdoshi_com_euclidean]: http://samdoshi.com/post/2016/03/teletype-euclidean/ +[euclidean_rhythm_paper]: http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf +[^euclidean_rhythm_citation]: Toussaint, G. T. (2005, July). The Euclidean algorithm generates traditional musical rhythms. _In Proceedings of BRIDGES: Mathematical Connections in Art, Music and Science_ (pp. 47-56). +""" + +[NR] +prototype = "NR p m f s" +short = "Numeric Repeater, `p` is prime pattern (`0-31`), `m` is & mask (`0-3`), `f` is variation factor (`0-16`) and `s` is step (`0-15`), returns `0` or `1`" +description = """ +Numeric Repeater is similar to ER, except it generates patterns using the binary arithmetic process found in ["Noise Engineering's Numeric Repetitor"][numeric_repetitor]. From the description: + +Numeric Repetitor is a rhythmic gate generator based on binary arithmetic. A core pattern forms the basis and variation is achieved by treating this pattern as a binary number and multiplying it by another. NR contains 32 prime rhythms derived by examining all possible rhythms and weeding out bad ones via heuristic. + +All parameters wrap around their specified ranges automatically and support negative indexing. + +Masks + - `0` is no mask + - `1` is `0x0F0F` + - `2` is `0xF003` + - `3` is `0x1F0` + +For further detail ["see the manual"][nr_manual]. + +[numeric_repetitor]: https://www.noiseengineering.us/shop/numeric-repetitor +[nr_manual]: https://static1.squarespace.com/static/58c709192e69cf2422026fa6/t/5e6041ad4cbc0979d6d793f2/1583366574430/NR_manual.pdf +""" + +["DR.P"] +prototype = "DR.P b p s" +short = "Drum pattern helper, `b` is the drum bank (`0-4`), `p` is the pattern (0-215) and step is the step number (0-15), returns `0` or `1`" +description = """ +The drum helper uses preset drum patterns to give 16-step gate patterns. Gates wrap after step 16. Bank 0 is a set of pseudo random gates increasing in density at higher numbered patterns, where pattern 0 is empty, +and pattern 215 is 1s. Bank 1 is bass drum patterns. Bank 2 is snare drum patterns. Bank 3 is closed hi-hats. Bank 4 is open hi-hits and in some cases cymbals. Bank 1-4 patterns are related to each other (bank 1 pattern 1's bass drum pattern fits bank 2 pattern 1's snare drum pattern). +The patterns are from [Paul Wenzel's "Pocket Operations" book](https://shittyrecording.studio/). +""" + +["DR.T"] +prototype = "DR.T b p q l s" +short = "Tresillo helper, `b` is the drum bank (`0-4`), `p` is first pattern (0-215), `q` is the second pattern (0-215), `l` is length (`1-64`), and step is the step number (0-length-1), returns `0` or `1`" +description = """ +The Tresillo helper uses the preset drum patterns described in the drum pattern help function in a 3, 3, 2 rythmic formation. In the tresillo, pattern 1 will be repeated twice for a number of steps determined by the overall length of the pattern. A pattern of length 8 will play the first three steps of your selected pattern 1 twice, and +the first two steps of pattern 2 once. A pattern length of 16 will play the first six steps of selected pattern 1 twice, and the first four steps of pattern 2 once. And so on. The max length is 64. Length will be rounded down to the nearest multiple of 8. The step number wraps at the given length. +""" + +["DR.V"] +prototype = "DR.V p s" +short = "Velocity helper. `p` is the pattern (0-19). `s` is the step number (0-15)" +description = """ +The velocity helper gives velocity values (0-16383) at each step. The values are intended to be used for drum hit velocities. There are 16 steps, which wrap around. Divide by 129 to convert to midi cc values. +""" \ No newline at end of file diff --git a/docs/ops/variables.toml b/docs/ops/variables.toml index 8d63425e..a5368d1a 100644 --- a/docs/ops/variables.toml +++ b/docs/ops/variables.toml @@ -53,19 +53,36 @@ prototype = "FLIP" prototype_set = "FLIP x" short = "returns inverted state (`0` or `1`) on each read (also settable)" - [I] prototype = "I" prototype_set = "I x" short = """get / set the variable `I`""" description=""" -Get / set the variable `I`, this variable is overwritten by `L`, but can be used +Get / set the variable `I`. This variable is overwritten by `L`, but can be used freely outside an `L` loop. Each script gets its own `I` variable, so if you call a script from another script's loop you can still use and modify `I` without affecting the calling loop. In this scenario the script getting called will have its `I` value initialized with the calling loop's current `I` value. """ +[J] +prototype = "J" +prototype_set = "J x" +short = """get / set the variable `J`""" +description=""" +get / set the variable `J`, each script gets its own `J` variable, so if you call +a script from another script you can still use and modify `J` without affecting the calling script. +""" + +[K] +prototype = "K" +prototype_set = "K x" +short = """get / set the variable `K`""" +description=""" +get / set the variable `K`, each script gets its own `K` variable, so if you call +a script from another script you can still use and modify `K` without affecting the calling script. +""" + [O] prototype = "O" prototype_set = "O x" @@ -95,7 +112,6 @@ O => 61 ``` """ - ["O.INC"] prototype = "O.INC" prototype_set = "O.INC x" @@ -160,21 +176,3 @@ short = "get / set the variable `Y`, default `0`" prototype = "Z" prototype_set = "Z x" short = "get / set the variable `Z`, default `0`" - -[J] -prototype = "J" -prototype_set = "J x" -short = """get / set the variable `J`""" -description=""" -get / set the variable `J`, each script gets its own `J` variable, so if you call -a script from another script you can still use and modify `J` without affecting the calling script. -""" - -[K] -prototype = "K" -prototype_set = "K x" -short = """get / set the variable `K`""" -description=""" -get / set the variable `K`, each script gets its own `K` variable, so if you call -a script from another script you can still use and modify `K` without affecting the calling script. -""" diff --git a/utils/cheatsheet.py b/utils/cheatsheet.py index 2556bea0..7c7caa82 100755 --- a/utils/cheatsheet.py +++ b/utils/cheatsheet.py @@ -46,41 +46,46 @@ def inject_latex(value): # determines the order in which sections are displayed, # final column indicates that a new page is inserted _after_ that section -OPS_SECTIONS = [ - ("variables", "Variables", False), - ("hardware", "Hardware", False), - ("patterns", "Patterns", False), - ("controlflow", "Control flow", False), - ("maths", "Maths", False), - ("metronome", "Metronome", False), - ("delay", "Delay", False), - ("stack", "Stack", False), - ("queue", "Queue", False), - ("seed", "Seed", False), - ("turtle", "Turtle", True), - ("grid", "Grid", True), - ("midi_in", "MIDI In", True), - ("i2c", "Generic I2C", True), - ("ansible", "Ansible", False), - ("whitewhale", "Whitewhale", False), - ("meadowphysics", "Meadowphysics", False), - ("earthsea", "Earthsea", False), - ("orca", "Orca", True), - ("justfriends", "Just Friends", False), - ("wslash", "W/", False), - ("er301", "ER-301", False), - ("fader", "Fader", False), - ("matrixarchate", "Matrixarchate", True), - ("telex_i", "TELEXi", False), - ("telex_o", "TELEXo", False), - ("disting", "Disting EX", True), - ("wslashdelay", "W/2.0 delay", False), - ("wslashsynth", "W/2.0 synth", False), - ("wslashtape", "W/2.0 tape", False), - ("crow", "Crow", True), - ("i2c2midi", "I2C2MIDI", True) -] - +OPS_SECTIONS = { + "core": [ + ("variables", "Variables", False), + ("hardware", "Hardware", False), + ("patterns", "Patterns", False), + ("controlflow", "Control flow", False), + ("maths", "Maths", False), + ("music", "Musical Maths", False), + ("metronome", "Metronome", False), + ("delay", "Delay", False), + ("stack", "Stack", False), + ("queue", "Queue", False), + ("seed", "Seed", False), + ("turtle", "Turtle", False), + ("grid", "Grid", False), + ("midi_in", "MIDI In", False), + ("hardware_setup", "Hardware Setup", True) + ], + "i2c": [ + ("i2c", "Generic I2C", False), + ("ansible", "Ansible", False), + ("whitewhale", "Whitewhale", False), + ("meadowphysics", "Meadowphysics", False), + ("earthsea", "Earthsea", False), + ("orca", "Orca", False), + ("justfriends", "Just Friends", False), + ("wslash", "W/", False), + ("er301", "ER-301", False), + ("fader", "Fader", False), + ("matrixarchate", "Matrixarchate", False), + ("telex_i", "TELEXi", False), + ("telex_o", "TELEXo", False), + ("disting", "Disting EX", False), + ("wslashdelay", "W/2.0 delay", False), + ("wslashsynth", "W/2.0 synth", False), + ("wslashtape", "W/2.0 tape", False), + ("crow", "Crow", False), + ("i2c2midi", "I2C2MIDI", False) + ] +} def latex_safe(s): # backslash must be first, otherwise it will duplicate itself @@ -92,13 +97,13 @@ def latex_safe(s): return s -def cheatsheet_tex(): +def cheatsheet_tex(sections): print(f"Using docs directory: {DOCS_DIR}") print(f"Using ops docs directory: {OP_DOCS_DIR}") print() output = VERSION_STR + "\n\n" - for (section, title, new_page) in OPS_SECTIONS: + for (section, title, new_page) in sections: toml_file = Path(OP_DOCS_DIR, section + ".toml") if toml_file.exists() and toml_file.is_file(): output += f"\\group{{{ title }}}\n\n" @@ -125,12 +130,12 @@ def cheatsheet_tex(): def main(): - if len(sys.argv) != 2: - sys.exit("Please supply a filename") - - p = Path(sys.argv[1]).resolve() - p.write_text(cheatsheet_tex()) + if len(sys.argv) != 3: + sys.exit("Please supply a cheatsheet category and filename") + category = sys.argv[1] + p = Path(sys.argv[2]).resolve() + p.write_text(cheatsheet_tex(OPS_SECTIONS[category])) if __name__ == "__main__": main() diff --git a/utils/docs.py b/utils/docs.py index 1f514ec7..d47ff7ec 100755 --- a/utils/docs.py +++ b/utils/docs.py @@ -37,6 +37,7 @@ "patterns", "controlflow", "maths", + "music", "metronome", "delay", "stack", @@ -45,6 +46,7 @@ "turtle", "grid", "midi_in", + "hardware_setup", "i2c", "ansible", "whitewhale", From 0b5c558cd9aa96157498bc5dced3f54a501d6921 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Sun, 17 Dec 2023 23:18:53 -0500 Subject: [PATCH 02/11] Fix docs build --- .gitignore | 2 +- docs/Makefile | 14 +- .../{cheatsheet-common.tex => cs-common.tex} | 2 +- docs/ops/i2c2midi.toml | 4 +- docs/ops/music.toml | 169 +++++++++--------- utils/cheatsheet.py | 74 ++++---- 6 files changed, 131 insertions(+), 134 deletions(-) rename docs/cheatsheet/{cheatsheet-common.tex => cs-common.tex} (98%) diff --git a/.gitignore b/.gitignore index ac9b6a4c..22903d05 100644 --- a/.gitignore +++ b/.gitignore @@ -53,5 +53,5 @@ __pycache__/ /docs/teletype.pdf /docs/teletype.html /docs/cheatsheet/* -!/docs/cheatsheet/cheatsheet-common.tex +!/docs/cheatsheet/cs-common.tex /docs/testServe/ diff --git a/docs/Makefile b/docs/Makefile index 4e0e175f..6d5f4e31 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -5,7 +5,7 @@ build: teletype.pdf teletype.html cheatsheet/cheatsheet-core.pdf cheatsheet/chea clean: rm -f teletype.pdf && \ rm -f teletype.html && \ - rm -f cheatsheet/include.tex && \ + rm -f cheatsheet/cheatsheet-*.tex && \ cd cheatsheet && \ latexmk -xelatex -c && \ rm -f cheatsheet.pdf @@ -18,12 +18,8 @@ teletype.html: $(wildcard *.md ops/*.md ops/*.toml) \ ../utils/docs.py ../CHANGELOG.md $(wildcard ../utils/templates/*) ../utils/docs.py teletype.html -cheatsheet/cheatsheet-%.pdf: $(wildcard ops/*.toml) ../utils/cheatsheet.py cheatsheet/cheatsheet.tex - ../utils/cheatsheet.py $* "cheatsheet/include.tex" - cd cheatsheet && latexmk -xelatex cheatsheet.tex -jobname=cheatsheet-$* +cheatsheet/cheatsheet-%.tex: $(wildcard ops/*.toml) ../utils/cheatsheet.py + ../utils/cheatsheet.py $* "cheatsheet/cheatsheet-$*.tex" -cheatsheet/%.tex: $(wildcard ops/*.toml) ../utils/cheatsheet.py - ../utils/cheatsheet.py $* "cheatsheet/$*.tex" - -cheatsheet/%.pdf: cheatsheet/cheatsheet.tex cheatsheet/include.tex - cd cheatsheet && latexmk -xelatex cheatsheet-common.tex -jobname=$* \ No newline at end of file +cheatsheet/cheatsheet-%.pdf: cheatsheet/cs-common.tex cheatsheet/cheatsheet-%.tex + cd cheatsheet && latexmk -xelatex cs-common.tex -jobname=cheatsheet-$* \ No newline at end of file diff --git a/docs/cheatsheet/cheatsheet-common.tex b/docs/cheatsheet/cs-common.tex similarity index 98% rename from docs/cheatsheet/cheatsheet-common.tex rename to docs/cheatsheet/cs-common.tex index 4321da00..c02f0377 100644 --- a/docs/cheatsheet/cheatsheet-common.tex +++ b/docs/cheatsheet/cs-common.tex @@ -59,7 +59,7 @@ \begin{document} \begin{multicols}{5} - \input{include.tex} + \input{\jobname.tex} %% add a page break at the end to force the last column to not balance \pagebreak diff --git a/docs/ops/i2c2midi.toml b/docs/ops/i2c2midi.toml index 7b03a0eb..51d6c033 100644 --- a/docs/ops/i2c2midi.toml +++ b/docs/ops/i2c2midi.toml @@ -418,7 +418,7 @@ Set strumming of chord `x` (0..8) to `x` ms (0..32767). Strumming plays the note ["I2M.C.VCUR"] prototype = "I2M.C.VCUR w x y z" -alias = ["I2M.C.V~"] +aliases = ["I2M.C.V~"] short = "Set velocity curve for chord `w` (0..8) with curve type `x` (0..5), start value `y`% (0..32767) and end value `z`% (0..32767), use `w = 0` to set for all chords, use `x = 0` to turn off" description = """ Set velocity curve for chord `w` (0..8) with curve type `x` (0..5), start value `y`% (0..32767) and end value `z`% (0..32767). This will affect the velocity of the notes in the order they are defined in the chord. Start and end percentages refer to the velocity with which the chord is played via `I2M.C`. Use `x = 0` to turn velocity curve off. The following curves are available: 0) Off 1) Linear 2) Exponential 3) Triangle 4) Square 5) Random. Use `w = 0` to set velocity curve for all chords. Try a random curve with subtle values for a humanizing effect. @@ -426,7 +426,7 @@ Set velocity curve for chord `w` (0..8) with curve type `x` (0..5), start value ["I2M.C.TCUR"] prototype = "I2M.C.TCUR w x y z" -alias = ["I2M.C.T~"] +aliases = ["I2M.C.T~"] short = "Set time curve to strumming for chord `w` (0..8) with curve type `x` (0..5), start value `y`% (0..32767) and end value `z`% (0..32767), use `w = 0` to set for all chords, use `x = 0` to turn off" description = """ Set time curve for chord `w` (0..8) with curve type `x` (0..5), start value `y`% (0..32767) and end value `z`% (0..32767). This will affect the time interval between the notes in the order they are defined in the chord. Start and end percentages refer to the current strumming setting of the chord, set via `I2M.C.STR`. Use `x = 0` to turn time curve off. The following curves are available: 0) Off 1) Linear 2) Exponential 3) Triangle 4) Square 5) Random. Use `w = 0` to set time curve for all chords. Try a square curve with similar values to create swing. Try a random curve with subtle values for a humanizing effect. diff --git a/docs/ops/music.toml b/docs/ops/music.toml index 53558ff5..59d94a96 100644 --- a/docs/ops/music.toml +++ b/docs/ops/music.toml @@ -1,21 +1,55 @@ +[BPM] +prototype = "BPM x" +short = "milliseconds per beat in BPM `x`" -[N] -prototype = "N x" -short = "converts an equal temperament note number to a value usable by the CV outputs (`x` in the range `-127` to `127`)" +["DR.P"] +prototype = "DR.P b p s" +short = "Drum pattern helper, `b` is the drum bank (`0-4`), `p` is the pattern (0-215) and step is the step number (0-15), returns `0` or `1`" description = """ -The `N` OP converts an equal temperament note number to a value usable by the CV outputs. +The drum helper uses preset drum patterns to give 16-step gate patterns. Gates wrap after step 16. Bank 0 is a set of pseudo random gates increasing in density at higher numbered patterns, where pattern 0 is empty, +and pattern 215 is 1s. Bank 1 is bass drum patterns. Bank 2 is snare drum patterns. Bank 3 is closed hi-hats. Bank 4 is open hi-hits and in some cases cymbals. Bank 1-4 patterns are related to each other (bank 1 pattern 1's bass drum pattern fits bank 2 pattern 1's snare drum pattern). +The patterns are from [Paul Wenzel's "Pocket Operations" book](https://shittyrecording.studio/). +""" -Examples: +["DR.T"] +prototype = "DR.T b p q l s" +short = "Tresillo helper, `b` is the drum bank (`0-4`), `p` is first pattern (0-215), `q` is the second pattern (0-215), `l` is length (`1-64`), and step is the step number (0-length-1), returns `0` or `1`" +description = """ +The Tresillo helper uses the preset drum patterns described in the drum pattern help function in a 3, 3, 2 rythmic formation. In the tresillo, pattern 1 will be repeated twice for a number of steps determined by the overall length of the pattern. A pattern of length 8 will play the first three steps of your selected pattern 1 twice, and +the first two steps of pattern 2 once. A pattern length of 16 will play the first six steps of selected pattern 1 twice, and the first four steps of pattern 2 once. And so on. The max length is 64. Length will be rounded down to the nearest multiple of 8. The step number wraps at the given length. +""" + +["DR.V"] +prototype = "DR.V p s" +short = "Velocity helper. `p` is the pattern (0-19). `s` is the step number (0-15)" +description = """ +The velocity helper gives velocity values (0-16383) at each step. The values are intended to be used for drum hit velocities. There are 16 steps, which wrap around. Divide by 129 to convert to midi cc values. +""" + +[ER] +prototype = "ER f l i" +short = "Euclidean rhythm, `f` is fill (`1-32`), `l` is length (`1-32`) and `i` is step (any value), returns `0` or `1`" +description=""" +Euclidean rhythm helper, as described by Godfried Toussaint in his 2005 paper ["The Euclidean Algorithm Generates Traditional Musical Rhythms"][euclidean_rhythm_paper][^euclidean_rhythm_citation]. From the abstract: + + - `f` is fill (`1-32`) and should be less then or equal to length + - `l` is length (`1-32`) + - `i` is the step index, and will work with negative as well as positive numbers + +If you wish to add rotation as well, use the following form: ``` -CV 1 N 60 => set CV 1 to middle C, i.e. 5V -CV 1 N RAND 24 => set CV 1 to a random note from the lowest 2 octaves +ER f l SUB i r ``` -""" -[VN] -prototype = "VN x" -short = "converts 1V/OCT value `x` to an equal temperament note number" +where `r` is the number of step of _forward_ rotation you want. + +For more info, see the post on [samdoshi.com][samdoshi_com_euclidean] + +[samdoshi_com_euclidean]: http://samdoshi.com/post/2016/03/teletype-euclidean/ +[euclidean_rhythm_paper]: http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf +[^euclidean_rhythm_citation]: Toussaint, G. T. (2005, July). The Euclidean algorithm generates traditional musical rhythms. _In Proceedings of BRIDGES: Mathematical Connections in Art, Music and Science_ (pp. 47-56). +""" [HZ] prototype = "HZ x" @@ -25,9 +59,19 @@ short = "converts 1V/OCT value `x` to Hz/Volt value, useful for controlling non- prototype = "JI x y" short = "just intonation helper, precision ratio divider normalised to 1V" -[BPM] -prototype = "BPM x" -short = "milliseconds per beat in BPM `x`" +[N] +prototype = "N x" +short = "converts an equal temperament note number to a value usable by the CV outputs (`x` in the range `-127` to `127`)" +description = """ +The `N` OP converts an equal temperament note number to a value usable by the CV outputs. + +Examples: + +``` +CV 1 N 60 => set CV 1 to middle C, i.e. 5V +CV 1 N RAND 24 => set CV 1 to a random note from the lowest 2 octaves +``` +""" ["N.S"] prototype = "N.S r s d" @@ -47,24 +91,6 @@ Scales - `8` = Locrian """ -["QT.S"] -prototype = "QT.S x r s" -short = "quantize 1V/OCT signal `x` to scale `s` (0-8, reference N.S scales) with root 1V/OCT pitch `r`" - -["QT.CS"] -prototype = "QT.CS x r s d c" -short = "quantize 1V/OCT signal `x` to chord `c` (1-7) from scale `s` (0-8, reference N.S scales) at degree `d` (1-7) with root 1V/OCT pitch `r`" -description = """ -Quantize 1V/OCT signal `x` to chord `c` (1-7) from scale `s` (0-8, reference N.S scales) at degree `d` (1-7) with root 1V/OCT pitch `r`. - -Chords (1-7) - - `1` = Tonic - - `2` = Third - - `3` = Triad - - `4` = Seventh - - etc. -""" - ["N.C"] prototype = "N.C r c d" short = "Note Chord operator, `r` is the root note (`0-127`), `c` is the chord (`0-12`) and `d` is the degree (`0-3`), returns a value from the `N` table." @@ -177,39 +203,6 @@ N.BX 2 5 -3 ==> set scale at index 2 to F-lydian using preset """ -["QT.B"] -prototype = "QT.B x" -short = "quantize 1V/OCT signal `x` to scale defined by `N.B`" - -["QT.BX"] -prototype = "QT.BX i x" -short = "quantize 1V/OCT signal `x` to scale defined by `N.BX` in scale index `i`" - -[ER] -prototype = "ER f l i" -short = "Euclidean rhythm, `f` is fill (`1-32`), `l` is length (`1-32`) and `i` is step (any value), returns `0` or `1`" -description=""" -Euclidean rhythm helper, as described by Godfried Toussaint in his 2005 paper ["The Euclidean Algorithm Generates Traditional Musical Rhythms"][euclidean_rhythm_paper][^euclidean_rhythm_citation]. From the abstract: - - - `f` is fill (`1-32`) and should be less then or equal to length - - `l` is length (`1-32`) - - `i` is the step index, and will work with negative as well as positive numbers - -If you wish to add rotation as well, use the following form: - -``` -ER f l SUB i r -``` - -where `r` is the number of step of _forward_ rotation you want. - -For more info, see the post on [samdoshi.com][samdoshi_com_euclidean] - -[samdoshi_com_euclidean]: http://samdoshi.com/post/2016/03/teletype-euclidean/ -[euclidean_rhythm_paper]: http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf -[^euclidean_rhythm_citation]: Toussaint, G. T. (2005, July). The Euclidean algorithm generates traditional musical rhythms. _In Proceedings of BRIDGES: Mathematical Connections in Art, Music and Science_ (pp. 47-56). -""" - [NR] prototype = "NR p m f s" short = "Numeric Repeater, `p` is prime pattern (`0-31`), `m` is & mask (`0-3`), `f` is variation factor (`0-16`) and `s` is step (`0-15`), returns `0` or `1`" @@ -232,26 +225,32 @@ For further detail ["see the manual"][nr_manual]. [nr_manual]: https://static1.squarespace.com/static/58c709192e69cf2422026fa6/t/5e6041ad4cbc0979d6d793f2/1583366574430/NR_manual.pdf """ -["DR.P"] -prototype = "DR.P b p s" -short = "Drum pattern helper, `b` is the drum bank (`0-4`), `p` is the pattern (0-215) and step is the step number (0-15), returns `0` or `1`" -description = """ -The drum helper uses preset drum patterns to give 16-step gate patterns. Gates wrap after step 16. Bank 0 is a set of pseudo random gates increasing in density at higher numbered patterns, where pattern 0 is empty, -and pattern 215 is 1s. Bank 1 is bass drum patterns. Bank 2 is snare drum patterns. Bank 3 is closed hi-hats. Bank 4 is open hi-hits and in some cases cymbals. Bank 1-4 patterns are related to each other (bank 1 pattern 1's bass drum pattern fits bank 2 pattern 1's snare drum pattern). -The patterns are from [Paul Wenzel's "Pocket Operations" book](https://shittyrecording.studio/). -""" +[VN] +prototype = "VN x" +short = "converts 1V/OCT value `x` to an equal temperament note number" -["DR.T"] -prototype = "DR.T b p q l s" -short = "Tresillo helper, `b` is the drum bank (`0-4`), `p` is first pattern (0-215), `q` is the second pattern (0-215), `l` is length (`1-64`), and step is the step number (0-length-1), returns `0` or `1`" -description = """ -The Tresillo helper uses the preset drum patterns described in the drum pattern help function in a 3, 3, 2 rythmic formation. In the tresillo, pattern 1 will be repeated twice for a number of steps determined by the overall length of the pattern. A pattern of length 8 will play the first three steps of your selected pattern 1 twice, and -the first two steps of pattern 2 once. A pattern length of 16 will play the first six steps of selected pattern 1 twice, and the first four steps of pattern 2 once. And so on. The max length is 64. Length will be rounded down to the nearest multiple of 8. The step number wraps at the given length. -""" +["QT.B"] +prototype = "QT.B x" +short = "quantize 1V/OCT signal `x` to scale defined by `N.B`" -["DR.V"] -prototype = "DR.V p s" -short = "Velocity helper. `p` is the pattern (0-19). `s` is the step number (0-15)" +["QT.BX"] +prototype = "QT.BX i x" +short = "quantize 1V/OCT signal `x` to scale defined by `N.BX` in scale index `i`" + +["QT.S"] +prototype = "QT.S x r s" +short = "quantize 1V/OCT signal `x` to scale `s` (0-8, reference N.S scales) with root 1V/OCT pitch `r`" + +["QT.CS"] +prototype = "QT.CS x r s d c" +short = "quantize 1V/OCT signal `x` to chord `c` (1-7) from scale `s` (0-8, reference N.S scales) at degree `d` (1-7) with root 1V/OCT pitch `r`" description = """ -The velocity helper gives velocity values (0-16383) at each step. The values are intended to be used for drum hit velocities. There are 16 steps, which wrap around. Divide by 129 to convert to midi cc values. -""" \ No newline at end of file +Quantize 1V/OCT signal `x` to chord `c` (1-7) from scale `s` (0-8, reference N.S scales) at degree `d` (1-7) with root 1V/OCT pitch `r`. + +Chords (1-7) + - `1` = Tonic + - `2` = Third + - `3` = Triad + - `4` = Seventh + - etc. +""" diff --git a/utils/cheatsheet.py b/utils/cheatsheet.py index 7c7caa82..7a47e514 100755 --- a/utils/cheatsheet.py +++ b/utils/cheatsheet.py @@ -45,45 +45,45 @@ def inject_latex(value): ) # determines the order in which sections are displayed, -# final column indicates that a new page is inserted _after_ that section +# last two columns indicates when a column break or page break is inserted _after_ that section OPS_SECTIONS = { "core": [ - ("variables", "Variables", False), - ("hardware", "Hardware", False), - ("patterns", "Patterns", False), - ("controlflow", "Control flow", False), - ("maths", "Maths", False), - ("music", "Musical Maths", False), - ("metronome", "Metronome", False), - ("delay", "Delay", False), - ("stack", "Stack", False), - ("queue", "Queue", False), - ("seed", "Seed", False), - ("turtle", "Turtle", False), - ("grid", "Grid", False), - ("midi_in", "MIDI In", False), - ("hardware_setup", "Hardware Setup", True) + ("variables", "Variables", False, False), + ("hardware", "Hardware", False, False), + ("patterns", "Patterns", True, False), + ("controlflow", "Control flow", False, False), + ("maths", "Maths", False, False), + ("music", "Musical Maths", False, False), + ("metronome", "Metronome", False, False), + ("delay", "Delay", False, False), + ("stack", "Stack", True, False), + ("queue", "Queue", True, False), + ("seed", "Seed", True, False), + ("turtle", "Turtle", False, True), + ("grid", "Grid", False, False), + ("midi_in", "MIDI In", False, False), + ("hardware_setup", "Hardware Setup", False, False) ], "i2c": [ - ("i2c", "Generic I2C", False), - ("ansible", "Ansible", False), - ("whitewhale", "Whitewhale", False), - ("meadowphysics", "Meadowphysics", False), - ("earthsea", "Earthsea", False), - ("orca", "Orca", False), - ("justfriends", "Just Friends", False), - ("wslash", "W/", False), - ("er301", "ER-301", False), - ("fader", "Fader", False), - ("matrixarchate", "Matrixarchate", False), - ("telex_i", "TELEXi", False), - ("telex_o", "TELEXo", False), - ("disting", "Disting EX", False), - ("wslashdelay", "W/2.0 delay", False), - ("wslashsynth", "W/2.0 synth", False), - ("wslashtape", "W/2.0 tape", False), - ("crow", "Crow", False), - ("i2c2midi", "I2C2MIDI", False) + ("i2c", "Generic I2C", False, False), + ("ansible", "Ansible", False, False), + ("whitewhale", "Whitewhale", True, False), + ("meadowphysics", "Meadowphysics", False, False), + ("earthsea", "Earthsea", False, False), + ("orca", "Orca", False, False), + ("justfriends", "Just Friends", True, False), + ("er301", "ER-301", False, False), + ("fader", "Faderbank", False, False), + ("matrixarchate", "Matrixarchate", False, False), + ("telex_i", "TELEXi", False, False), + ("telex_o", "TELEXo", False, False), + ("disting", "Disting EX", False, False), + ("wslash", "W/1.0", False, False), + ("wslashdelay", "W/2.0 delay", False, False), + ("wslashsynth", "W/2.0 synth", False, False), + ("wslashtape", "W/2.0 tape", False, False), + ("crow", "Crow", False, True), + ("i2c2midi", "I2C2MIDI", False, False) ] } @@ -103,7 +103,7 @@ def cheatsheet_tex(sections): print() output = VERSION_STR + "\n\n" - for (section, title, new_page) in sections: + for (section, title, new_col, new_page) in sections: toml_file = Path(OP_DOCS_DIR, section + ".toml") if toml_file.exists() and toml_file.is_file(): output += f"\\group{{{ title }}}\n\n" @@ -126,6 +126,8 @@ def cheatsheet_tex(sections): output += "\n\n" if new_page: output += "\\pagebreak\n\n" + if new_col: + output += "\\vfill\\null\n\\columnbreak\n" return output From 38cdc2989030f511430731c2bd1eda1bb734da19 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 18 Dec 2023 01:12:16 -0500 Subject: [PATCH 03/11] Move things around a bit more --- docs/ops/calibration.md | 1 + .../{hardware_setup.toml => calibration.toml} | 4 +- docs/ops/controlflow.toml | 4 +- docs/ops/hardware.toml | 8 ++ docs/ops/hardware_setup.md | 1 - docs/ops/maths.toml | 47 -------- docs/ops/music.md | 3 - docs/ops/pitch.md | 3 + docs/ops/{music.toml => pitch.toml} | 75 ------------- docs/ops/random.md | 1 + docs/ops/random.toml | 103 ++++++++++++++++++ docs/ops/rhythm.md | 3 + docs/ops/rhythm.toml | 74 +++++++++++++ docs/ops/seed.md | 2 - docs/ops/seed.toml | 34 ------ docs/ops/variables.toml | 32 +----- utils/cheatsheet.py | 35 +++--- utils/docs.py | 19 ++-- 18 files changed, 227 insertions(+), 222 deletions(-) create mode 100644 docs/ops/calibration.md rename docs/ops/{hardware_setup.toml => calibration.toml} (99%) delete mode 100644 docs/ops/hardware_setup.md delete mode 100644 docs/ops/music.md create mode 100644 docs/ops/pitch.md rename docs/ops/{music.toml => pitch.toml} (59%) create mode 100644 docs/ops/random.md create mode 100644 docs/ops/random.toml create mode 100644 docs/ops/rhythm.md create mode 100644 docs/ops/rhythm.toml delete mode 100644 docs/ops/seed.md delete mode 100644 docs/ops/seed.toml diff --git a/docs/ops/calibration.md b/docs/ops/calibration.md new file mode 100644 index 00000000..cf5c082d --- /dev/null +++ b/docs/ops/calibration.md @@ -0,0 +1 @@ +# Calibration \ No newline at end of file diff --git a/docs/ops/hardware_setup.toml b/docs/ops/calibration.toml similarity index 99% rename from docs/ops/hardware_setup.toml rename to docs/ops/calibration.toml index 261113c1..90f241f4 100644 --- a/docs/ops/hardware_setup.toml +++ b/docs/ops/calibration.toml @@ -1,3 +1,4 @@ + ["DEVICE.FLIP"] prototype = "DEVICE.FLIP" short = "Flip the screen/inputs/outputs" @@ -88,4 +89,5 @@ short = "Reset calibration data for CV output `n`" description = """ Clear the calibration data for CV output `n` and return it to its default behavior, with no calibration adjustment. -""" \ No newline at end of file +""" + diff --git a/docs/ops/controlflow.toml b/docs/ops/controlflow.toml index 1ec523b3..d06c82df 100644 --- a/docs/ops/controlflow.toml +++ b/docs/ops/controlflow.toml @@ -398,7 +398,7 @@ Does not affect the CV input (IN) or the Parameter knob (PARAM) values. ["INIT.P"] prototype = "INIT.P x" -short = "clears pattern associated with pattern number x" +short = "clears pattern number x" ["INIT.P.ALL"] prototype = "INIT.P.ALL" @@ -422,7 +422,7 @@ short = "clear time on trigger x" ["INIT.TR"] prototype = "INIT.TR x" -short = "clear all parameters on trigger associated with TR x" +short = "clear all parameters on trigger x" ["INIT.TR.ALL"] prototype = "INIT.TR.ALL" diff --git a/docs/ops/hardware.toml b/docs/ops/hardware.toml index 3c40c0ff..873a00fc 100644 --- a/docs/ops/hardware.toml +++ b/docs/ops/hardware.toml @@ -41,6 +41,14 @@ Get the slew time in ms associated with CV output `x`. Set the slew time associated with CV output `x` to `y` ms. """ +[V] +prototype = "V x" +short = "converts a voltage to a value usable by the CV outputs (`x` between `0` and `10`)" + +[VV] +prototype = "VV x" +short = "converts a voltage to a value usable by the CV outputs (`x` between `0` and `1000`, `100` represents 1V)" + ["IN"] prototype = "IN" short = "Get the value of IN jack (0-16383)" diff --git a/docs/ops/hardware_setup.md b/docs/ops/hardware_setup.md deleted file mode 100644 index 8faf9fa0..00000000 --- a/docs/ops/hardware_setup.md +++ /dev/null @@ -1 +0,0 @@ -# Hardware Setup \ No newline at end of file diff --git a/docs/ops/maths.toml b/docs/ops/maths.toml index 8a928f91..a53a6a2f 100644 --- a/docs/ops/maths.toml +++ b/docs/ops/maths.toml @@ -24,20 +24,6 @@ prototype = "MOD x y" aliases = ["%"] short = "find the remainder after division of `x` by `y`" -[RAND] -prototype = "RAND x" -aliases = ["RND"] -short = "generate a random number between `0` and `x` inclusive" - -[RRAND] -prototype = "RRAND x y" -aliases = ["RRND"] -short = "generate a random number between `x` and `y` inclusive" - -[TOSS] -prototype = "TOSS" -short = "randomly return `0` or `1`" - ["?"] prototype = "? x y z" short = "if condition `x` is true return `y`, otherwise return `z`" @@ -245,14 +231,6 @@ prototype = "SCALE a b i" aliases = ["SCL0"] short = "scale `i` from range `0` to `a` to range `0` to `b`" -[V] -prototype = "V x" -short = "converts a voltage to a value usable by the CV outputs (`x` between `0` and `10`)" - -[VV] -prototype = "VV x" -short = "converts a voltage to a value usable by the CV outputs (`x` between `0` and `1000`, `100` represents 1V)" - [EXP] prototype = "EXP x" short = "exponentiation table lookup. `0-16383` range (V `0-10`)" @@ -260,28 +238,3 @@ short = "exponentiation table lookup. `0-16383` range (V `0-10`)" [SGN] prototype = "SGN x" short = "sign function: 1 for positive, -1 for negative, 0 for 0" - -[CHAOS] -prototype = "CHAOS x" -short = "get next value from chaos generator, or set the current value" - -["CHAOS.R"] -prototype = "CHAOS.R x" -short = "get or set the `R` parameter for the `CHAOS` generator" - -["CHAOS.ALG"] -prototype = "CHAOS.ALG x" -short = "get or set the algorithm for the `CHAOS` generator. 0 = LOGISTIC, 1 = CUBIC, 2 = HENON, 3 = CELLULAR" - -[R] -prototype = "R" -prototype_set = "R x" -short = "get a random number/set `R.MIN` and `R.MAX` to same value `x` (effectively allowing `R` to be used as a global variable)" - -["R.MIN"] -prototype = "R.MIN x" -short = "set the lower end of the range from -32768 – 32767, default: 0" - -["R.MAX"] -prototype = "R.MAX x" -short = "set the upper end of the range from -32768 – 32767, default: 16383" diff --git a/docs/ops/music.md b/docs/ops/music.md deleted file mode 100644 index 7337adb4..00000000 --- a/docs/ops/music.md +++ /dev/null @@ -1,3 +0,0 @@ -## Musical Maths - -Mathematical calcuations and tables helpful in specific musical contexts. diff --git a/docs/ops/pitch.md b/docs/ops/pitch.md new file mode 100644 index 00000000..c4e1905b --- /dev/null +++ b/docs/ops/pitch.md @@ -0,0 +1,3 @@ +## Pitch + +Mathematical calcuations and tables helpful for musical pitch. diff --git a/docs/ops/music.toml b/docs/ops/pitch.toml similarity index 59% rename from docs/ops/music.toml rename to docs/ops/pitch.toml index 59d94a96..231989de 100644 --- a/docs/ops/music.toml +++ b/docs/ops/pitch.toml @@ -1,56 +1,3 @@ -[BPM] -prototype = "BPM x" -short = "milliseconds per beat in BPM `x`" - -["DR.P"] -prototype = "DR.P b p s" -short = "Drum pattern helper, `b` is the drum bank (`0-4`), `p` is the pattern (0-215) and step is the step number (0-15), returns `0` or `1`" -description = """ -The drum helper uses preset drum patterns to give 16-step gate patterns. Gates wrap after step 16. Bank 0 is a set of pseudo random gates increasing in density at higher numbered patterns, where pattern 0 is empty, -and pattern 215 is 1s. Bank 1 is bass drum patterns. Bank 2 is snare drum patterns. Bank 3 is closed hi-hats. Bank 4 is open hi-hits and in some cases cymbals. Bank 1-4 patterns are related to each other (bank 1 pattern 1's bass drum pattern fits bank 2 pattern 1's snare drum pattern). -The patterns are from [Paul Wenzel's "Pocket Operations" book](https://shittyrecording.studio/). -""" - -["DR.T"] -prototype = "DR.T b p q l s" -short = "Tresillo helper, `b` is the drum bank (`0-4`), `p` is first pattern (0-215), `q` is the second pattern (0-215), `l` is length (`1-64`), and step is the step number (0-length-1), returns `0` or `1`" -description = """ -The Tresillo helper uses the preset drum patterns described in the drum pattern help function in a 3, 3, 2 rythmic formation. In the tresillo, pattern 1 will be repeated twice for a number of steps determined by the overall length of the pattern. A pattern of length 8 will play the first three steps of your selected pattern 1 twice, and -the first two steps of pattern 2 once. A pattern length of 16 will play the first six steps of selected pattern 1 twice, and the first four steps of pattern 2 once. And so on. The max length is 64. Length will be rounded down to the nearest multiple of 8. The step number wraps at the given length. -""" - -["DR.V"] -prototype = "DR.V p s" -short = "Velocity helper. `p` is the pattern (0-19). `s` is the step number (0-15)" -description = """ -The velocity helper gives velocity values (0-16383) at each step. The values are intended to be used for drum hit velocities. There are 16 steps, which wrap around. Divide by 129 to convert to midi cc values. -""" - -[ER] -prototype = "ER f l i" -short = "Euclidean rhythm, `f` is fill (`1-32`), `l` is length (`1-32`) and `i` is step (any value), returns `0` or `1`" -description=""" -Euclidean rhythm helper, as described by Godfried Toussaint in his 2005 paper ["The Euclidean Algorithm Generates Traditional Musical Rhythms"][euclidean_rhythm_paper][^euclidean_rhythm_citation]. From the abstract: - - - `f` is fill (`1-32`) and should be less then or equal to length - - `l` is length (`1-32`) - - `i` is the step index, and will work with negative as well as positive numbers - -If you wish to add rotation as well, use the following form: - -``` -ER f l SUB i r -``` - -where `r` is the number of step of _forward_ rotation you want. - -For more info, see the post on [samdoshi.com][samdoshi_com_euclidean] - -[samdoshi_com_euclidean]: http://samdoshi.com/post/2016/03/teletype-euclidean/ -[euclidean_rhythm_paper]: http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf -[^euclidean_rhythm_citation]: Toussaint, G. T. (2005, July). The Euclidean algorithm generates traditional musical rhythms. _In Proceedings of BRIDGES: Mathematical Connections in Art, Music and Science_ (pp. 47-56). -""" - [HZ] prototype = "HZ x" short = "converts 1V/OCT value `x` to Hz/Volt value, useful for controlling non-euro synths like Korg MS-20" @@ -203,28 +150,6 @@ N.BX 2 5 -3 ==> set scale at index 2 to F-lydian using preset """ -[NR] -prototype = "NR p m f s" -short = "Numeric Repeater, `p` is prime pattern (`0-31`), `m` is & mask (`0-3`), `f` is variation factor (`0-16`) and `s` is step (`0-15`), returns `0` or `1`" -description = """ -Numeric Repeater is similar to ER, except it generates patterns using the binary arithmetic process found in ["Noise Engineering's Numeric Repetitor"][numeric_repetitor]. From the description: - -Numeric Repetitor is a rhythmic gate generator based on binary arithmetic. A core pattern forms the basis and variation is achieved by treating this pattern as a binary number and multiplying it by another. NR contains 32 prime rhythms derived by examining all possible rhythms and weeding out bad ones via heuristic. - -All parameters wrap around their specified ranges automatically and support negative indexing. - -Masks - - `0` is no mask - - `1` is `0x0F0F` - - `2` is `0xF003` - - `3` is `0x1F0` - -For further detail ["see the manual"][nr_manual]. - -[numeric_repetitor]: https://www.noiseengineering.us/shop/numeric-repetitor -[nr_manual]: https://static1.squarespace.com/static/58c709192e69cf2422026fa6/t/5e6041ad4cbc0979d6d793f2/1583366574430/NR_manual.pdf -""" - [VN] prototype = "VN x" short = "converts 1V/OCT value `x` to an equal temperament note number" diff --git a/docs/ops/random.md b/docs/ops/random.md new file mode 100644 index 00000000..fb338934 --- /dev/null +++ b/docs/ops/random.md @@ -0,0 +1 @@ +## Randomness diff --git a/docs/ops/random.toml b/docs/ops/random.toml new file mode 100644 index 00000000..424cd8b8 --- /dev/null +++ b/docs/ops/random.toml @@ -0,0 +1,103 @@ +[RAND] +prototype = "RAND x" +aliases = ["RND"] +short = "generate a random number between `0` and `x` inclusive" + +[RRAND] +prototype = "RRAND x y" +aliases = ["RRND"] +short = "generate a random number between `x` and `y` inclusive" + +[TOSS] +prototype = "TOSS" +short = "randomly return `0` or `1`" + +[R] +prototype = "R" +prototype_set = "R x" +short = "get a random number/set `R.MIN` and `R.MAX` to same value `x` (effectively allowing `R` to be used as a global variable)" + +["R.MIN"] +prototype = "R.MIN x" +short = "set the lower end of the range from -32768 – 32767, default: 0" + +["R.MAX"] +prototype = "R.MAX x" +short = "set the upper end of the range from -32768 – 32767, default: 16383" + +[CHAOS] +prototype = "CHAOS x" +short = "get next value from chaos generator, or set the current value" + +["CHAOS.R"] +prototype = "CHAOS.R x" +short = "get or set the `R` parameter for the `CHAOS` generator" + +["CHAOS.ALG"] +prototype = "CHAOS.ALG x" +short = "get or set the algorithm for the `CHAOS` generator. 0 = LOGISTIC, 1 = CUBIC, 2 = HENON, 3 = CELLULAR" + +[DRUNK] +prototype = "DRUNK" +prototype_set = "DRUNK x" +short = """changes by `-1`, `0`, or `1` upon each read saving its state, +setting will give it a new value for the next read""" +description=""" +Changes by `-1`, `0`, or `1` upon each read, saving its state. Setting `DRUNK` +will give it a new value for the next read, and drunkedness will continue on +from there with subsequent reads. + +Setting `DRUNK.MIN` and `DRUNK.MAX` controls the lower and upper bounds +(inclusive) that `DRUNK` can reach. `DRUNK.WRAP` controls whether the value can +wrap around when it reaches it's bounds. +""" + +["DRUNK.MIN"] +prototype = "DRUNK.MIN" +prototype_set = "DRUNK.MIN x" +short = "set the lower bound for `DRUNK`, default `0`" + +["DRUNK.MAX"] +prototype = "DRUNK.MAX" +prototype_set = "DRUNK.MAX x" +short = "set the upper bound for `DRUNK`, default `255`" + +["DRUNK.WRAP"] +prototype = "DRUNK.WRAP" +prototype_set = "DRUNK.WRAP x" +short = "should `DRUNK` wrap around when it reaches it's bounds, default `0`" + +["SEED"] +prototype = "SEED" +prototype_set = "SEED x" +short = "get / set the random number generator seed for all `SEED` ops" + +["RAND.SEED"] +prototype = "RAND.SEED" +prototype_set = "RAND.SEED x" +aliases = ["RAND.SD", "R.SD"] +short = "get / set the random number generator seed for `R`, `RRAND`, and `RAND` ops" + +["TOSS.SEED"] +prototype = "TOSS.SEED" +prototype_set = "TOSS.SEED x" +aliases = ["TOSS.SD"] +short = "get / set the random number generator seed for the `TOSS` op" + +["PROB.SEED"] +prototype = "PROB.SEED" +prototype_set = "PROB.SEED x" +aliases = ["PROB.SD"] +short = "get / set the random number generator seed for the `PROB` mod" + +["DRUNK.SEED"] +prototype = "DRUNK.SEED" +prototype_set = "DRUNK.SEED x" +aliases = ["DRUNK.SD"] +short = "get / set the random number generator seed for the `DRUNK` op" + +["P.SEED"] +prototype = "P.SEED" +prototype_set = "P.SEED x" +aliases = ["P.SD"] +short = "get / set the random number generator seed for the `P.RND` and `PN.RND` ops" diff --git a/docs/ops/rhythm.md b/docs/ops/rhythm.md new file mode 100644 index 00000000..580ae12f --- /dev/null +++ b/docs/ops/rhythm.md @@ -0,0 +1,3 @@ +## Rhythm + +Mathematical calculations and tables helpful for rhythmic decisions. diff --git a/docs/ops/rhythm.toml b/docs/ops/rhythm.toml new file mode 100644 index 00000000..9ef05387 --- /dev/null +++ b/docs/ops/rhythm.toml @@ -0,0 +1,74 @@ +[BPM] +prototype = "BPM x" +short = "milliseconds per beat in BPM `x`" + +["DR.P"] +prototype = "DR.P b p s" +short = "Drum pattern helper, `b` is the drum bank (`0-4`), `p` is the pattern (0-215) and step is the step number (0-15), returns `0` or `1`" +description = """ +The drum helper uses preset drum patterns to give 16-step gate patterns. Gates wrap after step 16. Bank 0 is a set of pseudo random gates increasing in density at higher numbered patterns, where pattern 0 is empty, +and pattern 215 is 1s. Bank 1 is bass drum patterns. Bank 2 is snare drum patterns. Bank 3 is closed hi-hats. Bank 4 is open hi-hits and in some cases cymbals. Bank 1-4 patterns are related to each other (bank 1 pattern 1's bass drum pattern fits bank 2 pattern 1's snare drum pattern). +The patterns are from [Paul Wenzel's "Pocket Operations" book](https://shittyrecording.studio/). +""" + +["DR.T"] +prototype = "DR.T b p q l s" +short = "Tresillo helper, `b` is the drum bank (`0-4`), `p` is first pattern (0-215), `q` is the second pattern (0-215), `l` is length (`1-64`), and step is the step number (0-length-1), returns `0` or `1`" +description = """ +The Tresillo helper uses the preset drum patterns described in the drum pattern help function in a 3, 3, 2 rythmic formation. In the tresillo, pattern 1 will be repeated twice for a number of steps determined by the overall length of the pattern. A pattern of length 8 will play the first three steps of your selected pattern 1 twice, and +the first two steps of pattern 2 once. A pattern length of 16 will play the first six steps of selected pattern 1 twice, and the first four steps of pattern 2 once. And so on. The max length is 64. Length will be rounded down to the nearest multiple of 8. The step number wraps at the given length. +""" + +["DR.V"] +prototype = "DR.V p s" +short = "Velocity helper. `p` is the pattern (0-19). `s` is the step number (0-15)" +description = """ +The velocity helper gives velocity values (0-16383) at each step. The values are intended to be used for drum hit velocities. There are 16 steps, which wrap around. Divide by 129 to convert to midi cc values. +""" + +[ER] +prototype = "ER f l i" +short = "Euclidean rhythm, `f` is fill (`1-32`), `l` is length (`1-32`) and `i` is step (any value), returns `0` or `1`" +description=""" +Euclidean rhythm helper, as described by Godfried Toussaint in his 2005 paper ["The Euclidean Algorithm Generates Traditional Musical Rhythms"][euclidean_rhythm_paper][^euclidean_rhythm_citation]. From the abstract: + + - `f` is fill (`1-32`) and should be less then or equal to length + - `l` is length (`1-32`) + - `i` is the step index, and will work with negative as well as positive numbers + +If you wish to add rotation as well, use the following form: + +``` +ER f l SUB i r +``` + +where `r` is the number of step of _forward_ rotation you want. + +For more info, see the post on [samdoshi.com][samdoshi_com_euclidean] + +[samdoshi_com_euclidean]: http://samdoshi.com/post/2016/03/teletype-euclidean/ +[euclidean_rhythm_paper]: http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf +[^euclidean_rhythm_citation]: Toussaint, G. T. (2005, July). The Euclidean algorithm generates traditional musical rhythms. _In Proceedings of BRIDGES: Mathematical Connections in Art, Music and Science_ (pp. 47-56). +""" + +[NR] +prototype = "NR p m f s" +short = "Numeric Repeater, `p` is prime pattern (`0-31`), `m` is & mask (`0-3`), `f` is variation factor (`0-16`) and `s` is step (`0-15`), returns `0` or `1`" +description = """ +Numeric Repeater is similar to ER, except it generates patterns using the binary arithmetic process found in ["Noise Engineering's Numeric Repetitor"][numeric_repetitor]. From the description: + +Numeric Repetitor is a rhythmic gate generator based on binary arithmetic. A core pattern forms the basis and variation is achieved by treating this pattern as a binary number and multiplying it by another. NR contains 32 prime rhythms derived by examining all possible rhythms and weeding out bad ones via heuristic. + +All parameters wrap around their specified ranges automatically and support negative indexing. + +Masks + - `0` is no mask + - `1` is `0x0F0F` + - `2` is `0xF003` + - `3` is `0x1F0` + +For further detail ["see the manual"][nr_manual]. + +[numeric_repetitor]: https://www.noiseengineering.us/shop/numeric-repetitor +[nr_manual]: https://static1.squarespace.com/static/58c709192e69cf2422026fa6/t/5e6041ad4cbc0979d6d793f2/1583366574430/NR_manual.pdf +""" diff --git a/docs/ops/seed.md b/docs/ops/seed.md deleted file mode 100644 index 40a76a4c..00000000 --- a/docs/ops/seed.md +++ /dev/null @@ -1,2 +0,0 @@ -## Seed - diff --git a/docs/ops/seed.toml b/docs/ops/seed.toml deleted file mode 100644 index 8301af14..00000000 --- a/docs/ops/seed.toml +++ /dev/null @@ -1,34 +0,0 @@ -["SEED"] -prototype = "SEED" -prototype_set = "SEED x" -short = "get / set the random number generator seed for all `SEED` ops" - -["RAND.SEED"] -prototype = "RAND.SEED" -prototype_set = "RAND.SEED x" -aliases = ["RAND.SD", "R.SD"] -short = "get / set the random number generator seed for `R`, `RRAND`, and `RAND` ops" - -["TOSS.SEED"] -prototype = "TOSS.SEED" -prototype_set = "TOSS.SEED x" -aliases = ["TOSS.SD"] -short = "get / set the random number generator seed for the `TOSS` op" - -["PROB.SEED"] -prototype = "PROB.SEED" -prototype_set = "PROB.SEED x" -aliases = ["PROB.SD"] -short = "get / set the random number generator seed for the `PROB` mod" - -["DRUNK.SEED"] -prototype = "DRUNK.SEED" -prototype_set = "DRUNK.SEED x" -aliases = ["DRUNK.SD"] -short = "get / set the random number generator seed for the `DRUNK` op" - -["P.SEED"] -prototype = "P.SEED" -prototype_set = "P.SEED x" -aliases = ["P.SD"] -short = "get / set the random number generator seed for the `P.RND` and `PN.RND` ops" diff --git a/docs/ops/variables.toml b/docs/ops/variables.toml index a5368d1a..efc23c4f 100644 --- a/docs/ops/variables.toml +++ b/docs/ops/variables.toml @@ -18,40 +18,10 @@ prototype = "D" prototype_set = "D x" short = "get / set the variable `D`, default `4`" -[DRUNK] -prototype = "DRUNK" -prototype_set = "DRUNK x" -short = """changes by `-1`, `0`, or `1` upon each read saving its state, -setting will give it a new value for the next read""" -description=""" -Changes by `-1`, `0`, or `1` upon each read, saving its state. Setting `DRUNK` -will give it a new value for the next read, and drunkedness will continue on -from there with subsequent reads. - -Setting `DRUNK.MIN` and `DRUNK.MAX` controls the lower and upper bounds -(inclusive) that `DRUNK` can reach. `DRUNK.WRAP` controls whether the value can -wrap around when it reaches it's bounds. -""" - -["DRUNK.MIN"] -prototype = "DRUNK.MIN" -prototype_set = "DRUNK.MIN x" -short = "set the lower bound for `DRUNK`, default `0`" - -["DRUNK.MAX"] -prototype = "DRUNK.MAX" -prototype_set = "DRUNK.MAX x" -short = "set the upper bound for `DRUNK`, default `255`" - -["DRUNK.WRAP"] -prototype = "DRUNK.WRAP" -prototype_set = "DRUNK.WRAP x" -short = "should `DRUNK` wrap around when it reaches it's bounds, default `0`" - [FLIP] prototype = "FLIP" prototype_set = "FLIP x" -short = "returns inverted state (`0` or `1`) on each read (also settable)" +short = "returns the opposite of its previous state (`0` or `1`) on each read (also settable)" [I] prototype = "I" diff --git a/utils/cheatsheet.py b/utils/cheatsheet.py index 7a47e514..8b70d07c 100755 --- a/utils/cheatsheet.py +++ b/utils/cheatsheet.py @@ -48,41 +48,42 @@ def inject_latex(value): # last two columns indicates when a column break or page break is inserted _after_ that section OPS_SECTIONS = { "core": [ - ("variables", "Variables", False, False), + ("variables", "Variables", True, False), ("hardware", "Hardware", False, False), - ("patterns", "Patterns", True, False), + ("pitch", "Pitch", True, False), + ("rhythm", "Rhythm", False, False), + ("metronome", "Metronome", False, False), + ("random", "Randomness", True, False), ("controlflow", "Control flow", False, False), ("maths", "Maths", False, False), - ("music", "Musical Maths", False, False), - ("metronome", "Metronome", False, False), ("delay", "Delay", False, False), - ("stack", "Stack", True, False), - ("queue", "Queue", True, False), - ("seed", "Seed", True, False), - ("turtle", "Turtle", False, True), - ("grid", "Grid", False, False), + ("stack", "Stack", True, False), + ("patterns", "Patterns", True, False), + ("queue", "Queue", True, False), + ("turtle", "Turtle", False, True), + ("grid", "Grid", True, False), ("midi_in", "MIDI In", False, False), - ("hardware_setup", "Hardware Setup", False, False) + ("calibration", "Calibration", False, False) ], "i2c": [ ("i2c", "Generic I2C", False, False), ("ansible", "Ansible", False, False), - ("whitewhale", "Whitewhale", True, False), + ("whitewhale", "White Whale", False, False), ("meadowphysics", "Meadowphysics", False, False), ("earthsea", "Earthsea", False, False), ("orca", "Orca", False, False), - ("justfriends", "Just Friends", True, False), - ("er301", "ER-301", False, False), + ("justfriends", "Just Friends", True, False), ("fader", "Faderbank", False, False), + ("er301", "ER-301", False, False), ("matrixarchate", "Matrixarchate", False, False), ("telex_i", "TELEXi", False, False), - ("telex_o", "TELEXo", False, False), - ("disting", "Disting EX", False, False), + ("telex_o", "TELEXo", True, False), ("wslash", "W/1.0", False, False), ("wslashdelay", "W/2.0 delay", False, False), ("wslashsynth", "W/2.0 synth", False, False), - ("wslashtape", "W/2.0 tape", False, False), - ("crow", "Crow", False, True), + ("wslashtape", "W/2.0 tape", True, False), + ("crow", "Crow", False, False), + ("disting", "Disting EX", False, True), ("i2c2midi", "I2C2MIDI", False, False) ] } diff --git a/utils/docs.py b/utils/docs.py index d47ff7ec..6a28d6dd 100755 --- a/utils/docs.py +++ b/utils/docs.py @@ -34,19 +34,20 @@ OPS_SECTIONS = [ "variables", "hardware", - "patterns", + "pitch", + "rhythm", + "metronome", + "random", "controlflow", "maths", - "music", - "metronome", "delay", "stack", + "patterns", "queue", - "seed", "turtle", "grid", "midi_in", - "hardware_setup", + "calibration", "i2c", "ansible", "whitewhale", @@ -54,17 +55,17 @@ "earthsea", "orca", "justfriends", + "fader", + "er301", + "matrixarchate", "telex_i", "telex_o", - "er301", - "fader", "wslash", - "matrixarchate", - "disting", "wslashdelay", "wslashsynth", "wslashtape", "crow", + "disting", "i2c2midi" ] From bb75cc703b1cc12fa13667d31499aa047e272930 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 18 Dec 2023 01:26:12 -0500 Subject: [PATCH 04/11] remove unimplemented see_also props --- docs/ops/hardware.toml | 3 --- docs/ops/maths.toml | 5 ++++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/ops/hardware.toml b/docs/ops/hardware.toml index 873a00fc..4b077503 100644 --- a/docs/ops/hardware.toml +++ b/docs/ops/hardware.toml @@ -6,7 +6,6 @@ description = """ Get the value of CV associated with output `x`, or set the CV output of `x` to `y`. """ -see_also = "`V` and `VV` in Maths, `N` in Musical Maths, `CV.CAL` in Hardware Setup" ["CV.OFF"] prototype = "CV.OFF x" @@ -55,7 +54,6 @@ short = "Get the value of IN jack (0-16383)" description = """ Get the value of the IN jack. This returns a valuue in the range 0-16383. """ -see_also = "`IN.CAL` ops in Hardware Setup" ["IN.SCALE"] prototype = "IN.SCALE min max" @@ -68,7 +66,6 @@ short = "Get the value of PARAM knob (0-16383)" description = """ Get the value of the PARAM knob. This returns a valuue in the range 0-16383. """ -see_also = "`PARAM.CAL` ops in Hardware Setup" ["PARAM.SCALE"] prototype = "PARAM.SCALE min max" diff --git a/docs/ops/maths.toml b/docs/ops/maths.toml index a53a6a2f..0eec7e75 100644 --- a/docs/ops/maths.toml +++ b/docs/ops/maths.toml @@ -48,7 +48,10 @@ short = "limit the value `x` to the range `y` to `z` inclusive, but with wrappin [QT] prototype = "QT x y" short = "round `x` to the closest multiple of `y` (quantise)" -see_also = "`QT.S`, `QT.CS`, `QT.B`, `QT.BX` in Musical Maths" +description = """ +Round `x` to the closest multiple of `y`. +*See also: `QT.S`, `QT.CS`, `QT.B`, `QT.BX` in the Pitch section*. +""" [AVG] prototype = "AVG x y" From 6e38c54d016a676601ed5d86eb19f3682fba270d Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 18 Dec 2023 02:15:55 -0500 Subject: [PATCH 05/11] Compress TXo short descriptions, reorder i2c sections --- docs/ops/telex_o.toml | 98 +++++++++++++++++++++++++++++++++++-------- utils/cheatsheet.py | 18 ++++---- utils/docs.py | 6 +-- 3 files changed, 93 insertions(+), 29 deletions(-) diff --git a/docs/ops/telex_o.toml b/docs/ops/telex_o.toml index 18a423f5..ef7959f5 100644 --- a/docs/ops/telex_o.toml +++ b/docs/ops/telex_o.toml @@ -272,12 +272,16 @@ You will find that the offset is now zero, but the output is at the value that y ["TO.CV.RESET"] prototype = "TO.CV.RESET x" -short = "Clears the calibration offset for output `x`." +short = "Clears the calibration offset for output `x`" ["TO.OSC"] prototype = "TO.OSC x y" -short = "targets oscillation for CV output `x` to `y` with the portamento rate determined by the `TO.OSC.SLEW` value; `y` is 1v/oct translated from the standard range (1-16384); a value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "Targets oscillation for CV output `x` to `y`" description = """ +Targets oscillation for CV output `x` to `y` with the portamento rate determined by the `TO.OSC.SLEW` value. +`y` is 1V/oct translated from the standard range (1-16384). +A value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. + Setting an `OSC` frequency greater than zero for a `CV` output will start that output oscillating. It will swing its voltage between to the current `CV` value and its polar opposite. For example: ``` @@ -302,39 +306,79 @@ If you want to go back to regular `CV` behavior, you need to set the oscillation ["TO.OSC.SET"] prototype = "TO.OSC.SET x y" -short = "set oscillation for CV output `x` to `y` (ignores `CV.OSC.SLEW`); `y` is 1v/oct translated from the standard range (1-16384); a value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "set oscillation for CV output `x` to `y` (ignores slew)" +description = """ +Set oscillation for CV output `x` to `y` (ignores `CV.OSC.SLEW`.) `y` is 1V/oct translated from the standard range (1-16384); +a value of `0` disables oscillation. `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. +""" ["TO.OSC.QT"] prototype = "TO.OSC.QT x y" -short = "targets oscillation for CV output `x` to `y` with the portamento rate determined by the `TO.OSC.SLEW` value; `y` is 1v/oct translated from the standard range (1-16384) and quantized to current `OSC.SCALE`; a value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "targets oscillation for CV output `x` to `y`" +description = """ +Targets oscillation for CV output `x` to `y` with the portamento rate determined by the `TO.OSC.SLEW` value. +`y` is 1V/oct translated from the standard range (1-16384) and quantized to current `OSC.SCALE`. +A value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. +""" ["TO.OSC.QT.SET"] prototype = "TO.OSC.QT.SET x y" -short = "set oscillation for CV output `x` to `y` (ignores `CV.OSC.SLEW`); `y` is 1v/oct translated from the standard range (1-16384) and quantized to current `OSC.SCALE`; a value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "set oscillation for CV output `x` to `y`, quantized to the current scale (ignores slew)" +description = """ +Set oscillation for CV output `x` to the 1V/oct value `y` (ignores `CV.OSC.SLEW`.) +`y` is 1v/oct translated from the standard range (1-16384) and quantized to current `OSC.SCALE`. +A value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. +""" ["TO.OSC.N"] prototype = "TO.OSC.N x y" -short = "targets oscillation for CV output `x` to note `y` with the portamento rate determined by the `TO.OSC.SLEW` value; see quantization scale reference for `y`; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "targets oscillation for CV output `x` to note `y`" +description = """ +Targets oscillation for CV output `x` to note `y` with the portamento rate determined by the `TO.OSC.SLEW` value. +See quantization scale reference for `y`; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. +""" ["TO.OSC.N.SET"] prototype = "TO.OSC.N.SET x y" -short = "sets oscillation for CV output `x` to note `y` (ignores `CV.OSC.SLEW`); see quantization scale reference for `y`; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "sets oscillation for CV output `x` to note `y` (ignores slew)" +description = """ +Sets oscillation for CV output `x` to note `y` (ignores `CV.OSC.SLEW`.) +See quantization scale reference for `y`; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. +""" ["TO.OSC.FQ"] prototype = "TO.OSC.FQ x y" -short = "targets oscillation for CV output `x` to frequency `y` with the portamento rate determined by the `TO.OSC.SLEW` value; `y` is in Hz; a value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "targets oscillation for CV output `x` to frequency `y` in Hertz" +description = """ +Targets oscillation for CV output `x` to frequency `y` with the portamento rate determined by the `TO.OSC.SLEW` value. +`y` is in Hz; a value of `0` disables oscillation. `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. +""" ["TO.OSC.FQ.SET"] prototype = "TO.OSC.FQ.SET x y" -short = "sets oscillation for CV output `x` to frequency `y` (ignores `CV.OSC.SLEW`); `y` is in Hz; a value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "targets oscillation for CV output `x` to frequency `y` in Hertz (ignores slew)" +description = """ +Sets oscillation for CV output `x` to frequency `y` (ignores `CV.OSC.SLEW`.) +`y` is in Hz; a value of `0` disables oscillation. `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. +""" ["TO.OSC.LFO"] prototype = "TO.OSC.LFO x y" -short = "targets oscillation for CV output `x` to LFO frequency `y` with the portamento rate determined by the `TO.OSC.SLEW` value; `y` is in mHz (millihertz: 10^-3 Hz); a value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "Targets oscillation for CV output `x` to LFO frequency `y` in millihertz" +description = """ +Targets oscillation for CV output `x` to LFO frequency `y` with the portamento rate determined by the `TO.OSC.SLEW` value. +`y` is in mHz (millihertz: 10^-3 Hz); a value of `0` disables oscillation. +`CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. +""" ["TO.OSC.LFO.SET"] prototype = "TO.OSC.LFO.SET x y" -short = "sets oscillation for CV output `x` to LFO frequency `y` (ignores `CV.OSC.SLEW`); `y` is in mHz (millihertz: 10^-3 Hz); a value of `0` disables oscillation; `CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable" +short = "Targets oscillation for CV output `x` to LFO frequency `y` in millihertz (ignores slew)" +description = """ +Sets oscillation for CV output `x` to LFO frequency `y` (ignores `CV.OSC.SLEW`.) +`y` is in mHz (millihertz: 10^-3 Hz); a value of `0` disables oscillation. +`CV` amplitude is used as the peak for oscillation and needs to be `> 0` for it to be perceivable. +""" ["TO.OSC.CYC"] prototype = "TO.OSC.CYC x y" @@ -386,11 +430,15 @@ description = """ ["TO.OSC.WAVE"] prototype = "TO.OSC.WAVE x y" -short = "set the waveform for output `x` to `y`; `y` values range `0-4500`. There are 45 different waveforms, values translate to sine (0), triangle (100), saw (200), pulse (300) all the way to random/noise (4500); oscillator shape between values is a blend of the pure waveforms" +short = "set the waveform for output `x` to `y`; `y` range is `0-4500`, blending between 45 waveforms" +description = """ +There are 45 different waveforms, values translate to sine (0), triangle (100), saw (200), pulse (300) all the way to random/noise (4500). +Oscillator shape between values is a blend of the pure waveforms. +""" ["TO.OSC.RECT"] prototype = "TO.OSC.RECT x y" -short = "rectifies the polarity of the oscillator for output `x` to `y`; range for `y` is -2 to 2; default is 0 (no rectification); 1 & -1 are partial rectification - omitting all values on the other side of the sign; 2 & -2 are full rectification - inverting values from the other pole" +short = "rectifies the polarity of the oscillator for output `x` to `y`; 0 is no rectification, +/-1 is partial rectification, +/-2 is full rectification" description = """ The rectification command performs a couple of levels of rectification based on how you have it set. The following values for `y` work as follows: @@ -470,7 +518,12 @@ To return your `CV` output to normal function, either deactivate the envelope (` ["TO.ENV"] prototype = "TO.ENV x y" -short = "This parameter essentially allows output `x` to act as a gate between the 0 and 1 state. Changing this value from 0 to 1 causes the envelope to trigger the attack phase and hold at the peak CV value; changing this value from 1 to 0 causes the decay stage of the envelope to be triggered." +short = "trigger the attack stage of output `x` when `y` changes to 1, or decay stage when it changes to 0" +description = """ +This parameter essentially allows output `x` to act as a gate between the 0 and 1 state. Changing this value from 0 to 1 +causes the envelope to trigger the attack phase and hold at the peak CV value; changing this value from 1 to 0 causes the +decay stage of the envelope to be triggered. +""" ["TO.ENV.TRIG"] prototype = "TO.ENV.TRIG x" @@ -502,8 +555,11 @@ short = "set the envelope decay time to `y` for `CV` output `x`; `y` in minutes" ["TO.ENV.EOR"] prototype = "TO.ENV.EOR x n" -short = "fires a `PULSE` at the End of Rise to the unit-local trigger output 'n' for the envelope on `CV` output `x`; `n` refers to trigger output 1-4 on the same TXo as CV output 'y'" +short = "at the end of rise of `CV` output `x`, fires a `PULSE` to the trigget output `n`" description = """ +Fires a `PULSE` at the End of Rise to the unit-local trigger output `n` for the envelope on `CV` output `x`; +`n` refers to trigger output 1-4 on the same TXo as CV output `x`. + The most important thing to know with this operator is that you can only cause the EOR trigger to fire on the same device as the TXo with the envelope. For this command, the outputs are numbered LOCALLY to the unit with the envelope. For example, if you have an envelope running on your second TXo, you can only send the EOR pulse to the four outputs on that device: @@ -517,8 +573,11 @@ This will cause the first output on TXo #2 (`TO.TR 5`) to pulse after the envelo ["TO.ENV.EOC"] prototype = "TO.ENV.EOC x n" -short = "fires a `PULSE` at the End of Cycle to the unit-local trigger output 'n' for the envelope on `CV` output `x`; `n` refers to trigger output 1-4 on the same TXo as CV output 'y'" +short = "at the end of cycle of `CV` output `x`, fires a `PULSE` to the trigget output `n`" description = """ +Fires a `PULSE` at the End of Cycle to the unit-local trigger output `n` for the envelope on `CV` output `x`. +`n` refers to trigger output 1-4 on the same TXo as CV output 'y'. + The most important thing to know with this operator is that you can only cause the EOC trigger to fire on the same device as the TXo with the envelope. For this command, the outputs are numbered LOCALLY to the unit with the envelope. For example, if you have an envelope running on your second TXo, you can only send the EOC pulse to the four outputs on that device: @@ -532,7 +591,12 @@ This will cause the first output on TXo #2 (`TO.TR 5`) to pulse after the envelo ["TO.ENV.LOOP"] prototype = "TO.ENV.LOOP x y" -short = "causes the envelope on `CV` output `x` to loop for `y` times; a `y` of `0` will cause the envelope to loop infinitely; setting `y` to 1 (default) disables looping and (if currently looping) will cause it to finish its current cycle and cease" +short = "causes the envelope on `CV` output `x` to loop for `y` times" +description = """ +Causes the envelope on `CV` output `x` to loop for `y` times. +A `y` of `0` will cause the envelope to loop infinitely; setting `y` to 1 (default) disables looping and (if currently looping) will +cause it to finish its current cycle and cease. +""" ["TO.TR.INIT"] prototype = "TO.TR.INIT x" diff --git a/utils/cheatsheet.py b/utils/cheatsheet.py index 9dbbaf0c..44d1df59 100755 --- a/utils/cheatsheet.py +++ b/utils/cheatsheet.py @@ -70,21 +70,21 @@ def inject_latex(value): ("ansible", "Ansible", False, False), ("whitewhale", "White Whale", False, False), ("meadowphysics", "Meadowphysics", False, False), - ("earthsea", "Earthsea", False, False), + ("earthsea", "Earthsea", True, False), ("orca", "Orca", False, False), ("justfriends", "Just Friends", True, False), ("fader", "Faderbank", False, False), ("er301", "ER-301", False, False), - ("matrixarchate", "Matrixarchate", False, False), - ("telex_i", "TELEXi", False, False), + ("telex_i", "TELEXi", True, False), ("telex_o", "TELEXo", True, False), - ("wslash", "W/1.0", False, False), - ("wslash_shared", "W/2.0", False, False), - ("wslashdelay", "W/2.0 delay", False, False), - ("wslashsynth", "W/2.0 synth", False, False), - ("wslashtape", "W/2.0 tape", True, False), ("crow", "Crow", False, False), - ("disting", "Disting EX", False, True), + ("wslash", "W/1.0", True, False), + ("wslash_shared", "W/2.0", False, False), + ("wslashtape", "W/2.0 tape", False, False), + ("wslashdelay", "W/2.0 delay", True, False), + ("wslashsynth", "W/2.0 synth", True, False), + ("disting", "Disting EX", True, False), + ("matrixarchate", "Matrixarchate", False, True), ("i2c2midi", "I2C2MIDI", False, False) ] } diff --git a/utils/docs.py b/utils/docs.py index 5c30bb09..7218bd39 100755 --- a/utils/docs.py +++ b/utils/docs.py @@ -57,16 +57,16 @@ "justfriends", "fader", "er301", - "matrixarchate", "telex_i", "telex_o", + "crow", "wslash", "wslash_shared", + "wslashtape", "wslashdelay", "wslashsynth", - "wslashtape", - "crow", "disting", + "matrixarchate", "i2c2midi" ] From 0c3f77f9cfa5c6769955d5eeb4ffe6bcfac56333 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 18 Dec 2023 02:44:18 -0500 Subject: [PATCH 06/11] Tweak hardware section a bit more --- docs/ops/hardware.toml | 28 ++++++++++++++-------------- utils/cheatsheet.py | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/ops/hardware.toml b/docs/ops/hardware.toml index 4b077503..9a5c199a 100644 --- a/docs/ops/hardware.toml +++ b/docs/ops/hardware.toml @@ -18,8 +18,8 @@ output `x` to `y`. """ ["CV.SET"] -prototype = "CV.SET x" -short = "Set CV value" +prototype = "CV.SET x y" +short = "Set CV value, ignoring slew" description = """ Set the CV value at output `x` bypassing any slew settings. """ @@ -80,14 +80,12 @@ Get the current state of trigger output `x`. Set the state of trigger output `x` to `y` (0-1). """ -["TR.POL"] -prototype = "TR.POL x" -prototype_set = "TR.POL x y" -short = "Set polarity of trigger output x to y (0-1)" +["TR.PULSE"] +prototype = "TR.PULSE x" +aliases = ["TR.P"] +short = "Pulse trigger output x" description = """ -Get the current polarity of trigger output `x`. Set the polarity of trigger -output `x` to `y` (0-1). When TR.POL = 1, the pulse is 0 to 1 then back to 0. -When TR.POL = 0, the inverse is true, 1 to 0 to 1. +Pulse trigger output x. """ ["TR.TIME"] @@ -106,12 +104,14 @@ description = """ Flip the state of trigger output `x`. """ -["TR.PULSE"] -prototype = "TR.PULSE x" -aliases = ["TR.P"] -short = "Pulse trigger output x" +["TR.POL"] +prototype = "TR.POL x" +prototype_set = "TR.POL x y" +short = "Set polarity of trigger output x to y (0-1)" description = """ -Pulse trigger output x. +Get the current polarity of trigger output `x`. Set the polarity of trigger +output `x` to `y` (0-1). When TR.POL = 1, the pulse is 0 to 1 then back to 0. +When TR.POL = 0, the inverse is true, 1 to 0 to 1. """ ["MUTE"] diff --git a/utils/cheatsheet.py b/utils/cheatsheet.py index 44d1df59..2fb07db1 100755 --- a/utils/cheatsheet.py +++ b/utils/cheatsheet.py @@ -49,7 +49,7 @@ def inject_latex(value): OPS_SECTIONS = { "core": [ ("variables", "Variables", True, False), - ("hardware", "Hardware", False, False), + ("hardware", "Hardware I/O", False, False), ("pitch", "Pitch", True, False), ("rhythm", "Rhythm", False, False), ("metronome", "Metronome", False, False), From 9373f6b946d62368a2146edf3f68810cf0274748 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 18 Dec 2023 02:46:41 -0500 Subject: [PATCH 07/11] Update CHANGELOG and whats_new --- CHANGELOG.md | 1 + docs/whats_new.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 574fc76e..f62371be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ - **NEW**: apply VCV Rack compatibility patches, so branches off main can be used in both hardware and software - **FIX**: update Disting EX looper ops to work with Disting EX firmware 1.23+ - **NEW**: new dual W/ ops: `W/.SEL`, `W/S.POLY`, `W/S.POLY.RESET`, `W/1`, `W/2` +- **NEW**: split cheatsheets into separate PDFs for core ops and i2c ## v4.0.0 diff --git a/docs/whats_new.md b/docs/whats_new.md index de74dc10..46e7a073 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -33,6 +33,7 @@ - **NEW**: apply VCV Rack compatibility patches, so branches off main can be used in both hardware and software - **FIX**: update Disting EX looper ops to work with Disting EX firmware 1.23+ - **NEW**: new dual W/ ops: `W/.SEL`, `W/S.POLY`, `W/S.POLY.RESET`, `W/1`, `W/2` +- **NEW**: split cheatsheets into separate PDFs for core ops and i2c ## v4.0.0 From abe72cfc2d76def850f2301fdb8821558e9332b5 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 18 Dec 2023 02:52:31 -0500 Subject: [PATCH 08/11] Fix calibration section heading level --- docs/ops/calibration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ops/calibration.md b/docs/ops/calibration.md index cf5c082d..fbf47db6 100644 --- a/docs/ops/calibration.md +++ b/docs/ops/calibration.md @@ -1 +1 @@ -# Calibration \ No newline at end of file +## Calibration \ No newline at end of file From 076c950d89b6430537d5d3b49eaf5faa9be2fd59 Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 18 Dec 2023 03:10:16 -0500 Subject: [PATCH 09/11] make clean in docs should be more effective --- docs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index 6d5f4e31..e6b622f2 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -5,7 +5,7 @@ build: teletype.pdf teletype.html cheatsheet/cheatsheet-core.pdf cheatsheet/chea clean: rm -f teletype.pdf && \ rm -f teletype.html && \ - rm -f cheatsheet/cheatsheet-*.tex && \ + rm -f cheatsheet/cheatsheet-*.* && \ cd cheatsheet && \ latexmk -xelatex -c && \ rm -f cheatsheet.pdf From bac0c86876f890b643bd7b361f3a95bf9278b74c Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 18 Dec 2023 03:10:43 -0500 Subject: [PATCH 10/11] tweak IJK short blurbs --- docs/ops/variables.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/ops/variables.toml b/docs/ops/variables.toml index efc23c4f..0c460355 100644 --- a/docs/ops/variables.toml +++ b/docs/ops/variables.toml @@ -26,7 +26,7 @@ short = "returns the opposite of its previous state (`0` or `1`) on each read (a [I] prototype = "I" prototype_set = "I x" -short = """get / set the variable `I`""" +short = """get / set the per-script variable `I`. *See also `L:` in control flow*""" description=""" Get / set the variable `I`. This variable is overwritten by `L`, but can be used freely outside an `L` loop. Each script gets its own `I` variable, so if you call @@ -38,7 +38,7 @@ its `I` value initialized with the calling loop's current `I` value. [J] prototype = "J" prototype_set = "J x" -short = """get / set the variable `J`""" +short = """get / set the per-script variable `J`""" description=""" get / set the variable `J`, each script gets its own `J` variable, so if you call a script from another script you can still use and modify `J` without affecting the calling script. @@ -47,7 +47,7 @@ a script from another script you can still use and modify `J` without affecting [K] prototype = "K" prototype_set = "K x" -short = """get / set the variable `K`""" +short = """get / set the per-script variable `K`""" description=""" get / set the variable `K`, each script gets its own `K` variable, so if you call a script from another script you can still use and modify `K` without affecting the calling script. From eaaedbec4224a763e25461560139617e7ba59d0b Mon Sep 17 00:00:00 2001 From: Michael Dewberry Date: Mon, 18 Dec 2023 03:16:26 -0500 Subject: [PATCH 11/11] Keep original name for core cheatsheet --- docs/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index e6b622f2..391c3550 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,6 +1,6 @@ .PHONY: build clean -build: teletype.pdf teletype.html cheatsheet/cheatsheet-core.pdf cheatsheet/cheatsheet-i2c.pdf +build: teletype.pdf teletype.html cheatsheet/cheatsheet.pdf cheatsheet/cheatsheet-i2c.pdf clean: rm -f teletype.pdf && \ @@ -22,4 +22,7 @@ cheatsheet/cheatsheet-%.tex: $(wildcard ops/*.toml) ../utils/cheatsheet.py ../utils/cheatsheet.py $* "cheatsheet/cheatsheet-$*.tex" cheatsheet/cheatsheet-%.pdf: cheatsheet/cs-common.tex cheatsheet/cheatsheet-%.tex - cd cheatsheet && latexmk -xelatex cs-common.tex -jobname=cheatsheet-$* \ No newline at end of file + cd cheatsheet && latexmk -xelatex cs-common.tex -jobname=cheatsheet-$* + +cheatsheet/cheatsheet.pdf: cheatsheet/cheatsheet-core.pdf + cd cheatsheet && cp cheatsheet-core.pdf cheatsheet.pdf \ No newline at end of file