Пример #1
0
 def test2():
     intermed = notesinterpret.IntermediateList((4, 4))
     #tests ties, rests, notes
     rlist = [64, 64, 64, 64, 32, 32, 16, 16, 8, 8, 4, 4, 2, 2, 1, 1]
     noteList = []
     curtime = 0
     for i in range(len(rlist)):
         n = rlist[i]
         pitch = 60 + i % 3
         if i % 2 == 1: pitch = 0  #a rest
         noteList.append(
             NotesRealtimeNoteEvent([pitch], curtime, curtime +
                                    old_div(4 * intermed.baseDivisions, n)))
         noteList[-1].isTied = False
         curtime += old_div(4 * intermed.baseDivisions, n)
     for i in range(len(rlist)):
         n = rlist[i]
         noteList.append(
             NotesRealtimeNoteEvent([70], curtime, curtime +
                                    old_div(4 * intermed.baseDivisions, n)))
         noteList[-1].isTied = True
         curtime += old_div(4 * intermed.baseDivisions, n)
     intermed.noteList = noteList
     intermed.bSharps = True
     return intermed
def createIntermediateList(listNotes, timesig, quantize, bIsTreble, bSharps):
    #inserts rests between notes, standardizes all durations to be whole,half,qtr,8th,and so on, tied notes if necessary

    divisions = old_div(quantize, 4)  #because each pulse is a qtr note
    assert quantize >= 4

    intermed = IntermediateList(timesig, bSharps=bSharps)

    fQtrnotespermeasure = float(timesig[0]) / (old_div(timesig[1], 4))
    nTimestepspermeasure = int(fQtrnotespermeasure * intermed.baseDivisions)

    #insert rests between notes
    newlist = []
    for i in range(len(listNotes)):
        if listNotes[i][1] == listNotes[i][2]:
            raise 'Cannot have note of length 0.'
        newlist.append(listNotes[i])
        if i < len(listNotes) - 1:
            restLength = listNotes[i + 1][1] - listNotes[i][2]
            assert restLength >= 0
            if restLength != 0:
                newlist.append(((0, ), listNotes[i][2], listNotes[i + 1][1]))

    #convert to a standard time base, where each unit is 1/baseDivisions of a qtr note.
    def qStepToTimeBase(x):
        return int((float(x) / (divisions) * intermed.baseDivisions))

    #standardize durations, creating tied notes when necessary.
    currentMeasureTime = 0
    for note in newlist:
        length = qStepToTimeBase(note[2] - note[1])
        results = intermed.effectivelyTieLongNotesBarlines(
            currentMeasureTime, length, nTimestepspermeasure)
        for i in range(len(results)):
            duration = results[i]
            bIsTied = i != len(results) - 1

            newnote = NotesRealtimeNoteEvent(pitch=note[0],
                                             start=currentMeasureTime,
                                             end=currentMeasureTime + duration)
            newnote.isTied = bIsTied
            intermed.noteList.append(newnote)

            currentMeasureTime += duration

            assert currentMeasureTime <= nTimestepspermeasure
            if currentMeasureTime == nTimestepspermeasure:
                # begin the next measure...
                currentMeasureTime = 0

    return intermed
Пример #3
0
 def test1():
     intermed = notesinterpret.IntermediateList((4, 4))
     #tests notes, sharps, different durations
     sampleList = [
         1, 2, 2, 4, 8, 4, 4, 8, 64, 64, 64, 64, 32, 32, 16, 16, 2, 4, 8, 8,
         8, 8, 4, 4, 4, 4, 8, 8, 8, 8
     ]
     noteList = []
     curtime = 0
     for n in sampleList:
         noteList.append(
             NotesRealtimeNoteEvent([60 + curtime % 7], curtime, curtime +
                                    old_div(4 * intermed.baseDivisions, n)))
         noteList[-1].isTied = False
         curtime += old_div(4 * intermed.baseDivisions, n)
     intermed.noteList = noteList
     intermed.bSharps = True
     return intermed
 def convCoord(x):
     return int((old_div(x,maxx)) * w)
    def draw(self,listPulses, listFinal ):
        im = Image.new('RGB', (w,h*3) , 0xffffff)
        
        listQuantize = self.listSteps
        listPulses = listPulses
        listNotes = self.listPrequantized
        listNotesQuantized = self.listPostquantized
        listFinal = listFinal
        

        maxx = listQuantize[-1]
        def convCoord(x):
            return int((old_div(x,maxx)) * w)
        def convCoordQ(x):
            return convCoord(listQuantize[x])
        def  convCoordQRegular(x):
            return int((float(x)/(len(listQuantize)-1)) * w)
        
        self.prevpitch=0; self.curlevel=0
        def getnote(x):
            if x!=self.prevpitch: self.curlevel= (self.curlevel+1)%4
            self.prevpitch=x
            return self.curlevel

        draw = ImageDraw.Draw(im)
        #~ draw.line((0, 0) + im.size, fill=128)
        #~ draw.line((0, im.size[1], im.size[0], 0), fill=128)
        
        for q in listQuantize:
            x= convCoord(q)
            draw.line( (x,0,x,h), fill=0xaaaaaa)
        
        for q in listPulses:
            x= convCoord(q)
            draw.line( (x,0,x,old_div(h,16)), fill=0x4444ff, width=4)
        
        for note in listNotes:
            start, stop = convCoord(note[1]),convCoord(note[2])
            y=old_div(h,2) - (old_div(getnote(note[0])*h,8))  
            draw.rectangle( (start,y,stop,y+old_div(h,8)), fill=0x44ff44)
        
        
        for note in listNotesQuantized:
            start, stop = convCoordQ(note[1]),convCoordQ(note[2])
            y=old_div(h,2) - (old_div(getnote(note[0])*h,8)) 
            y+=old_div(h,2)
            draw.rectangle( (start,y,stop,y+old_div(h,8)), fill=0xff4444)
        
        
        #draw "final" version
        for q in range(len(listQuantize)):
            x= convCoordQRegular(q)
            draw.line( (x,h*2,x,h*3), fill=0xaaaaaa)
        
        for note in listFinal:
            start, stop = convCoordQRegular(note[1]),convCoordQRegular(note[2])
            for pitch in note[0]:
                y=old_div(h,2) - (old_div(getnote(pitch)*h,8)) 
                draw.rectangle( (start,y + h*2,stop,y+old_div(h,8)+ h*2), fill=0xffff44)
        
        
        del draw 
        im.save('out.png', "PNG")
class IntermediateList(object):
    #an intermediate list of notes. timings in terms of baseDivisions.
    noteList = None  # list of NotesRealtimeNoteEvent.
    bSharps = True
    timesig = None
    baseDivisions = 64  #each qtr note can be divided into this many pieces. 64 units always = 1 qtr note

    atomicnotes = [
        int(old_div(baseDivisions, n))
        for n in [0.25, 0.5, 1, 2, 4, 8, 16, 32]
    ]

    #							     whole, half, qtr, 8th, 16, 32, 64, 138

    def __init__(self, timesig, bSharps=True):
        self.timesig = timesig
        self.bSharps = bSharps
        self.noteList = []

    def effectivelyTieLongNotes(self, currentMeasureTime, length):
        #spell a long note on the beat. for example, turn something 3 beats long into halfnote tied to qtr
        # probably only looks well for duple times!
        #returns list of atoms
        results = []
        lengthleft = length

        while lengthleft > 0:
            found = False
            for atom in self.atomicnotes:
                if atom <= lengthleft and isDivisible(currentMeasureTime,
                                                      atom):
                    results.append(atom)
                    lengthleft -= atom
                    currentMeasureTime += atom
                    found = True
                    break
            assert found

        assert lengthleft == 0
        return results

    def effectivelyTieLongNotesBarlines(self, currentMeasureTime, length,
                                        measureLength):
        #spell a long note, taking measures into account (must tie across barlines)
        #returns list of atoms.
        results = []

        if currentMeasureTime + length <= measureLength:
            return self.effectivelyTieLongNotes(currentMeasureTime, length)
        else:
            lengthleft = length
            firstnotelength = measureLength - currentMeasureTime
            results.extend(
                self.effectivelyTieLongNotes(currentMeasureTime,
                                             firstnotelength))
            lengthleft -= firstnotelength
            currentMeasureTime += firstnotelength

            #add any full measures
            while lengthleft >= measureLength:
                results.extend(
                    self.effectivelyTieLongNotes(currentMeasureTime,
                                                 measureLength))
                lengthleft -= measureLength
                currentMeasureTime += measureLength

            #add the rest
            if lengthleft != 0:
                results.extend(
                    self.effectivelyTieLongNotes(currentMeasureTime,
                                                 lengthleft))
                lengthleft -= lengthleft
                currentMeasureTime += lengthleft

            return results
def createQuantizedList(objResults, quantize):
    #quantizes and eliminate overlapping notes
    if isinstance(objResults, NotesinterpretException): raise objResults
    if useVisualTest: vis = testdepiction.TestDepiction()
    listPulses, listNotes = objResults.listPulses, objResults.listNotes

    # how many subdivisions?
    divisions = old_div(quantize, 4)  #because each pulse is a qtr note
    assert quantize >= 4
    #for example, if quantize by 8th note, and each pulse is a qtr note, there are two possible values per pulse.

    #create quantization list (contains all acceptible times).
    #divides linearly. one might also smooth intra-pulse timing with a spline...
    listQuantize = []
    listQuantize.append(0.0)
    prevTime = 0.0
    for pulseTime in listPulses:
        inc = old_div((pulseTime - prevTime), divisions)
        for i in range(divisions):
            listQuantize.append(prevTime + i * inc)
        prevTime = pulseTime

    if useVisualTest: vis.addPreQuantize(listQuantize, listNotes)
    #quantize all of the times
    for note in listNotes:
        note.start = findclosest(listQuantize, note.start)
        note.end = findclosest(listQuantize, note.end)
        #now times are integers, corresponding to multiples of time unit. So if quantize=8, each unit is an 8th note

    if useVisualTest: vis.addQuantized(listNotes)

    #now get rid of overlapping notes, using some heuristics.
    #this logic is not currently used since polyphony no longer supported...
    #although could occur if two notes played rapidly
    listFinal = []
    while listNotes:
        currentPitchGroup = [listNotes.pop(0)]
        currentPitchStartTime = currentPitchGroup[0].start
        while listNotes and listNotes[0].start == currentPitchStartTime:
            currentPitchGroup.append(listNotes.pop(0))

        #length of this pitch group is the longest in the group...
        currentPitchEndTime = 0
        for note in currentPitchGroup:
            if note.end > currentPitchEndTime: currentPitchEndTime = note.end

        #...unless it is interrupted by some other note.
        if listNotes and listNotes[0].start < currentPitchEndTime:
            currentPitchEndTime = listNotes[0].start

        #can't have a note of length 0.
        if currentPitchEndTime == currentPitchStartTime:
            currentPitchEndTime += 1

        #quantize currentPitchEndTime to have it fill to next note?
        if listNotes and currentPitchEndTime != listNotes[0].start:
            if listNotes[0].start - currentPitchEndTime < quantize:
                currentPitchEndTime = listNotes[
                    0].start  #bleed into next note.
        assert currentPitchEndTime > currentPitchStartTime

        listFinal.append(([m.pitch for m in currentPitchGroup],
                          currentPitchStartTime, currentPitchEndTime))

    if useVisualTest: vis.draw(listPulses, listFinal)
    return listFinal