Mercurial > hg > syncopation-dataset
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 |