comparison Syncopation models/WNBD.py @ 20:b959c2acb927

Refactored all models except for KTH, all past testing except for SG.
author csong <csong@eecs.qmul.ac.uk>
date Tue, 07 Apr 2015 19:05:07 +0100
parents 031e2ccb1fb6
children df1e7c378ee0
comparison
equal deleted inserted replaced
19:9030967a05f8 20:b959c2acb927
1 ''' 1 '''
2 Author: Chunyang Song 2 Author: Chunyang Song
3 Institution: Centre for Digital Music, Queen Mary University of London 3 Institution: Centre for Digital Music, Queen Mary University of London
4 4
5 ''' 5 '''
6 from BasicFuncs import repeat, get_note_indices 6 from basic_functions import repeat, get_note_indices
7 7
8 # To find the product of multiple numbers 8 # To find the product of multiple numbers
9 def cumu_multiply(numbers): 9 def cumu_multiply(numbers):
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): 15 #def get_syncopation(seq, subdivision_seq, strong_beat_level, postbar_seq):
16 def get_syncopation(bar, parameters = None):
16 syncopation = None 17 syncopation = None
17 18
18 num_beats = cumu_multiply(subdivision_seq[0:strong_beat_level+1]) # num_beats is the number of strong beats 19 binarySequence = bar.get_binary_sequence()
20 sequenceLength = len(binarySequence)
21 subdivisionSequence = bar.get_subdivision_sequence()
22 strongBeatLevel = bar.get_beat_level()
23 nextbarBinarySequence = None
24
25 if bar.get_next_bar() != None:
26 nextbarBinarySequence = bar.get_next_bar().get_binary_sequence()
27
28 numberOfBeats = cumu_multiply(subdivisionSequence[0:strongBeatLevel+1]) # numberOfBeats is the number of strong beats
19 29
20 if len(seq)%num_beats != 0: 30 if sequenceLength % numberOfBeats != 0:
21 print 'Error: the length of sequence is not subdivable by the subdivision factor in subdivision_seq.' 31 print 'Error: the length of sequence is not subdivable by the subdivision factor in subdivision sequence.'
22 else: 32 else:
23 # Find the indices of all the strong-beats 33 # Find the indices of all the strong-beats
24 beat_indices = [] 34 beatIndices = []
25 beat_interval = len(seq)/num_beats 35 beatInterval = sequenceLength / numberOfBeats
26 for i in range(num_beats+1): 36 for i in range(numberOfBeats+1):
27 beat_indices.append(i*beat_interval) 37 beatIndices.append(i*beatInterval)
28 if postbar_seq != None: # if there is a postbar_seq, add another two beats index for later calculation 38 if nextbarBinarySequence != None: # if there is a postbar_seq, add another two beats index for later calculation
29 beat_indices += [len(seq)+beat_interval, len(seq)+ 2* beat_interval] 39 beatIndices += [sequenceLength+beatInterval, sequenceLength+ 2* beatInterval]
30 40
31 note_indices = get_note_indices(seq) # all the notes 41 noteIndices = get_note_indices(binarySequence) # all the notes
32 42
33 # Calculate the WNBD measure for each note 43 # Calculate the WNBD measure for each note
34 def measure_pernote(note_index, nextnote_index): 44 def measure_pernote(noteIndices, nextNoteIndex):
35 # Find the nearest beats where this note locates - in [beat_indices[j], beat_indices[j+1]) 45 # Find the nearest beats where this note locates - in [beat_indices[j], beat_indices[j+1])
36 j = 0 46 j = 0
37 while note_index < beat_indices[j] or note_index >= beat_indices[j+1]: 47 while noteIndices < beatIndices[j] or noteIndices >= beatIndices[j+1]:
38 j = j + 1 48 j = j + 1
39 49
40 # The distance of note to nearest beat normalised by the beat interval 50 # The distance of note to nearest beat normalised by the beat interval
41 distance_nearest_beat = min(abs(note_index - beat_indices[j]), abs(note_index - beat_indices[j+1]))/float(beat_interval) 51 distanceToNearestBeat = min(abs(noteIndices - beatIndices[j]), abs(noteIndices - beatIndices[j+1]))/float(beatInterval)
42 52
43 # if this note is on-beat 53 # if this note is on-beat
44 if distance_nearest_beat == 0: 54 if distanceToNearestBeat == 0:
45 measure = 0 55 measure = 0
46 # or if this note is held on past the following beat, but ends on or before the later beat 56 # or if this note is held on past the following beat, but ends on or before the later beat
47 elif beat_indices[j+1] < nextnote_index <= beat_indices[j+2]: 57 elif beatIndices[j+1] < nextNoteIndex <= beatIndices[j+2]:
48 measure = float(2)/distance_nearest_beat 58 measure = float(2)/distanceToNearestBeat
49 else: 59 else:
50 measure = float(1)/distance_nearest_beat 60 measure = float(1)/distanceToNearestBeat
51
52 return measure 61 return measure
53 62
54 total = 0 63 total = 0
55 for i in range(len(note_indices)): 64 for i in range(len(noteIndices)):
56 if i == len(note_indices)-1:# if this is the last note, end_time is the index of the following note in the next bar 65 # if this is the last note, end_time is the index of the following note in the next bar
57 if postbar_seq != None and postbar_seq != repeat([0],len(postbar_seq)): 66 if i == len(noteIndices)-1:
58 nextnote_index = get_note_indices(postbar_seq)[0]+len(seq) 67 # if the next bar is not none or a bar of full rest,
59 else: # or if the next bar is none or full rest, end_time is the end of this sequence. 68 # the nextNoteIndex is the sum of sequence length in the current bar and the noteIndex in the next bar
60 nextnote_index = len(seq) 69 if nextbarBinarySequence != None and nextbarBinarySequence != repeat([0],len(nextbarBinarySequence)):
70 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.
72 else:
73 nextNoteIndex = sequenceLength
74 # else this is not the last note, the nextNoteIndex is the following element in the noteIndices list
61 else: 75 else:
62 nextnote_index = note_indices[i+1] 76 nextNoteIndex = noteIndices[i+1]
63 total += measure_pernote(note_indices[i],nextnote_index) 77 # sum up the syncopation value for individual note at noteIndices[i]
78 total += measure_pernote(noteIndices[i],nextNoteIndex)
64 79
65 #syncopation = float(total) / len(note_indices) 80 #syncopation = float(total) / len(note_indices)
66 81
82 # return the total value, leave the normalisation done in the end
67 return total 83 return total