예제 #1
0
def align_tracks(pr0, pr1, unit_type, gapopen, gapextend):
    # Get trace from needleman_wunsch algorithm

    # First extract binary representation, whatever unit_type is
    pr0_trace = sum_along_instru_dim(
        Unit_type.from_type_to_binary(pr0, unit_type))
    pr1_trace = sum_along_instru_dim(
        Unit_type.from_type_to_binary(pr1, unit_type))

    # Traces are computed from binaries matrices
    # Traces are binary lists, 0 meaning a gap is inserted
    trace_0, trace_1, this_sum_score, this_nbId, this_nbDiffs = needleman_chord_wrapper(
        pr0_trace, pr1_trace, gapopen, gapextend)

    ####################################
    # Wrap dictionnaries according to the traces
    assert (len(trace_0) == len(trace_1)), "size mismatch"
    pr0_warp = warp_dictionnary_trace(pr0, trace_0)
    pr1_warp = warp_dictionnary_trace(pr1, trace_1)

    ####################################
    # Trace product
    trace_prod = [e1 * e2 for (e1, e2) in zip(trace_0, trace_1)]
    duration = sum(trace_prod)
    if duration == 0:
        return [None] * 5
    # Remove gaps
    pr0_aligned = remove_zero_in_trace(pr0_warp, trace_prod)
    pr1_aligned = remove_zero_in_trace(pr1_warp, trace_prod)

    return pr0_aligned, trace_0, pr1_aligned, trace_1, trace_prod, duration
예제 #2
0
def remove_match_silence(pr0, pr1):
    # Detect problems
    flat_0 = sum_along_instru_dim(pr0).sum(axis=1)
    flat_1 = sum_along_instru_dim(pr1).sum(axis=1)
    ind_clean = np.where(np.logical_not((flat_0 == 0) & (flat_1 == 0)))[0]

    def keep_clean(pr, ind_clean):
        pr_out = {}
        for k, v in pr.iteritems():
            pr_out[k] = v[ind_clean]
        return pr_out

    pr0_clean = keep_clean(pr0, ind_clean)
    pr1_clean = keep_clean(pr1, ind_clean)
    duration = len(ind_clean)

    return pr0_clean, pr1_clean, duration
    def file_processing(path, quantization, clip):
        if re.search(r'.*\.mid$', path):
            reader_midi = Read_midi(path, quantization)
            # Read midi
            pianoroll = reader_midi.read_file()
        elif re.search(r'.*\.xml$', path):
            pianoroll, articulation, staccato_curve = mxml_to_pr(
                path, quantization)
            pr = sum_along_instru_dim(pianoroll)
            arti = sum_along_instru_dim(articulation)
            stacc = sum_along_instru_dim(staccato_curve)
        else:
            raise Exception("invalid extension {}, use either mid or xml")

        # Clip
        if clip:
            pianoroll = clip_pr(pianoroll)
        return pianoroll, get_pianoroll_time(pianoroll)
예제 #4
0
def visualize_dict(pr, path, file_name_no_extension, time_indices=None):
    if not os.path.exists(path):
        os.makedirs(path)
    AAA = sum_along_instru_dim(pr)
    if time_indices:
        start_time, end_time = time_indices
        AAA = AAA[start_time:end_time, :]
    temp_csv = path + '/' + file_name_no_extension + '.csv'
    np.savetxt(temp_csv, AAA, delimiter=',')
    dump_to_csv(temp_csv, temp_csv)
    write_numpy_array_html(
        path + '/' + file_name_no_extension + ".html",
        file_name_no_extension,
        d3js_source_path=
        '/Users/leo/Recherche/GitHub_Aciditeam/acidano/acidano/visualization/d3.v3.min.js'
    )
예제 #5
0
def remove_silence(pr):
    # Detect silences
    flat = sum_along_instru_dim(pr).sum(axis=1)
    ind_clean = np.where(np.logical_not(flat == 0))[0]

    def keep_clean(pr, ind_clean):
        pr_out = {}
        for k, v in pr.iteritems():
            pr_out[k] = v[ind_clean]
        return pr_out
    pr_clean = keep_clean(pr, ind_clean)

    mapping = np.zeros((flat.shape[0]), dtype=np.int) - 1
    counter = 0
    for elem in ind_clean:
        mapping[elem] = counter
        counter += 1

    return pr_clean, mapping
예제 #6
0
def process_folder_NP(folder_path, quantization, binary_piano, binary_orch,
                      temporal_granularity):
    """Get the pianoroll from a folder path with containing only an orchestral score. 
    Piano score is created by simply crushing all the instruments on 88 pitches
    """
    # Get instrus and prs from a folder name name
    pr_orch, instru_orch, T, name = get_instru_and_pr_from_folder_path_NP(
        folder_path, quantization)
    # Create the piano score
    pr_piano = {'Piano': sum_along_instru_dim(pr_orch)}
    # Process the two files (remember that even in this context, piano can be real-valued and orchestra discrete)
    pr_piano = process_data_piano(pr_piano, binary_piano)
    pr_orch = process_data_orch(pr_orch, binary_orch)

    # Temporal granularity (use only orchestra to compute events)
    if temporal_granularity == 'event_level':
        event_orch = get_event_ind_dict(pr_orch)
        T = len(event_orch)

        def get_duration(event, last_time):
            start_ind = event[:]
            end_ind = np.zeros(event.shape, dtype=np.int)
            end_ind[:-1] = event[1:]
            end_ind[-1] = last_time
            duration_list = end_ind - start_ind
            return duration_list

        duration_orch = get_duration(event_orch, T)
        # Get the duration of each event
        pr_orch = warp_pr_aux(pr_orch, event_orch)
        pr_piano = warp_pr_aux(pr_piano, event_orch)
    else:
        event_orch = None

    # Fill identical values
    event_piano = event_orch
    duration_piano = duration_orch
    instru_piano = {'Piano': 'Piano'}
    name_piano = name

    return pr_piano, event_piano, duration_piano, instru_piano, name_piano, pr_orch, event_orch, duration_orch, instru_orch, name, T
예제 #7
0
def get_number_of_file_per_composer(files):

    dict_orch = {}
    dict_piano = {}
    T_orch = 0
    T_piano = 0

    for file in files:
        with open(file, 'rb') as csvfile:
            spamreader = csv.DictReader(csvfile,
                                        delimiter=';',
                                        fieldnames=[
                                            "id", "path", "orch_composer",
                                            "orch_song", "orch_audio_path",
                                            "solo_composer", "solo_song",
                                            "solo_audio_path"
                                        ])
            # Avoid header
            spamreader.next()
            for row in spamreader:
                # Name and path
                orch_composer = row['orch_composer']
                piano_composer = row['solo_composer']
                path = DATABASE_PATH + '/' + row['path']
                # Get instrus and prs from a folder name name
                pr0, instru0, T0, name0, pr1, instru1, T1, name1 = get_instru_and_pr_from_folder_path(
                    folder_path, quantization)

                pr_piano, _, _, _, pr_orch, _, _, _=\
                    discriminate_between_piano_and_orchestra(pr0, instru0, T0, name0, pr1, instru1, T1, name1)

                if (pr_piano == None) or (pr_orch == None):
                    print("Skipping " + path)
                    continue

                try:
                    length_piano = len(sum_along_instru_dim(pr_piano))
                    length_orch = len(sum_along_instru_dim(pr_orch))
                except:
                    import pdb
                    pdb.set_trace()

                if orch_composer in dict_orch.keys():
                    dict_orch[orch_composer]['num_file'] += 1
                    dict_orch[orch_composer]['relative_length'] += length_orch
                else:
                    dict_orch[orch_composer] = {}
                    dict_orch[orch_composer]['num_file'] = 1
                    dict_orch[orch_composer]['relative_length'] = length_orch
                T_orch += length_orch

                if piano_composer in dict_piano.keys():
                    dict_piano[piano_composer]['num_file'] += 1
                    dict_piano[piano_composer][
                        'relative_length'] += length_piano
                else:
                    dict_piano[piano_composer] = {}
                    dict_piano[piano_composer]['num_file'] = 1
                    dict_piano[piano_composer][
                        'relative_length'] = length_piano
                T_piano += length_piano

    for k, v in dict_orch.iteritems():
        dict_orch[k]['relative_length'] = (
            100 * dict_orch[k]['relative_length'] + 0.) / T_orch
    for k, v in dict_piano.iteritems():
        dict_piano[k]['relative_length'] = (
            100 * dict_piano[k]['relative_length'] + 0.) / T_piano

    # Merge the two dictionnaries
    merge_dict = {}
    for k, v in dict_piano.iteritems():
        merge_dict[k] = {
            'relative_length_piano': v['relative_length'],
            'relative_length_orch': None,
            'num_file_piano': v['num_file'],
            'num_file_orch': None,
        }

    for k, v in dict_orch.iteritems():
        if k in merge_dict.keys():
            merge_dict[k]['relative_length_orch'] = v['relative_length']
            merge_dict[k]['num_file_orch'] = v['num_file']
        else:
            merge_dict[k] = {
                'relative_length_piano': None,
                'relative_length_orch': v['relative_length'],
                'num_file_piano': None,
                'num_file_orch': v['num_file'],
            }

    # Replace '' by unknown
    merge_dict['unknown'] = merge_dict.pop('', None)
    merge_dict_name = {}
    for k, v in merge_dict.iteritems():
        name_list = re.split(' ', k)
        new_name = name_list[-1] + '. ' + ' '.join(name_list[:-1])
        merge_dict_name[new_name] = v
    merge_dict = merge_dict_name

    # write a csv file containing these information
    def float_to_string(s):
        return '' if s is None else "{:2.2f}".format(s)

    def format_none(s):
        return '' if s is None else "{}".format(s)

    with open('stat_composer.csv', 'wb') as f:
        f.write("composer,numpiano,percentagepiano,numorch,percentageorch\n")
        for k, v in sorted(merge_dict.items()):
            # f.write("{};{};{:2.2f};{};{:2.2f}".format(k, v['num_file_piano'], v['relative_length_piano'], v['num_file_orch'], v['relative_length_orch']))
            f.write("{},{},{},{},{}\n".format(
                format_none(k).title(), format_none(v['num_file_piano']),
                float_to_string(v['relative_length_piano']),
                format_none(v['num_file_orch']),
                float_to_string(v['relative_length_orch'])))

    # barplot
    fig, ax = plt.subplots()
    width = 0.35
    x = []
    y = []
    for k, v in merge_dict.iteritems():
        if v['relative_length_orch']:
            x.append(k[:3])
            y.append(v['relative_length_orch'])
    ind = range(len(y))
    barplot = ax.bar(ind, y, width, alpha=0.7, color='b')

    ax.set_title('Representativeness of composers in the database',
                 fontsize=14,
                 fontweight='bold')
    ax.set_xlabel('Composers')
    ax.set_ylabel('Ratio of frame occurences per composer')
    ax.set_xticks([e + width / 2 for e in ind])
    ax.set_xticklabels(x)
    plt.savefig('ratio_composer.pdf')

    return
def process_folder(folder_path, quantization, binary_piano, binary_orch, temporal_granularity, gapopen=3, gapextend=1, align_bool=True):
    ##############################
    # Get instrus and prs from a folder name name
    pr0, articulation_0, staccato_0, T0, name0, pr1, articulation_1, staccato_1, T1, name1 = get_instru_and_pr_from_folder_path(folder_path, quantization)
    data_0 = (pr0, articulation_0, staccato_0, T0, name0)
    data_1 = (pr1, articulation_1, staccato_1, T1, name1)

    (pr_piano_X, articulation_piano, staccato_piano, T_piano, name_piano), \
    (pr_orch, articulation_orch, staccato_orch, T_orch, name_orch)=\
            discriminate_between_piano_and_orchestra(data_0, data_1)

    # if pr_contrabass[:, 62:].sum() > 1:
    #     import pdb; pdb.set_trace()

    # If corrupted files, pr_piano (and pr_orch) will be None
    if pr_piano_X is None:
        return [None] * 9

    # Remove from orch
    if "Remove" in pr_orch.keys():
        pr_orch.pop("Remove")
    # Group in piano
    pr_piano = {'Piano': sum_along_instru_dim(pr_piano_X)}

    # try:
    #     write_midi(pr_piano, ticks_per_beat=quantization, write_path="../DEBUG/test_piano.mid", articulation=articulation_piano)
    #     write_midi(pr_orch, ticks_per_beat=quantization, write_path="../DEBUG/test_orch.mid", articulation=articulation_orch)
        # write_midi({k: v*90 for k,v in pr_piano.items()}, ticks_per_beat=quantization, write_path="../DEBUG/test_piano.mid", articulation=articulation_piano)
        # write_midi({k: v*90 for k,v in pr_orch.items() if (v.sum()>0)}, ticks_per_beat=quantization, write_path="../DEBUG/test_orch.mid", articulation=articulation_orch)
    # except:
    #     print("Because of mixed instru cannot write reference")

    ##############################
    # Process pr (mostly binarized)
    pr_piano = process_data_piano(pr_piano, binary_piano)
    pr_orch = process_data_orch(pr_orch, binary_orch)

    # Temporal granularity
    if temporal_granularity == 'event_level':
        event_piano = get_event_ind_dict(articulation_piano, pr_piano)
        event_orch = get_event_ind_dict(articulation_orch, pr_orch)
        def get_duration(event, last_time):
            start_ind = event[:]
            end_ind = np.zeros(event.shape, dtype=np.int)
            end_ind[:-1] = event[1:]
            end_ind[-1] = last_time
            duration_list = end_ind - start_ind
            return duration_list
        duration_piano = get_duration(event_piano, T_piano)
        duration_orch = get_duration(event_orch, T_orch)
        # Get the duration of each event
        pr_piano_event = warp_pr_aux(pr_piano, event_piano)
        pr_orch_event = warp_pr_aux(pr_orch, event_orch)
    else:
        event_piano = None
        event_orch = None
        duration_piano = None
        duration_orch = None
        pr_piano_event = pr_piano
        pr_orch_event = pr_orch

    ##############################
    ##############################
    # # Test for event-leve -> beat reconstruction
    # ##############################
    # # Instru mapping
    # import pickle as pkl
    # import LOP_database.utils.event_level as event_level
    # import LOP_database.utils.reconstruct_pr as reconstruct_pr
    # temp = pkl.load(open("/Users/crestel/Recherche/lop/LOP/Data/Data_A_ref_bp_bo_noEmb_tempGran32/temp.pkl", 'rb'))
    # instru_mapping = temp['instru_mapping']
    # N_orchestra = temp['N_orchestra']
    # N_piano = temp['instru_mapping']['Piano']['index_max']
    # matrix_orch = cast_small_pr_into_big_pr(pr_orch_event, 0, len(event_orch), instru_mapping, np.zeros((len(event_orch), N_orchestra)))
    # matrix_piano = cast_small_pr_into_big_pr(pr_piano_event, 0, len(event_piano), instru_mapping, np.zeros((len(event_piano), N_piano)))
    # ##############################
    # # Reconstruct rhythm
    # pr_orchestra_rhythm = event_level.from_event_to_frame(matrix_orch, event_orch)
    # pr_orchestra_rhythm_I = reconstruct_pr.instrument_reconstruction(pr_orchestra_rhythm, instru_mapping)
    # pr_piano_rhythm = event_level.from_event_to_frame(matrix_piano, event_piano)
    # pr_piano_rhythm_I = reconstruct_pr.instrument_reconstruction_piano(pr_piano_rhythm, instru_mapping)
    # ##############################
    # # Write midi
    # write_midi({k: v*90 for k,v in pr_piano_rhythm_I.items()}, ticks_per_beat=quantization, write_path="../DEBUG/test_piano_event.mid", articulation=articulation_piano)
    # write_midi({k: v*90 for k,v in pr_orchestra_rhythm_I.items() if (v.sum()>0)}, ticks_per_beat=quantization, write_path="../DEBUG/test_orch_event.mid", articulation=articulation_orch)
    ############################## 

    ##############################
    # Align tracks
    if align_bool:
        # piano_aligned, trace_piano, orch_aligned, trace_orch, trace_prod, total_time = align_pianorolls(pr_piano_event, pr_orch_event, gapopen, gapextend)
        piano_aligned, trace_piano, orch_aligned, trace_orch, trace_prod, total_time = align_pianorolls(pr_piano_event, pr_orch_event, gapopen, gapextend)
        # Clean events
        if (temporal_granularity == 'event_level'):
            if (trace_piano is None) or (trace_orch is None):
                event_piano_aligned = None
                event_orch_aligned = None
                duration_piano_aligned = None
                duration_orch_aligned = None
            else:
                event_piano_aligned = clean_event(event_piano, trace_piano, trace_prod)
                event_orch_aligned = clean_event(event_orch, trace_orch, trace_prod)
                duration_piano_aligned = clean_event(duration_piano, trace_piano, trace_prod)
                duration_orch_aligned = clean_event(duration_orch, trace_orch, trace_prod)
        else:
            event_piano_aligned = []
            event_orch_aligned = []
            duration_piano_aligned = []
            duration_orch_aligned = []
    else:
        piano_aligned = pr_piano_event
        event_piano_aligned = event_piano
        duration_piano_aligned = duration_piano
        orch_aligned = pr_orch_event
        event_orch_aligned = event_orch
        duration_orch_aligned = duration_orch
        total_time = T_piano
    ##############################

    ##############################
    ##############################
    # Test for aligned event Piano/Orch
    ##############################
    # Instru mapping
    # import pickle as pkl
    # import LOP_database.utils.event_level as event_level
    # import LOP_database.utils.reconstruct_pr as reconstruct_pr
    # temp = pkl.load(open("/Users/leo/Recherche/lop/LOP/Data/Data_DEBUG_bp_bo_noEmb_tempGran32/temp.pkl", 'rb'))
    # instru_mapping = temp['instru_mapping']
    # N_orchestra = temp['N_orchestra']
    # N_piano = temp['instru_mapping']['Piano']['index_max']
    # matrix_orch = cast_small_pr_into_big_pr(orch_aligned, 0, len(event_orch_aligned), instru_mapping, np.zeros((len(event_orch_aligned), N_orchestra)))
    # matrix_piano = cast_small_pr_into_big_pr(piano_aligned, 0, len(event_piano_aligned), instru_mapping, np.zeros((len(event_piano_aligned), N_piano)))
    # ##############################
    # # Reconstruct rhythm
    # pr_orchestra_I = reconstruct_pr.instrument_reconstruction(matrix_orch, instru_mapping)
    # pr_orchestra_rhythm = event_level.from_event_to_frame(matrix_orch, event_orch_aligned)
    # pr_orchestra_rhythm_I = reconstruct_pr.instrument_reconstruction(pr_orchestra_rhythm, instru_mapping)
    # #
    # pr_piano_I = reconstruct_pr.instrument_reconstruction_piano(matrix_piano, instru_mapping)
    # pr_piano_rhythm = event_level.from_event_to_frame(matrix_piano, event_piano_aligned)
    # pr_piano_rhythm_I = reconstruct_pr.instrument_reconstruction_piano(pr_piano_rhythm, instru_mapping)
    # ##############################
    # # Write midi
    # write_midi({k: v*90 for k,v in pr_piano_I.items()}, ticks_per_beat=1, write_path="../DEBUG/test_piano_event_aligned.mid", articulation=None)
    # write_midi({k: v*90 for k,v in pr_piano_rhythm_I.items()}, ticks_per_beat=quantization, write_path="../DEBUG/test_piano_rhythm_aligned.mid", articulation=None)
    # #
    # write_midi({k: v*90 for k,v in pr_orchestra_I.items() if (v.sum()>0)}, ticks_per_beat=1, write_path="../DEBUG/test_orch_event_aligned.mid", articulation=None)
    # write_midi({k: v*90 for k,v in pr_orchestra_rhythm_I.items() if (v.sum()>0)}, ticks_per_beat=quantization, write_path="../DEBUG/test_orch_rhythm_aligned.mid", articulation=None)
    # import pdb; pdb.set_trace()
    ##############################

    return piano_aligned, event_piano_aligned, duration_piano_aligned, name_piano, orch_aligned, event_orch_aligned, duration_orch_aligned, name_orch, total_time
예제 #9
0
def get_event_ind_dict(pr_dict):
    pr_flat = sum_along_instru_dim(pr_dict)
    return get_event_ind(pr_flat)
예제 #10
0
def align_tracks_removing_silences(pr0, pr1, unit_type, gapopen, gapextend):
    # Mapping_0 is a vector of size pr0, with values of the index in the new pr and -1 for a silence
    # Remove zeros
    pr0_no_silence, mapping_0 = remove_silence(pr0)
    pr1_no_silence, mapping_1 = remove_silence(pr1)

    # Get trace from needleman_wunsch algorithm
    # Traces are computed from binaries matrices
    # Traces are binary lists, 0 meaning a gap is inserted
    pr0_trace = sum_along_instru_dim(
        Unit_type.from_type_to_binary(pr0_no_silence, unit_type))
    pr1_trace = sum_along_instru_dim(
        Unit_type.from_type_to_binary(pr1_no_silence, unit_type))
    trace_0, trace_1, this_sum_score, this_nbId, this_nbDiffs = needleman_chord_wrapper(
        pr0_trace, pr1_trace, gapopen, gapextend)

    ####################################
    ####################################
    # Wrap dictionnaries according to the traces
    assert (len(trace_0) == len(trace_1)), "size mismatch"
    pr0_warp = warp_dictionnary_trace(pr0_no_silence, trace_0)
    pr1_warp = warp_dictionnary_trace(pr1_no_silence, trace_1)
    ####################################
    ####################################

    ####################################
    ####################################
    # Trace product
    trace_prod = [e1 * e2 for (e1, e2) in zip(trace_0, trace_1)]
    duration = sum(trace_prod)
    if duration == 0:
        return [None] * 5
    # Remove gaps
    pr0_aligned = remove_zero_in_trace(pr0_warp, trace_prod)
    pr1_aligned = remove_zero_in_trace(pr1_warp, trace_prod)

    # New mapping :
    # some element are lost, replace them by silences
    # and decrease the indices
    def remove_gaps_mapping(mapping, trace, trace_prod):
        index = 0
        counter = 0
        for (t, t_prod) in zip(trace, trace_prod):
            if (t == 1) and (t_prod == 0):
                # Element lost
                while (mapping[index] == -1):
                    index += 1
                # Replace i with a silence
                mapping[index] = -1
            elif (t == 1) and (t_prod == 1):
                while (mapping[index] == -1):
                    index += 1
                mapping[index] = counter
                counter += 1
                index += 1
        return mapping

    mapping_0_aligned = remove_gaps_mapping(mapping_0, trace_0, trace_prod)
    mapping_1_aligned = remove_gaps_mapping(mapping_1, trace_1, trace_prod)
    # Actually it is easier to have the indices of the non silent frames in the original score :
    non_silent_0 = np.where(mapping_0_aligned != -1)[0]
    non_silent_1 = np.where(mapping_1_aligned != -1)[0]
    ####################################
    ####################################

    # # Remove zeros in one score, but not in the other
    # pr0_no_unmatched_silence, pr1_no_unmatched_silence, duration = remove_unmatched_silence(pr0_aligned, pr1_aligned)
    #
    # # Remove zeros in both piano and orchestra : we don't want to learn mapping from zero to zero
    # pr0_out, pr1_out, duration = remove_match_silence(pr0_no_unmatched_silence, pr1_no_unmatched_silence)

    return pr0_aligned, non_silent_0, pr1_aligned, non_silent_1, duration