comparison Syncopation models/WNBD.py @ 23:df1e7c378ee0

fixed KTH, and WNBD
author csong <csong@eecs.qmul.ac.uk>
date Sun, 12 Apr 2015 13:06:17 +0100
parents b959c2acb927
children
comparison
equal deleted inserted replaced
22:2dbc09ca8013 23:df1e7c378ee0
10 product = 1 10 product = 1
11 for n in numbers: 11 for n in numbers:
12 product = product*n 12 product = product*n
13 return product 13 return product
14 14
15 #def get_syncopation(seq, subdivision_seq, strong_beat_level, postbar_seq):
16 def get_syncopation(bar, parameters = None): 15 def get_syncopation(bar, parameters = None):
17 syncopation = None 16 syncopation = None
18 17
19 binarySequence = bar.get_binary_sequence() 18 noteSequence = bar.get_note_sequence()
20 sequenceLength = len(binarySequence) 19 barTicks = bar.get_bar_ticks()
21 subdivisionSequence = bar.get_subdivision_sequence() 20 subdivisionSequence = bar.get_subdivision_sequence()
22 strongBeatLevel = bar.get_beat_level() 21 strongBeatLevel = bar.get_beat_level()
23 nextbarBinarySequence = None 22
23 nextbarNoteSequence = None
24 if bar.get_next_bar() != None:
25 nextbarNoteSequence = bar.get_next_bar().get_note_sequence()
24 26
25 if bar.get_next_bar() != None: 27 # calculate each strong beat ticks
26 nextbarBinarySequence = bar.get_next_bar().get_binary_sequence() 28 numberOfBeats = cumu_multiply(subdivisionSequence[:strongBeatLevel+1])
29 beatIntervalTicks = barTicks/numberOfBeats
30 # beatsTicks represents the ticks for all the beats in the current bar and the first two beats in the next bar
31 beatsTicks = [i*beatIntervalTicks for i in range(numberOfBeats+2)]
32 #print beatsTicks
33 totalSyncopation = 0
34 for note in noteSequence:
35 # print note.to_string()
36 # find such beatIndex such that note.startTime is located between (including) beatsTicks[beatIndex] and (not including) beatsTicks[beatIndex+1]
37 beatIndex = 0
38 while note.startTime < beatsTicks[beatIndex] or note.startTime >= beatsTicks[beatIndex+1]:
39 beatIndex += 1
27 40
28 numberOfBeats = cumu_multiply(subdivisionSequence[0:strongBeatLevel+1]) # numberOfBeats is the number of strong beats 41 # print beatIndex
42 # calculate the distance of this note to its nearest beat
43 distanceToBeatOnLeft = abs(note.startTime - beatsTicks[beatIndex])/float(beatIntervalTicks)
44 distanceToBeatOnRight = abs(note.startTime - beatsTicks[beatIndex+1])/float(beatIntervalTicks)
45 distanceToNearestBeat = min(distanceToBeatOnLeft,distanceToBeatOnRight)
46 # print distanceToNearestBeat
47
48 # calculate the WNBD measure for this note, and add to total syncopation value for this bar
49 if distanceToNearestBeat == 0:
50 totalSyncopation += 0
51 # or if this note is held on past the following beat, but ends on or before the later beat
52 elif beatsTicks[beatIndex+1] < note.startTime+note.duration <= beatsTicks[beatIndex+2]:
53 totalSyncopation += float(2)/distanceToNearestBeat
54 else:
55 totalSyncopation += float(1)/distanceToNearestBeat
56 # print totalSyncopation
57
58 return totalSyncopation
59
60 #def get_syncopation(seq, subdivision_seq, strong_beat_level, postbar_seq):
61 # def get_syncopation(bar, parameters = None):
62 # syncopation = None
29 63
30 if sequenceLength % numberOfBeats != 0: 64 # binarySequence = bar.get_binary_sequence()
31 print 'Error: the length of sequence is not subdivable by the subdivision factor in subdivision sequence.' 65 # sequenceLength = len(binarySequence)
32 else: 66 # subdivisionSequence = bar.get_subdivision_sequence()
33 # Find the indices of all the strong-beats 67 # strongBeatLevel = bar.get_beat_level()
34 beatIndices = [] 68 # nextbarBinarySequence = None
35 beatInterval = sequenceLength / numberOfBeats
36 for i in range(numberOfBeats+1):
37 beatIndices.append(i*beatInterval)
38 if nextbarBinarySequence != None: # if there is a postbar_seq, add another two beats index for later calculation
39 beatIndices += [sequenceLength+beatInterval, sequenceLength+ 2* beatInterval]
40 69
41 noteIndices = get_note_indices(binarySequence) # all the notes 70 # if bar.get_next_bar() != None:
71 # nextbarBinarySequence = bar.get_next_bar().get_binary_sequence()
42 72
43 # Calculate the WNBD measure for each note 73 # numberOfBeats = cumu_multiply(subdivisionSequence[0:strongBeatLevel+1]) # numberOfBeats is the number of strong beats
44 def measure_pernote(noteIndices, nextNoteIndex): 74
45 # Find the nearest beats where this note locates - in [beat_indices[j], beat_indices[j+1]) 75 # if sequenceLength % numberOfBeats != 0:
46 j = 0 76 # print 'Error: the length of sequence is not subdivable by the subdivision factor in subdivision sequence.'
47 while noteIndices < beatIndices[j] or noteIndices >= beatIndices[j+1]: 77 # else:
48 j = j + 1 78 # # Find the indices of all the strong-beats
79 # beatIndices = []
80 # beatInterval = sequenceLength / numberOfBeats
81 # for i in range(numberOfBeats+1):
82 # beatIndices.append(i*beatInterval)
83 # if nextbarBinarySequence != None: # if there is a postbar_seq, add another two beats index for later calculation
84 # beatIndices += [sequenceLength+beatInterval, sequenceLength+ 2* beatInterval]
85
86 # noteIndices = get_note_indices(binarySequence) # all the notes
87
88 # # Calculate the WNBD measure for each note
89 # def measure_pernote(noteIndices, nextNoteIndex):
90 # # Find the nearest beats where this note locates - in [beat_indices[j], beat_indices[j+1])
91 # j = 0
92 # while noteIndices < beatIndices[j] or noteIndices >= beatIndices[j+1]:
93 # j = j + 1
49 94
50 # The distance of note to nearest beat normalised by the beat interval 95 # # The distance of note to nearest beat normalised by the beat interval
51 distanceToNearestBeat = min(abs(noteIndices - beatIndices[j]), abs(noteIndices - beatIndices[j+1]))/float(beatInterval) 96 # distanceToNearestBeat = min(abs(noteIndices - beatIndices[j]), abs(noteIndices - beatIndices[j+1]))/float(beatInterval)
52 97
53 # if this note is on-beat 98 # # if this note is on-beat
54 if distanceToNearestBeat == 0: 99 # if distanceToNearestBeat == 0:
55 measure = 0 100 # measure = 0
56 # or if this note is held on past the following beat, but ends on or before the later beat 101 # # or if this note is held on past the following beat, but ends on or before the later beat
57 elif beatIndices[j+1] < nextNoteIndex <= beatIndices[j+2]: 102 # elif beatIndices[j+1] < nextNoteIndex <= beatIndices[j+2]:
58 measure = float(2)/distanceToNearestBeat 103 # measure = float(2)/distanceToNearestBeat
59 else: 104 # else:
60 measure = float(1)/distanceToNearestBeat 105 # measure = float(1)/distanceToNearestBeat
61 return measure 106 # return measure
62 107
63 total = 0 108 # total = 0
64 for i in range(len(noteIndices)): 109 # for i in range(len(noteIndices)):
65 # if this is the last note, end_time is the index of the following note in the next bar 110 # # if this is the last note, end_time is the index of the following note in the next bar
66 if i == len(noteIndices)-1: 111 # if i == len(noteIndices)-1:
67 # if the next bar is not none or a bar of full rest, 112 # # if the next bar is not none or a bar of full rest,
68 # the nextNoteIndex is the sum of sequence length in the current bar and the noteIndex in the next bar 113 # # the nextNoteIndex is the sum of sequence length in the current bar and the noteIndex in the next bar
69 if nextbarBinarySequence != None and nextbarBinarySequence != repeat([0],len(nextbarBinarySequence)): 114 # if nextbarBinarySequence != None and nextbarBinarySequence != repeat([0],len(nextbarBinarySequence)):
70 nextNoteIndex = get_note_indices(nextbarBinarySequence)[0]+sequenceLength 115 # nextNoteIndex = get_note_indices(nextbarBinarySequence)[0]+sequenceLength
71 # else when the next bar is none or full rest, end_time is the end of this sequence. 116 # # else when the next bar is none or full rest, end_time is the end of this sequence.
72 else: 117 # else:
73 nextNoteIndex = sequenceLength 118 # nextNoteIndex = sequenceLength
74 # else this is not the last note, the nextNoteIndex is the following element in the noteIndices list 119 # # else this is not the last note, the nextNoteIndex is the following element in the noteIndices list
75 else: 120 # else:
76 nextNoteIndex = noteIndices[i+1] 121 # nextNoteIndex = noteIndices[i+1]
77 # sum up the syncopation value for individual note at noteIndices[i] 122 # # sum up the syncopation value for individual note at noteIndices[i]
78 total += measure_pernote(noteIndices[i],nextNoteIndex) 123 # total += measure_pernote(noteIndices[i],nextNoteIndex)
79 124
80 #syncopation = float(total) / len(note_indices) 125 # #syncopation = float(total) / len(note_indices)
81 126
82 # return the total value, leave the normalisation done in the end 127 # # return the total value, leave the normalisation done in the end
83 return total 128 # return total