def rapids(chord, time, instrument): """ Rapids event generator. Returns an odot bundle for the rapids engine. API: /engine : "rapids" /instrument : (string) -- instrument used /samples : (list) -- a list of samples for polybuffer~ /suffix : (string) -- filename suffix /time : (float) -- total time in seconds /events : (list of bundles) -- bundles containing all of the information to play back a list of samples, rapidly. """ # Figure out event times and update time if necessary: event_times, time = rapids_time(chord, time) # Figure out useful articulation categories: categories = [] for pitch in chord: categories.append(filterCategories(pitch, instrument, autocat[instrument])) # create a dictionary of sound queries to be resolved by getSamples: soundqueries = [{'pitch' : elem[0], 'artic': elem[1]} for elem in collect(chord, categories) if not(not elem[1])] # discard impossible notes (empty category) # execute the query, giving us the samples we'd need: seqfiles = [one(getSamples(sq['pitch'], instrument, sq['artic'])) for sq in soundqueries] print('-' * 100) print(len(soundqueries) == len(seqfiles)) print('-' * 100) # determine transposition ratios for sample playback: #correct = [pitch - ratio(sample['midi']) for sample in seqfiles] correct = [ratio(pair[0]['pitch'] - pair[1]['midi']) for pair in collect(soundqueries, seqfiles)] # filter redundant files: filenames = [e for e in set([sample['files'] for sample in seqfiles])] # determine the index of sample playback in polybuffer~: fileindices = [filenames.index(filename) + 1 for filename in [sq['files'] for sq in seqfiles]] # construct bundle: oengine = o.message('/engine', 'rapids') oinstr = o.message('/insturment', instrument) osamp = o.message('/samples', filenames) osuffix = o.message('/suffix', '_' + instrument + '_rapids.wav') otime = o.message('/time', time) events = [] for index, value in enumerate(fileindices): opitch = o.message('/pitch', correct[index]) obuffer = o.message('/buffer', instrument + '.rapids.' + str(value)) oeventtime = o.message('/event/time', event_times[index] + 0.02) events.append(o.bundle(messages = [opitch, obuffer, oeventtime])) oevents = o.message('/events', events) return o.bundle(messages = [oengine, oinstr, osamp, osuffix, otime, oevents])
def filterCategories(pitch, instrument, categories): """ Returns new list of categories that contain desired pitch. """ diffs = [min([abs(pitch - midi) for midi in SAMPLES[instrument][category]['midi']]) for category in categories] return [elem[0] for elem in collect(categories, diffs) if elem[1] < 7]