Mercurial > hg > syncopation-dataset
view 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 |
line wrap: on
line source
''' Author: Chunyang Song Institution: Centre for Digital Music, Queen Mary University of London ** Sioros and Guedes's Model ** Algorithm: Only applicable to monorhythms. This version of implementation follows the description in authors' 2011 ISMIR paper and assumes each bar of rhythm is looped. Therefore each bar is calculated seperatedly in a loop-mode and summed up in the end as the total syncopation. ''' from MeterStructure import MeterStructure from math import pow def subdivide(sequence, segments_num): subSeq = [] if len(sequence) % segments_num != 0: print 'Error: rhythm segment cannot be equally subdivided ' else: n = len(sequence) / segments_num start , end = 0, n for i in range(segments_num): subSeq.append(sequence[start : end]) start = end end = end + n return subSeq def sgModel(rhythm, time_sig, category, bar): ms = MeterStructure(time_sig) mWeights = ms.getLHLWeights(1) #print "hierarchy", mWeights num_onsets = 0 h_min = min(mWeights) syncAbsolute = 0 syncNormM = 0 syncNormE = 0 if 'poly' in category: syncAbsolute = -1 else: # segment rhythm into bars rhythm_byBar = subdivide (rhythm, bar) def measurePerBar(rhythm): syncopation = 0 def aveNeighbours(index, h): averages = [] parameter_k = 0.8 def findPre(h_hat): pre_index = index - 1 while(mWeights[pre_index] < h_hat): pre_index = (pre_index - 1)%len(mWeights) #print "h_hat and pre", h_hat, pre_index return pre_index def findPost(h_hat): post_index = (index + 1)%len(mWeights) while(mWeights[post_index] < h_hat): post_index = (post_index + 1)%len(mWeights) #print "h_hat and post", h_hat, post_index return post_index def dif(index1,index2): parameter_beta = 0.5 pos1 = int(float(index1)/len(mWeights)*48) pos2 = int(float(index2)/len(mWeights)*48) dif_v = rhythm[pos1]-rhythm[pos2] dif_h = abs(mWeights[index1]-mWeights[index2]) dif = dif_v*(parameter_beta*dif_h/4+1-parameter_beta) #print 'dif', dif return dif for h_hat in range(h_min,h+1): ave = ( parameter_k*dif(index,findPre(h_hat))+dif(index,findPost(h_hat)) )/(1+parameter_k) #print 'ave', ave averages.append(ave) return averages for pos in range(len(rhythm)): if rhythm[pos] != 0: # Onset detected #num_onsets += 1 i = int((pos/48.0*len(mWeights))) h = mWeights[i] potential = 1 - pow(0.5,(-h)) #print "intermediate", min(aveNeighbours(i,h)) syncopation += min(aveNeighbours(i, h))*potential return syncopation for r in rhythm_byBar: syncAbsolute = syncAbsolute + measurePerBar(r) #syncAbsolute /= 2.0 return syncAbsolute # Retrieve the stimuli #f = file('stimuli.txt') #f = file('stimuli_34only.txt') f = file('clave.txt') #Calculate syncopation for each rhythm pattern #while True: for i in range(1): line = f.readline().split(';') if len(line) == 1: break else: sti_name = line[0] rhythmString = line[1].split() time_sig = line[2] category = line[3] bar = int(line[4]) rhythm = map(int,rhythmString[0].split(',')) print sti_name, sgModel(rhythm, time_sig, category, bar)