def find_best_note_distribution(self, args): best_file_name = None best_score = 0.0 reference = score.Score().load(args.reference) sys.stderr.write(args.reference.name + '\n') for filename in args.infile: if best_file_name is None: # Avoids returning empty values best_file_name = filename with open(filename, 'rb') as handler: a = score.Score().load(handler) n_est, n_ref, n_correct = self.evaluate(a, reference,\ args.onset_tolerance, args.duration_tolerance) r = float(n_correct) / n_ref p = float(n_correct) / n_est if (r + p) > 0: f = 2 * (r * p) / (r + p) else: f = 0.0 sys.stderr.write(filename + ': ' + str(r) + \ ', ' + str(p) + ', ' + str(f) + '\n') if f > best_score: best_score = f best_file_name = filename print best_file_name
def run(self, args): e = self.evaluate(args.id, score.Score().load(args.estimated), score.Score().load(args.reference), args.frame_length, False) e.metadata.estimated_input = md.FileMetadata(args.estimated) e.metadata.reference_input = md.FileMetadata(args.reference) e.save(args.outfile)
def run(self, args): e = self.evaluate(args.id, score.Score().load(args.estimated), score.Score().load(args.reference), args.onset_tolerance, args.duration_tolerance, args.ignore_pitch, False) e.metadata.estimated_input = md.FileMetadata(args.estimated) e.metadata.reference_input = md.FileMetadata(args.reference) e.save(args.outfile)
def eof(self): self.scores = {} for channel in self.channels.keys(): s = score.Score() for n in self.channels[channel].keys(): onsets = self.channels[channel][n]['onset'] offsets = self.channels[channel][n]['offset'] onsets.sort() offsets.sort() if len(onsets) != len(offsets): raise IOError, \ """Got different number of onsets and offsets for the same note.""" wrong_durations = [(off-on) < 0 for on,off in zip(onsets,offsets)] if any(wrong_durations): raise IOError, 'Got negative note durations.' s.append([note.Note(pitch=n, onset=on, offset=off) for on,off in zip(onsets,offsets)]) s.metadata.method_metadata = md.Metadata(type="midi") s.metadata.input = md.FileMetadata(self.file_handle) self.scores[channel] = s
def run(self, args): s = score.Score().load(args.infile) events = feats.event_list(s.data) histogram, lim = feats.rhythm_histogram(events, args.resolution) for i in xrange(args.resolution): print histogram[i], print " "
def run(self, args): new_s = self.trim_notes(score.Score().load(args.infile), args.minimum_duration, args.maximum_duration, args.minimum_pitch, args.maximum_pitch, args.minimum_onset, args.maximum_onset, args.minimum_offset, args.maximum_offset, False) new_s.metadata.input = md.FileMetadata(args.infile) new_s.save(args.outfile)
def find_best_note_distribution(self, args): best_file_name = None best_score = 9000000000 for filename in args.infile: if best_file_name is None: # Avoids returning empty values best_file_name = filename with open(filename, 'rb') as handler: a = sc.Score().load(handler) event_list = feats.event_list(a.data) if len(event_list) > 0: # Avoids empty scores (max_range, mean_range, std_range) = \ feats.relative_range(event_list) if max_range < best_score: best_score = max_range best_file_name = filename print best_file_name
def find_best_note_distribution(self, args): best_file_name = None best_score = 9000000000 for filename in args.infile: if best_file_name is None: # Avoids returning empty values best_file_name = filename with open(filename, 'rb') as handler: a = sc.Score().load(handler) if len(a.data) > 0: # Avoids empty scores pitchclass_histogram = feats.pitchclass_histogram(a.data) e = scipy.stats.entropy(pitchclass_histogram) if e < best_score: best_score = e best_file_name = filename print best_file_name
def run(self, args): s = score.Score().load(args.infile) histogram = feats.pitchclass_histogram(s.data, args.duration) if args.tonality is True: (tone, histogram) = feats.tonality(histogram) print tone, if args.statistics is True: h = numpy.array(histogram) print numpy.mean(h), print numpy.std(h), print numpy.sum(numpy.array([h[i] * numpy.log2(h[i])\ for i in xrange(len(h))\ if h[i] > 0])), for i in xrange(4): m = numpy.argmax(h) print m, h[m] = 0 for i in xrange(12): print histogram[i], print " "
def run(self, args): s = score.Score().load(args.infile) events = feats.event_list(s.data) histogram = feats.interval_histogram(events, args.fold,\ args.time_tolerance, args.duration) for i in xrange(args.fold): print histogram[i], if args.statistics is True: h = numpy.array(histogram) print numpy.mean(h), print numpy.std(h), print numpy.sum(numpy.array([h[i] * numpy.log2(h[i])\ for i in xrange(len(h))\ if h[i] > 0])), for i in xrange(4): m = numpy.argmax(h) print m, h[m] = 0 print " "
def run(self, args): args.outfile.writelines(self.convert(score.Score().load(args.infile)))
def run(self, args): s = score.Score().load(args.infile) events = feats.event_list(s.data) (maxRange, meanRange, devRange) = feats.relative_range(events,\ args.time_tolerance, args.duration) print maxRange, meanRange, devRange
def run(self, args): s = score.Score().load(args.infile) events = feats.event_list(s.data) (dMean, dDev, dMin, dMax) = feats.note_density(events) print dMean, dDev, dMin, dMax
def trim_notes(self, s, min_duration=0, max_duration=float('inf'), min_pitch=0, max_pitch=float('inf'), min_onset=0, max_onset=float('inf'), min_offset=0, max_offset=float('inf'), save_metadata=True): """Removes from a score notes that don't satisfy a criteria. Trims the transcription so notes that are out of the specified bonds will be cut out of the transcription. The notes aren't copied for the new Score, so any modification on them alters both the original and trimmed. This function is useful when you are trying to exclude notes that are obviously wrong in a certain transcription. By default, all arguments not provided don't cause any note to be removed. Args: s: Score object. min_duration: minimum duration to keep. Default: 0. max_duration: maximum duration to keep. Default: inf. min_pitch: minimum pitch to keep. Default: 0. max_pitch: maximum pitch to keep. Default: inf. min_onset: minimum onset to keep. Default: 0. max_onset: maximum onset to keep. Default: inf. min_offset: minimum offset to keep. Default: 0. max_offset: maximum offset to keep. Default: inf. save_metadata: flag indicating whether the metadata should be computed. Default: True. Returns: Trimmed Score object. """ new_s = score.Score() new_s.append([ n for n in s.data if n.data.duration >= min_duration and n.data.duration <= max_duration and n.data.onset >= min_onset and n.data.onset <= max_onset and n.data.offset >= min_offset and n.data.offset <= max_offset and n.data.pitch >= min_pitch and n.data.pitch <= max_pitch ]) new_s.metadata.instrument = s.metadata.instrument new_s.metadata.method_metadata = md.Metadata( type="trim", min_duration=min_duration, max_duration=max_duration, min_onset=min_onset, max_onset=max_onset, min_offset=min_offset, max_offset=max_offset, min_pitch=min_pitch, max_pitch=max_pitch, previous_method=s.metadata.method_metadata, previous_input=s.metadata.input) if save_metadata: s.metadata.input = md.ObjectMetadata(s) return new_s
def convert(self, d, instrument, frequency, minimum_length, save_metadata=True): """Converts an linear decomposition to a score. If the given frequency is 0, then the frequency becomes the one in the spectrogram used to compute the linear decomposition activation. Args: a: LinearDecomposition object with binary right side. instrument: name of the instrument to be extracted. frequency: frequency used to transfer activation time bins to timestamps. minimum_length: minimum length of note to be considered. save_metadata: flag indicating whether the metadata should be computed. Default: True. Returns: Score object. """ # Loads valid frequency to be used if frequency == 0.: ofs = d.metadata.get('sampling_configuration.ofs') else: ofs = float(frequency) s = score.Score() s.metadata.instrument = instrument if save_metadata: s.metadata.input = md.ObjectMetadata(d) s.metadata.method_metadata = \ md.Metadata(type='algorithm', algorithm='binary activation', frequency=ofs, minimum_length=minimum_length, activation_metadata=d.metadata.right) # TODO: check if this parameter really does what it's supposed to. # Currently it ignores zeros in the activation matrix once a not has # been detected and the minimum window haven't been found. minimum_window = minimum_length * ofs for k, data, metadata in d.right(): if k[0] != instrument: continue note_start = -1 activation = data # Considers only one line per note for now. TODO: consider more for t in range(activation.shape[1]): # Checks if starting a new note if activation[0, t] and note_start == -1: note_start = t # Checks for note ending elif not activation[0, t] and note_start != -1: # If minum length is met, adds note if t - note_start > minimum_window: s.append(note.Note(onset=note_start/float(ofs),\ offset=t/float(ofs), name=k[1])) # Marks note as finished note_start = -1 return s
def run(self, args): s = score.Score().load(args.infile) with MidiWriter(args.outfile) as mw: for n in s.data: mw.add_note(n)
def run(self, args): s = score.Score().load(args.infile) (min_note, max_note) = feats.range(s.data) print min_note, max_note
def plotList(score_file, width=400, height=300, roll_width=40, tLimits=None, nLimits=None, fontsize=14, color=(220, 220, 220), thickness=0.5, previousState=None): # This functions returns a Scene (see the svglib) that is a representation for the transcription. The parameters are: # width, height: the total width and height of the plot # roll_width: the width of the reference roll on the left. If you use 0, then you will see no reference keyboard # (it is very recommended that you don't do it, because, the keyboard is really cute!) # tLimits, nLimits: lists with two elements [a, b] specifying the limits within the piano roll will be plotted. If none is specified, uses the whole transcription # fontsize: the size of the font that will be used in the text # color, opacity: parameters that tells the color of the boxes that will be shown s = score.Score().load(score_file) if nLimits == None: minNote = s.data[0].data.pitch maxNote = s.data[0].data.pitch for n in s.data: if n.data.pitch < minNote: minNote = n.data.pitch if n.data.pitch > maxNote: maxNote = n.data.pitch minNote = minNote - 1 maxNote = maxNote + 1 else: minNote = int(nLimits[0]) maxNote = int(nLimits[1]) if tLimits == None: minT, maxT = s.get_timespan() else: minT = tLimits[0] maxT = tLimits[1] if maxT == minT: maxT = minT + 1 space_for_axis = fontsize * 2 space_per_note = (height - space_for_axis) / (maxNote - minNote + 1) space_per_second = (width - roll_width) / (maxT - minT) legendY = height - fontsize if previousState == None: canvas = Scene('svg', height, width) canvas = make_keyboard(canvas, roll_width, 0, fontsize, space_per_note, minNote, maxNote) canvas = make_time_divisions(canvas, roll_width, 0, fontsize, legendY, minT, maxT, space_per_second, 0.5) canvas = make_lanes(canvas, roll_width, 0, space_per_note, minNote, maxNote, space_per_second, minT, maxT) else: canvas = previousState for note in s.data: newnote = [note.data.onset, note.data.offset, int(note.data.pitch)] canvas = add_note(canvas, newnote, roll_width, 0, space_per_note, space_per_second, maxNote, minT, color, thickness) return canvas