def playchords(imu): key = Note('E3') scale = Scale(key, 'harmonic minor') progression = Chord.progression(scale, base_octave=key.octave) time = 0.0 timeline = Timeline() chord = progression[0] d = 3.0 #length of time (seconds) chords = [Hit(chord.notes[0], d), Hit(chord.notes[1], d), Hit(chord.notes[2], d), Hit(chord.notes[0], d)] amp = 0.25 #Amplitude thrd = None while True: timeline = Timeline() acc = imu.getacc() #print "acc is {}".format(acc) ax, ay, az = acc if ax > 1.5: timeline.add(0.0, chords[0]) elif ax < -1.5: timeline.add(0.0, chords[1]) if ay > 1.5: timeline.add(0.0, chords[2]) elif ay < -1.5: timeline.add(0.0, chords[3]) data = timeline.render() * amp if thrd == None or not thrd.isAlive(): thrd = threading.Thread(target=play, args=(data,)) thrd.start()
def get_chord(self, root, is_major): third = root + 4 if is_major else root + 3 fifth = root + 7 return Chord( [self.get_note(root), self.get_note(third), self.get_note(fifth)])
def generate_song( notes_per_chord, num_repeats, note_time=0.25, prog_intervals=(7, 2, -4j, 5) ): # generate a random major key root = Note(rand.choice(Note.NOTES)) scale_notes = Scale(root, 'major') octave = 3 progression = Chord.progression( Scale( root, [int(p.real + p.imag) for p in prog_intervals] ), octave ) for i, z in enumerate(prog_intervals): if z.imag != 0: # TODO: cannot have a repeated chord be minor progression[i] = major_to_minor(progression[i]) # generates a melody for the progression low_octave = 4 prev_note = rand.choice(list(scale_notes)).at_octave(low_octave) melody = [] for _ in range(notes_per_chord * len(progression) * num_repeats): note_dist = int(round(rand.gauss(0, 2))) prev_note = scale_notes.transpose(prev_note, note_dist) melody.append(prev_note) # build up the HLR from the melody progression song = [] t = 0 for i in range(num_repeats): for chord in progression: song.append( (t*note_time, chord, note_time*notes_per_chord) ) t += notes_per_chord for i in range(len(melody)): note = melody[i] song.append((i*note_time, Chord([note]), note_time)) return song
def get_real_universe_dist(cls, U, V): zero_hit = (Chord([Note('c0')]), 0) if len(U) == 0: U = [zero_hit] if len(V) == 0: V = [zero_hit] # sum(dist(u,v) for all u,v) total_sum = 0 for u in U: for v in V: total_sum += cls.get_real_pairwise_dist(u, v) normed_sum = total_sum / (len(U) * len(V)) return normed_sum
def get_hlr_from_latent(self, latent): song = [] t = 0 for i in range(self.num_repeats): for j in range(self.num_chords): chord_root = latent[2 * j] is_major = latent[2 * j + 1] chord = self.get_chord(chord_root, is_major) song.append((t * self.time_per_note, chord, self.time_per_note * self.notes_per_chord)) t += self.notes_per_chord num_melody_notes = self.num_repeats * self.num_chords num_melody_notes *= self.notes_per_chord offset = 2 * self.num_chords for i in range(num_melody_notes): song.append((i * self.time_per_note, Chord([self.get_note(latent[offset + i])]), self.time_per_note)) return song
if len(argv) >= 2: random_seed = argv[1] seed(random_seed) filepath = "public/generated_songs/song_" + random_seed + ".wav" if len(argv) > 2: filepath = argv[2] # Define key and scale random_note = choice(Note.NOTES) key = Note(random_note + '3') # scale = Scale(key, choice([l for l in list(NAMED_SCALES.values()) if len(l) == 7])) scale = Scale(key, uniform(0, 1) > 0.3 and 'major' or 'minor') # Grab key_chords chords from scale starting at the octave of our key key_chords = Chord.progression(scale, base_octave=key.octave) time = 0.0 # Keep track of currect note placement time in seconds rhythm_mod = uniform(0.5, 1.5) # lower number = faster tempo print("rhythm_mod = " + str(rhythm_mod)) timeline = Timeline() def render_melody(rhythm, melody): global time print("r = " + str(rhythm)) for r, m in zip(rhythm, melody): # print("len(chords) = %s, m = %s" %(len(key_chords), m)) note = key_chords[m]
from musical.theory import Note, Scale, Chord from musical.audio import playback from timeline import Hit, Timeline # Define key and scale key = Note('D3') scale = Scale(key, 'minor') # Grab progression chords from scale starting at the octave of our key progression = Chord.progression(scale, base_octave=key.octave) time = 0.0 # Keep track of currect note placement time in seconds timeline = Timeline() # Add progression to timeline by arpeggiating chords from the progression for index in [0, 2, 3, 1, 0, 2, 3, 4, 5, 4, 0]: chord = progression[index] root, third, fifth = chord.notes arpeggio = [root, third, fifth, third, root, third, fifth, third] for i, interval in enumerate(arpeggio): ts = float(i * 2) / len(arpeggio) timeline.add(time + ts, Hit(interval, 1.0)) time += 2.0 # Strum out root chord to finish chord = progression[0] timeline.add(time + 0.0, Hit(chord.notes[0], 4.0)) timeline.add(time + 0.1, Hit(chord.notes[1], 4.0)) timeline.add(time + 0.2, Hit(chord.notes[2], 4.0))
def generate_progression(*args, **kwargs): if not kwargs.get('progression', False): kwargs['key'] = Note(kwargs.get('note', 'D3')) kwargs['scale'] = Scale(kwargs['key'], kwargs.get('scale', 'major')) kwargs['progression'] = Chord.progression(kwargs['scale'], base_octave=kwargs['key'].octave) return func(*args, **kwargs)
def main(argv): try: opts, args = getopt.getopt(argv, "hdsm", ['help', 'debug', 'startup', 'morning']) except getopt.GetoptError: usage() sys.exit(2) global _debug _debug = 0 morning = False for opt, arg in opts: if opt in ("-h", "--help"): usage() sys.exit() if opt in ("-m", "--morning"): morning = True _debug = 1 if opt == '-d': _debug = 1 if opt in ("-s", "--startup"): import time time.sleep(90) #os.system("/usr/bin/tvservice -o") # Increase chance of singing at sunrise/sunset import ephem birdcage = ephem.Observer() birdcage.lat = '51.497517' birdcage.lon = '0.080380' birdcage.date = str(datetime.datetime.now()) birdcage.elevation = 5 sun = ephem.Sun() next_sunrise = birdcage.next_rising(sun) early_next_sunrise = ephem.Date(next_sunrise - 15 * ephem.minute) late_next_sunrise = ephem.Date(next_sunrise + 15 * ephem.minute) next_sunset = birdcage.next_setting(sun) early_next_sunset = ephem.Date(next_sunset - 15 * ephem.minute) late_next_sunset = ephem.Date(next_sunset + 15 * ephem.minute) sunrise = False; sunset = False; if (birdcage.date > early_next_sunrise and birdcage.date < late_next_sunrise): #print 'Sunrise roll' sunrise = true; dice_roll = random.choice([1,2,3,4,5,6,7,8]) elif (birdcage.date > early_next_sunset and birdcage.date < late_next_sunset): #print 'Sunset roll' sunset = true; dice_roll = random.choice([1,2,3,4,5,6,7,8]) else: dice_roll = random.choice([1,2,3,4,5,6]) if (dice_roll < 5 and _debug <> 1): #print "Going back to sleep" sys.exit() # We're alive, import what else we need now sys.path.append(os.path.join(os.path.dirname(__file__), 'python-musical')) from musical.theory import Note, Scale, Chord from musical.audio import effect, playback from timeline import Hit, Timeline # Define key and scale key = Note((random.choice(Note.NOTES), random.choice([2,3,3]))) scales = ['major', 'minor', 'melodicminor', 'harmonicminor', 'pentatonicmajor', 'bluesmajor', 'pentatonicminor', 'bluesminor', 'augmented', 'diminished', 'wholehalf', 'halfwhole', 'augmentedfifth', 'japanese', 'oriental', 'ionian', 'phrygian', 'lydian', 'mixolydian', 'aeolian', 'locrian'] random.shuffle(scales) scale = Scale(key, random.choice(scales)) #print key #print scale # Grab progression chords from scale starting at the octave of our key progression = Chord.progression(scale, base_octave=key.octave) time = 0.0 # Keep track of correct note placement time in seconds timeline = Timeline() # Pick a notes from a chord randomly chosen from a list of notes in this progression chord = progression[ random.choice(range(len(progression)-1)) ] notes = chord.notes melodies = [ [0.8, 0.2], [0.4, 0.2], [0.2, 0.8], [0.2, 0.4], [0.6, 0.2], [0.4, 0.4, 0.2], [0.6, 0.1, 0.1], [0.8, 0.1, 0.2], [0.2, 0.2, 0.2], [0.2, 0.4, 0.2], [1.0, 0.1, 0.2, 0.1, 0.2, 0.10, 0.1], [0.8, 0.4, 0.1, 0.2, 0.4, 0.1, 0.2], [0.8, 0.4, 0.4, 0.2, 0.2, 0.1, 0.1], [0.4, 0.0, 0.1, 0.1, 0.2, 0, 0.1, 0.4], [0.1, 0.1, 0.1, 0.0, 0.2, 0.0, 0.1, 0.2, 0.4], [0.8, 0.4, 0.1, 0.4, 0.2, 0.2, 0.1, 0.2, 0.8, 0.1, 0.4, 0.1], [0.2, 0.2, 0.4, 0.2, 0.1, 0.1, 0.0, 0.2], [1.0, 0.1, 0.2, 0.1, 0.2, 0.2], [0.2, 0.1, 0.2, 0.4, 0.1, 0.2, 0.4], [0.4, 0.1, 0.4, 0.2, 0.4, 0.1, 0.4, 0.2], [0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.1, 0.2, 0.0], [0.1, 0.0, 0.1, 0.0, 0.1, 0.0, 0.2, 0.0, 0.2, 0.0, 0.1, 0.1, 0.3], ] if sunrise or sunset: random_melody = random.choice(melodies[0:12]) else: random_melody = random.choice(melodies) # Testing a new melody-generation idea - duncan 11/4/20 # - needs more work, disabling for now - 12/4/20 #random_melody = [] #melody_length = random.randrange(1, 12) # #for i in range(0, melody_length): # random_melody.append( round(random.uniform(0.1, 0.6), 1) ) # test end if morning: random_melody = melodies[-1] print random_melody last_interval = 0.0 last_transpose = 0 for i, interval in enumerate(random_melody): random_note = random.choice(notes) # the first note should be high # identical intervals should often hold the same pitch # otherwise, pick a random pitch if i == 0: random_transpose = random.choice([8, 12]) elif (last_interval == interval): if random.choice([0,1,2]) == 2: random_transpose = last_transpose else: random_transpose = 0 else: random_transpose = random.choice([0,2,4,6,8,10,12]) last_interval = interval last_transpose = random_transpose note = random_note.transpose(random_transpose) #print note # favour queued notes, but occasionally overlap them too if (random.choice([1,2,3,4,5,6]) > 2): time = time + interval timeline.add(time, Hit(note, interval)) else: timeline.add(time, Hit(note, interval)) time = time + interval #print "Rendering audio..." data = timeline.render() # Reduce volume to 50% data = data * 0.5 print "Playing audio..." if morning: for i in range(2): playback.play(data) else: for i in range(random.choice([1,2])): playback.play(data)
def major_to_minor(chord): root = chord.notes[0] third = chord.notes[1] minor_third = third.transpose(-1) fifth = chord.notes[2] return Chord([root, minor_third, fifth])
from musical.theory import Note, Scale, Chord # generate a random major key root = Note('c') scale = Scale(root, 'major') # generate a I-V-vi-IV progression progression = Chord.progression(Scale(root, (7, 2, -4, -5)), 3) for chord in progression: print chord
def main(argv): try: opts, args = getopt.getopt(argv, "hds", ['help', 'debug', 'startup']) except getopt.GetoptError: usage() sys.exit(2) global _debug _debug = 0 for opt, arg in opts: if opt in ("-h", "--help"): usage() sys.exit() elif opt == '-d': _debug = 1 elif opt in ("-s", "--startup"): import time time.sleep(90) os.system("/usr/bin/tvservice -o") _debug = 1 # Increase chance of singing at sunrise/sunset import ephem birdcage = ephem.Observer() birdcage.lat = '51.5034070' birdcage.lon = '-0.1275920' birdcage.elevation = 19 sun = ephem.Sun() next_sunrise = birdcage.next_rising(sun) early_next_sunrise = ephem.Date(next_sunrise - 15 * ephem.minute) late_next_sunrise = ephem.Date(next_sunrise + 15 * ephem.minute) next_sunset = birdcage.next_setting(sun) early_next_sunset = ephem.Date(next_sunset - 15 * ephem.minute) late_next_sunset = ephem.Date(next_sunset + 15 * ephem.minute) if (birdcage.date > early_next_sunrise and birdcage.date < late_next_sunrise): print 'Sunrise roll' dice_roll = random.choice([1,2,3,4,5]) elif (birdcage.date > early_next_sunset and birdcage.date < late_next_sunset): print 'Sunset roll' dice_roll = random.choice([1,2,3,4,5]) else: dice_roll = random.choice([1,2,3,4,5,6]) if (dice_roll < 5 and _debug <> 1): print "Going back to sleep" sys.exit() # We're alive, import what else we need now sys.path.append(os.path.join(os.path.dirname(__file__), 'python-musical')) from musical.theory import Note, Scale, Chord from musical.audio import effect, playback from timeline import Hit, Timeline # Define key and scale key = Note((random.choice(Note.NOTES), random.choice([2,3,3]))) scales = ['major', 'minor', 'melodicminor', 'harmonicminor', 'pentatonicmajor', 'bluesmajor', 'pentatonicminor', 'bluesminor', 'augmented', 'diminished', 'wholehalf', 'halfwhole', 'augmentedfifth', 'japanese', 'oriental', 'ionian', 'phrygian', 'lydian', 'mixolydian', 'aeolian', 'locrian'] scale = Scale(key, random.choice(scales)) print key print scale # Grab progression chords from scale starting at the octave of our key progression = Chord.progression(scale, base_octave=key.octave) time = 0.0 # Keep track of currect note placement time in seconds timeline = Timeline() # Pick a notes from a chord randomly chosen from a list of notes in this progression chord = progression[ random.choice(range(len(progression)-1)) ] notes = chord.notes melodies = [ [1.0, 0.1, 0.2, 0.1, 0.2, 0.10, 0.1], [0.8, 0.1, 0.1, 0.2], [0.8, 0.4, 0.1, 0.2, 0.4, 0.1, 0.2], [0.8, 0.4, 0.4, 0.2, 0.2, 0.1, 0.1], [0.4, 0.0, 0.1, 0.1, 0.2, 0, 0.1, 0.4], [0.1, 0.1, 0.1, 0.0, 0.2, 0.0, 0.1, 0.2, 0.4], [0.8, 0.4, 0.1, 0.4, 0.2, 0.2, 0.1, 0.2, 0.8, 0.1, 0.4, 0.1], [0.2, 0.2, 0.4, 0.2, 0.1, 0.1, 0.0, 0.2], [1.0, 0.1, 0.2, 0.1, 0.2, 0.2], [0.2, 0.1, 0.2, 0.4, 0.1, 0.2, 0.4], [0.4, 0.1, 0.4, 0.2, 0.4, 0.1, 0.4, 0.2], [0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.2], [0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.1, 0.2, 0.0], [0.1, 0.0, 0.1, 0.0, 0.1, 0.0, 0.2, 0.0, 0.2, 0.0, 0.1, 0.1, 0.3], ] random_melody = random.choice(melodies) print random_melody last_interval = 0.0 last_transpose = 0 for i, interval in enumerate(random_melody): random_note = random.choice(notes) # the first note should be high # identical intervals should often hold the same pitch # otherwise, pick a random pitch if i == 0: random_transpose = random.choice([8, 12]) elif (last_interval == interval): if random.choice([0,1,2]) == 2: random_transpose = last_transpose else: random_transpose = 0 else: random_transpose = random.choice([0, 2,4,6,8,10,12]) last_interval = interval last_transpose = random_transpose note = random_note.transpose(random_transpose) #print note # favour queued notes, but occasionally overlap them too if (random.choice([1,2,3,4,5,6]) > 2): time = time + interval timeline.add(time, Hit(note, interval)) else: timeline.add(time, Hit(note, interval)) time = time + interval print "Rendering audio..." data = timeline.render() # Reduce volume to 95% data = data * 0.95 print "Playing audio..." for i in range(random.choice([1,2])): playback.play(data) print "Done!"