comparison Syncopation models/KTH.py @ 1:b2da092dc2e0

The consolidated syncopation software. Have finished individual model and basic functions. Need to revise the coding in main.py, and add rhythm-input interface.
author Chunyang Song <csong@eecs.qmul.ac.uk>
date Sun, 05 Oct 2014 21:52:41 +0100
parents
children 031e2ccb1fb6
comparison
equal deleted inserted replaced
0:76ce27beba95 1:b2da092dc2e0
1 '''
2 Author: Chunyang Song
3 Institution: Centre for Digital Music, Queen Mary University of London
4
5 '''
6 ## Problems! Note indices, post bar
7
8 from basic_functions import get_min_timeSpan, get_note_indices, repeat
9
10 # To find the nearest power of 2 equal to or less than the given number
11 def roundDownPower2(number):
12 i = 0
13 if number > 0:
14 while pow(2,i) > number or number >= pow(2,i+1):
15 i = i+1
16 power2 = pow(2,i)
17 else:
18 print 'Error: numbers that are less than 1 cannot be rounded down to its nearest power of two.'
19 power2 = None
20 return power2
21
22 # To find the nearest power of 2 equal to or more than the given number
23 def roundUpPower2(number):
24 i = 0
25 while pow(2,i) < number:
26 i = i + 1
27 return pow(2,i)
28
29 # To examine whether start_time is 'off-beat'
30 def start(start_time, c_n):
31 s = 0
32 if start_time % c_n != 0:
33 s = 2
34 return s
35
36 # To examine whether end_time is 'off-beat'
37 def end(end_time, c_n):
38 s = 0
39 if end_time % c_n != 0:
40 s = 1
41 return s
42
43 # To calculate syncopation value of the sequence in the given time-signature.
44 def get_syncopation(seq, timesig, postbar_seq):
45 syncopation = 0
46
47 numerator = int(timesig.split("/")[0])
48 if numerator == roundDownPower2(numerator): # if is a binary time-signature
49 # converting to minimum time-span format
50 seq = get_min_timeSpan(seq)
51 if postbar_seq != None:
52 postbar_seq = get_min_timeSpan(postbar_seq)
53
54 # sf is a stretching factor matching rhythm sequence and meter, as Keith defines the note duration as a multiple of 1/(2^d) beats where d is number of metrical level
55 sf = roundUpPower2(len(seq))
56
57 # retrieve all the indices of all the notes in this sequence
58 note_indices = get_note_indices(seq)
59
60 for i in range(len(note_indices)):
61 # Assuming start_time is the index of this note, end_time is the index of the following note
62 start_time = note_indices[i]*sf/float(len(seq))
63
64 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 postbar_seq != None and postbar_seq != repeat([0],len(postbar_seq)):
66 next_index = get_note_indices(postbar_seq)[0]+len(seq)
67 end_time = next_index*sf/float(len(seq))
68 else: # or if the next bar is none or full rest, end_time is the end of this sequence.
69 end_time = sf
70 else:
71 end_time = note_indices[i+1]*sf/float(len(seq))
72
73 duration = end_time - start_time
74 c_n = roundDownPower2(duration)
75 syncopation = syncopation + start(start_time,c_n) + end(end_time,c_n)
76 else:
77 print 'Error: KTH model can only deal with binary time-signature, e.g. 2/4 and 4/4. '
78 syncopation = None
79
80 return syncopation