torstenanders
-
Posts
497 -
Joined
-
Last visited
Content Type
Forums
Events
Store
Video Gallery
Posts posted by torstenanders
-
-
Great. How do we document such features so that there is an obvious place for them for new users?
Best,
Torsten
-
Dear Achim,
From your error message at the end (There is no package named "PW" ) it looks like you did not follow the installation instructions, which you can find at https://github.com/tanders/cluster-engine In a nutshell, you should load it with ASDF and for that put it at a location where ASDF can find it. Instead, when you are putting it into ~/Opusmodus/Extensions/ then files are loaded in a wrong order.
Best,
Torsten
-
I just got a copy of EW ComposerCloud and had a look at this. Wow -- this setup is a true monster, and way too much for my poor mere 8GB laptop (with unfortunately no way to extend the memory). I can confirm that in principle your setup works on my computer (Opusmodus can control sound playback of the instruments), but even when I reduce the bidule-file to only the string section, my machine has difficulties handling it. Sigh.
How much memory are you using?
I wish Play would have a purge feature similar to Kontakt, where you can basically start with an empty patch, and all samples needed are by and by loaded. (Play has some purge functionality, but it is more limited, only useful when the score is already fixed, which is not terribly useful in an environment like Opumodus). (I would probably need a second computer and something like Vienna Ensemble Pro to handle a full orchestra, in particular as I would be interested in using multiple articulations...)
In your setup, you are running a separate Play instance for each instrument, and then you load several articulations per instrument into that Play instance, each on a different MIDI channel. I don't quite understand how this should work, as each instrument is controlled by only a single MIDI channel.
Best,
Torsten
-
I assume internally of tonality-map there is a comparison of pitch classes (modulus 12 of pitches) deduced from the input "raw" music with the input pitch classes of the underlying harmony/spectra (called tonalities here). All that would be needed technically is to instead allow for a comparison among pitches or MIDI note numbers instead (i.e. skipping the modulus 12 calculation). This behaviour could be the default or controlled with a keyword argument to tonality-map.
Best,
Torsten
-
Simply slightly edit the algorithms below by inserting some additional output. Below I simply took one of the algorithms you linked and added a single print statement. If instead you want to collect all the results, then just accumulate them in some variable with a scope surrounding your algorithm function.
(defun bubble-sort/naive (sequence) (let ((end (length sequence))) (labels ((compare-and-swap (index modified) ;; print intermediate results (print sequence) (if (= index (1- end)) (if modified (compare-and-swap 0 nil) (values)) (let ((index+1 (1+ index))) (if (> (elt sequence index) (elt sequence index+1)) (let ((x (elt sequence index))) (setf (elt sequence index) (elt sequence index+1) (elt sequence index+1) x) (compare-and-swap index+1 t)) (compare-and-swap index+1 modified)))))) (unless (< end 2) (compare-and-swap 0 nil)) sequence))) (bubble-sort/naive '(3 1 9 5 3 6 4 2 3 7))
Best,Torsten
-
Nice. You might like the graphical explanation of search algorithms and other algorithms at https://idea-instructions.com. They are visualising such algorithms basically following an IKAE style of graphics.
Best,
Torsten
-
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
-
Citing the documentation: "INIT-SEED can be used at the start of algorithmic compositions employing high degrees of randomness in order to create consisted results, without having to worry about supplying seed N values to all the other functions which may also use random generation."
The function init-seed does not give you any new value actually (it just returns its argument), but in the background as a side-effect initialises the random generation of all Opusmodus random functions, so that their results are consistent on re-evaluation.
Just try removing it in your function :)
Besides, programs that reduce any changes to global states and side effects to the absolute minimum (which is most often using no stateful programming at all) are more easy to maintain and expand. Your little function introduces two stateful operations that are not needed here: setf (better use a local let) and init-seed. (This is even more important when writing concurrent code, which can be necessary when doing real-time stuff, e.g., when you have multiple processes running in parallel changing the same global variables without further precaution.)
Best,
Torsten
-
On 3/31/2018 at 7:40 PM, lviklund said:
(defun doseed (&key seed) (setf seed (init-seed (rnd-range 1 999999))) (print seed)) (rnd-sample 5 '(c4 e4 g4 b4) :seed (doseed))
This works for me.
/Lasse
Below is a more secure variant of that function, which does not overwrite the seeds of all other functions. Calling init-seed is not needed here...
I avoided using do in the function name, as functions/macros named such are by convention looping constructs.
Best,
Torsten
(defun mk-seed (&optional seed) "Generates a random seed value, prints and returns it. Useful for exploring different results of random processes, but then keeping a found solution. Args: - seed (int): optionally fixes generated seed. Examples: (rnd-sample 3 '(c4 d4 e4) :seed (mk-seed)) ; 405621 rnd-sample => (c4 e4 d4) (rnd-sample 3 '(c4 d4 e4) :seed (mk-seed 13)) ; 13 rnd-sample => (e4 d4 e4) " (print (if seed seed (rnd-range 1 999999))))
-
> Perhaps if possible also with the variable name as a label to keep track of things when using several random functions in complex code:
(setf bin-rhythm (gen-binary-rnd 5 5 2 1)) => bin-rhytm gen-binary-rnd :seed 37
This should be easy to do with a revision of the macro do-verbose, but as users, we have no access to its definition to change it. (The macro would check the value of the variable seed in its environment.)
Side remark: If anyone revises do-verbose, it would be highly welcome to be able to switch off its effect altogether, because Common Lisp offers much better builtin debugging facilities than what this macro does.
Anyway, here is an easy workaround for your particular situation.
(setf bin-rhythm (gen-binary-rnd 5 5 2 1 :seed (print 123))) ; printed: 123 gen-binary-rnd => ((0 0 1 0 0) (1 0 1 0 1) (0 1 1 0 1) (1 1 0 1 1) (0 1 0 1 1))
See also the discussion in the thread linked below.Best,
Torsten
-
Wow, that is fancy :)
Here is one that is even slightly more fancy, where the resulting softer velocity values also react to the velocity input, and also the pitch of easy beats is slightly different.
(defun metronome (sequence &key (pitch 'c4) (velocity 90))
(let* ((ts (get-time-signature sequence))
(len (loop for i in ts
collect (gen-repeat (car i) (list (/ 1 (second i))))))
(vel (loop for i in ts
collect (append (get-velocity (list velocity) :type :symbol)
(gen-repeat (1- (car i))
(get-velocity (list (- velocity 25))
:type :symbol)))))
(pitch (loop for i in ts
collect (cons pitch
(pitch-transpose
-2 (gen-repeat (1- (car i)) pitch))))))
(make-omn :length len
:pitch pitch
:velocity vel)))TA
-
I suggest you simply and an explicit track to your score with repeated note values, e.g., quarter notes (crotchets), perhaps like the following.
(make-omn :length (gen-repeat 16 '(1/4)))
In your MIDI setup you may assign this to a percussive instrument, if you prefer.
Best,
Torsten
-
> If you open a midi-file created with Opusmodus with Logic, all the tracks will be created, the tempo map, the bar changes and logic will load instruments exactly as you describe.
Yes, indeed. The only thing missing from Jor's list would be proper automation data, AFAIK. You can have CC data, but Logic automation data is a different animal.
Best,
Torsten
-
Are you talking about something different than MIDI realtime output to a DAW like Logic? What exactly do you mean by "compile a project to a DAW" that goes beyond MIDI routing?
Best,
Torsten
-
I see -- they need to be declared in in the :controllers section. Thanks a lot!
I now got it almost working. Below is my current sound set again. I had to simplify the combination symbols to I1, I2 etc (the former underscore was confusing the OMN parser).
What is missing still is support for combining articulations like II+II2 (i.e., use division II with combination 2 of that division). I can have combinations like stacc+II or leg+II2, but II+II2 is only notated, the playback does not work.Here are two examples. The first one works fine, but is not actually what I need.
'((q c4 stacc+II) (e c4 leg d4 stacc e4 II4+leg f4 stacc) (q g4 marc -q -h))
The second example demonstrates the problem.
'((q c4 II+II2) (e c4 leg d4 stacc e4 II4+leg f4 stacc) (q g4 marc -q -h))
Specifically, whether I notate II+II2 or II2+II, II is executed, but II2 is not. The later II4+leg again triggers the combination 4 fine.
I had a look at a resulting exported MIDI file, and indeed in the combination II+II2 the CC message for II is output, but the program change message for II2 is not. If II2 or one of its friends is used independently or in a combination like stacc+II2 it does work, though.
Is there perhaps some bug in the sound set definition here that only kicks in when user-defined articulations are combined?
Thanks again!
Best,
Torsten
PS: I only define support for predefined combinations of stops instead of stops directly for multiple reasons. This is more easy to define (less symbols overall), and is independent of specific organs or chosen stop combinations -- I can change the registration (combinations of stops used at certain moments) and even the organ without changing the score (generation).
(add-text-attributes
;; Setting divisions and couplings
;; Note: I don't notate couplers with plus (e.g., I + II), but instead simply I and II
;; (Notation revised manually later in Sibelius)
'(G_C "G.C.")
'(Ped "Ped")
'(I "I")
'(II "II")
'(III "III")
'(-Ped "- Ped")
'(-I "- I")
'(-II "- II")
'(-III "- III");; divisional combinations for the organ
;;
;; Pedal
'(P1 "P: 1")
'(P2 "P: 2")
'(P3 "P: 2")
'(P4 "P: 4")
'(P5 "P: 5")
'(P6 "P: 6")
'(P7 "P: 7")
'(P8 "P: 8")
'(P9 "P: 9")
'(P10 "P: 10")
;;
;; I
'(I1 "I: 1")
'(I2 "I: 2")
'(I3 "I: 2")
'(I4 "I: 4")
'(I5 "I: 5")
'(I6 "I: 6")
'(I7 "I: 7")
'(I8 "I: 8")
'(I9 "I: 9")
'(I10 "I: 10")
;;
;; II
'(II1 "II: 1")
'(II2 "II: 2")
'(II3 "II: 2")
'(II4 "II: 4")
'(II5 "II: 5")
'(II6 "II: 6")
'(II7 "II: 7")
'(II8 "II: 8")
'(II9 "II: 9")
'(II10 "II: 10")
;;
;; III
'(III1 "III: 1")
'(III2 "III: 2")
'(III3 "III: 2")
'(III4 "III: 4")
'(III5 "III: 5")
'(III6 "III: 6")
'(III7 "III: 7")
'(III8 "III: 8")
'(III9 "III: 9")
'(III10 "III: 10"))
;;; TODO: uncomment when errors like "there is no controller named: cc20" are fixed
(def-sound-set GrandOrgue-organ
:programs
(:group couplers
Ped (cc20 127)
-Ped (cc20 1)
I (cc21 127)
-I (cc21 1)
II (cc22 127)
-II (cc22 1)
III (cc23 127)
-III (cc23 1)
G_C (cc30 127);; sends program change messages to switch combinations for a certain division
:group combinations
P1 1
P2 2
P3 3
P4 4
P5 5
P6 6
P7 7
P8 8
P9 9
P10 10I1 21
I2 22
I3 23
I4 24
I5 25
I6 26
I7 27
I8 28
I9 29
I10 30
II1 41
II2 42
II3 43
II4 44
II5 45
II6 46
II7 47
II8 48
II9 49
II10 50III1 61
III2 62
III3 63
III4 64
III5 65
III6 66
III7 67
III8 68
III9 69
III10 70
)
:controllers
(:group Default-Settings
Pitch 0
Velocity-XF 2
Volume 7
Pan 10
Expression 11
Reverb-Dry/Wet 14
Reverb-On/Off 15
Slot-XF 20
Start-Scaler 21
Master-Attack 22
Master-Release 23
Master-Filter 24
Delay-Scaler 25
Tuning-Scaler 26
Humanize 27
Velocity-XF-On-Off 28
Rsamp-On-Off 29
Dynamics-Scaler 30:group Pedal
Pedal 64 ; not 'Ped'
Sustain 64
Sost-Ped 66
Sostenuto 66
Una-Corda 67
Soft-Pedal 67
:group Matrix
cc1 1
cc20 20
cc21 21
cc22 22
cc23 23
cc30 30
)) -
I would like to define a new sound set to control a particular setting of the virtual organ GrandOrgue (https://sourceforge.net/projects/ourorgan/), a very nice and flexible pipe organ simulator. After investing quite some amount of time I now got some setting that allows me to nicely control GrandOrgue from Sibelius, and I would like to reproduce that control in Opusmodus. For that, I need to send certain CC messages and program change messages depending on articulations in the score. For example, I use articulations like 'I', to set the current staff to the organ division I (usually main) or 'II" for the division II (swell).
Now, I might be simply missing something obvious here (e.g., a typo), but I keep getting error messages like the following when evaluating my sound set below this message, but I cannot find out what I am doing wrong.
> Error: In sound set grandorgue-organ, program ped, there is no controller named: cc20
Can anyone perhaps see what I am missing here? Thanks a lot!
Best,
Torsten
(def-sound-set GrandOrgue-organ :programs (:group couplers Ped (cc20 127) -Ped (cc20 1) I (cc21 127) -I (cc21 1) II (cc22 127) -II (cc22 1) III (cc23 127) -III (cc23 1) G_C (cc30 127) ;; sends program change messages to switch combinations for a certain division :group combinations P_1 1 P_2 2 P_3 3 P_4 4 P_5 5 P_6 6 P_7 7 P_8 8 P_9 9 P_10 10 I_1 21 I_2 22 I_3 23 I_4 24 I_5 25 I_6 26 I_7 27 I_8 28 I_9 29 I_10 30 II_1 41 II_2 42 II_3 43 II_4 44 II_5 45 II_6 46 II_7 47 II_8 48 II_9 49 II_10 50 III_1 61 III_2 62 III_3 63 III_4 64 III_5 65 III_6 66 III_7 67 III_8 68 III_9 69 III_10 70 ) :controllers (:group Default-Settings Pitch 0 Velocity-XF 2 Volume 7 Pan 10 Expression 11 Reverb-Dry/Wet 14 Reverb-On/Off 15 Slot-XF 20 Start-Scaler 21 Master-Attack 22 Master-Release 23 Master-Filter 24 Delay-Scaler 25 Tuning-Scaler 26 Humanize 27 Velocity-XF-On-Off 28 Rsamp-On-Off 29 Dynamics-Scaler 30 :group Pedal Pedal 64 ; not 'Ped' Sustain 64 Sost-Ped 66 Sostenuto 66 Una-Corda 67 Soft-Pedal 67 :group Matrix cc1 1 ))
-
Thank you very much. Any chance to make legato notes slightly longer at a later stage? Doing so would trigger, e.g., certain orchestral libraries (e.g., I am using LASS) to play the legato articulations, which it does not play with non-legato notes.
Best,
Torsten
-
It would be useful for playback, if certain articulations would affect the sounding note durations and velocity values. With some articulations this already seems to be the case (e.g., stacc seems to reduce note durations by 50%), while other articulations are ignored during playback in that regard (e.g., leg is notated, but makes seemingly no difference in playback -- notes played legato are not overlapping, as would be expected, nor are non-legato notes very slightly separated). Other articulations are seemingly even wrongly set (e.g., marc is an accent, but it instead shortens the note).
Here is a little example demonstrating the problem, which results in the attached MIDI file.
EDIT: The upload failed, but you can easily listening to this or export it to MIDI yourself.
'((e c4 leg d4 e4 leg f4) (q g4 marc -q -h))
Can users somewhere set/correct these playback settings?
BTW: Ideally settings would allow for code (functions) evaluationed on the fly. That would allow, e.g., to add custom humanisation, e.g., to slightly vary the length of staccato articuations, or the velocity values set by non-legato notes....
Thanks!
Best,
Torsten
-
It would also be useful, e.g., for combining sample instruments by different brands etc. where certain articulations are available in one plugin, and others in another.
Best,
Torsten
-
If that is currently not possible then I can simply write unconventionally for different organ divisions directly for now. There is also a workaround with Hauptwerk using its so-called floating division MIDI keyboards (not sure about GrandOrgue yet). No worrries :)
Best,
Torsten
-
How is it possible to change the MIDI output channel of an instrument? For example, when writing for organ, you have two staffs for the right and left hand, but hands can change manuals, and this is best represented by different MIDI channels. Is there a way to define articulations that result in changing the MIDI channel?
Thanks!
Best,
Torsten
-
30 minutes ago, JulioHerrlein said:
I'd like to find something more idiomatic.
:)
-
You already know how to translate a MIDI pitch number into a representation consisting of two pieces of information, a pitch class integer and an octave integer. The conversion can be applied in both directions.
Now, you can apply a similar conversion to a pitch class integers, converting them into a scale degree (integer) and an accidental (another integer), depending on a scale (a set of pitch classes). Again, this conversion can be done in both ways (there are multiple solutions if you allow for enharmonic equivalence).
Once you have such a representation, you can then do diatonic transpositions (depending on whatever scale) within the scale degree domain, and finally translate your results back into pitch classes, or MIDI pitch numbers.
I have a draft of a paper discussing this formally. A preliminary version of this paper has been published at SMC, http://uobrep.openrepository.com/uobrep/handle/10547/622264 Don't get scared away by the constraint programming aspect. Such conversions can also be implemented as plain deterministic functions.
This can be seen as a kind of mapping, if you want, if you also see the relation between MIDI pitch numbers and pitch classes as a mapping :)
Best,
Torsten
- JulioHerrlein and lviklund
- 2
-
You can roll such a function easily yourself. The modulus function is part of Common Lisp.
;; modulus 12 of 60
(mod 60 12)
; => 0
(defun mod12 (xs)
(loop for x in xs
collect (mod x 12)))(mod12 '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 24 48))
; => (0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 0 0)To empower yourself, once you know how to program a simple function, you simply need to google for the modulus function
http://lmgtfy.com/?q=common lisp modulo
:)
Best,
Torsten
Re-auditioning selected shown scores/snippets
in Support & Troubleshooting
Posted
It is handy that Opusmodus can display multiple score snippets and full scores alongside each other.
Is there perhaps also a way to re-play some snippet still shown? Either with some GUI element that I may have missed or programmatically (they all have a unique name shown, like "UNTITLED 101 (Snippet)").? There is a function audition-musicxml-last-score, is there perhaps a function to again audition a score that is specified by its name?
Thanks!
Best,
Torsten