CoolFace
Apppublic

LyndonCatan/audio-forensic-app

sourceHugging Faceupdated 8mo agoView on Hugging Face
1likes
audio_analysis.py180 linesDownload Raw Back to scripts
1# ================================2# Audio Forensic Analysis Script3# ================================4 5import librosa6import librosa.display7import matplotlib8import matplotlib.pyplot as plt9import numpy as np10from scipy.signal import find_peaks11import json12import sys13import base6414import io15from scipy.io import wavfile16import tempfile17import os18 19# Set matplotlib to use Agg backend for server environments20matplotlib.use('Agg')21 22def analyze_audio(audio_data_base64, filename="uploaded_audio"):23    """24    Analyze audio data and return comprehensive forensic analysis results25    """26    try:27        # Decode base64 audio data28        audio_bytes = base64.b64decode(audio_data_base64)29        30        # Create temporary file31        with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as temp_file:32            temp_file.write(audio_bytes)33            temp_path = temp_file.name34        35        # Load audio with librosa36        y, sr = librosa.load(temp_path, sr=None)37        38        print(f"โœ… Audio loaded: {filename}")39        print(f"Sample Rate: {sr} Hz")40        print(f"Duration: {librosa.get_duration(y=y, sr=sr):.2f} seconds")41        42        # ================================43        # STFT - Short-Time Fourier Transform44        # ================================45        stft_result = librosa.stft(y)46        stft_db = librosa.amplitude_to_db(np.abs(stft_result), ref=np.max)47        48        # ================================49        # FFT - Fast Fourier Transform50        # ================================51        fft_result = np.fft.fft(y)52        magnitude = np.abs(fft_result)53        frequency = np.linspace(0, sr, len(magnitude))54        55        # ================================56        # Detect Sound Events57        # ================================58        frame_length = 102459        hop_length = 51260        energy = np.array([61            sum(abs(y[i:i+frame_length]**2))62            for i in range(0, len(y), hop_length)63        ])64        65        # Normalize energy66        energy = energy / np.max(energy) if np.max(energy) > 0 else energy67        68        # Find peaks (sound events)69        peaks, properties = find_peaks(energy, height=0.2, distance=5)70        num_sounds = len(peaks)71        72        # ================================73        # Advanced Analysis74        # ================================75        duration = librosa.get_duration(y=y, sr=sr)76        rms = np.mean(librosa.feature.rms(y=y))77        78        # Spectral features79        spectral_centroids = librosa.feature.spectral_centroid(y=y, sr=sr)[0]80        dominant_frequency = np.mean(spectral_centroids)81        82        # Convert to decibels83        max_decibels = 20 * np.log10(np.max(np.abs(y))) if np.max(np.abs(y)) > 0 else -np.inf84        85        # Detect different types of sounds based on frequency characteristics86        sound_events = []87        for i, peak in enumerate(peaks):88            time_pos = (peak * hop_length) / sr89            freq_at_peak = spectral_centroids[min(peak, len(spectral_centroids)-1)]90            amplitude = energy[peak]91            92            # Classify sound type based on frequency93            if freq_at_peak < 300:94                sound_type = "Low Frequency/Bass"95            elif freq_at_peak < 1000:96                sound_type = "Voice/Mid Range"97            elif freq_at_peak < 4000:98                sound_type = "High Voice/Instruments"99            else:100                sound_type = "High Frequency/Noise"101            102            sound_events.append({103                "time": round(time_pos, 2),104                "frequency": round(freq_at_peak, 1),105                "amplitude": round(amplitude, 3),106                "type": sound_type,107                "decibels": round(20 * np.log10(amplitude) if amplitude > 0 else -np.inf, 1)108            })109        110        # Sort by amplitude (loudest first)111        sound_events.sort(key=lambda x: x["amplitude"], reverse=True)112        113        # Create frequency spectrum data114        freq_spectrum = []115        freq_step = len(frequency) // 100  # Sample 100 points116        for i in range(0, len(frequency)//2, freq_step):117            if i < len(magnitude):118                freq_spectrum.append({119                    "frequency": round(frequency[i], 1),120                    "magnitude": round(magnitude[i] / np.max(magnitude), 3) if np.max(magnitude) > 0 else 0121                })122        123        # ================================124        # Generate Analysis Report125        # ================================126        analysis_results = {127            "filename": filename,128            "duration": round(duration, 2),129            "sampleRate": int(sr),130            "averageRMS": round(float(rms), 6),131            "detectedSounds": num_sounds,132            "dominantFrequency": round(float(dominant_frequency), 1),133            "maxDecibels": round(float(max_decibels), 1),134            "soundEvents": sound_events[:10],  # Top 10 events135            "frequencySpectrum": freq_spectrum,136            "analysisComplete": True,137            "timestamp": "2024-01-01T00:00:00Z"138        }139        140        print("\n๐Ÿ“Š Audio Analysis Report")141        print(f"๐Ÿ“ File Name: {filename}")142        print(f"โฑ Duration: {duration:.2f} seconds")143        print(f"๐ŸŽ™ Sample Rate: {sr} Hz")144        print(f"๐Ÿ“ˆ Average RMS Energy: {rms:.6f}")145        print(f"๐Ÿ”Š Detected Sound Events: {num_sounds}")146        print(f"๐ŸŽต Dominant Frequency: {dominant_frequency:.1f} Hz")147        print(f"๐Ÿ“ข Max Decibels: {max_decibels:.1f} dB")148        149        print("\n๐ŸŽฏ Top Sound Events:")150        for i, event in enumerate(sound_events[:5]):151            print(f"{i+1}. {event['type']} at {event['time']}s - {event['frequency']:.1f}Hz ({event['decibels']:.1f}dB)")152        153        # Clean up temporary file154        os.unlink(temp_path)155        156        return json.dumps(analysis_results, indent=2)157        158    except Exception as e:159        error_result = {160            "error": str(e),161            "analysisComplete": False,162            "message": "Audio analysis failed"163        }164        print(f"โŒ Analysis Error: {str(e)}")165        return json.dumps(error_result, indent=2)166 167if __name__ == "__main__":168    # Example usage - in real implementation, this would receive base64 data169    print("๐ŸŽต Audio Forensic Analysis System Ready")170    print("Waiting for audio data...")171    172    # This script can be called with audio data as argument173    if len(sys.argv) > 1:174        audio_data = sys.argv[1]175        filename = sys.argv[2] if len(sys.argv) > 2 else "uploaded_audio"176        result = analyze_audio(audio_data, filename)177        print(result)178    else:179        print("No audio data provided. Script ready for integration.")180