def testprimeform(notes, correct): keys = keynum(notes) normal = normalform(pcset(keys)) #, sort=True result = primeform(normal) print( f'{notes}: normal => {normal} prime => {result} => {pitchclassnames(result)}' ) assert result == correct, f'{result} does not match authority {correct}.'
def pctest(notes): knums = keynum(notes) pcs = pcset(knums) normal = normalform(pcs) prime = primeform(pcs) vector = pcivector(prime) print( f'{notes}: pcset => {pcs} normal => {normal} prime => {prime} vector => {vector}' )
def composer_stephen_foster(score, num, shift=0, chan=0): # A second-order markov process generates the melody. melody = pattern_stephen_foster() # randomly select rhythmic patterns characterisitic of Foster's style rhythms = choose( [[2, 2], [1, 1, 1, 1], [2, 1, 1], [1, 1, 2], [1, 2, 1], [4]], [.375, .125, .125, .125, .25, .125]) for _ in range(num): n = 0 for r in next(rhythms): k = keynum(next(melody)) + (shift * 12) r = intempo(r, 200) m = Note(time=score.now + n, duration=r, pitch=k, amplitude=.5, instrument=chan) score.add(m) n += r yield n
def matrix(notes): keys = keynum(notes) pcs = pcset(keys) mat = pcmatrix(pcs) ppmatrix(mat) return mat
def testinversion(notes, t, correct): keys = keynum(notes) pcs = pcset(keys) result = pcinvert(pcs, t) print(f'{notes}: => T{t}I => {result} => {pitchclassnames(result)}') assert result == correct, f'{result} does not match authority {correct}.'
def testnormal(notes, correct): keys = keynum(notes) result = normalform(pcset(keys)) #, sort=True print(f'{notes}: => {result} => {pitchclassnames(result)}') assert result == correct, f'{result} does not match authority {correct}.'
yield dur if __name__ == "__main__": # It's good practice to add any metadata such as tempo, midi instrument # assignments, micro tuning, etc. to track 0 in your midi file. track0 = MidiFile.metatrack() # Track 1 will hold the composition. track1 = Seq() # Create a scheduler and give it t1 as its output object. score = Score(out=track1) # Create the composition. Specify levels and melody length with care! # The number of events that are generateed is exponentially related to # the length of the melody and the number of levels. For example the # first compose() generates 120 events, the second 726, and the third 2728! score.compose(sierpinski(score, keynum('a0'), [0, 7, 5], 12, 4, 3, .5)) #score.compose(sierpinski(score, keynum('a0'), [0, 7, 5], 8, 5, 7, .5)) #score.compose(sierpinski(score, keynum('a0'), [0, -1, 2, 13], 12, 5, 24, .5)) # Write the tracks to a midi file in the current directory. file = MidiFile("sierpinski.mid", [track0, track1]).write() print(f"Wrote '{file.pathname}'.") # To automatially play demos use setmidiplayer() and playfile(). # Example: # setmidiplayer("fluidsynth -iq -g1 /usr/local/sf/MuseScore_General.sf2") # playfile(file.pathname)
# It's good practice to add any metadata such as tempo, midi instrument # assignments, micro tuning, etc. to track 0 in your midi file. track0 = MidiFile.metatrack() # Track 1 will hold the composition. track1 = Seq() # Create a scheduler and give it t1 as its output object. score = Score(out=track1) # Create the composition. Specify levels and melody length with care! # The number of events that are generateed is exponentially related to # the length of the melody and the number of levels. For example the # first compose() generates 120 events, the second 726, and the third 2728! #score.compose(sierpinski(score, keynum('a0'), [0, 7, 5], 12, 4, 3, .5)) score.compose(sierpinski(score, keynum('a0'), [0, 7, 5], 8, 5, 7, .5)) #score.compose(sierpinski(score, musx.keynum('a0'), [0, -1, 3, 11], 12, 5, 24, .5)) #score.compose(sierpinski(score, 24., [0, -1, 2, 13], 12, 5, 24, .5)) # Write the tracks to a midi file in the current directory. midi_file = MidiFile("sierpinski.mid", [track0, track1]).write() print(f"Wrote '{midi_file.pathname}'.") # To automatially play demos use setmidiplayer() and playfile(). # Example: # setmidiplayer("fluidsynth -iq -g1 /usr/local/sf/MuseScore_General.sf2") # playfile(midi_file.pathname) # Now the Csound stuff. orc = '''
# Add the midi note to the score. score.add(note) # Return the amount of time until this composer runs again. yield rate if __name__ == '__main__': # It's good practice to add any metadata such as tempo, midi instrument # assignments, micro tuning, etc. to track 0 in your midi file. track0 = MidiFile.metatrack() # Track 1 will hold the composition. track1 = Seq() # Create a score and give it tr1 to hold the score event data. score = Score(out=track1) # Convert Reich's notes to a list of midi key numbers to phase. keys = keynum("e4 f# b c#5 d f#4 e c#5 b4 f# d5 c#") # Create two composer generators that run at slightly different # rates and cause the phase effect. pianos = [ piano_phase(score, 20, keys, .167), piano_phase(score, 20, keys, .170) ] # Create the composition. score.compose(pianos) # Write the tracks to a midi file in the current directory. file = MidiFile("reich.mid", [track0, track1]).write() print(f"Wrote '{file.pathname}'.") # To automatially play demos use setmidiplayer() and playfile(). # Example: # setmidiplayer("fluidsynth -iq -g1 /usr/local/sf/MuseScore_General.sf2")
'e': [261, 432, 564, 760.5, 928, 1366, 1858], 'f': [234.5, 410, 514, 672, 842, 1239, 1697], 'g': [201, 360, 444, 598, 740, 1103, 1517], 'h': [186, 365, 427, 552.5, 695.5, 1025.5, 1404.5], 'i': [175, 304, 376, 514.5, 616, 908, 1243], 'j': [159, 283.5, 343, 453.5, 558, 823, 1126] } """ Conventry had 10 bells, represented here as letters 'a' to 'j' with 'a' being the highest bell. Rows are bell harmonics, with the 'prime' harmonic being the main tone in each bell. """ # convert bell hertz values into equivalent floating point key numbers _conventry_fkeys = { b: [keynum(h, filt=None) for h in l] for b, l in coventry_bells.items() } def playbells(q, peal, bells, rhy, dur, amp): # each bell represented by its 'prime' harmonic. primes = {k: bells[k][1] for k in bells.keys()} # play the peal (the ordered list of bells to play) for b in peal: # emphasize top and bottom bell by playing all its harmonics. if b in ['a', 'j']: # keynums are quantized to 25 cents for k in [x for x in bells[b]]: m = MidiNote(time=q.now, dur=dur * 4, key=k, amp=amp, tuning=4) q.out.addevent(m)
python3 -m demos.messiaen ``` """ from musx import Score, Seq, MidiFile, rhythm, keynum from musx.midi.gm import AcousticGrandPiano, Violin from musx.paint import brush piano_talea = rhythm('q q q e e. e e e e e. e. e. s e e. q h', tempo=80) piano_color = keynum([ "f3 g bf c4 ef b e5", "f3 g bf c4 e a d5", "f3 af bf df4 ef a d5", "f3 af bf df4 ef g c5", "f3 g bf d4 fs b c5", "f3 g bf d4 e a c5", "f3 a c4 d g cs5 fs", "f3 g c4 d g b e5", "f3 bf df4 gf e5", "f3 b d4 g e5 g", "f3 c4 ef af g5", "f3 cs4 e a g5 b", "af3 ef4 gf bf ef5 gf cf6", "af3 ef4 f bf df5 f5 bf5", "gf3 df4 af ef af cf6 ef", "gf3 df4 bf d5 f bf d6", "a3 c4 d fs bf df5 gf bf df6", "bf3 cs e gs c5 d gs c6", "c4 d f a4 cs5 e a", "cs4 e fs bf d5 f", "fs4 g bf d5 fs a", "fs4 a b ds5 es gs", "f4 bf d5 e g", "e4 af cs5 d", "d4 g b cs5 e", "cs4 f bf b f5", "b3 e4 af bf", "af3 cs4 f g", "gf3 cf4 ef f" ]) cello_talea = rhythm('h q. h h e e q. e e e e q. e e h', tempo=80) cello_color = keynum('c6 e d f# bf5') if __name__ == '__main__': # It's good practice to add any metadata such as tempo, midi instrument # assignments, micro tuning, etc. to track 0 in your midi file. track0 = MidiFile.metatrack(ins={0: AcousticGrandPiano, 1: Violin}) # Track 1 will hold the composition.
# It's good practice to add any metadata such as tempo, midi instrument # assignments, micro tuning, etc. to track 0 in your midi file. track0 = MidiFile.metatrack() # Track 1 will hold the composition. track1 = Seq() # Create a scheduler and give it t1 as its output object. score = Score(out=track1) # Create the composition. Specify levels and melody length with care! # The number of events that are generateed is exponentially related to # the length of the melody and the number of levels. For example the # first compose() generates 120 events, the second 726, and the third 2728! #score.compose(sierpinski(score, keynum('a0'), [0, 7, 5], 12, 4, 3, .5)) #score.compose(sierpinski(score, keynum('a0'), [0, 7, 5], 8, 5, 7, .5)) score.compose( sierpinski(score, keynum('a0'), [0, -1, 2, 13], 12, 5, 24, .5)) # Write the tracks to a midi file in the current directory. file = MidiFile("sierpinski.mid", [track0, track1]).write() print(f"Wrote '{file.pathname}'.") # To automatially play demos use setmidiplayer() and playfile(). # Example: # setmidiplayer("fluidsynth -iq -g1 /usr/local/sf/MuseScore_General.sf2") # playfile(file.pathname) # Now the Csound stuff. orc = ''' sr = 48000
def fm_chords(score, reps, cen, cm1, cm2, in1, in2, rhy): """ Generates a series of FM chords with random fluctuations in its C/M ratios and indexes to yield variations of chordal notes. """ for _ in reps: spec = fmspectrum(hertz(cen), between(cm1, cm2), between(in1, in2)) for k in spec.keynums(minpitch=48, maxpitch=72): m = Note(time=score.now, duration=rhy, pitch=k, amplitude=.5) score.add(m) yield rhy contour = keynum("a4 g f e a4 b c d gs b c5 ef fs g a5 bf g f e a5 b c d \ gs3 f e cs c bf5 gs5 as3 cs5 e6 f4 gs5 d6 e f g c5 b a \ g bf c5 cs e4 f gs d4 c b a4 e5 f g a5") def fm_improv(score, line, beat): """ Uses a contour line of carrier frequencies (specified as midi keynums) to produces fm spectra that creates both melodic and harmoinc gestures. The inputs and outputs of the fmspectrum() calls are printed during the improvisation. """ amp = .7 dur = beat for knum in line: ismel = odds(.7) rhy = pick(dur, dur / 2, dur / 4)
# It's good practice to add any metadata such as tempo, midi instrument # assignments, micro tuning, etc. to track 0 in your midi file. track0 = MidiFile.metatrack() # Track 1 will hold the composition. track1 = Seq() # Create a scheduler and give it t1 as its output object. score = Score(out=track1) # Create the composition. Specify levels and melody length with care! # The number of events that are generateed is exponentially related to # the length of the melody and the number of levels. For example the # first compose() generates 120 events, the second 726, and the third 2728! #score.compose(sierpinski(score, keynum('a0'), [0, 7, 5], 12, 4, 3, .5)) #score.compose(sierpinski(score, keynum('a0'), [0, 7, 5], 8, 5, 7, .5)) score.compose(sierpinski(score, musx.keynum('a0'), [0, -1, 3, 11], 12, 5, 24, .5)) #score.compose(sierpinski(score, 24., [0, -1, 2, 13], 12, 5, 24, .5)) # Write the tracks to a midi file in the current directory. file = MidiFile("sierpinski.mid", [track0, track1]).write() print(f"Wrote '{file.pathname}'.") # To automatially play demos use setmidiplayer() and playfile(). # Example: # setmidiplayer("fluidsynth -iq -g1 /usr/local/sf/MuseScore_General.sf2") # playfile(file.pathname) # Now the Csound stuff. orc = '''
To run this script cd to the parent directory of demos/ and do: ```bash python3 -m demos.jazz ``` """ import types from musx import Score, Note, Seq, MidiFile, keynum, cycle, \ choose, jumble, intempo, odds, pick, between from musx.midi.gm import AcousticGrandPiano, AcousticBass jazz_scale = [0, 2, 3, 5, 7, 9, 10, 12, 14] """The scale used by the improvisor.""" jazz_changes = keynum('bf3 ef4 bf3 bf ef4 ef bf3 bf f4 ef bf3 bf') """The chord changes for the piano and bass parts.""" jazz_tempo = 120 """The tempo of the compostion.""" def jazz_high_hat(score, tmpo, ampl): """ Plays the High Hat on the second and fourth quarter of every measure and rests on the first and third beats. Each sound lasts for the duration one triplet eighth note i.e. 1/3 of a beat. """ rhy = intempo(1, tmpo) dur = intempo(1 / 3, tmpo) amp = .5