Exemplo n.º 1
0
def match_one_midi(midi_file):
    '''
    Hash and match a single MIDI file against the MSD

    :parameters:
        - midi_file : str
            Path to a MIDI file to match
    '''
    # Get a beat-synchronous piano roll of the MIDI
    pm = pretty_midi.PrettyMIDI(midi_file)
    piano_roll = pm.get_piano_roll(times=pm.get_beats()).T
    piano_roll = piano_roll[np.newaxis, :, 36:84]
    # Make the piano roll look like it does when we trained the hasher
    piano_roll = (piano_roll - train_stats['mean'])/train_stats['std']
    hashed_piano_roll = hash(
        piano_roll[np.newaxis].astype(theano.config.floatX))
    # Compute hash sequence
    query = hash_match.vectors_to_ints(hashed_piano_roll > 0)
    query = query.astype('uint16')
    # Get indices of sequences which are within 40% -> 1/40% of this seq length
    valid_length_indices = hash_match.filter_by_length(query, sequences, .4)
    # Compute MIDI mean chroma vector
    query_chroma = pm.get_chroma().mean(axis=1)
    # Get sequences less than the mean chroma distance
    valid_chroma_indices = hash_match.filter_by_mean_chroma(
        query_chroma, mean_chromas, 20)
    # Intersect to get valid index set
    valid_indices = np.intersect1d(valid_length_indices, valid_chroma_indices)
    # Match the MIDI file query hash list against all sequences
    matches, scores = hash_match.match_one_sequence(
        query, sequences, .9, 4, valid_indices)
    return matches, scores
Exemplo n.º 2
0
def match_one_midi(midi_data, msd_match_indices):
    '''
    Match a MIDI sequence against the MSD and evaluate whether a good match was
    found

    :parameters:
        - midi_data : dict
            Dict of MIDI data, including mean chroma vector, hash sequence, etc
        - msd_match_indices : list-like of int
            indices of entries in the MSD this MIDI should potentially match to

    :returns:
        - results : dict
            Dictionary with diagnostics about whether this match was successful
    '''
    # Match this MIDI sequence against MSD sequences
    matches, scores, n_pruned_dist = hash_match.match_one_sequence(
        midi_data['hash_list'], sequences, GULLY, PENALTY)
    # Store results of the match
    results = {}
    results['midi_md5'] = midi_data['md5']
    results['msd_match_ids'] = [data[n]['id'] for n in msd_match_indices]
    # Compile the rank and score for each MSD entry which should match the MIDI
    matched_ranks = []
    matched_scores = []
    for msd_index in msd_match_indices:
        # If it was pruned by mean chroma/length pruning, compute manually
        if msd_index not in matches:
            _, score, _ = hash_match.match_one_sequence(
                midi_data['hash_list'], [sequences[msd_index]], GULLY, PENALTY)
            score = score[0]
            rank = (scores < score).sum()
        # Otherwise find the result
        else:
            rank = matches.index(msd_index)
            score = scores[rank]
        matched_ranks.append(rank)
        matched_scores.append(score)
    results['msd_match_ranks'] = matched_ranks
    results['msd_match_scores'] = matched_scores
    results['n_pruned_dist'] = n_pruned_dist

    return results