Skip to content

Instantly share code, notes, and snippets.

@samhann
Created November 24, 2016 06:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samhann/7bdf88615cbdae5261c86589fe3109c5 to your computer and use it in GitHub Desktop.
Save samhann/7bdf88615cbdae5261c86589fe3109c5 to your computer and use it in GitHub Desktop.
Music gen
from midiutil.MidiFile import MIDIFile
from random import randint
from random import randrange
class MIDIGenerator(object):
def __init__(self,fileName):
self.outputFileName = fileName
self.MIDIObject = MIDIFile(1)
self.track = 0
self.MIDIObject.addTrackName(self.track,0,"Sample Track")
self.MIDIObject.addTempo(self.track,0,240)
self.volume = 100
self.channel = 0
self.notes = ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B']
self.basePitchOfC = 50
def addNote(self,note,time,duration,octave):
self.MIDIObject.addNote(self.track,self.channel,self.notePitch(note,octave),time,duration,self.volume)
def addChord(self,notes,time,duration):
for noteInfo in notes:
note = noteInfo[0]
octave = noteInfo[1]
self.MIDIObject.addNote(self.track,self.channel,self.notePitch(note,octave),time,duration,self.volume)
def notePitch(self,note,octave):
return self.notes.index(note) + self.basePitchOfC + (12 * octave)
def addMelody(self,melody):
trackTime = 0
for noteInfo in melody:
note = noteInfo[0]
octave = noteInfo[1]
duration = noteInfo[2]
if(note != ''):
self.addNote(note,trackTime,duration,octave)
trackTime = trackTime + duration
def writeMidiToFile(self):
binfile = open(self.outputFileName, 'wb')
self.MIDIObject.writeFile(binfile)
binfile.close()
class Composer(object):
def compose(self,scaleNotes,rhythmIntervals,duration):
scaleLen = len(scaleNotes)
counter = 0
melody = []
octave = 2
counter = 0
octaveOffset = 0
multiplier = randint(2,1000)
noteCounter = randint(1,5000)
base = randint(1,1000)
while counter < duration:
if counter % 8 == 0:
multiplier = randint(2,1000)
noteCounter = randint(1,5000)
base = randint(1,1000)
noteOffset = generateNoteDelta(noteCounter+counter,multiplier,base)
melody.append((scaleNotes[noteOffset % scaleLen],octave + octaveOffset,rhythmIntervals[counter % len(rhythmIntervals)]))
counter = counter + 1
return melody
def numberToBase(n, b):
if n == 0:
return [0]
digits = []
while n:
digits.append(int(n % b))
n /= b
return digits[::-1]
def sumOfDigits(num):
result = 0
for digit in num:
result = result + int(digit)
return result
def generateNoteDelta(counter,base,multiplier):
return sumOfDigits(numberToBase((counter * multiplier),base))
def composeAndWriteToFile(scale,intervals,duration,fileName):
mozart = Composer()
testMelody = mozart.compose(scale,intervals,duration)
MIDIGen = MIDIGenerator(fileName)
MIDIGen.addMelody(testMelody)
MIDIGen.writeMidiToFile()
intervals = [1,2,1,1,2];
majorScaleNotes = ['C','D','E','F','G','A','B']
bluesScaleNotes = ['C','D#','F','F#','A#']
arabScaleNotes = ['C','C#','E','F','G','G#','B']
composeAndWriteToFile(majorScaleNotes,intervals,125,"major.mid")
composeAndWriteToFile(bluesScaleNotes,intervals,125,"blues.mid")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment