예제 #1
0
    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
예제 #2
0
 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)
예제 #3
0
 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)
예제 #4
0
    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
예제 #5
0
    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 " "
예제 #6
0
 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)
예제 #7
0
    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
예제 #8
0
    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
예제 #9
0
    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 " "
예제 #10
0
    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 " "
예제 #11
0
 def run(self, args):
     args.outfile.writelines(self.convert(score.Score().load(args.infile)))
예제 #12
0
 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
예제 #13
0
 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
예제 #14
0
    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
예제 #15
0
    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
예제 #16
0
    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)
예제 #17
0
 def run(self, args):
     s = score.Score().load(args.infile)
     (min_note, max_note) = feats.range(s.data)
     print min_note, max_note
예제 #18
0
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