csong@9: ''' csong@35: Authors: Chunyang Song, Christopher Harte csong@9: Institution: Centre for Digital Music, Queen Mary University of London csong@9: ''' csong@9: csong@9: # Parse the rhythm file and return a list of Bar objects christopher@29: #Piece = [] csong@9: csong@20: from parameter_setter import timeSignatureBase christopher@29: from music_objects import * csong@9: csong@9: comment_sign = '#' christopher@38: christopher@29: def discard_comments(line): csong@9: if comment_sign in line: csong@9: line = line[0:line.find(comment_sign)] csong@9: return line csong@9: christopher@29: def discard_spaces(line): csong@9: line = line.replace(" ", '').replace("\t", '') csong@9: return line csong@9: csong@35: # def extractInfo(line): csong@35: # try: csong@35: # if '{' not in line and '}' not in line: csong@35: # raise RhythmSyntaxError(line) csong@35: # else: csong@35: # return line[line.find('{')+1 : line.find('}')] csong@35: # except RhythmSyntaxError: csong@35: # print 'Rhythmic information needs to be enclosed by "{" and "}"' csong@9: christopher@29: christopher@29: def read_rhythm(fileName): christopher@29: fileContent = file(fileName) christopher@29: christopher@29: barList = BarList() christopher@29: christopher@29: tempo=None christopher@29: timeSignature=None christopher@29: ticksPerQuarter=None christopher@29: christopher@29: # for each line in the file, parse the line and add any christopher@29: # new bars to the main bar list for the piece christopher@29: for line in fileContent: christopher@29: christopher@29: # ignore the line if it's only a comment christopher@29: if is_comment(line) or line=="\n": christopher@29: continue christopher@29: christopher@29: # if time signature has not yet been set then it should be the first christopher@29: # thing we find in a file after the comments at the top christopher@29: if timeSignature==None: christopher@29: (field, line) = get_next_field(line) christopher@29: # if there is a valid field, it should be a time signature christopher@29: if field!=None: christopher@29: [fieldname,value] = field christopher@29: if fieldname=="t": christopher@29: timeSignature = TimeSignature(value) christopher@29: else: christopher@29: print 'Error, first field in the file should set the time signature.' christopher@29: christopher@29: # parse the line christopher@29: (newbarlist, tempo, timeSignature, ticksPerQuarter) = parse_line(line, timeSignature, tempo, ticksPerQuarter) christopher@29: christopher@29: # if we found some bars in this line then add them to the overall bar list christopher@29: if len(newbarlist)>0: christopher@29: barList.concat(newbarlist) christopher@29: christopher@29: return barList christopher@29: christopher@29: def is_comment(line): csong@35: if discard_spaces(line)[0]==comment_sign: christopher@29: return True christopher@29: else: christopher@29: return False christopher@29: christopher@29: def parse_line(line, timeSignature=None, tempo=None, ticksPerQuarter=None): christopher@29: christopher@29: #strip the line of spaces and comments christopher@29: line = discard_spaces(discard_comments(line)).replace("\n","") christopher@29: christopher@29: bars = BarList() christopher@29: christopher@29: #work through each field in the line christopher@29: while len(line)>0: christopher@29: (field, line) = get_next_field(line) christopher@29: christopher@29: if field!=None: christopher@29: christopher@29: [fieldname, value] = field christopher@29: christopher@29: if fieldname.lower() == "v": christopher@29: #velocity sequence christopher@29: bar = Bar(VelocitySequence(value),timeSignature, ticksPerQuarter, tempo) christopher@29: bars.append(bar) christopher@29: christopher@29: elif fieldname.lower() == "y": christopher@29: #note sequence christopher@29: bar = Bar(NoteSequence(value), timeSignature, ticksPerQuarter, tempo) christopher@29: bars.append(bar) christopher@29: christopher@29: elif fieldname.lower() == "t": christopher@29: #time signature christopher@29: timeSignature = TimeSignature(value) christopher@29: christopher@29: elif fieldname.lower() == "tpq": christopher@29: #ticks per quarter christopher@29: ticksPerQuarter = int(value) christopher@29: christopher@29: elif fieldname.lower() == "qpm": christopher@29: #tempo christopher@29: tempo = int(value) christopher@29: csong@9: else: christopher@29: print 'Unrecognised field type: "' + fieldname + '"' csong@9: christopher@29: return bars, tempo, timeSignature, ticksPerQuarter csong@9: csong@9: christopher@29: def get_next_field(line): christopher@29: index = line.find("}") christopher@29: field = None christopher@29: if index>=0: christopher@29: fieldtext = line[:index] christopher@29: line = line[index+1:] christopher@29: field = fieldtext.split("{") christopher@29: else: christopher@29: print 'Error, incorrect syntax: "'+line+'"' christopher@29: #raise RhythmSyntaxError(line) csong@9: christopher@29: return field,line csong@9: csong@9: csong@9: csong@9: csong@9: