Spaces:
Running
Running
| import os | |
| import pandas as pd | |
| import numpy as np | |
| import librosa | |
| from tqdm import tqdm | |
| import sys | |
| # Add src to path | |
| sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) | |
| from src.config import DATA_DIR, SAMPLE_RATE | |
| def extract_dsp_features(file_path): | |
| try: | |
| y, sr = librosa.load(file_path, sr=SAMPLE_RATE) | |
| features = {} | |
| # 1. MFCC (Mel-frequency cepstral coefficients) | |
| mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13) | |
| features['mfcc_mean'] = np.mean(mfcc) | |
| features['mfcc_var'] = np.var(mfcc) | |
| # Add individual MFCC stats if needed, but mean/var aggregation is common for baselines | |
| for i in range(1, 14): | |
| features[f'mfcc_{i}_mean'] = np.mean(mfcc[i-1]) | |
| features[f'mfcc_{i}_var'] = np.var(mfcc[i-1]) | |
| # 2. Spectral Features | |
| spectral_centroid = librosa.feature.spectral_centroid(y=y, sr=sr) | |
| features['spec_cent_mean'] = np.mean(spectral_centroid) | |
| features['spec_cent_var'] = np.var(spectral_centroid) | |
| spectral_flatness = librosa.feature.spectral_flatness(y=y) | |
| features['spec_flat_mean'] = np.mean(spectral_flatness) | |
| features['spec_flat_var'] = np.var(spectral_flatness) | |
| spectral_rolloff = librosa.feature.spectral_rolloff(y=y, sr=sr) | |
| features['spec_roll_mean'] = np.mean(spectral_rolloff) | |
| # 3. Energy / RMS | |
| rms = librosa.feature.rms(y=y) | |
| features['rms_mean'] = np.mean(rms) | |
| features['rms_var'] = np.var(rms) | |
| # 4. Zero Crossing Rate | |
| zcr = librosa.feature.zero_crossing_rate(y) | |
| features['zcr_mean'] = np.mean(zcr) | |
| features['zcr_var'] = np.var(zcr) | |
| # 5. Chroma | |
| chroma = librosa.feature.chroma_stft(y=y, sr=sr) | |
| features['chroma_mean'] = np.mean(chroma) | |
| # 6. Pitch (using simple piptrack) | |
| pitches, magnitudes = librosa.piptrack(y=y, sr=sr) | |
| # Select pitches with high magnitude | |
| pitches_filtered = pitches[magnitudes > np.median(magnitudes)] | |
| if len(pitches_filtered) > 0: | |
| features['pitch_mean'] = np.mean(pitches_filtered) | |
| features['pitch_std'] = np.std(pitches_filtered) | |
| else: | |
| features['pitch_mean'] = 0 | |
| features['pitch_std'] = 0 | |
| return features | |
| except Exception as e: | |
| print(f"Error extracting features for {file_path}: {e}") | |
| return None | |
| def main(): | |
| master_csv = os.path.join(DATA_DIR, 'master_dataset.csv') | |
| if not os.path.exists(master_csv): | |
| print("Master dataset not found. Run preprocessing first.") | |
| return | |
| df = pd.read_csv(master_csv) | |
| feature_list = [] | |
| print("Extracting DSP Features...") | |
| for index, row in tqdm(df.iterrows(), total=len(df)): | |
| file_path = row['path'] | |
| features = extract_dsp_features(file_path) | |
| if features: | |
| # Combine meta info with features | |
| features['filename'] = row['filename'] | |
| features['label'] = row['label'] # Target | |
| feature_list.append(features) | |
| # Save Feature Dataset | |
| feature_df = pd.DataFrame(feature_list) | |
| output_path = os.path.join(DATA_DIR, 'features', 'dsp_features.csv') | |
| feature_df.to_csv(output_path, index=False) | |
| print(f"DSP Feature Extraction Complete! Saved to {output_path}") | |
| if __name__ == "__main__": | |
| main() | |