def audio_to_chroma(input_wavfile, hopsize, fx, norm=0): """Method for turning a wavefile into chroma features. Parameters ---------- input_wavfile : str Path to a wavefile. hopsize : int Number of samples between frames. fx : function Function that consumes 2D matrices of DFT coefficients and outputs chroma features. norm : scalar, default=0 Lp norm to apply to the features; skipped if not > 0. Returns ------- features : np.ndarray Matrix of time-aligned chroma vectors, shaped (num_frames, 12). """ sigbuff = signal_buffer(input_wavfile, hopsize=hopsize) pitch_spec = np.concatenate([CT.cqt_pool(batch) for batch in sigbuff], axis=0) features = fx(pitch_spec) if norm > 0: features = CT.lp_norm(features, norm) return features
def generate_chroma_templates(num_qualities): """Generate chroma templates for some number of chord qualities. The supported qualities are, in order: [maj, min, maj7, min7, 7, maj6, min6, dim, aug, sus4, sus2, hdim7, dim7] Parameters ---------- num_qualities : int Number of chord qualities to generate chroma templates. Returns ------- templates : np.ndarray Array of chroma templates, ordered by quality. The first 12 are Major, the next 12 are minor, and so on. """ templates = [] position_idx = np.arange(12) # For all qualities ... for qual_idx in range(num_qualities): quality = CT.QUALITIES[qual_idx] # Translate the string into a bit-vector. qual_array = np.array([int(v) for v in CT.QUALITY_MAP[quality]]) for root_idx in range(12): # Rotate for all roots, C, C#, D ... templates.append(qual_array[(position_idx - root_idx) % 12]) templates.append(np.ones(12)) return CT.lp_norm(np.array(templates), 1.0)