annotate Syncopation models/rhythm_parser.py @ 35:3a878de00d19

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