File size: 4,161 Bytes
2d5fdd1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import librosa
import numpy as np
from pathlib import Path
import json
import os.path
import sys
import argparse

THIS_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = os.path.abspath(os.path.join(THIS_DIR, os.pardir))
sys.path.append(ROOT_DIR)
from audio_feature_utils import *
from utils import distribute_tasks

parser = argparse.ArgumentParser(description="Preprocess audio data")

parser.add_argument("data_path", type=str, help="Directory contining Beat Saber level folders")
parser.add_argument("--feature_names", metavar='', type=str, default="mel", help="mel, chroma, multi_mel, spectralflux, madmombeats. Comma separated")
parser.add_argument("--combined_feature_name", metavar='', type=str, default=None, help="name for the combined features, if several")
parser.add_argument("--audio_format", type=str, default="mp3")
parser.add_argument("--mel_feature_size", metavar='', type=int, default=None)
# parser.add_argument("--step_size", metavar='', type=float, default=0.01666666666)
parser.add_argument("--fps", metavar='', type=float, default=60)
parser.add_argument("--sampling_rate", metavar='', type=float, default=96000)
parser.add_argument("--replace_existing", action="store_true")
parser.add_argument("--notranspose", action="store_true")

args = parser.parse_args()

# makes arugments into global variables of the same name, used later in the code
globals().update(vars(args))
step_size=1.0/fps
data_path = Path(data_path)

feature_names = feature_names.split(",")
if len(feature_names) > 1 and combined_feature_name is None:
    combined_feature_name = "_".join(feature_names)
elif len(feature_names) == 1:
    combined_feature_name = feature_names[0]

## distributing tasks accross nodes ##
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
print(rank)
print("creating {} of size {}".format(",".join(feature_names), mel_feature_size))

#assuming mp3 for now.
candidate_audio_files = sorted(data_path.glob('**/*.'+audio_format), key=lambda path: path.parent.__str__())
tasks = distribute_tasks(candidate_audio_files,rank,size)

for i in tasks:
    path = candidate_audio_files[i]
    song_file_path = path.__str__()
    # feature files are going to be saved as numpy files
    if feature_names == ["mel"] or feature_names == ["multi_mel"]:
        features_file = song_file_path+"_"+combined_feature_name+"_"+str(mel_feature_size)+".npy"
    else:
        features_file = song_file_path+"_"+combined_feature_name+".npy"

    if replace_existing or not os.path.isfile(features_file):
        print("creating feature file",i)
        featuress = []
        for feature_name in feature_names:
            # get song
            y_wav, sr = librosa.load(song_file_path, sr=sampling_rate)

            sr = sampling_rate
            hop = int(round(sr * step_size))
            # hop = int(sr * step_size)

            #get feature
            if feature_name == "chroma":
                features = extract_features_hybrid(y_wav,sr,hop).transpose(1,0)[1:]
            elif feature_name == "mel":
                features = extract_features_mel(y_wav,sr,hop,mel_dim=mel_feature_size).transpose(1,0)[1:]
            elif feature_name == "envelope":
                features = extract_features_envelope(y_wav,sr,hop)[1:]
            elif feature_name == "multi_mel":
                features = extract_features_multi_mel(y_wav, sr=sampling_rate, hop=hop, nffts=[1024,2048,4096], mel_dim=mel_feature_size)
            elif feature_name == "spectralflux": #actually this is the same as envelope I think
                features = extract_features_spectral_flux(song_file_path,fps)
            elif feature_name == "madmombeats":
                features = extract_features_madmombeat(song_file_path,fps)

            featuress.append(features)

        shortest_length = 99999999999
        for feat in featuress:
            if feat.shape[0] < shortest_length:
                shortest_length = feat.shape[0]
        for i in range(len(featuress)):
            featuress[i] = featuress[i][:shortest_length]

        featuress = np.concatenate(featuress,1)

        np.save(features_file,featuress)