Commit ab17afad authored by Marie Tahon's avatar Marie Tahon
Browse files

add musical density and correct absolute value for delta features for visualization

parent ee81020e
#general load WAV
begin = 0.0 #start reading the analysed signal after this time (in seconds)
duration = 60*2 # duration of the analysed signal (in seconds).
duration = 60*2 # duration of the analysed signal (in seconds) ou None.
begin_ref = 0.0 #beginning of the reference signal for computing cosine distance between clusters (in seconds).
end_ref = 0.05 #end of the reference signal for computing cosine distance between clusters (in seconds).
BINS_PER_OCTAVE = 12 * 3
......@@ -9,12 +9,12 @@ NFFT = 2 ** 11 #(> 2**10) duration of analysis window in samples for feature ext
STEP = NFFT / 2 #(>2**6) et (STEP < NFFT) 50% overlap between time windows / also sub-frequency after analyzing spectral structure.
#dimensionality reduction synchronisation on downsampled time (mean aggregate function)
onset = 'beat' #onsets that are extracted: no (regular onset extraction), 'onset' (onset extraction) 'beat' (beat extraction), 'manual' (manual annotations of onsets)
onset = 'manual' #onsets that are extracted: no (regular onset extraction), 'onset' (onset extraction) 'beat' (beat extraction), 'manual' (manual annotations of onsets)
onset_percu = False #extract onsets on percussive part of the signal. Also create percu and harmonic wav files.
onset_plot = True
#features
feat = ['chroma'] #feat = ['spectral', 'chroma', 'cepstral']
feat = ['chroma', 'spectral'] #feat = ['spectral', 'chroma', 'cepstral']
#compute spectral features: centroid, flatness, rolloff (5, 25, 50, 75, 95), contrast
#compute chroma featues: N_OCTAVES chroma + N_OCTAVES Dchroma
#compute cepstral featues: 20MFCC + 20DMFCC
......@@ -22,14 +22,18 @@ opt_tuning = False
#clustering
cluster_method = 'fixed' #method for searching for cluster number: fixed (fixed nb of cluster), max (find the right number in a range), evals (find the right number using eigen values) silhouette, davies_bouldin, or calinski_harabaz (find the right number with these methods)
cluster_nb = [4,6]#[3,4,6,8] #if method == 'fixed'
cluster_nb = [6,8]#[3,4,6,8] #if method == 'fixed'
cluster_max = 10 #if method == 'max'
cluster_dist = True # add cosine distance between clusters on final plot
cluster_nb_max = 5 #maximum nb of clusters in 1 sec.
#plot_density
norm_density_win = 60 #duration in sec. for sliding normalization of density
alpha = 0.6 # coefficient for counting which chromas energy overpass this threshold (alpha * max)
#plots
plot_simi = True
plot_struct = True
plot_dist = True
plot_simi = False
plot_struct = False
plot_dist = False
plot_features = True
timestamps = True
......@@ -267,6 +267,8 @@ def build_laplacian_and_evec(Rf, R_path, opt, onsets):
################################################
def compute_nb_clusters(method, evals, evecs, Tmax):
......@@ -401,39 +403,69 @@ def plot_structure(Rf, X, seg_ids, k, onset_times):
plt.tight_layout()
#################################################
def compute_musical_density(C, onset_times, w, alpha):
N = C.shape[1]
density = []
for n in range(N):
t1 = np.min([onset_times[-1], onset_times[n] + w])
t2 = np.min([onset_times[-1] -w, onset_times[n]])
idw = np.where((onset_times < t1) & (onset_times >= t2))
#if n + w < :
threshold_chroma = np.max(C[:,idw])
#else:
#threshold_chroma = np.mean(C[:, N - w : N])
idx = np.where(C[:,n] > alpha * threshold_chroma)
density.append(len(idx[0]))
return density
def plot_features(X, onsets, onset_times):
Xsync = librosa.util.sync(X, onsets, aggregate=np.median)
print(X.shape, Xsync.shape)
#print(X.shape, Xsync.shape)
#print(onset_times)
if params.feat[0] == 'chroma':
plt.figure(figsize=(12, 4))
plt.subplot(2,1,1)
plt.title('onset-synchronous chroma (12)')
librosa.display.specshow(Xsync[:13,:], y_axis='chroma', x_axis='time', x_coords=onset_times)
plt.colorbar()
plt.tight_layout()
fig_c = plt.figure(figsize=(12, 6))
ax0_c = fig_c.add_subplot(3,1,1)
ax0_c.set_title('onset-synchronous chroma (12)')
#ax0_c.pcolor(distance, cmap = 'plasma')
librosa.display.specshow(Xsync[:12,:], y_axis='chroma', x_axis='time', x_coords=onset_times, cmap = 'OrRd')
#plt.colorbar()
plt.subplot(2,1,2)
plt.title('onset-synchronous delta chroma (12)')
librosa.display.specshow(Xsync[12:,:], y_axis='chroma', x_axis='time', x_coords=onset_times)
plt.colorbar()
ax1_c = fig_c.add_subplot(3,1,2, sharex = ax0_c)
ax1_c.set_title('onset-synchronous delta chroma (12)')
librosa.display.specshow(np.abs(Xsync[12:,:]), y_axis='chroma', x_axis='time', x_coords=onset_times, cmap = 'OrRd')
#plt.colorbar()
density = compute_musical_density(Xsync[:12,:], onset_times, params.norm_density_win, params.alpha)
print(len(onset_times), len(density))
ax2_c = fig_c.add_subplot(3,1,3, sharex = ax0_c)
ax2_c.set_title('musical density')
ax2_c.plot(onset_times, density)
plt.tight_layout()
elif params.feat[0] == 'cepstral':
plt.figure(figsize=(12, 4))
plt.subplot(2,1,1)
plt.title('onset-synchronous MFCC (20)')
fig_s = plt.figure(figsize=(12, 6))
ax0_s = fig_s.add_subplot(3,1,1)
ax0_s.set_title('onset-synchronous MFCC (20)')
librosa.display.specshow(Xsync[:21,:], x_axis='time', x_coords=onset_times)
plt.colorbar()
plt.tight_layout()
#plt.colorbar()
#plt.tight_layout()
plt.subplot(2,1,2)
plt.title('onset-synchronous delta MFCC (20)')
librosa.display.specshow(Xsync[20:,:], x_axis='time', x_coords=onset_times)
plt.colorbar()
ax1_s = fig_s.add_subplot(3,1,2, sharex = ax0_s)
ax1_s.set_title('onset-synchronous delta MFCC (20)')
librosa.display.specshow(np.abs(Xsync[20:,:]), x_axis='time', x_coords=onset_times)
#plt.colorbar()
density = compute_musical_density(Xsync[:21,:], onset_times, params.norm_density_win, params.alpha)
ax2_s = fig_s.add_subplot(3,1,2, sharex = ax0_s)
ax2_s.set_title('musical density')
ax2_s.plot(onset_times, density)
plt.tight_layout()
else:
print('these parameters can not be plot')
......@@ -469,6 +501,7 @@ def feature_extraction(y, sr, opt_tuning):
print('Features for local similarity: ', ' '.join(params.feat))
full = []
idx_chroma = 0
if 'cepstral' in params.feat:
mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc = 20, n_fft = NFFT, hop_length = STEP)
......@@ -480,6 +513,7 @@ def feature_extraction(y, sr, opt_tuning):
chroma = librosa.feature.chroma_cqt(y=y, sr=sr, n_chroma = 12, n_octaves = N_OCTAVES, hop_length = STEP, norm = None, tuning= A440)
chroma_delta = librosa.feature.delta(chroma)
fchr = np.concatenate((chroma, chroma_delta), axis=0)
idx_chroma = len(full)
full.append(fchr)
if 'spectral' in params.feat:
......@@ -499,7 +533,7 @@ def feature_extraction(y, sr, opt_tuning):
full = np.array(full)[0]
print('feature shape', full.shape)
return full
return full, idx_chroma
def extract_time_boundaries(cluster_ids, onsets, nb_frames, sr):
......@@ -550,7 +584,7 @@ def extract_distance_between_clusters(center_clusters, type_dist = 'cos'):
y = range(j+1)
xloc = [c + 0.5 for c in x]
cx = [str(c) for c in x]
print(cx)
#print(cx)
fig_d, ax_d = plt.subplots(figsize=(5, 4))
p_d = ax_d.pcolor(distance, cmap = 'inferno_r')
cb = fig_d.colorbar(p_d)
......@@ -590,11 +624,14 @@ def main():
print('signal shape:', y.shape, ' sr=', sr, 'win duration=%.2f' %(NFFT / sr))
#extract acoustic feature from audio signal feat is a matrix np.array((nb features, Tmax*sr/STEP))
feat = feature_extraction(y, sr, params.opt_tuning)
feat, idx_chroma = feature_extraction(y, sr, params.opt_tuning)
#extract onset indexes and times + onset-synchronous CQT transform on onsets.
onsets, onset_times, Csync = extract_onsets(y, sr, args.manual_onset)
#if 'chroma' in params.feat:
# compute_musical_density(Csync, onset_times, idx_chroma, params.norm_density_win, params.alpha, sr)
if params.plot_features: plot_features(feat, onsets, onset_times)
#================
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment