Spaces:
Running
Running
Download utils/audio_processor.py from adidtiya/deepfake-shield-api: direct link, hf CLI and curl.
- Browser
- Download file 2.3 kB
-
https://huggingface.co/spaces/adidtiya/deepfake-shield-api/resolve/main/utils/audio_processor.py
- Command line
-
hf download hf://spaces/adidtiya/deepfake-shield-api/utils/audio_processor.py
-
curl -L -o audio_processor.py https://huggingface.co/spaces/adidtiya/deepfake-shield-api/resolve/main/utils/audio_processor.py
2.3 kB
| """ | |
| audio_processor.py | |
| ================== | |
| Utilitas untuk preprocessing audio chunk sebelum dianalisis. | |
| """ | |
| import numpy as np | |
| import librosa | |
| import io | |
| import soundfile as sf | |
| from typing import Tuple, Optional | |
| def bytes_to_audio(audio_bytes: bytes) -> Tuple[np.ndarray, int]: | |
| """ | |
| Konversi bytes audio ke numpy array PCM. | |
| Mendukung format: WAV, MP3, OGG, FLAC. | |
| Returns: | |
| Tuple (audio_array float32 mono, sample_rate) | |
| """ | |
| buffer = io.BytesIO(audio_bytes) | |
| # Coba baca dengan soundfile terlebih dahulu | |
| try: | |
| audio, sr = sf.read(buffer, dtype='float32') | |
| except Exception: | |
| # Fallback ke librosa (lebih lambat tapi mendukung lebih banyak format) | |
| buffer.seek(0) | |
| audio, sr = librosa.load(buffer, sr=None, mono=True) | |
| return audio, sr | |
| # Konversi stereo ke mono jika diperlukan | |
| if audio.ndim == 2: | |
| audio = np.mean(audio, axis=1) | |
| return audio, sr | |
| def normalize_audio(audio: np.ndarray) -> np.ndarray: | |
| """ | |
| Normalisasi amplitudo audio ke range [-1.0, 1.0]. | |
| Mencegah saturasi dan memastikan konsistensi input model. | |
| """ | |
| max_val = np.max(np.abs(audio)) | |
| if max_val > 0: | |
| audio = audio / max_val | |
| return audio | |
| def split_audio_chunks( | |
| audio: np.ndarray, | |
| sample_rate: int, | |
| chunk_duration: float = 2.0, | |
| overlap: float = 0.5 | |
| ) -> list: | |
| """ | |
| Bagi audio panjang menjadi chunks kecil dengan overlap. | |
| Args: | |
| audio : Array audio PCM | |
| sample_rate : Sample rate (Hz) | |
| chunk_duration: Durasi setiap chunk (detik) | |
| overlap : Overlap antar chunk (detik) | |
| Returns: | |
| List of numpy arrays, masing-masing adalah satu chunk | |
| """ | |
| chunk_samples = int(chunk_duration * sample_rate) | |
| hop_samples = int((chunk_duration - overlap) * sample_rate) | |
| chunks = [] | |
| start = 0 | |
| while start + chunk_samples <= len(audio): | |
| chunk = audio[start:start + chunk_samples] | |
| chunks.append(chunk) | |
| start += hop_samples | |
| # Tambahkan sisa audio jika belum masuk (dengan padding) | |
| if start < len(audio): | |
| remainder = audio[start:] | |
| padded = np.pad(remainder, (0, chunk_samples - len(remainder))) | |
| chunks.append(padded) | |
| return chunks | |