Ejemplo n.º 1
0
class MidiWriter:
    def __init__(self):
        # Log frequencies and durations to files. We can then parse these in the autochord class. 
        self.file = MIDIFile(1)
        self.chord_file = MIDIFile(3)
        self.rest_length = 0
        self.prev_start_time = 0

    def add_tempo(self, tempo): 
        self.file.addTempo(0, 0, tempo)
        self.chord_file.addTempo(0, 0, tempo)


    def add_midi_note(self, volume, pitch, beat, duration, rest_state, des_len):
        if(check_rest(rest_state) == True):
            self.rest_length = duration
        else:
            if(self.prev_start_time != beat):
                if(duration + beat < des_len):
                    self.file.addNote(0, 0, pitch, beat + self.rest_length, duration, volume)
                    self.prev_start_time = beat + self.rest_length
                    self.rest_length = 0

    def add_midi_chord(self, c, chord_volume, root_n, third_n, fifth_n, chord_beat, chord_duration, desired_length):
        if(check_chord(c) == True):
            if(chord_duration + chord_beat < desired_length):
                self.chord_file.addNote(0, 0, root_n, chord_beat, chord_duration, chord_volume)
                self.chord_file.addNote(0, 0, third_n, chord_beat, chord_duration, chord_volume)
                self.chord_file.addNote(0, 0, fifth_n, chord_beat, chord_duration, chord_volume)

    def write(self):
        with open("midi.mid", "wb") as f:
            self.file.writeFile(f)
        with open("chord_midi.mid", "wb") as f:
            self.chord_file.writeFile(f)

    def close_midi(self):
        self.file.close()
        self.chord_file.close()
Ejemplo n.º 2
0
                else:
                    logging.info('accepted proposal')
                    result.append(prop_sp)
                    prev_interval = prop_interval
                    break

    return result


sm = cg.ScaleManager()
cp_scale = sm.build_scale()

midi_content = MIDIFile(2)
midi_content.addTrackName(0, 0, 'cantus firmus')
midi_content.addTrackName(1, 0, 'counterpoint')

cf_tune = cg.Tune(
    cp_scale,
    ['C1', 'D1', 'F1', 'E1', 'F1', 'G1', 'A1', 'G1', 'E1', 'D1', 'C1'])
cp_tune = cg.Tune(cp_scale, real_cp2(cp_scale, cf_tune))

for i, v in enumerate(cf_tune.mps):
    midi_content.addNote(0, 0, v, i, 1, 100)

for i, v in enumerate(cp_tune.mps):
    midi_content.addNote(1, 0, v, i + 0.25, 1, 100)

with open('c:/temp/test.mid', "wb+") as f:
    midi_content.writeFile(f)
    midi_content.close()
Ejemplo n.º 3
0
    image = Image.fromarray(imagePix)

# Preview the image if desired
if args.s:
    image.show()

# Start our MIDI file.
mFile = MIDIFile(numTracks=1, adjust_origin=True,file_format=1)
             
# Loop through image
for y in range(newSize[1]):
    for x in range(128):
        pixel = imagePix[y,x]
        if (args.g):
            OnPixelGrad(mFile,x,y,pixel,args.y)
        else:
            OnPixelThresh(mFile,x,y,pixel,args.y,args.t)

# End any notes we had.
for x in range(128):
    if (args.g):
        OnPixelGrad(mFile,x,newSize[1],0,args.y)
    else:
        OnPixelThresh(mFile,x,newSize[1],0, args.y,args.t)

# Write out the MIDI file.
midiOut = open(args.output_midi, 'wb')
mFile.writeFile(midiOut)
mFile.close()

Ejemplo n.º 4
0
class DrumMachine:
    # set global tempo will effect everything - no
    # tempo changes between cuts just one global tempo
    tempo = 0
    # holds the cuts which are to be rendered to the midi file
    allcuts = []
    # the print-out version of the cut ids so the user knows which beat is which number
    cutids = []
    # holds unique cuts for use with the buildFromArray method
    unique = []
    # holds unique id for each item of array above
    uniqueid = []
    # counter for number of allcuts - starts at 1 not 0
    globalid = 1
    # is incremented everytime a unique pattern is pushed and therefore saved in unique
    cutid = 1
    # If a new unique cut is made store it in unique and then set newcut to False
    # starts at True because first cut is always unique
    newcut = True
    # temp for patterns being edited
    edpad = None
    # id for pattern being editing
    editing = None
    # when editing drum layers
    # we can overwrite or add to the layers (discontinued)
    overwrite = True
    # push copy
    pushc = False
    # can copy
    cancopy = False

    def __init__(self):
        self.tempo = 120  # default
        self.tempcut = None
        # Create a Midi file
    def createMidi(self):
        self.midif = MIDIFile(3)
        self.midif.addTempo(0, 0, self.tempo)
        # make it so midi file is in memory so it can play without having to save to disk
    def createMem(self):
        self.memFile = BytesIO()
        # Write the Midi file to memory
        # and load it into pygame so it can be played
    def writeMidiMem(self):
        self.midif.writeFile(self.memFile)
        self.memFile.seek(0)
        pygame.mixer.music.load(self.memFile)
        # free memory and close files
    def freeMidiMem(self):
        ##        pygame.mixer.music.unload()
        self.memFile.close()
        self.midif.close()
        # create a drum layer of a given type
    def drumLayer(self, instr, beat, track, prob, pulse=0, barsin=0):
        bars = 4
        if self.overwrite == True or self.edpad == None:
            drumcut = DrumCutLayer(beat, track)
        else:
            if instr == Snare and self.edpad.snaredrumlayer != None:
                drumcut = self.edpad.snaredrumlayer
            else:
                drumcut = DrumCutLayer(beat, track)
            if instr == BassDrum and self.edpad.bassdrumlayer != None:
                drumcut = self.edpad.bassdrumlayer
            else:
                drumcut = DrumCutLayer(beat, track)
            if instr == Toms and self.edpad.tomsdrumlayer != None:
                drumcut = self.edpad.tomsdrumlayer
            else:
                drumcut = DrumCutLayer(beat, track)
            if instr != Snare and instr != BassDrum and instr != Toms:
                if self.edpad.cymbaldrumlayer != None:
                    drumcut = self.edpad.cymbaldrumlayer
                else:
                    drumcut = DrumCutLayer(beat, track)
        c = b = 0
        n = 1
        mod4hit = 3
        dec4hit = [1, 0.50, 0.25][randrange(0, 3)]
        addtovol = 0
        if instr == Snare:
            addtovol = 20
        elif instr == BassDrum:
            addtovol = 17
        while b < bars:
            hitit = randrange(0, prob) + 1
            if (pulse != 0 and n % pulse == 0) or (prob > 0 and hitit == 1):
                volu = randrange(100 + addtovol, 128)
                drumcut.ntimesbeat += [n * beat]
                drumcut.volumes += [volu]
                drumcut.whathit += [instr[randrange(0, len(instr))]]
            c += beat
            if c >= 1:
                c = 0
                b += 1
            n += 1
        return drumcut

    # a CompleteCut is made by layering -- calling drumLayer()
    def drumCut(self):
        cc = CompleteCut()
        cc.bassdrumlayer = self.drumLayer(BassDrum, ranbeat(), 0, hitprob(),
                                          pulseit(6), 1)

        cc.snaredrumlayer = self.drumLayer(Snare, snarebeat(), 1, hitprob(),
                                           pulseit(17) - 1, 1)

        if randrange(0, 2) == 1:
            cc.tomsdrumlayer = self.drumLayer(Toms, tombeat(), 1, hitprob(),
                                              pulseit(7) - 1, 1)
        for pc in range(8):
            if randrange(0, 8) == 1:
                cc.cymbaldrumlayer = self.drumLayer(randomcymbal(), cymbeat(),
                                                    2, hitprob(),
                                                    pulseit(7) - 1, 1)
        self.tempcut = cc

    # call after creating midi context
    def CreateDrumLayer(self, drumclayer, offset):
        if drumclayer == None:
            return
        for hit in range(len(drumclayer.whathit)):
            self.midif.addNote(drumclayer.track, 9, drumclayer.whathit[hit],
                               drumclayer.ntimesbeat[hit] + (offset * 4), 1,
                               drumclayer.volumes[hit])
        # create midi and memory for it
    def createMidiContext(self):
        self.createMidi()
        self.createMem()
        # put midi data into midi file
    def makeDemo(self, offset=0):
        ccobj = self.tempcut
        self.CreateDrumLayer(ccobj.bassdrumlayer, offset)
        self.CreateDrumLayer(ccobj.snaredrumlayer, offset)
        self.CreateDrumLayer(ccobj.tomsdrumlayer, offset)
        self.CreateDrumLayer(ccobj.cymbaldrumlayer, offset)
        # calls above function but for consecutive drum patterns
    def buildAllCuts(self):
        if len(self.allcuts) < 1:
            return
        for n, cut in enumerate(self.allcuts):
            self.tempcut = cut
            self.makeDemo((n))

    def playDemo(self):
        pygame.mixer.music.play()
        # stores cut and relevant variables in arrays for later use
    def storeCut(self):
        if self.pushc == True and self.cancopy == True:
            if self.cutid <= len(self.unique):
                self.cutid += 1
        self.allcuts += [self.tempcut]
        self.cutids += [self.cutid]
        self.globalid += 1
        if self.newcut == True or (self.pushc == True and self.cancopy):
            self.unique += [deepcopy(self.tempcut)]
            self.uniqueid += [self.cutid]
        self.pushc = False
        self.newcut = False
        if self.pushc == True and self.cancopy == True:
            self.newcut = True
        # deletes last added pattern
    def killCut(self):
        if self.globalid > 0:
            self.globalid -= 1
            del self.allcuts[self.globalid - 1]
            del self.cutids[self.globalid - 1]
        # saves pattern to disk
    def save(self):
        if (self.allcuts == []):
            return -1
        self.buildAllCuts()
        self.writeMidiMem()
        ##        try:
        outp = filedialog.asksaveasfile(initialdir="/",
                                        mode="wb",
                                        defaultextension=".mid")
        if outp is None:
            return -1
        self.midif.writeFile(outp)
        ##        except:
        ##            return -1
        return ""
        # format pattern string for output
    def formatfp(self):
        return "".join([str(x) + ',' for x in self.cutids])[:-1]
        # print-out for GUI for how many patterns can be used
    def ntoUse(self):
        if len(self.unique) < 1:
            return "0-0"
        else:
            return f"1-{len(self.unique)}"
        # build pattern from array entered by user
    def buildFromArray(self, temp):
        if len(self.unique) < 1:
            return -1
        try:
            temp = [int(x) for x in temp.split(',')]
        except:
            return -1
        for i in temp:
            if i not in self.uniqueid:
                return -1
        self.allcuts = []
        self.cutids = []
        for c in temp:
            self.allcuts += [self.unique[c - 1]]
            self.cutids += [self.uniqueid[c - 1]]
        self.globalid = len(self.allcuts)
        self.buildAllCuts()
        return 1

    # load a pattern to be edited in the pattern editor
    def loadForEdit(self, pat):
        pat = abs(int(pat))
        if len(self.unique) < 1:
            return -1
        while (pat not in self.uniqueid):
            pat -= 1
        self.edpad = self.unique[pat - 1]
        self.editing = pat
        return 1

    def editPattern(self, what):
        if what == "":
            return
        if what == "bass":
            if self.overwrite == True:
                self.edpad.bassdrumlayer = None
            self.edpad.bassdrumlayer = self.drumLayer(BassDrum, ranbeat(), 0,
                                                      hitprob(), pulseit(4), 1)
        elif what == "snare":
            if self.overwrite == True:
                self.edpad.snaredrumlayer = None
            self.edpad.snaredrumlayer = self.drumLayer(Snare, snarebeat(), 1,
                                                       hitprob(),
                                                       pulseit(3) - 1, 1)
        elif what == "toms":
            if self.overwrite == True:
                self.edpad.tomsdrumlayer = None
            if randrange(0, 4) != 0:
                self.edpad.tomsdrumlayer = self.drumLayer(
                    Toms, tombeat(), 1, hitprob(),
                    pulseit(7) - 1, 1)
        elif what == "cym":
            if self.overwrite == True:
                self.edpad.cymbaldrumlayer = None
            for pc in range(8):
                if randrange(0, 5) == 1:
                    self.edpad.cymbaldrumlayer = self.drumLayer(
                        randomcymbal(), cymbeat(), 2, hitprob(),
                        pulseit(3) - 1, 1)

    def updatePattern(self):
        self.unique[self.editing - 1]
        self.tempcut = self.unique[self.editing - 1]