changeset 9:c2843ef4de2c

changing filenames to Python conventions
author csong
date Fri, 03 Apr 2015 11:41:01 +0100
parents 2c5df6a4a22f
children a3ed7d2b57d8 4acddc008048
files Syncopation models/BasicFuncs.py Syncopation models/MusicObjects.py Syncopation models/ParameterSetter.py Syncopation models/RhythmParser.py Syncopation models/basic_functions.py Syncopation models/main.py Syncopation models/music_objects.py Syncopation models/parameter_setter.py Syncopation models/rhythm_parser.py Syncopation models/syncopation.py
diffstat 10 files changed, 576 insertions(+), 566 deletions(-) [+]
line wrap: on
line diff
--- a/Syncopation models/BasicFuncs.py	Thu Apr 02 00:06:57 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-# This python file is a collection of basic functions that are used in the syncopation models. 
-
-import math
-
-# The concatenation function is used to concatenate two sequences.
-def concatenate(seq1,seq2):
-	return seq1+seq2
-
-# The repetition function is to concatenate a sequence to itself for 'times' number of times.
-def repeat(seq,times):
-	new_seq = list(seq)
-	if times >= 1:
-		for i in range(times-1):
-			new_seq = concatenate(new_seq,seq)
-	else:
-		#print 'Error: repetition times needs to be no less than 1.'
-		new_seq = []
-	return new_seq
-
-# The subdivision function is to equally subdivide a sequence into 'divisor' number of segments.
-def subdivide(seq,divisor):
-	subSeq = []
-	if len(seq) % divisor != 0:
-		print 'Error: rhythmic sequence cannot be equally subdivided.'
-	else:
-		n = len(seq) / divisor
-		start , end = 0, n
-		for i in range(divisor):
-			subSeq.append(seq[start : end])
-			start = end
-			end = end + n	
-	return subSeq
-
-
-# The ceiling function is to round each number inside a sequence up to its nearest integer.
-def ceiling(seq):
-	seq_ceil = []
-	for s in seq:
-		seq_ceil.append(int(math.ceil(s)))
-	return seq_ceil
-
-# The find_divisor function returns a list of all possible divisors for a length of sequence.
-def find_divisor(number):
-	divisors = [1]
-	for i in range(2,number+1):
-		if number%i ==0:
-			divisors.append(i)
-	return divisors
-
-# The find_divisor function returns a list of all possible divisors for a length of sequence.
-def find_prime_factors(number):
-	prime_factors = find_divisor(number)
-	
-	def is_prime(num):
-		if num < 2:
-			return False
-		if num == 2:
-			return True
-		else:
-			for div in range(2,num):
-				if num % div == 0:
-					return False
-		return True
-
-	for i in range(len(prime_factors)-1,0,-1):
-		if is_prime(prime_factors[i]) == False:
-			del prime_factors[i]
-
-	return prime_factors
-
-# The min_timeSpan function searches for the shortest possible time-span representation for a sequence.
-def get_min_timeSpan(seq):
-	min_ts = [1]
-	for d in find_divisor(len(seq)):
-		segments = subdivide(seq,d)
-		if len(segments)!=0:
-			del min_ts[:]
-			for s in segments:
-				min_ts.append(s[0])
-			if sum(min_ts) == sum(seq):
-				break
-	return min_ts
-
-# get_note_indices returns all the indices of all the notes in this sequence
-def get_note_indices(seq):
-	note_indices = []
-
-	for index in range(len(seq)):
-		if seq[index] != 0:
-			note_indices.append(index)
-
-	return note_indices
-
-# The get_H returns a sequence of metrical weight for a certain metrical level (horizontal),
-# given the sequence of metrical weights in a hierarchy (vertical) and a sequence of subdivisions.
-def get_H(weight_seq,subdivision_seq, level):
-	H = []
-	#print len(weight_seq), len(subdivision_seq), level
-	if (level <= len(subdivision_seq)-1) & (level <= len(weight_seq)-1):
-		if level == 0:
-			H = repeat([weight_seq[0]],subdivision_seq[0])
-		else:
-			H_pre = get_H(weight_seq,subdivision_seq,level-1)
-			for h in H_pre:
-				H = concatenate(H, concatenate([h], repeat([weight_seq[level]],subdivision_seq[level]-1)))
-	else:
-		print 'Error: a subdivision factor or metrical weight is not defined for the request metrical level.'
-	return H
-
-# The get_subdivision_seq function returns the subdivision sequence of several common time-signatures defined by GTTM, 
-# or ask for the top three level of subdivision_seq manually set by the user.
-def get_subdivision_seq(timesig, L_max):
-	subdivision_seq = []
-
-	if timesig == '2/4' or timesig == '4/4':
-		subdivision_seq = [1,2,2]
-	elif timesig == '3/4' or timesig == '3/8':
-		subdivision_seq = [1,3,2]
-	elif timesig == '6/8':
-		subdivision_seq = [1,2,3]
-	elif timesig == '9/8':
-		subdivision_seq = [1,3,3]
-	elif timesig == '12/8':
-		subdivision_seq = [1,4,3]
-	elif timesig == '5/4' or timesig == '5/8':
-		subdivision_seq = [1,5,2]
-	elif timesig == '7/4' or timesig == '7/8':
-		subdivision_seq = [1,7,2]
-	elif timesig == '11/4' or timesig == '11/8':
-		subdivision_seq = [1,11,2]
-	else:
-		print 'Time-signature',timesig,'is undefined. Please indicate subdivision sequence for this requested time-signature, e.g. [1,2,2] for 4/4 meter.'
-		for i in range(3):
-			s = int(input('Enter the subdivision factor at metrical level '+str(i)+':'))
-			subdivision_seq.append(s)
-
-	if L_max > 2:
-		subdivision_seq = subdivision_seq + [2]*(L_max-2)
-	else:
-		subdivision_seq = subdivision_seq[0:L_max+1]
-	
-	return subdivision_seq
-
- # The split_by_bar function seperates the score representation of rhythm by bar lines, 
- # resulting in a list representingbar-by-bar rhythm sequence,
- # e.g. rhythm = ['|',[ts1,td1,v1], [ts2,td2,v2], '|',[ts3,td3,v3],'|'...]
- # rhythm_bybar = [ [ [ts1,td1,v1], [ts2,td2,v2] ], [ [ts3,td3,v3] ], [...]]
-# def split_by_bar(rhythm):
-# 	rhythm_bybar = []
-# 	bar_index = []
-# 	for index in range(len(rhythm)):
-# 		if rhythm[index] == '|':
-
-# 	return rhythm_bybar
-
-# def yseq_to_vseq(yseq):
-# 	vseq = []
-
-# 	return vseq
-
-
-# # testing
-# print find_prime_factors(10)
\ No newline at end of file
--- a/Syncopation models/MusicObjects.py	Thu Apr 02 00:06:57 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-
-from BasicFuncs import ceiling
-
-import ParameterSetter 
-import RhythmParser 
-
-class Note():
-	def __init__(self, argstring):
-		intlist = map(int,argstring.split(','))
-		self.startTime = intlist[0]
-		self.duration = intlist[1]
-		self.velocity = intlist[2]
-	
-	# toString()
-
-# NoteSequence is a list of Note
-class NoteSequence(list):
-	def __init__(self, noteSequenceString=None):
-		if noteSequenceString!=None:
-			self.string_to_note_sequence(noteSequenceString)
-
-	def string_to_note_sequence(self, noteSequenceString):
-		noteSequenceString = RhythmParser.discardSpaces(noteSequenceString)
-		# try:
-			# Turning "(1,2,3),(4,5,6),(7,8,9)" into ["1,2,3","4,5,6,","7,8,9"]
-		listStrings = noteSequenceString[1:-1].split("),(")
-		for localString in listStrings:
-			self.append(Note(localString))
-
-	# toString()
-
-
-print NoteSequence("(1,2,3),(4,5,6),(7,8,9)")
-# class VelocitySequence(list):
-# 	def __init__(self, noteSequenceString=None):
-# 		if noteSequenceString!=None:
-# 			self.string_to_note_sequence(noteSequenceString)
-
-# 	def string_to_note_sequence(string):
-
-
-class BarList(list):
-	def append(self,bar):
-		if(len(self)>0):
-			bar.set_previous_bar(self[-1])
-			self[-1].set_next_bar(bar)
-		super(BarList, self).append(bar)
-
-
-
-class Bar:
-
-	def __init__(self, rhythmSequence, timeSignature, ticksPerQuarter=None, qpmTempo=None, nextBar=None, prevBar=None):
-		if isinstance(rhythmSequence, NoteSequence):
-			self.noteSequence = rhythmSequence
-			self.velocitySequence = None 
-		elif isinstance(rhythmSequence, VelocitySequence):
-			self.velocitySequence = rhythmSequence
-			self.noteSequence = None 
-
-		self.tpq = ticksPerQuarter
-		self.qpm = qpmTempo
-		self.timeSignature = timeSignature
-		self.nextBar = nextBar
-		self.prevBar = prevBar
-
-	def get_note_sequence(self):
-		#if self.noteSequence==None:
-		#	self.noteSequence = velocitySequenceToNotes(self.velocitySequence)
-		return self.noteSequence
-
-	def get_velocity_sequence(self):
-		if self.velocitySequence==None:
-			self.velocitySequence = noteSequenceToVelocities(self.velocitySequence)
-		return self.velocitySequence
-
-	def get_binary_sequence(self):
-		return ceiling(self.get_velocity_sequence())
-
-	def get_next_bar(self):
-		return self.nextBar
-
-	def get_previous_bar(self):
-		return self.prevBar
-
-	def set_next_bar(self, bar):
-		self.nextBar = bar
-
-	def set_previous_bar(self, bar):
-		self.prevBar = bar		
-
-	def get_subdivision_sequence(self):
-		return ParameterSetter.get_subdivision_seq(self.timeSignature)
-
-	def get_beat_level(self):
-		return ParameterSetter.get_beat_level(self.timeSignature)
-
-	def get_time_signature(self):
-		return self.timeSignature
-
-	def get_t_span(self):
-		# return the length of a bar in time units
-		return None # NEED TO IMPLEMENT
-
--- a/Syncopation models/ParameterSetter.py	Thu Apr 02 00:06:57 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-'''
-Author: Chunyang Song
-Institution: Centre for Digital Music, Queen Mary University of London
-'''
-
-# Set the parameters: subdivision_seq, weight_seq, L_max, strong_beat_level
-
-L_max = 5
-
-# {'key': time-signature} :  
-# {'value': [subdivision_seq, theoretical beat-level represented by index in the subdivision_seq list]}
-timesigBase = {
-	'2/2': [[1,2,2,2,2],1],
-	'3/2': [[1,3,2,2,2],1],
-	'4/2': [[1,2,2,2,2],1],
-	'2/4': [[1,2,2,2,2],1],
-	'3/4': [[1,3,2,2,2],1],
-	'4/4': [[1,2,2,2,2],2],
-	'5/4': [[1,5,2,2,2],1],
-	'7/4': [[1,7,2,2,2],1],
-	'3/8': [[1,3,2,2,2],1],
-	'5/8': [[1,5,2,2,2],1],
-	'6/8': [[1,2,3,2,2],1],
-	'9/8': [[1,3,3,2,2],1],
-	'12/8':[[1,2,2,3,2],2],	
-}
-
-
-def addTimesig(timesig, subdivision_seq, beat_level):
-	if isTSValid(timesig,subdivision_seq,beat_level):
-		if timesig in timesigBase:
-			print 'This time-signature is existed already.'
-		else:
-			timesigBase[timesig] = [subdivision_seq, beat_level]
-			writeTimesig()
-
-def updateTimesig(timesig, subdivision_seq, beat_level):
-	if isTSValid(timesig,subdivision_seq,beat_level):
-		if timesig in timesigBase:
-			print 'Original settings for', timesig, ':',timesigBase[timesig] 
-			timesigBase[timesig] = [subdivision_seq, beat_level]
-			print 'Changed into:',timesigBase[timesig]
-			writeTimesig()
-
-def isTSValid(timesig, subdivision_seq, beat_level):
-	isValid = False
-	if ('/' not in timesig) or (not timesig.split('/')[0].isdigit()) or (not timesig.split('/')[1].isdigit()):
-		print 'Error: invalid time-signature. Please indicate in the form of fraction, e.g. 4/4, 6/8 or 3/4.'
-	elif subdivision_seq != [s for s in subdivision_seq if isinstance(s,int)]:
-		print 'Error: invalid subdivision sequence. Please indicate in the form of list of numbers, e.g [1,2,2,2,2].'
-	elif beat_level >= len(subdivision_seq):
-		print 'Error: beat-level exceeds the range of subdivision sequence list.'
-	else:
-		isValid = True
-	return isValid
-
-def writeTimesig():
-	import cPickle as pickle
-	timesigFile = open('TimeSignature.pkl', 'wb')
-	pickle.dump(timesigBase, timesigFile)
-	timesigFile.close()
-
-def readTimesig():
-	import cPickle as pickle
-	timesigFile = open('TimeSignature.pkl','rb')
-	data = pickle.load(timesigFile)
-	return data
-	timesigFile.close()
-
-def viewTimesigBase():
-	data = readTimesig()
-	for timesig, settings in data.items():
-		print timesig, settings
-
-def set_L_max(number):
-	L_max = number
-
-def get_subdivision_seq(timesig):
-	if timesig in readTimesig():
-		return timesigBase[timesig][0]
-	else:
-		print 'Error: the subdivision sequence for this time-signature is not defined.'
-		return None
-
-def get_beat_level(timesig):
-	if timesig in readTimesig():
-		return timesigBase[timesig][1]
-	else:
-		print 'Error: the subdivision sequence for this time-signature is not defined.'
-		return None
--- a/Syncopation models/RhythmParser.py	Thu Apr 02 00:06:57 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-'''
-Author: Chunyang Song
-Institution: Centre for Digital Music, Queen Mary University of London
-'''
-
-# Parse the rhythm file and return a list of Bar objects
-Piece = []
-
-from ParameterSetter import timesigBase
-
-
-comment_sign = '#'
-def discardComments(line):
-	if comment_sign in line:
-		line = line[0:line.find(comment_sign)]
-	return line
-
-def discardSpaces(line):
-	line = line.replace(" ", '').replace("\t", '')
-	return line
-
-def extractInfo(line):
-	try:
-		if '{' not in line and '}' not in line:
-			raise RhythmSyntaxError(line)
-		else:
-			return line[line.find('{')+1 : line.find('}')]
-	except RhythmSyntaxError:
-		print 'Rhythmic information needs to be enclosed by "{" and "}"'
-
-
-current_timesig = ''
-current_timesigValue = []
-def process(line):
-	try:
-		if 't' in line:
-			current_timesig = extractInfo(line)
-			if current_timesig in timesigBase:
-				current_timesigValue = timesigBase[current_timesig]
-			else:
-				raise NoTimesigError(current_timesig)
-		
-		elif 'v' in line:
-			if current_timesig == '':
-				raise InitialTimesigError(line)
-			else:
-				rhythmString = extractInfo(line)
-				rhythm_seq = map(int,rhythmString.split(','))
-				Piece.append(Bar(rhythm_seq, current_timesigValue[0], current_timesigValue[1]))
-		
-		else:
-			raise SymbolError(line)
-	
-	except InitialTimesigError:
-		print 'The initial time-signature is not given.'
-	except NoTimesigError:
-		print 'The time-signature is not recognised.'
-	except SymbolError:
-		print 'Unrecognised symbol.'
-
-
-def readRhythm(fileName):
-	try:
-		f = file(fileName)
-		
-		# Clean up each line by discarding comments and spaces; extract time-signature or sequence information
-		isfinished = False
-		while(not isfinished):
-			line = f.readline()
-			if len(line) == 0:
-				isfinished = True
-			else:
-				cleanline = discardSpaces(discardComments(line))
-				process(cleanline)
-
-		# Extract time-signature and rhythm sequence information
-
-	except IOError as e:
-		print "I/O error({0}): {1}".format(e.errno, e.strerror)
-	except:
-		print 'Unexpected error.'#, sys.exc_info()[0]
-
-# To check the 
-def isInfoValid(info):
-	# If two parts of information is not seperated by ;
-	# if 't' in info and 'q' in info:
-	# 	print 'Error: time-signature and rhythm sequence needs ";" to seperate. Please check this rhythm file: %s.' %fileName
-	# 	Piece = None
-	# 	break
-	# elif '{' not in info and '}' not in info:
-	# 	print 'Error: information needs to be enclosed by "{ }". Please check this rhythm file: %s.' %fileName
-	# 	Piece = None
-	# 	break				
-	# else:
-	return True			
-
-# To check whether the given time-signature is existed; if not then requires user to add in the new time-signature
-#def checkTimesig(input):
-
-
-# TESTING
-line = 't{4/4}	q{1,0,0,1,0,0,1,0,0,0,1,0,0.8,0,0,0} t{2/4} # This is a comment'
-# print discardSpaces(discardComments(line))
-print line[line.find('{')+1:line.find('}')]
-#print readRhythm("rhythmbase/testrhythm.txt")
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Syncopation models/basic_functions.py	Fri Apr 03 11:41:01 2015 +0100
@@ -0,0 +1,173 @@
+# This python file is a collection of basic functions that are used in the syncopation models. 
+
+import math
+
+# The concatenation function is used to concatenate two sequences.
+def concatenate(seq1,seq2):
+	return seq1+seq2
+
+# The repetition function is to concatenate a sequence to itself for 'times' number of times.
+def repeat(seq,times):
+	new_seq = list(seq)
+	if times >= 1:
+		for i in range(times-1):
+			new_seq = concatenate(new_seq,seq)
+	else:
+		#print 'Error: repetition times needs to be no less than 1.'
+		new_seq = []
+	return new_seq
+
+# The subdivision function is to equally subdivide a sequence into 'divisor' number of segments.
+def subdivide(seq,divisor):
+	subSeq = []
+	if len(seq) % divisor != 0:
+		print 'Error: rhythmic sequence cannot be equally subdivided.'
+	else:
+		n = len(seq) / divisor
+		start , end = 0, n
+		for i in range(divisor):
+			subSeq.append(seq[start : end])
+			start = end
+			end = end + n	
+	return subSeq
+
+
+# The ceiling function is to round each number inside a sequence up to its nearest integer.
+def ceiling(seq):
+	seq_ceil = []
+	for s in seq:
+		seq_ceil.append(int(math.ceil(s)))
+	return seq_ceil
+
+# The find_divisor function returns a list of all possible divisors for a length of sequence.
+def find_divisor(number):
+	divisors = [1]
+	for i in range(2,number+1):
+		if number%i ==0:
+			divisors.append(i)
+	return divisors
+
+# The find_divisor function returns a list of all possible divisors for a length of sequence.
+def find_prime_factors(number):
+	prime_factors = find_divisor(number)
+	
+	def is_prime(num):
+		if num < 2:
+			return False
+		if num == 2:
+			return True
+		else:
+			for div in range(2,num):
+				if num % div == 0:
+					return False
+		return True
+
+	for i in range(len(prime_factors)-1,0,-1):
+		if is_prime(prime_factors[i]) == False:
+			del prime_factors[i]
+
+	return prime_factors
+
+# The min_timeSpan function searches for the shortest possible time-span representation for a sequence.
+def get_min_timeSpan(seq):
+	min_ts = [1]
+	for d in find_divisor(len(seq)):
+		segments = subdivide(seq,d)
+		if len(segments)!=0:
+			del min_ts[:]
+			for s in segments:
+				min_ts.append(s[0])
+			if sum(min_ts) == sum(seq):
+				break
+	return min_ts
+
+# get_note_indices returns all the indices of all the notes in this sequence
+def get_note_indices(seq):
+	note_indices = []
+
+	for index in range(len(seq)):
+		if seq[index] != 0:
+			note_indices.append(index)
+
+	return note_indices
+
+# The get_H returns a sequence of metrical weight for a certain metrical level (horizontal),
+# given the sequence of metrical weights in a hierarchy (vertical) and a sequence of subdivisions.
+def get_H(weight_seq,subdivision_seq, level):
+	H = []
+	#print len(weight_seq), len(subdivision_seq), level
+	if (level <= len(subdivision_seq)-1) & (level <= len(weight_seq)-1):
+		if level == 0:
+			H = repeat([weight_seq[0]],subdivision_seq[0])
+		else:
+			H_pre = get_H(weight_seq,subdivision_seq,level-1)
+			for h in H_pre:
+				H = concatenate(H, concatenate([h], repeat([weight_seq[level]],subdivision_seq[level]-1)))
+	else:
+		print 'Error: a subdivision factor or metrical weight is not defined for the request metrical level.'
+	return H
+
+# The get_subdivision_seq function returns the subdivision sequence of several common time-signatures defined by GTTM, 
+# or ask for the top three level of subdivision_seq manually set by the user.
+def get_subdivision_seq(timesig, L_max):
+	subdivision_seq = []
+
+	if timesig == '2/4' or timesig == '4/4':
+		subdivision_seq = [1,2,2]
+	elif timesig == '3/4' or timesig == '3/8':
+		subdivision_seq = [1,3,2]
+	elif timesig == '6/8':
+		subdivision_seq = [1,2,3]
+	elif timesig == '9/8':
+		subdivision_seq = [1,3,3]
+	elif timesig == '12/8':
+		subdivision_seq = [1,4,3]
+	elif timesig == '5/4' or timesig == '5/8':
+		subdivision_seq = [1,5,2]
+	elif timesig == '7/4' or timesig == '7/8':
+		subdivision_seq = [1,7,2]
+	elif timesig == '11/4' or timesig == '11/8':
+		subdivision_seq = [1,11,2]
+	else:
+		print 'Time-signature',timesig,'is undefined. Please indicate subdivision sequence for this requested time-signature, e.g. [1,2,2] for 4/4 meter.'
+		for i in range(3):
+			s = int(input('Enter the subdivision factor at metrical level '+str(i)+':'))
+			subdivision_seq.append(s)
+
+	if L_max > 2:
+		subdivision_seq = subdivision_seq + [2]*(L_max-2)
+	else:
+		subdivision_seq = subdivision_seq[0:L_max+1]
+	
+	return subdivision_seq
+
+
+def get_rhythm_category(sequence, subdivision_seq):
+	rhythm_category = 'mono'
+	for f in find_prime_factors(len(get_min_timeSpan(sequence))):
+		if not (f in subdivision_seq): 
+			rhythm_category = 'poly'
+			break
+	return rhythm_category
+
+
+ # The split_by_bar function seperates the score representation of rhythm by bar lines, 
+ # resulting in a list representingbar-by-bar rhythm sequence,
+ # e.g. rhythm = ['|',[ts1,td1,v1], [ts2,td2,v2], '|',[ts3,td3,v3],'|'...]
+ # rhythm_bybar = [ [ [ts1,td1,v1], [ts2,td2,v2] ], [ [ts3,td3,v3] ], [...]]
+# def split_by_bar(rhythm):
+# 	rhythm_bybar = []
+# 	bar_index = []
+# 	for index in range(len(rhythm)):
+# 		if rhythm[index] == '|':
+
+# 	return rhythm_bybar
+
+# def yseq_to_vseq(yseq):
+# 	vseq = []
+
+# 	return vseq
+
+
+# # testing
+# print find_prime_factors(10)
\ No newline at end of file
--- a/Syncopation models/main.py	Thu Apr 02 00:06:57 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-'''
-Author: Chunyang Song
-Institution: Centre for Digital Music, Queen Mary University of London
-
-'''
-
-
-def sync_perbar_permodel(seq, model, timesig = None, subdivision_seq = None, weight_seq = None, L_max = 5, prebar_seq = None, postbar_seq = None, strong_beat_level = None):
-	syncopation = None
-
-	if seq == None or model == None:
-		print 'Error: please indicate rhythm sequence and syncopation model.'
-
-	elif timesig == None and subdivision_seq == None:
-		print 'Error: please indicate either time signature or subdivision sequence.'
-	
-	else:
-		while subdivision_seq == None:
-			from BasicFuncs import get_subdivision_seq
-			subdivision_seq = get_subdivision_seq(timesig, L_max)
-
-		# The get_rhythm_category function is used to detect rhythm category: monorhythm or polyrhythm.
-		# For monorhythms, all prime factors of the length of minimum time-span representation of this sequence are
-		# elements of its subdivision_seq, otherwise it is polyrhythm; 
-		# e.g. prime_factors of polyrhythm 100100101010 in 4/4 is [2,3] but subdivision_seq = [1,2,2] for 4/4 
-		def get_rhythm_category():
-			rhythm_category = 'mono'
-			from BasicFuncs import get_min_timeSpan, find_prime_factors
-			for f in find_prime_factors(len(get_min_timeSpan(seq))):
-				if not (f in subdivision_seq): 
-					rhythm_category = 'poly'
-					break
-			return rhythm_category
-		
-		rhythm_category = get_rhythm_category()
-
-		if model == 'LHL':	
-			import LHL
-			if weight_seq == None:
-				weight_seq = range(0,-L_max,-1)
-			syncopation = LHL.get_syncopation(seq, subdivision_seq, weight_seq, prebar_seq, rhythm_category)
-		elif model == 'PRS':	
-			import PRS
-			syncopation = PRS.get_syncopation(seq, subdivision_seq, postbar_seq, rhythm_category)
-		elif model == 'TMC':	
-			import TMC
-			if weight_seq == None:
-				weight_seq = range(L_max+1,0,-1)
-			syncopation = TMC.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category)
-		elif model == 'SG':		
-			import SG
-			if weight_seq == None:
-				weight_seq = range(L_max+1)
-			syncopation = SG.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category)
-		elif model == 'KTH':
-			import KTH
-			syncopation = KTH.get_syncopation(seq, timesig, postbar_seq)
-		elif model == 'TOB':	
-			import TOB
-			syncopation = TOB.get_syncopation(seq)
-		elif model == 'WNBD':
-			import WNBD
-			if strong_beat_level == None:
-				if timesig == '4/4':
-					strong_beat_level = 2
-				else:
-					strong_beat_level = 1 
-			syncopation = WNBD.get_syncopation(seq, subdivision_seq, strong_beat_level, postbar_seq)
-
-		else:
-			print 'Error: undefined syncopation model.'
-
-	return syncopation
-
-# def syncopation_all(rhythm, model, timesig, subdivision_seq = None, weight_seq = None, L_max = 5, strong_beat_level = None):
-# 	syncopation = 0
-# 	# Chope rhythm into seq
-# 	# ...
-
-# 	for (seq_perbar in seq):
-# 		sync_perbar = syncopation_perbar(seq_perbar,model, timesig, subdivision_seq, weight_seq, L_max, strong_beat_level)
-# 		if sync_perbar != None:
-# 			syncopation = syncopation + sync_perbar
-
-# 	return syncopation
-
-
-### TESTING
-# clave = [1,0,0,1,0,0,1,0,0,0,1,0,1,0,0,0]
-# bf = [0,0,0,1,0,0,0,0,0,0,1,0]
-# rhythm = [0,1,0,1,0,1,0,1]
-# classic1 = [1,0,1,1]*3 + [1,0,0,0]
-# classic2 = [1,0,0,1]*3 + [1,0,0,0]
-# shiko = [1,0,1,1,0,1,1,0]
-# rumba = [1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,0]
-# soukous = [1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0]
-# gahu = [1,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0]
-# bossanova = [1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0]
-
-# classic12 = [1,0,0,1,1,1,1,0,0,1,1,1]
-# soli = [1,0,1,0,1,0,1,0,1,1,0,1]
-
-# print sync_perbar(seq = clave, model = 'WNBD', timesig = '4/4')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Syncopation models/music_objects.py	Fri Apr 03 11:41:01 2015 +0100
@@ -0,0 +1,104 @@
+
+from BasicFuncs import ceiling
+
+import ParameterSetter 
+import RhythmParser 
+
+class Note():
+	def __init__(self, argstring):
+		intlist = map(int,argstring.split(','))
+		self.startTime = intlist[0]
+		self.duration = intlist[1]
+		self.velocity = intlist[2]
+	
+	# toString()
+
+# NoteSequence is a list of Note
+class NoteSequence(list):
+	def __init__(self, noteSequenceString=None):
+		if noteSequenceString!=None:
+			self.string_to_note_sequence(noteSequenceString)
+
+	def string_to_note_sequence(self, noteSequenceString):
+		noteSequenceString = RhythmParser.discardSpaces(noteSequenceString)
+		# try:
+			# Turning "(1,2,3),(4,5,6),(7,8,9)" into ["1,2,3","4,5,6,","7,8,9"]
+		listStrings = noteSequenceString[1:-1].split("),(")
+		for localString in listStrings:
+			self.append(Note(localString))
+
+	# toString()
+
+
+print NoteSequence("(1,2,3),(4,5,6),(7,8,9)")
+# class VelocitySequence(list):
+# 	def __init__(self, noteSequenceString=None):
+# 		if noteSequenceString!=None:
+# 			self.string_to_note_sequence(noteSequenceString)
+
+# 	def string_to_note_sequence(string):
+
+
+class BarList(list):
+	def append(self,bar):
+		if(len(self)>0):
+			bar.set_previous_bar(self[-1])
+			self[-1].set_next_bar(bar)
+		super(BarList, self).append(bar)
+
+
+
+class Bar:
+
+	def __init__(self, rhythmSequence, timeSignature, ticksPerQuarter=None, qpmTempo=None, nextBar=None, prevBar=None):
+		if isinstance(rhythmSequence, NoteSequence):
+			self.noteSequence = rhythmSequence
+			self.velocitySequence = None 
+		elif isinstance(rhythmSequence, VelocitySequence):
+			self.velocitySequence = rhythmSequence
+			self.noteSequence = None 
+
+		self.tpq = ticksPerQuarter
+		self.qpm = qpmTempo
+		self.timeSignature = timeSignature
+		self.nextBar = nextBar
+		self.prevBar = prevBar
+
+	def get_note_sequence(self):
+		#if self.noteSequence==None:
+		#	self.noteSequence = velocitySequenceToNotes(self.velocitySequence)
+		return self.noteSequence
+
+	def get_velocity_sequence(self):
+		if self.velocitySequence==None:
+			self.velocitySequence = noteSequenceToVelocities(self.velocitySequence)
+		return self.velocitySequence
+
+	def get_binary_sequence(self):
+		return ceiling(self.get_velocity_sequence())
+
+	def get_next_bar(self):
+		return self.nextBar
+
+	def get_previous_bar(self):
+		return self.prevBar
+
+	def set_next_bar(self, bar):
+		self.nextBar = bar
+
+	def set_previous_bar(self, bar):
+		self.prevBar = bar		
+
+	def get_subdivision_sequence(self):
+		return ParameterSetter.get_subdivision_seq(self.timeSignature)
+
+	def get_beat_level(self):
+		return ParameterSetter.get_beat_level(self.timeSignature)
+
+	def get_time_signature(self):
+		return self.timeSignature
+
+	def get_t_span(self):
+		# return the length of a bar in time units
+		return None # NEED TO IMPLEMENT
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Syncopation models/parameter_setter.py	Fri Apr 03 11:41:01 2015 +0100
@@ -0,0 +1,90 @@
+'''
+Author: Chunyang Song
+Institution: Centre for Digital Music, Queen Mary University of London
+'''
+
+# Set the parameters: subdivision_seq, weight_seq, L_max, strong_beat_level
+
+L_max = 5
+
+# {'key': time-signature} :  
+# {'value': [subdivision_seq, theoretical beat-level represented by index in the subdivision_seq list]}
+timesigBase = {
+	'2/2': [[1,2,2,2,2],1],
+	'3/2': [[1,3,2,2,2],1],
+	'4/2': [[1,2,2,2,2],1],
+	'2/4': [[1,2,2,2,2],1],
+	'3/4': [[1,3,2,2,2],1],
+	'4/4': [[1,2,2,2,2],2],
+	'5/4': [[1,5,2,2,2],1],
+	'7/4': [[1,7,2,2,2],1],
+	'3/8': [[1,3,2,2,2],1],
+	'5/8': [[1,5,2,2,2],1],
+	'6/8': [[1,2,3,2,2],1],
+	'9/8': [[1,3,3,2,2],1],
+	'12/8':[[1,2,2,3,2],2],	
+}
+
+
+def addTimesig(timesig, subdivision_seq, beat_level):
+	if isTSValid(timesig,subdivision_seq,beat_level):
+		if timesig in timesigBase:
+			print 'This time-signature is existed already.'
+		else:
+			timesigBase[timesig] = [subdivision_seq, beat_level]
+			writeTimesig()
+
+def updateTimesig(timesig, subdivision_seq, beat_level):
+	if isTSValid(timesig,subdivision_seq,beat_level):
+		if timesig in timesigBase:
+			print 'Original settings for', timesig, ':',timesigBase[timesig] 
+			timesigBase[timesig] = [subdivision_seq, beat_level]
+			print 'Changed into:',timesigBase[timesig]
+			writeTimesig()
+
+def isTSValid(timesig, subdivision_seq, beat_level):
+	isValid = False
+	if ('/' not in timesig) or (not timesig.split('/')[0].isdigit()) or (not timesig.split('/')[1].isdigit()):
+		print 'Error: invalid time-signature. Please indicate in the form of fraction, e.g. 4/4, 6/8 or 3/4.'
+	elif subdivision_seq != [s for s in subdivision_seq if isinstance(s,int)]:
+		print 'Error: invalid subdivision sequence. Please indicate in the form of list of numbers, e.g [1,2,2,2,2].'
+	elif beat_level >= len(subdivision_seq):
+		print 'Error: beat-level exceeds the range of subdivision sequence list.'
+	else:
+		isValid = True
+	return isValid
+
+def writeTimesig():
+	import cPickle as pickle
+	timesigFile = open('TimeSignature.pkl', 'wb')
+	pickle.dump(timesigBase, timesigFile)
+	timesigFile.close()
+
+def readTimesig():
+	import cPickle as pickle
+	timesigFile = open('TimeSignature.pkl','rb')
+	data = pickle.load(timesigFile)
+	return data
+	timesigFile.close()
+
+def viewTimesigBase():
+	data = readTimesig()
+	for timesig, settings in data.items():
+		print timesig, settings
+
+def set_L_max(number):
+	L_max = number
+
+def get_subdivision_seq(timesig):
+	if timesig in readTimesig():
+		return timesigBase[timesig][0]
+	else:
+		print 'Error: the subdivision sequence for this time-signature is not defined.'
+		return None
+
+def get_beat_level(timesig):
+	if timesig in readTimesig():
+		return timesigBase[timesig][1]
+	else:
+		print 'Error: the subdivision sequence for this time-signature is not defined.'
+		return None
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Syncopation models/rhythm_parser.py	Fri Apr 03 11:41:01 2015 +0100
@@ -0,0 +1,106 @@
+'''
+Author: Chunyang Song
+Institution: Centre for Digital Music, Queen Mary University of London
+'''
+
+# Parse the rhythm file and return a list of Bar objects
+Piece = []
+
+from ParameterSetter import timesigBase
+
+
+comment_sign = '#'
+def discardComments(line):
+	if comment_sign in line:
+		line = line[0:line.find(comment_sign)]
+	return line
+
+def discardSpaces(line):
+	line = line.replace(" ", '').replace("\t", '')
+	return line
+
+def extractInfo(line):
+	try:
+		if '{' not in line and '}' not in line:
+			raise RhythmSyntaxError(line)
+		else:
+			return line[line.find('{')+1 : line.find('}')]
+	except RhythmSyntaxError:
+		print 'Rhythmic information needs to be enclosed by "{" and "}"'
+
+
+current_timesig = ''
+current_timesigValue = []
+def process(line):
+	try:
+		if 't' in line:
+			current_timesig = extractInfo(line)
+			if current_timesig in timesigBase:
+				current_timesigValue = timesigBase[current_timesig]
+			else:
+				raise NoTimesigError(current_timesig)
+		
+		elif 'v' in line:
+			if current_timesig == '':
+				raise InitialTimesigError(line)
+			else:
+				rhythmString = extractInfo(line)
+				rhythm_seq = map(int,rhythmString.split(','))
+				Piece.append(Bar(rhythm_seq, current_timesigValue[0], current_timesigValue[1]))
+		
+		else:
+			raise SymbolError(line)
+	
+	except InitialTimesigError:
+		print 'The initial time-signature is not given.'
+	except NoTimesigError:
+		print 'The time-signature is not recognised.'
+	except SymbolError:
+		print 'Unrecognised symbol.'
+
+
+def readRhythm(fileName):
+	try:
+		f = file(fileName)
+		
+		# Clean up each line by discarding comments and spaces; extract time-signature or sequence information
+		isfinished = False
+		while(not isfinished):
+			line = f.readline()
+			if len(line) == 0:
+				isfinished = True
+			else:
+				cleanline = discardSpaces(discardComments(line))
+				process(cleanline)
+
+		# Extract time-signature and rhythm sequence information
+
+	except IOError as e:
+		print "I/O error({0}): {1}".format(e.errno, e.strerror)
+	except:
+		print 'Unexpected error.'#, sys.exc_info()[0]
+
+# To check the 
+def isInfoValid(info):
+	# If two parts of information is not seperated by ;
+	# if 't' in info and 'q' in info:
+	# 	print 'Error: time-signature and rhythm sequence needs ";" to seperate. Please check this rhythm file: %s.' %fileName
+	# 	Piece = None
+	# 	break
+	# elif '{' not in info and '}' not in info:
+	# 	print 'Error: information needs to be enclosed by "{ }". Please check this rhythm file: %s.' %fileName
+	# 	Piece = None
+	# 	break				
+	# else:
+	return True			
+
+# To check whether the given time-signature is existed; if not then requires user to add in the new time-signature
+#def checkTimesig(input):
+
+
+# TESTING
+line = 't{4/4}	q{1,0,0,1,0,0,1,0,0,0,1,0,0.8,0,0,0} t{2/4} # This is a comment'
+# print discardSpaces(discardComments(line))
+print line[line.find('{')+1:line.find('}')]
+#print readRhythm("rhythmbase/testrhythm.txt")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Syncopation models/syncopation.py	Fri Apr 03 11:41:01 2015 +0100
@@ -0,0 +1,103 @@
+'''
+Author: Chunyang Song
+Institution: Centre for Digital Music, Queen Mary University of London
+
+'''
+
+
+def sync_perbar_permodel(seq, model, timesig = None, subdivision_seq = None, weight_seq = None, L_max = 5, prebar_seq = None, postbar_seq = None, strong_beat_level = None):
+	syncopation = None
+
+	if seq == None or model == None:
+		print 'Error: please indicate rhythm sequence and syncopation model.'
+
+	elif timesig == None and subdivision_seq == None:
+		print 'Error: please indicate either time signature or subdivision sequence.'
+	
+	else:
+		while subdivision_seq == None:
+			from BasicFuncs import get_subdivision_seq
+			subdivision_seq = get_subdivision_seq(timesig, L_max)
+
+		# The get_rhythm_category function is used to detect rhythm category: monorhythm or polyrhythm.
+		# For monorhythms, all prime factors of the length of minimum time-span representation of this sequence are
+		# elements of its subdivision_seq, otherwise it is polyrhythm; 
+		# e.g. prime_factors of polyrhythm 100100101010 in 4/4 is [2,3] but subdivision_seq = [1,2,2] for 4/4 
+		def get_rhythm_category():
+			rhythm_category = 'mono'
+			from BasicFuncs import get_min_timeSpan, find_prime_factors
+			for f in find_prime_factors(len(get_min_timeSpan(seq))):
+				if not (f in subdivision_seq): 
+					rhythm_category = 'poly'
+					break
+			return rhythm_category
+		
+		rhythm_category = get_rhythm_category()
+
+		if model == 'LHL':	
+			import LHL
+			if weight_seq == None:
+				weight_seq = range(0,-L_max,-1)
+			syncopation = LHL.get_syncopation(seq, subdivision_seq, weight_seq, prebar_seq, rhythm_category)
+		elif model == 'PRS':	
+			import PRS
+			syncopation = PRS.get_syncopation(seq, subdivision_seq, postbar_seq, rhythm_category)
+		elif model == 'TMC':	
+			import TMC
+			if weight_seq == None:
+				weight_seq = range(L_max+1,0,-1)
+			syncopation = TMC.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category)
+		elif model == 'SG':		
+			import SG
+			if weight_seq == None:
+				weight_seq = range(L_max+1)
+			syncopation = SG.get_syncopation(seq, subdivision_seq, weight_seq, L_max, rhythm_category)
+		elif model == 'KTH':
+			import KTH
+			syncopation = KTH.get_syncopation(seq, timesig, postbar_seq)
+		elif model == 'TOB':	
+			import TOB
+			syncopation = TOB.get_syncopation(seq)
+		elif model == 'WNBD':
+			import WNBD
+			if strong_beat_level == None:
+				if timesig == '4/4':
+					strong_beat_level = 2
+				else:
+					strong_beat_level = 1 
+			syncopation = WNBD.get_syncopation(seq, subdivision_seq, strong_beat_level, postbar_seq)
+
+		else:
+			print 'Error: undefined syncopation model.'
+
+	return syncopation
+
+# def syncopation_all(rhythm, model, timesig, subdivision_seq = None, weight_seq = None, L_max = 5, strong_beat_level = None):
+# 	syncopation = 0
+# 	# Chope rhythm into seq
+# 	# ...
+
+# 	for (seq_perbar in seq):
+# 		sync_perbar = syncopation_perbar(seq_perbar,model, timesig, subdivision_seq, weight_seq, L_max, strong_beat_level)
+# 		if sync_perbar != None:
+# 			syncopation = syncopation + sync_perbar
+
+# 	return syncopation
+
+
+### TESTING
+# clave = [1,0,0,1,0,0,1,0,0,0,1,0,1,0,0,0]
+# bf = [0,0,0,1,0,0,0,0,0,0,1,0]
+# rhythm = [0,1,0,1,0,1,0,1]
+# classic1 = [1,0,1,1]*3 + [1,0,0,0]
+# classic2 = [1,0,0,1]*3 + [1,0,0,0]
+# shiko = [1,0,1,1,0,1,1,0]
+# rumba = [1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,0]
+# soukous = [1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0]
+# gahu = [1,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0]
+# bossanova = [1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0]
+
+# classic12 = [1,0,0,1,1,1,1,0,0,1,1,1]
+# soli = [1,0,1,0,1,0,1,0,1,1,0,1]
+
+# print sync_perbar(seq = clave, model = 'WNBD', timesig = '4/4')