Mercurial > hg > syncopation-dataset
comparison Syncopation models/PRS.py @ 12:4acddc008048
Revised LHL and PRS model's argument list; refactored the variable names
author | csong <csong@eecs.qmul.ac.uk> |
---|---|
date | Fri, 03 Apr 2015 16:38:32 +0100 |
parents | 031e2ccb1fb6 |
children | 9030967a05f8 |
comparison
equal
deleted
inserted
replaced
9:c2843ef4de2c | 12:4acddc008048 |
---|---|
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, subdivide, ceiling, get_min_timeSpan | 6 from basic_functions import repeat, subdivide, ceiling, get_min_timeSpan, get_rhythm_category |
7 | 7 |
8 def get_cost(seq,next_seq): | 8 def get_cost(sequence,nextSequence): |
9 seq = get_min_timeSpan(seq) # converting to the minimum time-span format | 9 sequence = get_min_timeSpan(sequence) # converting to the minimum time-span format |
10 | 10 |
11 if seq[1:] == repeat([0],len(seq)-1): # null prototype | 11 if sequence[1:] == repeat([0],len(sequence)-1): # null prototype |
12 cost = 0 | 12 cost = 0 |
13 elif seq == repeat([1],len(seq)): # filled prototype | 13 elif sequence == repeat([1],len(sequence)): # filled prototype |
14 cost = 1 | 14 cost = 1 |
15 elif seq[0] == 1 and seq[-1] == 0: # run1 prototype | 15 elif sequence[0] == 1 and sequence[-1] == 0: # run1 prototype |
16 cost = 2 | 16 cost = 2 |
17 elif seq[0] == 1 and (next_seq == None or next_seq[0] == 0): # run2 prototype | 17 elif sequence[0] == 1 and (nextSequence == None or nenextSequencext_seq[0] == 0): # run2 prototype |
18 cost = 2 | 18 cost = 2 |
19 elif seq[0] == 1 and seq[-1] == 1 and next_seq != None and next_seq[0] == 1: # upbeat prototype | 19 elif sequence[0] == 1 and sequence[-1] == 1 and nextSequence != None and nextSequence[0] == 1: # upbeat prototype |
20 cost = 3 | 20 cost = 3 |
21 elif seq[0] == 0: # syncopated prototype | 21 elif sequence[0] == 0: # syncopated prototype |
22 cost = 5 | 22 cost = 5 |
23 | 23 |
24 return cost | 24 return cost |
25 | 25 |
26 # This function calculates the syncopation value (cost) for the sequence with the postbar_seq for a certain level. | 26 # This function calculates the syncopation value (cost) for the sequence with the postbar_seq for a certain level. |
27 def syncopation_perlevel(sub_seqs, num_subs): | 27 def syncopation_perlevel(subSequences): |
28 total = 0 | 28 total = 0 |
29 for l in range(num_subs): | 29 for l in range(len(subSequences)-1): |
30 total = total + get_cost(sub_seqs[l], sub_seqs[l+1]) | 30 total = total + get_cost(subSequences[l], subSequences[l+1]) |
31 normalised = float(total)/num_subs | 31 normalised = float(total)/(len(subSequences)-1) |
32 | 32 |
33 return normalised | 33 return normalised |
34 | 34 |
35 # This function calculates the overall syncopation value for a bar of sequence.. | 35 #def get_syncopation(seq,subdivision_seq, postbar_seq, rhythm_category): |
36 def get_syncopation(seq,subdivision_seq, postbar_seq, rhythm_category): | 36 def get_syncopation(bar, weightSequence = None, LMax = None): |
37 ''' | |
38 The get_syncopation function calculates the overall syncopation value for a bar of sequence. | |
39 ''' | |
37 syncopation = None | 40 syncopation = None |
38 if rhythm_category == 'poly': | 41 |
39 print 'Error: PRS model cannot deal with polyrhythms.' | 42 binarySequence = bar.get_binary_sequence() |
43 subdivisionSequence = bar.get_subdivision_sequence() | |
44 | |
45 if get_rhythm_category(binarySequence, subdivisionSequence) == 'poly': | |
46 print 'Warning: PRS model detects polyrhythms so returning None.' | |
40 else: | 47 else: |
41 syncopation = 0 | 48 syncopation = 0 |
42 | 49 |
43 current_num_subs = 1 # the initial number of sub-sequences at a certain metrical level | 50 if bar.get_next_bar() != None: |
44 for subdivisor in subdivision_seq: | 51 nextbarBinarySequence = bar.get_next_bar().get_binary_sequence() |
52 else: | |
53 nextbarBinarySequence = None | |
54 | |
55 # the initial number of sub-sequences at a certain metrical level | |
56 numberOfSubSeqs = 1 | |
57 for subdivisor in subdivisionSequence: | |
45 # the number of sub-sequence at the current level is product of all the subdivisors up to the current level | 58 # the number of sub-sequence at the current level is product of all the subdivisors up to the current level |
46 current_num_subs = current_num_subs * subdivisor | 59 numberOfSubSeqs = numberOfSubSeqs * subdivisor |
47 # recursion stops when the length of sub-sequence is less than 2 | 60 # recursion stops when the length of sub-sequence is less than 2 |
48 if len(seq)/current_num_subs >= 2: | 61 if len(binarySequence)/numberOfSubSeqs >= 2: |
49 # generate sub-sequences and append the next bar sequence | 62 # generate sub-sequences and append the next bar sequence |
50 sub_seqs = subdivide(ceiling(seq), current_num_subs) | 63 subSequences = subdivide(ceiling(binarySequence), numberOfSubSeqs) |
51 sub_seqs.append(postbar_seq) | 64 subSequences.append(nextbarBinarySequence) |
52 # adding syncopation at each metrical level to the total syncopation | 65 # adding syncopation at each metrical level to the total syncopation |
53 syncopation += syncopation_perlevel(sub_seqs, current_num_subs) | 66 syncopation += syncopation_perlevel(subSequences) |
54 else: | 67 else: |
55 break | 68 break |
56 | 69 |
57 return syncopation | 70 return syncopation |