def melody(score, reps, dur, set3): """ Creates the melodic part out of the ring modulated output specta. Parameters ---------- score : Score The musical score. reps : int The number of sections to compose. dur : int The surface rhythm keys : list List of keynums from ring modulation output. """ # Create a cycle of the two inputs pat = cycle(set3) for _ in range(2 * reps): n = Note(time=score.now, duration=dur / 2, pitch=next(pat), amplitude=.7, instrument=1) score.add(n) # Wait till the next note yield dur
def piano_phase(score, end, keys, rate): """ Composes a piano part for Steve Reich's Piano Phase. Parameters ---------- score : Score The scheduling queue to run the composer in. end : int | float The total duration of the piece. keys : list A list of midi key numbers to play in a loop. rate : int | float The rhythm to use. """ # Create a cyclic pattern to produce the key numbers. pattern = cycle(keys) # Stop playing when score time is >= end. while score.now < end: # Get the next key number. knum = next(pattern) # Create a midi note to play it. note = Note(time=score.now, duration=rate, pitch=knum, amplitude=.9) # Add the midi note to the score. score.add(note) # Return the amount of time until this composer runs again. yield rate
def accompaniment(score, reps, dur, set1, set2): """ Creates the accompanyment part from the ring modulation input specta. Parameters ---------- score : Score The musical score. reps : int The number of sections to compose. dur : int The surface rhythm set1 : list Ring modulation input 1. set2 : list Ring modulation input 2. """ # Create a cycle of the two inputs pat = cycle([set1, set2]) for _ in range(reps * 2): # Get the next set. keys = next(pat) # Iterate the keys, play as a chord. for k in keys: # Create a midi note at the current time. n = Note(time=score.now, duration=dur, pitch=k, amplitude=.3, instrument=0) # Add it to our output seq. score.add(n) # Wait till the next chord. yield dur
def jazz_bass(score, on, tmpo, ampl): """ The bass part plays a melodic line built out of tones from the jazz-scale's tonic seventh chord alternating with color tones outside the tonic chord. The bass plays a series of 12 triplets per measure, on each triplet only one of the two sets is possible. On all but the first triplet a rest is also possible. """ # 5 possible patterns for triplets 1-4 a = choose(['trrc', 'trrr', 'trtc', 'tctc', 'tctr'], [1.0, .25, .22, .065, .014]) # 5 possible patterns for 5-7 b = choose(['rrt', 'rrr', 'rct', 'tct', 'tcr'], [1.0, .25, .22, .038, .007]) # 5 possible patterns for 8-10 c = choose(['rrc', 'rtc', 'rrr', 'ctc', 'ctr'], [1.0, .415, .25, .11, .018]) # two possible values for 11 d = choose(['r', 't'], [1, .25]) # two possible values for 12 e = choose(['r', 'c'], [1, .25]) # the measure map meas = next(a) + next(b) + next(c) + next(d) + next(e) rhy = intempo(1 / 3, tmpo) tonics = choose([jazz_scale[i] for i in [0, 2, 4, 6, 7]]) colors = choose([jazz_scale[i] for i in [1, 3, 5, 6, 8]]) amps = cycle([.5, .4, 1.0, .9, .4, .9, .5, .4, 1.0, .9, .5, .9]) durs = cycle([2 / 3, 1 / 3, 1 / 3]) for x in meas: k = -1 if x == 't': k = next(tonics) elif x == 'c': k = next(colors) if k > -1: a = next(amps) d = next(durs) m = Note(time=score.now, duration=d, pitch=on + k, amplitude=ampl * a, instrument=1) score.add(m) yield rhy
def jazz_cymbals(score, tmpo, ampl): """ The cymbals process performs a constant stream of triplet eighths in which the ride1 cymbal is played on the beginning of every quarter note. The second and third triplets of each beat are either rests or a random choice between ride1, ride2 or a rest. This is the beat map for a measure of the process, where '1' means the ride cymbal 1 is played, '-' means a rest, and 'x' means a random choice between ride1, ride2 or a rest: ```text Triplet 8th: 1 2 3 4 5 6 7 8 9 10 11 12 Cymbals: 1 - x 1 - 1 1 x x 1 x 1 ``` """ ride1 = 51 ride2 = 59 rhy = intempo(1 / 3, tmpo) amps = cycle([.6, .5, .9, .7, .5, 1, .6, .5, .9, .7, .5, 1]) def subpat(wt): r1 = choose([ride1, 'r'], [1, wt]) r2 = choose([ride2, 'r'], [1, wt]) return choose([r1, r2], [1.5, 1]) # the events that happen on each triplet of the measure meas = { 0: ride1, 1: 'r', 2: subpat(5), 3: ride1, 4: 'r', 5: ride1, 6: ride1, 7: subpat(7), 8: subpat(7), 9: ride1, 10: subpat(3), 11: ride1 } for b in meas: k = meas[b] if k != 'r': if type(k) is not int: # k is a subpattern k = next(next(k)) if k != 'r': a = next(amps) m = Note(time=score.now, duration=rhy, pitch=k, amplitude=a * ampl, instrument=9) score.add(m) yield rhy
def jazz_combo(score, measures, tempo): """ The conductor process adds combo parts for each meaure to the schedule generate sound. By adding parts at each measure the conductor could make changes to the overall texture, amplitude etc, as the pieces progresses. """ roots = cycle(jazz_changes) ampl = .9 for meas in range(measures): root = next(roots) if 0 == meas % 12: ampl = between(.5, 1) score.compose(jazz_piano(score, root, tempo, ampl)) score.compose(jazz_cymbals(score, tempo, ampl)) score.compose(jazz_high_hat(score, tempo, ampl)) score.compose(jazz_drums(score, tempo, ampl)) score.compose(jazz_bass(score, root - 12, tempo, ampl)) yield intempo(4, tempo)
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 pat = cycle(['r', 42, 'r', 42]) # 'r' is rest for _ in range(4): x = next(pat) if x != 'r': m = Note(time=score.now, duration=dur, pitch=x, amplitude=amp * ampl, instrument=9) score.add(m) yield rhy
def jazz_drums(score, tmpo, ampl): """ Randomly selects between playing the snare, the bass drum or resting one quarter of the time. One tenth of the time it produces a very loud tone. """ elec_snare = 40 bass_drum = 35 knums = choose(['r', elec_snare, bass_drum], [.25, 1, 1]) rhys = cycle([2 / 3, 1 / 3]) amps = choose([.7, .95], [1, .1]) for _ in range(8): k = next(knums) a = next(amps) r = intempo(next(rhys), tmpo) if k != 'r': m = Note(time=score.now, duration=r, pitch=k, amplitude=a * ampl, instrument=9) score.add(m) yield r
def jazz_piano(score, on, tmpo, ampl): """ The jazz piano improvises jazz chords based on a pattern of root changes and a scale pattern that is transposed to each root. The piano randomly choose between playing triplet eighths or straight eights for a given measure. """ reps = odds(.65, 8, 12) scal = jumble(jazz_scale) rhys = cycle([2 / 3, 1 / 3] if reps == 8 else [1 / 3]) for _ in range(reps): r = intempo(next(rhys), tmpo) l = [] if odds(2 / 5) else [next(scal) for _ in range(between(1, 9))] for k in l: a = pick(.4, .5, .6, .7, .8) m = Note(time=score.now, duration=r, pitch=on + k, amplitude=a, instrument=0) score.add(m) yield r
def brush(score, *, length=None, end=None, rhythm=.5, duration=None, pitch=60, amplitude=.5, instrument=0, microdivs=1): """ Outputs Notes in sequential order, automatically looping parameter list values until the algorithm stops. Parameters ---------- score : Score The Notes that are generated will be added to this score. length : number The number of MIDI events to generate. Either length or end must be specified. end : number An end time after which no more events will be generated. Either end or length must be specified. rhythm : number | list A rhythm or list of rhythms that specify the amount of time to wait between notes. Negative rhythm values are interpreted as musical rests, i.e. events are not output but time advances. The default value is 0.5. duration : number | list A duration or list of durations that specify the amount of time each MIDI event lasts. The default value is the current rhythm. pitch : number | list A MIDI key number or list of key numbers to play. The list can contain sublists of key numbers; in this case each sublist is treated as a chord (the key numbers in the sublist are performed simultaneously.) amplitude : number | list A value or list of values between 0.0 and 1.0 for determining the loudness of the MIDI events. instrument : number | list A MIDI channel number 0 to 15, or a list of channel numbers. Channel value 9 will send events to the synthesizer's drum map for triggering various percussion sounds. tuning : int A value 1 to 16 setting the divisions per semitone used for microtonal quantization of floating point keynums. See Note, Seq and the micro.py demo file for more information. """ # user must specify either length or end parameter counter = 0 if length: if end: raise TypeError("specify either length or end, not both.") stopitr = length thisitr = (lambda: counter) else: if not end: raise TypeError("specify either length or end.") stopitr = end thisitr = (lambda: score.elapsed) # convert all values into cycles cyc = (lambda x: cycle(x if type(x) is list else [x])) rhy = cyc(rhythm) dur = cyc(duration) key = cyc(pitch) amp = cyc(amplitude) chan = cyc(instrument) while (thisitr() < stopitr): t = score.now #print("counter=", counter, "now=", t) r = next(rhy) d = next(dur) k = next(key) a = next(amp) c = next(chan) if r > 0: if not d: d = r if type(k) is list: for j in k: m = Note(time=t, duration=d, pitch=j, amplitude=a, instrument=c) score.add(m) else: m = Note(time=t, duration=d, pitch=k, amplitude=a, instrument=c) score.add(m) counter += 1 yield abs(r)