Wim Dijkgraaf Posted December 7, 2016 Share Posted December 7, 2016 I'm not an expert in Neo-Riemannian Theory at all but as a consequence of my Common Lisp study and writing of some functions to do Diatonic Neigbour Tones and Leading Tones, I bumped into this and it's kind of what I'm trying to accomplish musically. Does Opusmodus have functions for this (implicitly or explicitly) or does anyone know of a Common Lisp library that is already specialized in Neo-Riemannian transformation? Basically the ability to do P R and L motions using elegant functions and calculating the shortest modulation (shortest Tonnetz steps) from any triad to any other triad. One of the many explanations on youtube: JulioHerrlein and opmo 1 1 Quote Link to comment Share on other sites More sharing options...
Stephane Boussuge Posted December 7, 2016 Share Posted December 7, 2016 Hi Wim, i have made some test not really on neo-riemannian style but a bit connected to this idea. I have tried to "navigate" form chord to chord with horizontal trajectory made with the Opusmodus function gen-tendency. Here's my attempt: ;;; Chords Trajectory ;;; ======================================== (setf base-chords '(c4e4g4c5 f4a4c5f5 d4fs4a4d5 g4b4d5g5)) ;; Extract horizontal pitch lines from base-chords (setf base-chords.v1 (pitch-demix 1 base-chords)) (setf base-chords.v2 (pitch-demix 2 base-chords)) (setf base-chords.v3 (pitch-demix 3 base-chords)) (setf base-chords.v4 (pitch-demix 4 base-chords)) ;; transpose them two octave up for greater than zero values (setf base-chords.v1.t (pitch-transpose 24 base-chords.v1)) (setf base-chords.v2.t (pitch-transpose 24 base-chords.v2)) (setf base-chords.v3.t (pitch-transpose 24 base-chords.v3)) (setf base-chords.v4.t (pitch-transpose 24 base-chords.v4)) ;; tendency trajectory with variance 0 (setf td-steps 4) (setf td-n (* (length base-chords) td-steps)) (setf v1.td (mapcar 'round (gen-tendency td-n (pitch-to-integer base-chords.v1.t) :variance 0))) (setf v2.td (mapcar 'round (gen-tendency td-n (pitch-to-integer base-chords.v2.t) :variance 0))) (setf v3.td (mapcar 'round (gen-tendency td-n (pitch-to-integer base-chords.v3.t) :variance 0))) (setf v4.td (mapcar 'round (gen-tendency td-n (pitch-to-integer base-chords.v4.t) :variance 0))) ;; convert back to pitch (setf v1.td.p (integer-to-pitch v1.td)) (setf v2.td.p (integer-to-pitch v2.td)) (setf v3.td.p (integer-to-pitch v3.td)) (setf v4.td.p (integer-to-pitch v4.td)) ;; back to chords (setf re-chords (pitch-transpose -24 (pitch-mix (apply-eval '(v1.td.p v2.td.p v3.td.p v4.td.p))))) ;; closest path (setf re-chords.closest (chord-closest-path (list (car re-chords)) re-chords)) ;; relative path (setf re-chords.relative (chord-relative-path (list (car re-chords)) re-chords)) Thank you for the videos links, very interesting. SB. Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 7, 2016 Author Share Posted December 7, 2016 Hi Stephane, Thanks, will have a look at this. I'm thinking of creating a Tonnetz object in Lisp that can be P R and L moved and potentially also polarized Tonnetz movements (feed it with a list of movements and it will return a list of triad harmonies with proper voice leading) as well as a modulation method to modulate to every other root of a triad. I'm trying to figure out the most elegant API for this right now ... implementation comes after that ;-) Just a thought in the back of my mind right now. If anyone has ideas ... please let me/all of us know. Anyhow looks like a great Common Lisp kata. Big hug, Wim Dijkgraaf Quote Link to comment Share on other sites More sharing options...
opmo Posted December 7, 2016 Share Posted December 7, 2016 At the moment I am working on other things but I will have a look and see if I can make a function for it. Stephane Boussuge 1 Quote Link to comment Share on other sites More sharing options...
Stephane Boussuge Posted December 7, 2016 Share Posted December 7, 2016 This book extend the concept to 3D tonnetz. Quite interesting but very complicated. http://dmitri.mycpanel.princeton.edu/geometry-of-music.html SB. Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 7, 2016 Author Share Posted December 7, 2016 Funny, I do have that book in my Kindle ... never had the time to give it a read. Thanks for the tip! Quote Link to comment Share on other sites More sharing options...
lviklund Posted December 7, 2016 Share Posted December 7, 2016 Amazing! Thank you guys for the info. /Lasse Quote Link to comment Share on other sites More sharing options...
torstenanders Posted December 9, 2016 Share Posted December 9, 2016 Dear Wim, neo Riemannian functions and Tonnetz functionality has been implemented as part of Music21, or extensions of it. E.g., see https://groups.google.com/forum/#!topic/music21list/crDnYIx6kvo Perhaps you want to port some of that Python code to Common Lisp, that might be easier than developing the algorithms from scratch? BTW, some of the code discussed there is by Dmitri Tymoczko, the author of A Geometry of Music (which, I agree, is a book really worth reading for the likes of us :). Best, Torsten PS: I assume you are not only programming in Common Lisp, so you may already know Python. (If not, that is rather easy to learn if you know Lisp already...) Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 10, 2016 Author Share Posted December 10, 2016 Have published the initial Tonnetz implementation (really bad code, has to be refactored and has some bugs): This is my first attempt ... still completely novice in Common Lisp. https://github.com/willemdijkgraaf/ClTonnetz Big hug Thanks Torsten! Will check it out. I'm fluent in C#, Typescript and Javascript but will check it out anyway. JulioHerrlein, Stephane Boussuge and opmo 2 1 Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 11, 2016 Author Share Posted December 11, 2016 Just updated github -> did some refactoring today. Still far from what it should be though :-) Quote Link to comment Share on other sites More sharing options...
opmo Posted December 11, 2016 Share Posted December 11, 2016 The update produces an error: (move-s '(c4 eb4 g4)) > Error: The value nil is not of the expected type fixnum. > While executing: move-r, in process Listener-3(11). > Type cmd-. to abort, cmd-\ for a list of available restarts. > Type :? for other options. Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 11, 2016 Author Share Posted December 11, 2016 I'm working on that bug ... still some refactoring to do too. Will keep you informed. Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 11, 2016 Author Share Posted December 11, 2016 I think it's working now. Have also removed workspace from source control. Guess that those paths to my file system are of no help to others :-) torstenanders 1 Quote Link to comment Share on other sites More sharing options...
torstenanders Posted December 12, 2016 Share Posted December 12, 2016 Very nice start! Unfortunately, the model results in some enharmonic problems. For example, (apply-tonnetz '(c4 e4 g4) '(n)) should result in f-minor, but instead results in (c4 f4 gs4). I assume there is no real way around that with Opusmodus and 12-EDO so far. I solved such problems once simply by using a different tuning system, e.g., 31-EDO, because that tuning has distinct pitch classes for tones like ab vs. gs, and distinct pitch class intervals for, say, a minor third vs an augmented second. Any plans to go beyond, e.g., having transformations for chords beyond major and minor, taking scales into account etc? Minor issue: some of your tests meanwhile fail, likely because of some later refactoring. (equal (triad-is-major '(c4 e4 g4)) 't) Also, you may want to introduce some function that allows for recursive transformations to avoid things like (move (move (move triad 'l) 'p) 'r)). Best, Torsten Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 12, 2016 Author Share Posted December 12, 2016 Hi Torsten, Yes, will be continued. I needed a "topic" to work on to improve my Lisp skills. This is something not too big to work on. My first aim is to implement the diagram you find on this wiki: https://en.wikipedia.org/wiki/Tonnetz . Still have to do some refactoring. Maybe trying a more OO approach too. Next step is to fully support this circle: https://commons.wikimedia.org/wiki/File:Circle_of_fifths,_clock_and_tonnetz.svg Besides this, I'm studying Dimitri's book (as you and Stephane mentioned). Too early to have plans to implement that but it looks interesting enough to support his approach(es). And of course the idea is to experiment with the Tonnetz and using it in a more free way by super-imposing triads, transposing voices, adding ornamentations etc. Any additional ideas are very welcome of course. Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 12, 2016 Author Share Posted December 12, 2016 Ah, and who knows ... something like this: http://www.mtosmt.org/issues/mto.10.16.3/mto.10.16.3.waters_williams.html Quote Link to comment Share on other sites More sharing options...
torstenanders Posted December 12, 2016 Share Posted December 12, 2016 Would it help to have your transformation functions be related to explicit scales and its scale degrees (instead of measuring intervals in semitones)? That is what I did in my own computational harmony model. That allowed me to use arbitrary scales and the chords that belong to those scales. The tricky bit is that I am using constraint programming, where each variable can be controlled by multiple restrictions (constraints). So, I can restrict both intervals measured in semitones and in scale degrees independently. Would be tricky to translate that into plain functions. Attached is a related (unpublished) paper that outlines the approach in principle, though many details are missing in that paper. Tricky to share the code on that, because there is lots. Some core functionality (the data structure) is defined here (Oz programming language). https://github.com/tanders/strasheela/blob/master/strasheela/contributions/anders/HarmonisedScore/source/Score.oz Constraint programming is also possible within Common Lisp (e.g., with Screamer, https://nikodemus.github.io/screamer/, and other constraint solvers exist as well), and for mere harmony modelling (in contrast to modelling polyphonic music composition in general) this might be rather fast. Best, Torsten TorstenAnders-HarmonyModel-CP2016.pdf lviklund 1 Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 13, 2016 Author Share Posted December 13, 2016 Hi Torsten, My main goal to learn Common Lisp, Opusmodus and have something like the Tonnetz to do musical experiments with. For that I'm happy with correct absolute pitches and less concerned with enharmonic correctness. Constraint programming is completely new to me. As soon as I've a bit of time I'll definitely have a look at it as well as to your paper. I've checked the link and browsed a bit through your projects. Wow, really impressive stuff! Great to get to know you a little bit through this forum. Best, Wim Quote Link to comment Share on other sites More sharing options...
Wim Dijkgraaf Posted December 14, 2016 Author Share Posted December 14, 2016 A little extra feature to play with: (apply-tonnetz '(c4 e4 g4) '(l r n s p)) => ((c4 e4 g4) (b3 e4 g4) (b3 d4 g4) (c4 eb4 g4) (b3 eb4 fs4) (b3 d4 fs4)) Ability to not include a move in the output (by putting that move between parentheses): (apply-tonnetz '(c4 e4 g4) '(l r n (s) p)) => ((c4 e4 g4) (b3 e4 g4) (b3 d4 g4) (c4 eb4 g4) (b3 d4 fs4)) opmo, Stephane Boussuge and JulioHerrlein 2 1 Quote Link to comment Share on other sites More sharing options...
JulioHerrlein Posted December 22, 2017 Share Posted December 22, 2017 Dear Wim I found your model very interesting and useful. It worked for me. Best ! Julio Quote Link to comment Share on other sites More sharing options...
opmo Posted December 10, 2019 Share Posted December 10, 2019 Following our successful presentation in the Museo di Storia Naturale in Venice on the 7th December, Achim Bornhoeft and I spent some time talking and playing with the Neo-Riemann theory with an outcome of a diagram and a function. This will be part of the next release. Post-Riemann Transformations on a C major triad One step transformation (basic transformations): P (parallel) R (relative) L (leading) Two step transformations: Parallel: PR and PL Relative: RL and RP Leading: LR and LP Three step transformations: Parallel: PLR and PRL Relative: RLP and RPL Leading: LPR and LPR Reflection: PLR and RLP are equal. PRL and LRP are equal. RPL and LPR are equal. Examples: (tonnetz 'c4e4g4 '(p p r r l l)) => (c4e4g4 c4eb4g4 c4e4g4 c4e4a4 c4e4g4 b3e4g4 c4e4g4) (tonnetz '(c4 e4 g4) '(p p r r l l)) => ((c4 e4 g4) (c4 eb4 g4) (c4 e4 g4) (c4 e4 a4) (c4 e4 g4) (b3 e4 g4) (c4 e4 g4)) (tonnetz 'e4g4b4 '(l r l r p l r l r p)) => (e4g4b4 e4g4c5 e4a4c5 f4a4c5 f4a4d5 fs4a4d5 fs4a4cs5 e4a4cs5 e4gs4cs5 e4gs4b4 e4g4b4) (tonnetz 'ab3c4eb4 '(p l p l p l p l)) => (ab3c4eb4 gs3b3eb4 gs3b3e4 g3b3e4 g3c4e4 g3c4eb4 gs3c4eb4 gs3b3eb4 gs3b3e4) (tonnetz 'ab3c4eb4 '(pl pl pl pl)) => (ab3c4eb4 gs3b3e4 g3c4e4 gs3c4eb4 gs3b3e4) (tonnetz 'c4e4g4 '(p r p r p r p r)) => (c4e4g4 c4eb4g4 bb3eb4g4 bb3eb4fs4 bb3cs4fs4 a3cs4fs4 a3cs4e4 a3c4e4 g3c4e4) (setf moves (rnd-order '(p l r lr lp rp rl pr pl plr prl rpl) :seed 26)) => (rp rl rpl pr prl lr r p plr pl lp l) (tonnetz 'c4e4g4 moves) => (c4e4g4 cs4e4a4 d4fs4a4 eb4fs4bb4 eb4g4c5 f4a4c5 e4g4c5 e4a4c5 e4a4cs5 f4a4d5 fs4a4cs5 f4a4d5 f4bb4d5) (setf transitions '(p l r lr lp rp rl pr pl plr prl rpl prlpr lrplprpp)) (setf rnd-transition (rnd-sample 15 transitions :seed 750989)) => (prlpr r r p pl pl lrplprpp lr prlpr rpl lp rl prl rl rpl) (tonnetz 'ab3c4eb4 rnd-transition)) => (ab3c4eb4 g3c4eb4 g3bb3eb4 g3c4eb4 g3c4e4 gs3c4eb4 gs3b3e4 f3bb3d4 f3a3c4 e3a3c4 eb3gs3c4 e3g3c4 f3a3c4 eb3g3c4 d3g3bb3 cs3fs3bb3) (tonnetz '(c maj) '(plp rpr lpl rpr lpl lpl rprp lpl)) => (c4e4g4 b3eb4gs4 a3d4fs4 bb3cs4f4 gs3b3e4 g3c4eb4 gs3b3e4 bb3d4f4 a3cs4fs4) AM, JulioHerrlein and lviklund 1 2 Quote Link to comment Share on other sites More sharing options...
JulioHerrlein Posted December 11, 2019 Share Posted December 11, 2019 Dear Janusz, This is a really cool feature I was looking for ! There is a lot of interesting transformations and graphs related to this subject, like this, compiled by my friend Ciro Visconti, who studied with Straus: THE FAMOUS "CUBE DANCE" PARSIMONIOUS TRANSFORMATIONS OF 4-NOTE CHORDS BORETZ SPIDER POWER TOWERS And so on, all related to the basic tonnetz transformations. A good idea is thinking how to model also four note structures. All the best ! Julio opmo 1 Quote Link to comment Share on other sites More sharing options...
opmo Posted December 12, 2019 Share Posted December 12, 2019 Many transformations indeed :-) JulioHerrlein 1 Quote Link to comment Share on other sites More sharing options...
torstenanders Posted December 17, 2019 Share Posted December 17, 2019 > Achim Bornhoeft and I spent some time talking and playing with the Neo-Riemann theory with an outcome of a diagram and a function Thanks for sharing. Do I understand correctly that these transformations always assume triads? Of course, one can always extend the triads afterwards... Best, Torsten Stephane Boussuge 1 Quote Link to comment Share on other sites More sharing options...
JulioHerrlein Posted December 17, 2019 Share Posted December 17, 2019 Dear Torsten, Some of the graphs above imply the concept of parsimounious voice leading among four-note chords also, as an extension of the classic operations (P,L,R) to the domain of the tetrachords. best, Julio Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.