Mercurial > hg > syncopation-dataset
comparison Syncopation models/SG.py @ 0:76ce27beba95
Have uploaded the syncopation dataset and audio wavefies.
author | Chunyang Song <csong@eecs.qmul.ac.uk> |
---|---|
date | Fri, 21 Mar 2014 15:49:46 +0000 |
parents | |
children | b2da092dc2e0 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:76ce27beba95 |
---|---|
1 ''' | |
2 Author: Chunyang Song | |
3 Institution: Centre for Digital Music, Queen Mary University of London | |
4 | |
5 ** Sioros and Guedes's Model ** | |
6 | |
7 Algorithm: | |
8 | |
9 Only applicable to monorhythms. | |
10 | |
11 This version of implementation follows the description in authors' 2011 ISMIR paper and assumes each bar of rhythm is looped. | |
12 Therefore each bar is calculated seperatedly in a loop-mode and summed up in the end as the total syncopation. | |
13 | |
14 ''' | |
15 | |
16 from MeterStructure import MeterStructure | |
17 from math import pow | |
18 | |
19 def subdivide(sequence, segments_num): | |
20 subSeq = [] | |
21 if len(sequence) % segments_num != 0: | |
22 print 'Error: rhythm segment cannot be equally subdivided ' | |
23 else: | |
24 n = len(sequence) / segments_num | |
25 start , end = 0, n | |
26 for i in range(segments_num): | |
27 subSeq.append(sequence[start : end]) | |
28 start = end | |
29 end = end + n | |
30 | |
31 return subSeq | |
32 | |
33 | |
34 def sgModel(rhythm, time_sig, category, bar): | |
35 ms = MeterStructure(time_sig) | |
36 mWeights = ms.getLHLWeights(1) | |
37 #print "hierarchy", mWeights | |
38 num_onsets = 0 | |
39 h_min = min(mWeights) | |
40 | |
41 syncAbsolute = 0 | |
42 syncNormM = 0 | |
43 syncNormE = 0 | |
44 | |
45 if 'poly' in category: | |
46 syncAbsolute = -1 | |
47 else: | |
48 # segment rhythm into bars | |
49 rhythm_byBar = subdivide (rhythm, bar) | |
50 | |
51 def measurePerBar(rhythm): | |
52 syncopation = 0 | |
53 | |
54 def aveNeighbours(index, h): | |
55 averages = [] | |
56 parameter_k = 0.8 | |
57 | |
58 def findPre(h_hat): | |
59 pre_index = index - 1 | |
60 while(mWeights[pre_index] < h_hat): | |
61 pre_index = (pre_index - 1)%len(mWeights) | |
62 #print "h_hat and pre", h_hat, pre_index | |
63 return pre_index | |
64 | |
65 def findPost(h_hat): | |
66 post_index = (index + 1)%len(mWeights) | |
67 while(mWeights[post_index] < h_hat): | |
68 post_index = (post_index + 1)%len(mWeights) | |
69 #print "h_hat and post", h_hat, post_index | |
70 return post_index | |
71 | |
72 def dif(index1,index2): | |
73 parameter_beta = 0.5 | |
74 pos1 = int(float(index1)/len(mWeights)*48) | |
75 pos2 = int(float(index2)/len(mWeights)*48) | |
76 dif_v = rhythm[pos1]-rhythm[pos2] | |
77 dif_h = abs(mWeights[index1]-mWeights[index2]) | |
78 dif = dif_v*(parameter_beta*dif_h/4+1-parameter_beta) | |
79 #print 'dif', dif | |
80 return dif | |
81 | |
82 for h_hat in range(h_min,h+1): | |
83 ave = ( parameter_k*dif(index,findPre(h_hat))+dif(index,findPost(h_hat)) )/(1+parameter_k) | |
84 #print 'ave', ave | |
85 averages.append(ave) | |
86 | |
87 return averages | |
88 | |
89 for pos in range(len(rhythm)): | |
90 if rhythm[pos] != 0: # Onset detected | |
91 #num_onsets += 1 | |
92 i = int((pos/48.0*len(mWeights))) | |
93 h = mWeights[i] | |
94 potential = 1 - pow(0.5,(-h)) | |
95 #print "intermediate", min(aveNeighbours(i,h)) | |
96 syncopation += min(aveNeighbours(i, h))*potential | |
97 | |
98 return syncopation | |
99 | |
100 for r in rhythm_byBar: | |
101 syncAbsolute = syncAbsolute + measurePerBar(r) | |
102 #syncAbsolute /= 2.0 | |
103 | |
104 return syncAbsolute | |
105 | |
106 # Retrieve the stimuli | |
107 #f = file('stimuli.txt') | |
108 #f = file('stimuli_34only.txt') | |
109 f = file('clave.txt') | |
110 | |
111 | |
112 #Calculate syncopation for each rhythm pattern | |
113 #while True: | |
114 for i in range(1): | |
115 line = f.readline().split(';') | |
116 if len(line) == 1: | |
117 break | |
118 else: | |
119 sti_name = line[0] | |
120 rhythmString = line[1].split() | |
121 time_sig = line[2] | |
122 category = line[3] | |
123 bar = int(line[4]) | |
124 | |
125 rhythm = map(int,rhythmString[0].split(',')) | |
126 print sti_name, sgModel(rhythm, time_sig, category, bar) |