Jump to content
Sign in to follow this  
erka

I try to set tonality for all midi-notes

Recommended Posts

Hi,

Just got the license and start getting into Opusmodus and lisp. The first task I try is to set the whole midirange to a tonality .

I tried to write a function but somehow i only get part of the expected result.

'(c0 d0 e0 f0)  ; plays with Cmd-1

(setf pat1 (flatten(pitch-transpose-repeat '(c0 c1 c2 c3 c4 c5 c6 c7) (expand-chord-name '(major) :type :pitch))))
;;(c1 d1 e1 f1 g1 a0 b0 c1 d1 e1 f1 g1 a1 b1 c2 d2 e2 f2 g2 a2 b2 c3 d3 e3 f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5 d5 e5 f5 g5 a5 b5 c6 d6 e6 f6 g6 a6 b6 c7 d7 e7 f7 g7 a7 b7

(defun gen-c0-scale (  shift chord_name &optional (ambituslist '(c0 b7)) )
(ambitus-remove ambituslist (pitch-transpose shift (flatten(pitch-transpose-repeat '(c0 c1 c2 c3 c4 c5 c6 c7) (expand-chord-name chord_name :type :pitch))))))

(setf pat2 (gen-c0-scale 0 '(major) ))
;;(c1 d1 e1 f1 g1 a0 b0 c1 d1 e1 f1 g1 a1 b1 c2 d2 e2 f2 g2 a2 b2 c3 d3 e3 f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5 d5 e5 f5 g5 a5 b5 c6 d6 e6 f6 g6 a6 b6 c7 d7 e7 f7 g7 a7 b7)
(setf pat2 (gen-c0-scale 0 '(minor) ))
;;(c1 d1 eb1 f1 g1 gs1 bb0 c1 d1 eb1 f1 g1 gs1 bb1 c2 d2 eb2 f2 g2 gs2 bb2 c3 d3 eb3 f3 g3 gs3 bb3 c4 d4 eb4 f4 g4 gs4 bb4 c5 d5 eb5 f5 g5 gs5 bb5 c6 d6 eb6 f6 g6 gs6 bb6 c7 d7 eb7 f7 g7 gs7 bb7)

(setf pat3 (gen-c0-scale 0 '(major) '(c1 b7) ))
;;(c1 d1 e1 f1 g1 c1 d1 e1 f1 g1 a1 b1 c2 d2 e2 f2 g2 a2 b2 c3 d3 e3 f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5 d5 e5 f5 g5 a5 b5 c6 d6 e6 f6 g6 a6 b6 c7 d7 e7 f7 g7 a7 b7)

 

I wonder why pat1 starts with c1 and jumps to a0 .

I guess there is a much better way to do that, that gives the expected result.

 

Share this post


Link to post
Share on other sites

Hi Rolf,

You are not getting the expected result because the default ambitus in transposition functions is set to 'piano.

Try this:

(setf pat1
      (flatten
       (pitch-transpose-start
        '(c0 c1 c2 c3 c4 c5 c6 c7)
        (gen-repeat 8 (expand-chord-name '(major) :type :pitch))
        :ambitus '(c0 c8))))

 

and this:

(defun gen-c0-scale (shift chord_name &optional (ambituslist '(c0 b7)))
  (ambitus-remove 
   ambituslist
   (pitch-transpose shift
                    (pitch-transpose-start
                     '(c0 c1 c2 c3 c4 c5 c6 c7)
                     (gen-repeat 8 (expand-chord-name chord_name :type :pitch))
                     :ambitus '(c0 c8))
                    :ambitus '(c0 c8))))

(gen-c0-scale 0 '(major))
=> ((c0 d0 e0 f0 g0 a0 b0)
    (c1 d1 e1 f1 g1 a1 b1)
    (c2 d2 e2 f2 g2 a2 b2)
    (c3 d3 e3 f3 g3 a3 b3)
    (c4 d4 e4 f4 g4 a4 b4)
    (c5 d5 e5 f5 g5 a5 b5)
    (c6 d6 e6 f6 g6 a6 b6)
    (c7 d7 e7 f7 g7 a7 b7))

Go to the 'System Function' library and check the TONALITY-MAP and TONALITY-SERIES functions.

Edited by Janusz Podrazik

Share this post


Link to post
Share on other sites

Thank you Janusz,

I checked the TONALITY-MAP. Some parameter i didn't understand, but that is for the future.

I tried:

(filter-repeat 1
(tonality-map '(major :ambitus '(a0 c8))
   (integer-to-pitch (gen-integer -39 48))))  => expected result

(filter-repeat 1
(tonality-map '(major :ambitus '(c0 c8))
   (integer-to-pitch (gen-integer -48 48)))) => returns notes starting with a0 

 

here the :ambitus didn't do the trick.

Is there a reason for not having the whole midi-range as default ambits? Is there a global-variable to set the default-ambitus?

I will try ways, which helps me to get some experience with lisp- and opusmodus

Share this post


Link to post
Share on other sites

The ambitus span of the tonality is (-38 48) now, I will extend the span to (-48 48.)

Results now:

(filter-repeat 2
 (tonality-map '(major :ambitus '(a0 c8))
  (integer-to-pitch (gen-integer -39 48))))
=> (a0 b0
    c1 d1 e1 f1 g1 a1 b1
    c2 d2 e2 f2 g2 a2 b2
    c3 d3 e3 f3 g3 a3 b3
    c4 d4 e4 f4 g4 a4 b4
    c5 d5 e5 f5 g5 a5 b5
    c6 d6 e6 f6 g6 a6 b6
    c7 d7 e7 f7 g7 a7 b7
    c8)

(filter-repeat 1
 (tonality-map '(major :ambitus '(c0 c8))
  (integer-to-pitch (gen-integer -48 48))))
=> (c0 d0 e0 f0 g0 a0 b0
    c1 d1 e1 f1 g1 a1 b1
    c2 d2 e2 f2 g2 a2 b2
    c3 d3 e3 f3 g3 a3 b3
    c4 d4 e4 f4 g4 a4 b4
    c5 d5 e5 f5 g5 a5 b5
    c6 d6 e6 f6 g6 a6 b6
    c7 d7 e7 f7 g7 a7 b7
    c8)

 

Share this post


Link to post
Share on other sites

I just found out that I had my midi-range wrong  (0-127) -> (-60 67).

(midi-to-hertz '(0 48 60 127))
(pitch-to-hertz '(c-1 c0 c1 c4 c8 c9 g9))
(pitch-to-integer '(c-1 c0 c1 c4 c8 c9 g9))


All work with the whole range.

(integer-to-pitch '(-60 -48 -36 0 48 60 67)) 

=> (c-1 c0 c1 c4 c8 c9 g8)  shifts above c9.

 

(integer-to-pitch (gen-integer -60 67))

=> (c-1 ........bb8 b8 c9 cs8 d8 eb8 e8 f8 fs8 g8)

 

PITCH-TO-INTEGER works, INTEGER-TO-PITCH does not for the  midi-(0-127).

Maybe you could also expand INTEGER-TO-PITCH and TONALITY-MAP to (c-1 g9).

I understand that when you compose for piano etc you don't need this range.

As you have a MIDI-TO-HERTZ, why not those:

defun midi-to-integer (midinrlist)
(mapcar #'(lambda (x) (- x 60)) midinrlist))

(midi-to-integer '( 0 60 90 127))

(defun midi-to-pitch (midinrlist)
(integer-to-pitch
(mapcar #'(lambda (x) (- x 60)) midinrlist)))

(midi-to-pitch '( 0 60 90 127))

 

Share this post


Link to post
Share on other sites

In the real world the c-1 g9 range make not much sense :-)

Share this post


Link to post
Share on other sites

Be careful !

Don't try to define MIDI-TO-PITCH and MIDI-TO-INTEGER functions as you made in your post because you'll broke opusmodus midi-player because this functions are already defined into the internal system.

SB.

Share this post


Link to post
Share on other sites

Thanks Stephane. Good to know.

I agree Janusz, (c-1 g9)  don't make sense in the real world. But they might in the midi-world. When you connect to ableton or Logic or else and have rigs with split keyboard  or samples  assigned. I plan to use opusmodus with my DAWs . That is even more confusing they have a range from C-2 to G8, all of them. MAX6, too.

I just see that some functions work with the whole range and some don't. Is it possible that functions have different default ambitus?

But I guess I should concentrate on other functions and just keep in the  'piano range for now.

Thanks for the update.

Share this post


Link to post
Share on other sites

If a function has ambitus keyword, then the default is set to 'piano. You always can extend the ambitus.
In the next update I will extend the tonality span to cover the entire midi range.

Share this post


Link to post
Share on other sites

Thanks Janusz.  

About the midi-functions. Is it the name of the function or what would ruin the midi engine?

Couldn't the concept of packages be used to protect data and functions that are essential for the system from user manipulation?

How can I know what functions are internal defined and shouldn't be altered ?

(fboundp 'midi-to-pitch)

 

I guess.

If it is only the name I would  just prefix all functions i define.

 Okay. Yes. I know. I should first get into all the defined functions and understand them and then build new ones.

 

Share this post


Link to post
Share on other sites

FBOUNDP is good way to see if true or nil.

or you could use:

(describe 'gen-weight)

Share this post


Link to post
Share on other sites

the output is:

Arglist: (Pizza Spagetti Chocolate Beer  Burger  Weißwurst &rest fat-objects )

Thanks. I also found  when the function exists there is a auto-complete in the status-bar of the composer. I will have a look for that and use prefix for own functions.

These (gen-weight and the twelve-tone-functions) are the kind of function I will have to look at.

I bought Nigel Morgan's e-book "Parametric compositions". Very good. A little hard for me, the non academic theory trained. So I have to repeat reading  while learning.

Today I should get Dominik Sedivy's "Serial composition and Tonality"    

Share this post


Link to post
Share on other sites

Dominik Sedivy's "Serial composition and Tonality" book is great indeed.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Similar Topics

    • By terekita
      Hello,
       
      So, this obviously works:
       
      (setf pitch (integer-to-pitch '(20 19 18 15))) (tonality-map '(minor-pentatonic :root c0 :map step :rotate 20) pitch) but this—passing in a variable to the :rotate key—doesn't. (Assuming because it's inside a quoted list?)
       
      (let ((offset 20)) (tonality-map '(minor-pentatonic :root c0 :map step :rotate offset) pitch))  
      I'd like to do something like the latter because I'd like to dynamically pass in changing values for :rotate. Any tips or suggestions?
       
      thanks for taking a look, Michael
       
       
       
    • By AM
      like this (?)...
       
      ;;; mapping to MAJOR (setf sort-seq (integer-to-pitch (flatten (gen-sort (rnd-order (gen-integer 24)) :type 'selection)))) (def-score example-score (:key-signature 'atonal :time-signature '(4 4) :tempo 90 :layout (treble-layout 'seq)) (seq :omn (make-omn :pitch (setf n (tonality-map '(major :map step :root 'c4) sort-seq)) :length (gen-repeat (length (flatten n)) '(t))))) ;;; mapping to MESSIAEN-mode (setf sort-seq (integer-to-pitch (flatten (gen-sort (rnd-order (gen-integer 24)) :type 'insertion)))) (def-score example-score (:key-signature 'atonal :time-signature '(4 4) :tempo 90 :layout (treble-layout 'seq)) (seq :omn (make-omn :pitch (setf n (tonality-map '(messiaen-mode5 :map step :root 'c4) sort-seq)) :length (gen-repeat (length (flatten n)) '(t))))) ;;; mapping to a XENAKIS-SIEVE -> how can i do that with TONALITY-MAP? (but not necessary) (setf sieve (gen-sieve '((c4 g7) (c1 g7)) '((2 1 12) (3 5)) :type :pitch)) (setf sort-seq (flatten (gen-sort (rnd-order (gen-integer (length sieve))) :type 'insertion :sort '?))) (def-score example-score (:key-signature 'atonal :time-signature '(4 4) :tempo 90 :layout (treble-layout 'seq)) (seq :omn (make-omn :pitch (setf n (loop for i in sort-seq collect (nth i sieve))) :length (gen-repeat (length (flatten n)) '(t)))))  
    • By torstenanders
      I like how the function tonality-map allows specifying some input harmony (called tonality) and raw music, where the "raw" music is then quasi-quantised into the given harmony. 
       
      However, I would like to control in which octaves specific tones are allowed to occur. tonality-map allows specifying an underlying harmony that ranges over multiple octaves, but it seems that internally only octave-less pitch classes are used, and any tone in the harmony can occur in any octave in the result. By contrast, in the spectral tradition of music thinking, you change the underlying spectrum if you scramble in which octaves pitches occur. For example, if you have a spectrum or chord that approximates the overtone series, then that spectrum sounds rather consonant, regardless how far up in the overtone series you allow tones to be included. However, if you then randomly octave-transpose the pitches of this spectrum/chord, then it can become much more dissonant, without changing any pitch classes.
       
      To be more specific here is a dummy example with simple traditional chords where tones are distributed across octaves in a certain way. 
       
      (tonality-map   ;; underlying harmony or spectra  '((c4g4e5b5d6) (g3d4b5f5a4))  ;; input music  '((h c4f5 cs4fs5) (d4g5 cs4gs5) (eb4as5 f4a5) (e4gs5 c4gs5))  ;; harmonic rhythm  :time '(w w w_w)) => ((h c4e5 c4g5) (h a3d5 g3d5) (h e4b5 e4b5) (h e4g5 c4g5))  
      As you can see, the tone G in the first tonality occurs only in octave 4, but in the result, in the second chord of the first bar (still following the first tonality) we have a g5 instead. Now, you might feel that the g5 does not musically do any harm, but in the second tonality, there is an A only in octave 6, while in the function output in the related third chord the A occurs three octaves lower in octave 3, where it greatly increases the dissonance degree of this chord/scale. 
       
      So, is there a way to restrict the octaves of tones in the result to be restricted to the octaves of these tones in the respective tonalities? Alternatively, is there another function that complements tonality-map, where I can force some "raw" music to follow some underlying harmony with a given harmonic rhythm, and where the octaves of the resulting pitches can be restricted?
       
      Thank you! 
       
      Best,
      Torsten
×
×
  • Create New...