def _chord_to_wave(self, chord_notes): '''Change lists of notes.Note() objects into numpy arrays of samples.''' # ring modulation done seperately for each indiv. note chord_waves = [] for note in chord_notes: dur = self._timer.samples_per_note(note.dur) self._total_dur += dur if note is None or note.dur == 0: continue if note.note == notes.REST: return oscil.Flat(dur=dur) carrier = self._oscil(note.freq, self._vol, dur=dur) if self._detune == 1: modulated_tone = carrier else: modulator = self._oscil(note.freq/self._detune, self._vol, dur=dur) modulated_tone = mixer.multiply((carrier, modulator)) chord_waves.append(modulated_tone) return mixer.add(chord_waves)
def metaform_ocd(vol=1, point=None): '''A short song inspired by a song called OCD, by Metaform: http://youtu.be/yTDls-QBAmQ Args: vol - multiplied by whatever the default is (so it can incr. or decr.) point - array in shared memory to read points in from the GUI Returns: None ''' time = timing.Timing(bpm=150, def_note_dur=4) # notes to play lead_notes = abcp.parse_str(" C ^D G C | ^D ^G G ^D" " C ^D G C | ^G, ^G G ^D") bass_intro = list(map(abcp.parse_str, [" C,,/2 C,,/2 | C,,/2 z/2", "^G,,,/2 ^G,,,/2 | ^G,,,/2 z/2"])) bass_notes = abcp.parse_str(" C,,/2 C,,/2 | C,,/2 C,,/2 |" "^G,,,/2 ^G,,,/2 | ^G,,,/2 ^D,,/2 |") # notes to conditionally play, depending on GUI mouse clicks # notice that there are 3 alternate sets of notes, but only 4 squares in # the gui -- this is because the first square represents the default set # of notes alt_lead_notes = list(map(abcp.parse_str, ["z ^D' G' z | z ^G' G' z" "z ^D' G' z | z ^G' G' z'", "C'' ^D'' G'' C'' | ^D'' ^G'' G'' ^D''" "C'' ^D'' G'' C'' | ^G' ^G'' G'' ^D''", "C'' z G'' z | ^D'' z G'' z" "C'' z G'' z | ^G' z G'' z"])) # construct playlist (map of notes to instruments/arguments in succession) lead = functools.partial(BeatingSynth, time, detune=2) bass = functools.partial(WubBass, time, oscillator='sawtooth') playlist = [ [[lead, {'notes': lead_notes, 'vol': .3*vol, 'slow_intro': True}]], [[lead, {'notes': lead_notes, 'vol': .3*vol}]], [[lead, {'notes': lead_notes, 'vol': .3*vol, 'oscillator': 'square'}]], [ [lead, {'notes': lead_notes, 'oscillator': 'square', 'vol': .3*vol}], [bass, {'notes': bass_intro[0], 'tremolo_freq': 100, 'vol': .4*vol}]], [ [lead, {'notes': lead_notes, 'oscillator': 'square', 'vol': .3*vol}], [bass, {'notes': bass_intro[1], 'tremolo_freq': 100, 'vol': .4*vol}]], [ [lead, {'notes': lead_notes, 'oscillator': 'square', 'vol': .3*vol}], [bass, {'notes': bass_notes, 'slow_intro': True, 'vol': .3*vol}]], [ [lead, {'notes': lead_notes, 'oscillator': 'square', 'vol': .3*vol}], [bass, {'notes': bass_notes, 'vol': .3*vol}]], [[bass, {'notes': bass_notes, 'tremolo_freq': 100, 'vol': .4*vol}]], [ [lead, {'notes': lead_notes, 'oscillator': 'square', 'vol': .3*vol}], [bass, {'notes': bass_notes, 'tremolo_freq': 50, 'vol': .45*vol}]], [ [lead, {'notes': lead_notes, 'oscillator': 'square', 'vol': .3*vol}], [bass, {'notes': bass_notes, 'tremolo_freq': 100, 'vol': .4*vol}]], [[lead, {'notes': lead_notes, 'oscillator': 'square', 'vol': .3*vol}]] ] # play playlist, possibly with procedural changes based on mouse clicks pa, stream = play.open_stream() for section in playlist: if point is not None: metaform_ocd_procedural_mod(point, section, lead, alt_lead_notes) #metaform_ocd_procedural_mod(point, section, bass, alt_bass_notes) waves = (i(**a) for i, a in section) wave = mixer.add(waves) play.source(stream, wave) play.close_stream(pa, stream)