示例#1
0
    def build_randomly_from_scale(root,
                                  octave,
                                  scale_name="major",
                                  num_note_choices=None):
        """Create a MidiChord object based on a given scale.

        :param root: the root note of the scale
        :param octave: the octave to be used when creating the chord
        :param scale_name: the scale name to be used
        :param num_note_choices: a list of how integers representing the number of notes allowed to be chosen at random
            when constructing the chord randomly. None will default to [3, 4, 5].

        :return: a MidiChord
        """
        if num_note_choices is None:
            num_note_choices = [3, 4, 5]
        named_scale = scale.NAMED_SCALES[scale_name]
        my_scale = Scale(Note((root.upper(), octave)), named_scale)
        num_notes_in_scale = len(my_scale)
        scale_start_num = octave * num_notes_in_scale
        num_notes_in_chord = np.random.choice(num_note_choices)
        possible_notes = [
            my_scale.get(temp_note)
            for temp_note in range(scale_start_num, scale_start_num +
                                   num_notes_in_scale * 2)
        ]
        notes = np.random.choice(possible_notes,
                                 size=num_notes_in_chord,
                                 replace=False)
        chord = MidiChord([note.note + str(note.octave) for note in notes])
        chord.build_chord()
        return chord
示例#2
0
    def build_from_intervals(self,
                             root,
                             octave,
                             intervals,
                             scale_name="major"):
        """Given chord specs return a MidiChord object of said chord.

        usage:
            chord = ChordBuilder().build_from_intervals('c', 6, ["1", "3", "5", "b7", "#9"])

        :param root: string of the note.
        :param octave: an integer between 0 and 8 (or 9 or something)
        :param intervals: a list of note intervals relative to the root. Use 'b' for flat and '#' for sharp.
        :param scale_name: the scale from which to select notes

        :return: a Chord object
        """
        named_scale = scale.NAMED_SCALES[scale_name]
        my_scale = Scale(Note((root.upper(), octave)), named_scale)
        num_notes_in_scale = len(my_scale)
        # TODO: is this the correct way to calculate the scale_start_num?
        scale_start_num = octave * num_notes_in_scale
        intervals = [
            self._deal_with_pitch_accidentals(interval)
            for interval in intervals
        ]
        notes = [
            my_scale.get(scale_start_num + interval[0] - 1).transpose(
                interval[1]) for interval in intervals
        ]
        chord = MidiChord([note.note + str(note.octave) for note in notes])
        chord.build_chord()
        return chord
 def __init__(self, event):
     Thread.__init__(self)
     # Define "stop" trigger
     self.stopped = event
     # Define key
     self.key = Note('C3')
     # Define scale
     self.scale = Scale(self.key, 'harmonic minor')
     self.note = self.key
     self.chunks = []
     self.chunks.append(source.sawtooth(self.note, 0.5))
     self.data = numpy.concatenate(self.chunks)
     self.data = self.data * 0.5
class sinePlayer(Thread):
    def __init__(self, event):
        Thread.__init__(self)
        # Define "stop" trigger
        self.stopped = event
        # Define key
        self.key = Note('C3')
        # Define scale
        self.scale = Scale(self.key, 'harmonic minor')
        self.note = self.key
        self.chunks = []
        self.chunks.append(source.sawtooth(self.note, 0.5))
        self.data = numpy.concatenate(self.chunks)
        self.data = self.data * 0.5

    # Adjust audio by x steps in scale defined above
    def adjustAudio(self, adjustment, loudness):
        self.note = self.scale.transpose(self.key, adjustment)
        self.chunks = []
        self.chunks.append(source.sawtooth(self.note, .5))
        self.data_adjusted = numpy.concatenate(self.chunks)
        self.data_adjusted = self.data_adjusted * 0.5 * loudness
        self.data = self.data_adjusted

    # Runs indefinitely until passed "stop" trigger
    def run(self):
        while not self.stopped.wait(0.001):
            playback.play(self.data)
示例#5
0
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
示例#6
0
class Melody:
    def __init__(self,
                 root_note=None,
                 octave=None,
                 scale_name=None,
                 melody_len=None,
                 quantization=None,
                 note_density=None,
                 note_len_choices=None):
        self.root_note = root_note
        self.octave = octave
        self.scale_name = scale_name
        self.melody_len = melody_len
        self.quantization = quantization  # this maybe should be at note level only
        self.note_density = note_density  # proportion of available ticks (determined by quantization) occupied by notes
        self.note_len_choices = note_len_choices

        self.root = Note((self.root_note, self.octave))
        self.named_scale = scale.NAMED_SCALES[self.scale_name]
        self.scale = Scale(self.root, self.named_scale)

        self.available_notes = [self.scale.get(x) for x in range(21, 30)]
        self.number_of_notes = self._compute_num_notes()
        self.start_ticks = self._get_start_ticks()

    def _compute_num_notes(self):
        return int(self.melody_len * self.note_density /
                   float(self.quantization))

    def _get_start_ticks(self):
        return np.unique(
            sorted([
                Rhythm().find_nearest_note(random.randint(0, self.melody_len),
                                           self.quantization)
                for _ in range(self.number_of_notes)
            ]))

    def _create_melody_note_tuple(self, start_tick):
        velocity = random.randint(50, 90)
        cur_note = random.choice(self.available_notes)
        cur_note = Note.index_from_string(cur_note.note + str(cur_note.octave))
        note_length = random.choice(self.note_len_choices)
        # ["event_type_fun", "tick", "duration", "pitch", "velocity"]
        return [
            MidiEventStager(midi.NoteOnEvent, start_tick, note_length,
                            cur_note, velocity),
            MidiEventStager(midi.NoteOffEvent, start_tick + note_length,
                            note_length, cur_note, 0)
        ]

    def create_melody(self):
        melody_notes = []
        for tick in self.start_ticks:
            melody_tuples = self._create_melody_note_tuple(tick)
            melody_notes.extend(melody_tuples)
        return melody_notes
示例#7
0
    def __init__(self,
                 root_note=None,
                 octave=None,
                 scale_name=None,
                 melody_len=None,
                 quantization=None,
                 note_density=None,
                 note_len_choices=None):
        self.root_note = root_note
        self.octave = octave
        self.scale_name = scale_name
        self.melody_len = melody_len
        self.quantization = quantization  # this maybe should be at note level only
        self.note_density = note_density  # proportion of available ticks (determined by quantization) occupied by notes
        self.note_len_choices = note_len_choices

        self.root = Note((self.root_note, self.octave))
        self.named_scale = scale.NAMED_SCALES[self.scale_name]
        self.scale = Scale(self.root, self.named_scale)

        self.available_notes = [self.scale.get(x) for x in range(21, 30)]
        self.number_of_notes = self._compute_num_notes()
        self.start_ticks = self._get_start_ticks()
示例#8
0
# Set random seed + filepath from command line
random_seed = "0"
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))
示例#9
0
import random

from musical.theory import Note, Scale
from musical.audio import effect, playback

from timeline import Hit, Timeline

# Define key and scale
key = Note('E3')
scale = Scale(key, 'harmonic minor')

time = 0.0  # Keep track of currect note placement time in seconds

timeline = Timeline()

note = key

# Semi-randomly queue notes from the scale
for i in range(64):
    if note.index > 50 or note.index < 24:
        # If note goes out of comfort zone, randomly place back at base octave
        note = scale.get(random.randrange(4) * 2)
        note = note.at_octave(key.octave)
    else:
        # Transpose the note by some small random interval
        note = scale.transpose(note, random.choice((-2, -1, 1, 2)))
    length = random.choice((0.125, 0.125, 0.25))
    timeline.add(time, Hit(note, length + 0.125))
    time += length

# Resolve
示例#10
0
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
note = Note('D3')
if note.note == "d":
    print(note)
示例#11
0
文件: gen.py 项目: iand/go
    data = note_data
    
    for i in xrange(ECHO_TIMES):
        factor *= ECHO_DECAY
        data = numpy.append(data, note_data * factor)
    
    fname = "out/%s%d.wav" % (note.note, note.octave)
    save.save_wave(data, fname)
    return fname

if os.path.exists("out"):
    shutil.rmtree("out")
os.mkdir("out")

root = Note(ROOT)
scale = Scale(root, SCALE)

notes = [None] * NUM_NOTES

mid = NUM_NOTES / 2
notes[mid] = root

for i in range(mid):
    notes[i] = scale.transpose(root, i - mid)

for i in range(mid + 1, NUM_NOTES):
    notes[i] = scale.transpose(root, i - mid)

files = []

for note in notes:
示例#12
0
import numpy

from musical.theory import Note, Scale
from musical.audio import source, playback

# Define key and scale
key = Note('C4')
scale = Scale(key, 'major')

note = key
chunks = []
for i in xrange(len(scale)):
  third = scale.transpose(note, 2)
  chunks.append(source.sine(note, 0.5) + source.square(third, 0.5))
  note = scale.transpose(note, 1)
fifth = scale.transpose(key, 4)
chunks.append(source.sine(key, 1.5) + source.square(fifth, 1.5))

print "Rendering audio..."

data = numpy.concatenate(chunks)

# Reduce volume to 50%
data = data * 0.5

print "Playing audio..."

playback.play(data)

print "Done!"
示例#13
0
import numpy

from musical.theory import Note, Scale
from musical.audio import source, playback

# Define key and scale
key = Note('C4')
scale = Scale(key, 'major')

note = key
chunks = []
for i in xrange(len(scale)):
    third = scale.transpose(note, 2)
    chunks.append(source.sine(note, 0.5) + source.square(third, 0.5))
    note = scale.transpose(note, 1)
fifth = scale.transpose(key, 4)
chunks.append(source.sine(key, 1.5) + source.square(fifth, 1.5))

print "Rendering audio..."

data = numpy.concatenate(chunks)

# Reduce volume to 50%
data = data * 0.5

print "Playing audio..."

playback.play(data)

print "Done!"
示例#14
0
import random

from musical.theory import Note, Scale
from musical.audio import effect, playback

from timeline import Hit, Timeline

# Define key and scale
key = Note('C3')
scale = Scale(key, 'Major')

time = 0.0  # Keep track of currect note placement time in seconds

timeline = Timeline()

note = key

for x in xrange(0, 12):

    if note.index == "C3":
        note = random.choice(C3, D3)

    if note.index == "D3":
        note = random.choice(D3, E3, C3)

    if note.index == "E3":
        note = random.choice(E3, F3, D3)

    if note.index == "F3":
        note = random.choice(F3, G3, E3)
示例#15
0
debug = False

bassArray = []

chordLetters = {
	"c" : ["c","e","g"],
	"d" : ["d","f","a"],
	"e" : ["e","g","b"],
	"f" : ["f","a","c"],
	"g" : ["g","b","d"],
	"a" : ["a","c","e"],
	"b" : ["b","d","f"]
}

key = Note("C3")
scale = Scale(key, 'major')


def returnChord(note):
	return([scale.transpose(note,2),scale.transpose(note,0)])

def nextNote(prevNote, bassNote):
	#if 'c' chordNotes is set to [Note("C3"),Note("E3"),Note("G3")]
	chordNotes = chordLetters[bassNote.note]
	print(chordNotes
		)
	possibleNext = []

	possibleNext.append(scale.transpose(prevNote,1))
	possibleNext.append(scale.transpose(prevNote,-1))
示例#16
0
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
示例#17
0
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)
import random

from musical.theory import Note, Scale
from musical.audio import effect, playback

from timeline import Hit, Timeline


# Define key and scale
key = Note('E3')
scale = Scale(key, 'major')

time = 0.0 # Keep track of currect note placement time in seconds

timeline = Timeline()

note = key

# Semi-randomly queue notes from the scale
for i in xrange(64):
  if note.index > 50 or note.index < 24:
    # If note goes out of comfort zone, randomly place back at base octave
    note = scale.get(random.randrange(4) * 2)
    note = note.at_octave(key.octave)
  else:
    # Transpose the note by some small random interval
    note = scale.transpose(note, random.choice((-2, -1, 1, 2)))
  length = random.choice((0.125, 0.125, 0.25))
  timeline.add(time, Hit(note, length + 0.125))
  time += length