annotate Syncopation models/rhythm_parser.py @ 42:121d0e1f1748

Added the R plots
author csong <csong@eecs.qmul.ac.uk>
date Thu, 23 Apr 2015 22:08:48 +0100
parents cc38b3047ed9
children 6371e8f21f7d
rev   line source
csong@9 1 '''
csong@35 2 Authors: Chunyang Song, Christopher Harte
csong@9 3 Institution: Centre for Digital Music, Queen Mary University of London
csong@9 4 '''
csong@9 5
csong@9 6 # Parse the rhythm file and return a list of Bar objects
christopher@29 7 #Piece = []
csong@9 8
csong@20 9 from parameter_setter import timeSignatureBase
christopher@29 10 from music_objects import *
csong@9 11
csong@9 12 comment_sign = '#'
christopher@38 13
christopher@29 14 def discard_comments(line):
csong@9 15 if comment_sign in line:
csong@9 16 line = line[0:line.find(comment_sign)]
csong@9 17 return line
csong@9 18
christopher@29 19 def discard_spaces(line):
csong@9 20 line = line.replace(" ", '').replace("\t", '')
csong@9 21 return line
csong@9 22
csong@35 23 # def extractInfo(line):
csong@35 24 # try:
csong@35 25 # if '{' not in line and '}' not in line:
csong@35 26 # raise RhythmSyntaxError(line)
csong@35 27 # else:
csong@35 28 # return line[line.find('{')+1 : line.find('}')]
csong@35 29 # except RhythmSyntaxError:
csong@35 30 # print 'Rhythmic information needs to be enclosed by "{" and "}"'
csong@9 31
christopher@29 32
christopher@29 33 def read_rhythm(fileName):
christopher@29 34 fileContent = file(fileName)
christopher@29 35
christopher@29 36 barList = BarList()
christopher@29 37
christopher@29 38 tempo=None
christopher@29 39 timeSignature=None
christopher@29 40 ticksPerQuarter=None
christopher@29 41
christopher@29 42 # for each line in the file, parse the line and add any
christopher@29 43 # new bars to the main bar list for the piece
christopher@29 44 for line in fileContent:
christopher@29 45
christopher@29 46 # ignore the line if it's only a comment
christopher@29 47 if is_comment(line) or line=="\n":
christopher@29 48 continue
christopher@29 49
christopher@29 50 # if time signature has not yet been set then it should be the first
christopher@29 51 # thing we find in a file after the comments at the top
christopher@29 52 if timeSignature==None:
christopher@29 53 (field, line) = get_next_field(line)
christopher@29 54 # if there is a valid field, it should be a time signature
christopher@29 55 if field!=None:
christopher@29 56 [fieldname,value] = field
christopher@29 57 if fieldname=="t":
christopher@29 58 timeSignature = TimeSignature(value)
christopher@29 59 else:
christopher@29 60 print 'Error, first field in the file should set the time signature.'
christopher@29 61
christopher@29 62 # parse the line
christopher@29 63 (newbarlist, tempo, timeSignature, ticksPerQuarter) = parse_line(line, timeSignature, tempo, ticksPerQuarter)
christopher@29 64
christopher@29 65 # if we found some bars in this line then add them to the overall bar list
christopher@29 66 if len(newbarlist)>0:
christopher@29 67 barList.concat(newbarlist)
christopher@29 68
christopher@29 69 return barList
christopher@29 70
christopher@29 71 def is_comment(line):
csong@35 72 if discard_spaces(line)[0]==comment_sign:
christopher@29 73 return True
christopher@29 74 else:
christopher@29 75 return False
christopher@29 76
christopher@29 77 def parse_line(line, timeSignature=None, tempo=None, ticksPerQuarter=None):
christopher@29 78
christopher@29 79 #strip the line of spaces and comments
christopher@29 80 line = discard_spaces(discard_comments(line)).replace("\n","")
christopher@29 81
christopher@29 82 bars = BarList()
christopher@29 83
christopher@29 84 #work through each field in the line
christopher@29 85 while len(line)>0:
christopher@29 86 (field, line) = get_next_field(line)
christopher@29 87
christopher@29 88 if field!=None:
christopher@29 89
christopher@29 90 [fieldname, value] = field
christopher@29 91
christopher@29 92 if fieldname.lower() == "v":
christopher@29 93 #velocity sequence
christopher@29 94 bar = Bar(VelocitySequence(value),timeSignature, ticksPerQuarter, tempo)
christopher@29 95 bars.append(bar)
christopher@29 96
christopher@29 97 elif fieldname.lower() == "y":
christopher@29 98 #note sequence
christopher@29 99 bar = Bar(NoteSequence(value), timeSignature, ticksPerQuarter, tempo)
christopher@29 100 bars.append(bar)
christopher@29 101
christopher@29 102 elif fieldname.lower() == "t":
christopher@29 103 #time signature
christopher@29 104 timeSignature = TimeSignature(value)
christopher@29 105
christopher@29 106 elif fieldname.lower() == "tpq":
christopher@29 107 #ticks per quarter
christopher@29 108 ticksPerQuarter = int(value)
christopher@29 109
christopher@29 110 elif fieldname.lower() == "qpm":
christopher@29 111 #tempo
christopher@29 112 tempo = int(value)
christopher@29 113
csong@9 114 else:
christopher@29 115 print 'Unrecognised field type: "' + fieldname + '"'
csong@9 116
christopher@29 117 return bars, tempo, timeSignature, ticksPerQuarter
csong@9 118
csong@9 119
christopher@29 120 def get_next_field(line):
christopher@29 121 index = line.find("}")
christopher@29 122 field = None
christopher@29 123 if index>=0:
christopher@29 124 fieldtext = line[:index]
christopher@29 125 line = line[index+1:]
christopher@29 126 field = fieldtext.split("{")
christopher@29 127 else:
christopher@29 128 print 'Error, incorrect syntax: "'+line+'"'
christopher@29 129 #raise RhythmSyntaxError(line)
csong@9 130
christopher@29 131 return field,line
csong@9 132
csong@9 133
csong@9 134
csong@9 135
csong@9 136