Mercurial > hg > syncopation-dataset
diff Syncopation models/syncopation.py @ 38:cc38b3047ed9
updated syncopation.y to allow output of sync for a bar list
also fixed some problems in models and other modules
author | christopherh <christopher.harte@eecs.qmul.ac.uk> |
---|---|
date | Mon, 13 Apr 2015 23:06:49 +0100 |
parents | 3a878de00d19 |
children | 6371e8f21f7d |
line wrap: on
line diff
--- a/Syncopation models/syncopation.py Mon Apr 13 22:36:51 2015 +0100 +++ b/Syncopation models/syncopation.py Mon Apr 13 23:06:49 2015 +0100 @@ -3,102 +3,77 @@ Institution: Centre for Digital Music, Queen Mary University of London ''' +from rhythm_parser import * +from music_objects import * + def sync_perbar_permodel (model, bar, parameters=None): return model.get_syncopation(bar, parameters) - def syncopation_barlist_permodel(model, source, parameters=None): - total = 0 +def syncopation_barlist_permodel(model, source, parameters=None): + total = 0.0 + barResults = [] numberOfNotes = 0 + barlist = None + + if isinstance(source, BarList): + barlist = source + sourceType = "bar list" + elif isinstance(source, basestring): + #treat source as a filename + sourceType = source + if source[-4:]==".mid": + import readmidi + midiFile = readmidi.read_midi_file(source) + barlist = readmidi.get_bars_from_midi(midiFile) + + elif source[-4:]==".rhy": + #import rhythm_parser + barlist = read_rhythm(source) + else: + print "Error in syncopation_barlist_permodel(): Unrecognised file type." + else: + print "Error in syncopation_barlist_permodel(): unrecognised source type." + barsDiscarded=0 - for bar in barlist: - if sync_perbar_permodel(model, bar, parameters) != None: - total += sync_perbar_permodel(model, bar, parameters) - numberOfNotes += sum(bar.get_binary_sequence()) - else: - print 'Bar %d cannot be measured, returning None.' % barlist.index(bar) + if barlist!=None: + for bar in barlist: + if not bar.is_empty(): + barSyncopation = sync_perbar_permodel(model, bar, parameters) + else: + barSyncopation = None + print 'Bar %d cannot be measured because it is empty, returning None.' % barlist.index(bar) + + barResults.append(barSyncopation) + if barSyncopation != None: + total += barSyncopation + numberOfNotes += sum(bar.get_binary_sequence()) + else: + barsDiscarded += 1 + print 'Model could not measure bar %d, returning None.' % barlist.index(bar) - if model is WNBD: - total = (float) total/ numberOfNotes + import WNBD + if model is WNBD: + total = total / numberOfNotes -# 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 + average = total / (len(barResults)-barsDiscarded) -# if seq == None or model == None: -# print 'Error: please indicate rhythm sequence and syncopation model.' + 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} -# elif timesig == None and subdivision_seq == None: -# print 'Error: please indicate either time signature or subdivision sequence.' - -# else: -# while subdivision_seq == None: -# from basic_functions 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 basic_functions 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) +def results_to_xml(results, outputFilename): + from xml.etree.ElementTree import Element, ElementTree -# else: -# print 'Error: undefined syncopation model.' + elem = Element("syncopation_results") -# return syncopation + for key, val in results.items(): + child = Element(key) + child.text = str(val) + elem.append(child) -# 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 -# # ... + ElementTree(elem).write(outputFilename) -# 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 -