def quantise_notes(notes): '''Quantises an array of note values in Hertz to those in a 12 tone equal temperment tuning. Parameters ---------- notes : array-like or tuple Either a list of note values, or a tuple of (note start times, note lengths, note values). Returns ------- notes : array List of quantised notes, matching the format of `notes`. Raises ------ ValueError If `notes` is not in a valid format. ''' if len(np.shape(notes)) == 2: notes = np.asarray(notes) notes[2] = midi_to_hz(np.round(hz_to_midi(notes[2]))) return notes elif len(np.shape(notes)) == 1: return midi_to_hz(np.round(hz_to_midi(notes))) else: raise ValueError( '`notes` must be one or two dimenstional array-like lists.')
def GetChromaFromPianoroll(arr_pianoroll,bass=False): chroma_filter = cq_to_chroma(n_input=128,fmin=midi_to_hz(0)) chroma = np.dot(chroma_filter,arr_pianoroll.T).T.astype("float32") chroma[chroma>0] = 1 if not bass: return chroma bass_chroma = np.zeros(shape=chroma.shape,dtype="float32") for t in range(bass_chroma.shape[0]): notes = arr_pianoroll[t,:] if np.sum(notes)>0: bass = np.min(np.where(notes>0)[0]) bass_chroma[i,bass%12] = 1 return np.concatenate([bass_chroma,chroma],axis=1)
def inference(feature, model, timestep=128, batch_size=10, feature_num=384): assert len(feature.shape) == 2 # Padding total_samples = len(feature) pad_bottom = (feature_num - feature.shape[1]) // 2 pad_top = feature_num - feature.shape[1] - pad_bottom pad_len = timestep - 1 feature = np.pad(feature, ((pad_len, pad_len), (pad_bottom, pad_top))) # Prepare for prediction output = np.zeros(feature.shape + (2, )) total_batches = int(np.ceil(total_samples / batch_size)) last_batch_idx = len(feature) - pad_len for bidx in range(total_batches): print(f"batch: {bidx+1}/{total_batches}", end="\r") # Collect batch feature start_idx = bidx * batch_size end_idx = min(start_idx + batch_size, last_batch_idx) batch = np.array([ feature[idx:idx + timestep] for idx in range(start_idx, end_idx) ]) # noqa: E226 batch = np.expand_dims(batch, axis=3) # Predict contour batch_pred = model.predict(batch) batch_pred = 1 / (1 + np.exp(-expit(batch_pred))) # Add the batch results to the output container. for idx, pred in enumerate(batch_pred): slice_start = start_idx + idx slice_end = slice_start + timestep output[slice_start:slice_end] += pred output = output[pad_len:-pad_len, pad_bottom:-pad_top, 1] # Remove padding # Filter values avg_max_val = np.mean(np.max(output, axis=1)) output = np.where(output > avg_max_val, output, 0) # Generate final output F0 f0 = [] # pylint: disable=invalid-name for pitches in output: if np.sum(pitches) > 0: pidx = np.argmax(pitches) f0.append(midi_to_hz(pidx / 4 + LOWEST_MIDI_NOTE)) else: f0.append(0) return np.array(f0)
def GetLabelarrFromPianoroll(arr_pianoroll): chroma_filter = cq_to_chroma(n_input = 128, fmin = midi_to_hz(0)).T chroma = np.dot(arr_pianoroll,chroma_filter).astype("int32") lab = np.zeros(chroma.shape[0],dtype="int32") for i in range(chroma.shape[0]): c = chroma[i,:] note = arr_pianoroll[i,:] bass = np.where(note>0)[0] if bass.size>0: c[np.min(bass)%12] = 20 #Force bass note to remain in template c_argsort = np.argsort(c,kind="mergesort") c[c_argsort[:9]] = 0 lab[i] = _getlabel(c) return lab
def GetTemplateChromaFromPianoroll(arr_pianoroll,bass=False): chroma_filter = cq_to_chroma(n_input = 128, fmin = midi_to_hz(0)).T chroma = np.dot(arr_pianoroll,chroma_filter).astype("int32") chroma_template = np.zeros(chroma.shape,dtype="int32") bass_template = np.zeros(chroma.shape,dtype="int32") for i in range(chroma.shape[0]): c = chroma[i,:] note = arr_pianoroll[i,:] bass = np.where(note>0)[0] if bass.size>0: if not bass: c[np.min(bass)%12] = 20 #Force bass note to remain in template bass_template[i,np.min(bass)] = 1 c_argsort = np.argsort(c,kind="mergesort") c[c_argsort[:9]] = 0 c[c>0] = 1 chroma_template[i,:] = c if bass: return np.concatenate([chroma_template,bass_template],axis=1) else: return chroma_template
def GetTargetsFromPianoroll(arr_pianoroll): chroma_filter = cq_to_chroma(n_input=128,fmin=midi_to_hz(0)) T = arr_pianoroll.shape[0] t_bass = np.zeros(T,dtype="int32") t_top = np.zeros(T,dtype="int32") for t in range(T): sum_notes = np.sum(arr_pianoroll[t,:]) if sum_notes==0: continue notes = np.where(arr_pianoroll[t,:]>0)[0] bassnote = np.min(notes) topnote = np.max(notes) arr_pianoroll[t,bassnote]=0 arr_pianoroll[t,topnote]=0 t_bass[t]=bassnote%12 t_top[t]=topnote%12 chroma = np.dot(chroma_filter,arr_pianoroll.T).T.astype("float32") feature = np.zeros((T,12),dtype="float32") feature[chroma>=1] = 1.0 return t_bass,feature,t_top
def GetConvnetTargetFromPianoroll(arr_pianoroll): chroma_filter = cq_to_chroma(n_input=128,fmin=midi_to_hz(0)) T = arr_pianoroll.shape[0] bass_chroma = np.zeros((T,12),dtype="float32") top_chroma = np.zeros((T,12),dtype="float32") for t in range(T): sum_notes = np.sum(arr_pianoroll[t,:]) if sum_notes==0: continue notes = np.where(arr_pianoroll[t,:]>0)[0] bassnote = np.min(notes) topnote = np.max(notes) arr_pianoroll[t,bassnote]=0 arr_pianoroll[t,topnote]=0 bass_chroma[t,bassnote%12]=1 top_chroma[t,topnote%12]=1 chroma = np.dot(chroma_filter,arr_pianoroll.T).T feature = np.zeros((T,12),dtype="float32") #feature = normalize(chroma,axis=1,norm=np.inf).astype("float32") feature[chroma>=1] = 1.0 feature = np.concatenate([bass_chroma,feature,top_chroma],axis=1) return feature