csong@9: ''' csong@9: Author: Chunyang Song csong@9: Institution: Centre for Digital Music, Queen Mary University of London csong@9: csong@9: ''' christopher@38: from rhythm_parser import * christopher@38: from music_objects import * christopher@38: csong@9: csong@35: def sync_perbar_permodel (model, bar, parameters=None): csong@21: return model.get_syncopation(bar, parameters) csong@9: christopher@38: def syncopation_barlist_permodel(model, source, parameters=None): christopher@38: total = 0.0 christopher@38: barResults = [] csong@23: numberOfNotes = 0 csong@28: christopher@38: barlist = None christopher@38: christopher@38: if isinstance(source, BarList): christopher@38: barlist = source christopher@38: sourceType = "bar list" christopher@38: elif isinstance(source, basestring): christopher@38: #treat source as a filename christopher@38: sourceType = source christopher@38: if source[-4:]==".mid": christopher@38: import readmidi christopher@38: midiFile = readmidi.read_midi_file(source) christopher@38: barlist = readmidi.get_bars_from_midi(midiFile) christopher@38: christopher@38: elif source[-4:]==".rhy": christopher@38: #import rhythm_parser christopher@38: barlist = read_rhythm(source) christopher@38: else: christopher@38: print "Error in syncopation_barlist_permodel(): Unrecognised file type." christopher@38: else: christopher@38: print "Error in syncopation_barlist_permodel(): unrecognised source type." csong@35: christopher@38: barsDiscarded=0 csong@28: christopher@38: if barlist!=None: christopher@38: for bar in barlist: christopher@38: if not bar.is_empty(): christopher@38: barSyncopation = sync_perbar_permodel(model, bar, parameters) christopher@38: else: christopher@38: barSyncopation = None christopher@38: print 'Bar %d cannot be measured because it is empty, returning None.' % barlist.index(bar) christopher@38: christopher@38: barResults.append(barSyncopation) christopher@38: if barSyncopation != None: christopher@38: total += barSyncopation christopher@38: numberOfNotes += sum(bar.get_binary_sequence()) christopher@38: else: christopher@38: barsDiscarded += 1 christopher@38: print 'Model could not measure bar %d, returning None.' % barlist.index(bar) csong@23: christopher@38: import WNBD christopher@38: if model is WNBD: christopher@38: total = total / numberOfNotes csong@9: christopher@38: average = total / (len(barResults)-barsDiscarded) csong@9: christopher@38: return {"summed_syncopation":total, "average_syncopation_per_bar":average, "source":sourceType, "number_of_bars":len(barResults), "number_of_bars_not_measured":barsDiscarded, "syncopation_by_bar":barResults} csong@21: csong@9: csong@9: christopher@38: def results_to_xml(results, outputFilename): christopher@38: from xml.etree.ElementTree import Element, ElementTree csong@9: christopher@38: elem = Element("syncopation_results") csong@9: christopher@38: for key, val in results.items(): christopher@38: child = Element(key) christopher@38: child.text = str(val) christopher@38: elem.append(child) csong@9: christopher@38: ElementTree(elem).write(outputFilename) csong@9: csong@9: