class MusicStand(object): """ An intelligent digital music stand. """ def __init__(self, algorithm, listener, profile, interpreter, debug=False): self._matcher = Matcher(algorithm, interpreter, self._position_changed, debug) self._capturer = Capturer(listener, self._handle_buckets) self._display = None self._running = False self._debug = debug def run(self): """ Runs the music stand. This method will not return until the application exits. """ callbacks = dict(song_loaded=self._start_song, song_stopped=self._abort_song, song_restarted=self._restart_song) self._capturer.start() # also starts the listener self._matcher.start() try: self._running = True root = Tk() self._display = Display(root, callbacks, self._debug) # run the Tkinter event loop root.mainloop() except KeyboardInterrupt: print finally: self._running = False self._matcher.shutdown() self._capturer.stop() # similarly, also stops the listener def _start_song(self, lilypond_file): if self._debug: print 'Song loaded: %s' % lilypond_file notes = parse_file(lilypond_file) self._matcher.load_piece(notes) def _abort_song(self): self._matcher.stop_piece() def _restart_song(self): self._display.reset_song_positions() self._display.reset_sheetmusic() self._matcher.restart_piece() def _handle_buckets(self, buckets): # XXX: this is dumb notes = [p[0] for p in sorted(buckets, key=lambda b: b[1], reverse=True)] self._matcher.add(notes) def _position_changed(self, matcher): if matcher.intervals is None: return self._display.update_position(matcher) if matcher.current_location >= (len(matcher.intervals) - 1): if self._debug: print 'Done with the piece!'
fingerprints = create_fingerprints(capturer, target, harmonics) if not (fingerprints and profile): continue if options.replace: for peak_note, notes in profile.peaks.iteritems(): while True: index = find_note(notes, target) if index < 0: break del notes[index] for fingerprint in fingerprints: if not fingerprint: continue peak_note = max((pair for pair in fingerprint.iteritems()), key=lambda (n, i): i)[0] if peak_note not in profile.peaks: profile.peaks[peak_note] = [] profile.peaks[peak_note].append((target, fingerprint)) except RuntimeError, e: # yeah, this is abuse of exceptions... I don't care print e.args[0] else: if profile: profile.save() finally: capturer.stop()