MalevolentSlice
DESIGN AND IMPLEMENTATION OF A VOICE ACTIVITY DETECTION-BASED AUDIO DATASET SEGMENTATION SYSTEM FOR MEMORY-EFFICIENT TEXT-TO-SPEECH
RANCANG BANGUN SISTEM SEGMENTASI DATASET AUDIO BERBASIS VOICE ACTIVITY DETECTION UNTUK PENGEMBANGAN TEXT-TO-SPEECH EFISIEN MEMORI RAM
🌐 English Quick Overview
MalevolentSlice (CLI alias: malevolentslice) is a lightweight, high-performance Python library and CLI tool designed to slice continuous, raw audio recordings (such as podcasts, audiobooks, and long interviews) into clean, high-quality audio segments formatted for training state-of-the-art Text-to-Speech (TTS) models (e.g., LJSpeech format for VITS, FastSpeech, or Tacotron).
Quick Installation:
pip install malevolentslice
Quick Run:
# Auto-detect audio in current directory and subfolders (up to 3 levels deep)
malevolentslice run
# Or specify custom input and output
malevolentslice run -i ./raw_audio/ -o ./tts_dataset/
📖 Dokumentasi Bahasa Indonesia
malevolentslice adalah pustaka (library) Python mandiri sekaligus perkakas baris perintah (Command Line Interface / CLI) berkinerja tinggi yang dirancang khusus untuk memotong rekaman audio panjang (seperti siniar/podcast, buku audio/audiobook, dan rekaman wawancara) menjadi segmen-segmen audio pendek, bersih, dan terstandarisasi yang siap digunakan untuk melatih model AI Text-to-Speech (TTS).
🌟 Fitur Utama
- Efisiensi Memori Konstan $O(1)$ (RAM $\le 100\text{ MB}$): Menggunakan generator aliran audio (streaming generator via
soundfile.blocks()) yang membaca data per blok dari penyimpanan sekunder langsung ke penyangga memori, mencegah risiko Out-of-Memory (OOM) meskipun memproses audio berdurasi puluhan jam. - Pencarian Audio Otomatis & Terbatas (
--max-depth): Cukup jalankanmalevolentslice runtanpa argumen, sistem akan otomatis mendeteksi berkas audio di direktori kerja hingga batas kedalaman bawaan 3 level subfolder (max_depth = 3), sambil mengecualikan folder sistem/virtual environment (.venv,.git,dataset, dsb.). - Hierarki Folder Fleksibel (
--preserve-structure/-p): Mendukung format standar korpus LJSpeech (semua segmen diwavs/), mode datar (--flat), maupun pencerminan hierarki subfolder masukan (mirrored hierarchy) ke folder luaran. - NumPy Vectorized Noise Gate: Penapisan awal derau latar (background noise) secara instan menggunakan komputasi vektor NumPy tanpa overhead komputasi tinggi.
- Mesin Deteksi Suara Silero-VAD ONNX: Inferensi keberadaan wicara presisi tingkat bingkai (frame-level) berbasis model Silero-VAD teroptimasi via ONNX Runtime CPU (ringan dan tanpa ketergantungan PyTorch yang berat).
- Proteksi Hang-over & Pemotongan Cerdas: Mencegah pemotongan konsonan akhir kata (word clipping) dengan penyangga jeda wicara (hangover buffer), serta membatasi durasi segmen ideal TTS ($1.0\text{s} \le t \le 12.0\text{s}$).
- Antarmuka Terminal Modern & Pythonic API: Tampilan CLI interaktif berbasis Rich dengan visualisasi progres real-time, pemantau alokasi RAM aktif dengan ambang batas kestabilan $\le 100\text{ MB}$
(STABLE), serta API Python yang elegan.
💻 Instalasi
Pastikan Anda menggunakan Python versi 3.8 atau lebih baru:
Pengguna Akhir (via PyPI)
pip install malevolentslice
Mode Pengembangan (Development)
Jika Anda mengkloning repositori ini secara lokal:
git clone https://github.com/drrri-py/malevolentslice.git
cd malevolentslice
# Pasang dalam mode editable beserta dependensi dev (pengujian & profiler)
pip install -e ".[dev]"
🚀 Panduan Penggunaan Cepat
1. Antarmuka Baris Perintah (CLI)
A. Eksekusi Otomatis (Zero-Configuration)
Jika Anda memiliki berkas audio di direktori kerja atau di dalam subfolder (misalnya di folder raw/, folder proyek, atau subfolder sesi), cukup jalankan:
malevolentslice run
Catatan: Perintah di atas akan secara otomatis memindai seluruh berkas audio hingga 3 tingkat subfolder, memprosesnya dengan alokasi RAM yang terjaga stabil, dan menyimpannya ke direktori
./dataset/.
B. Menentukan Sumber Masukan & Folder Luaran
# Memproses folder sumber tertentu ke folder tujuan tertentu
malevolentslice run -i ./rekaman_mentah/ -o ./dataset_tts/
# Memproses satu berkas audio tunggal
malevolentslice run -i ./rekaman_mentah/audio_wawancara.wav -o ./dataset/
C. Mempertahankan Struktur Hierarki Subfolder (-p / --preserve-structure)
Jika audio masukan Anda dikelompokkan ke dalam subfolder (misal: pembicara_1/, pembicara_2/) dan Anda ingin hasil potongannya terpisah dalam subfolder yang sama:
malevolentslice run -p
# atau:
malevolentslice run --preserve-structure
D. Mode Luaran Datar (--flat)
Mengekspor seluruh berkas .wav langsung ke dalam folder luaran utama tanpa membuat subfolder wavs/:
malevolentslice run --flat
E. Mengatur Batas Kedalaman Pencarian Folder (--max-depth)
# Menelusuri subfolder hingga kedalaman maksimal 5 tingkat
malevolentslice run --max-depth 5
Daftar Lengkap Opsi CLI (malevolentslice run --help)
| Opsi | Pilihan Singkat | Nilai Baku (Default) | Deskripsi |
|---|---|---|---|
--input |
-i |
None (Otomatis) |
Berkas audio atau direktori sumber masukan. |
--output |
-o |
./dataset/ |
Direktori luaran untuk dataset standar LJSpeech. |
--threshold |
-t |
-40.0 |
Ambang batas Noise Gate dalam satuan desibel (dB). |
--speech-threshold |
- | 0.5 |
Ambang batas probabilitas wicara model VAD ($0.0 - 1.0$). |
--silence |
-s |
400.0 |
Batas jeda hening minimum pemisah segmen (milidetik). |
--buffer |
-b |
10.0 |
Ukuran penyangga blok streaming data audio (MB). |
--min-speech |
- | 1000.0 |
Durasi segmen wicara minimum yang diekspor (milidetik). |
--max-speech |
- | 12000.0 |
Durasi segmen wicara maksimum yang diekspor (milidetik). |
--sr |
- | 16000 |
Frekuensi sampel target audio luaran (Hz). |
--wav-dir |
- | wavs |
Nama subfolder audio WAV (kosongkan '' jika --flat). |
--flat |
- | False |
Simpan berkas WAV langsung di root folder tanpa subfolder wavs/. |
--preserve-structure |
-p |
False |
Cerminkan susunan hierarki subfolder masukan ke folder luaran. |
--max-depth |
- | 3 |
Batas kedalaman penelusuran subfolder audio. |
--quiet |
-q |
False |
Jalankan proses secara senyap tanpa animasi terminal/banner. |
2. Antarmuka Pemrograman Python (Pythonic API)
Pustaka malevolentslice dapat diintegrasikan dengan mudah ke dalam skrip Python atau alur kerja (pipeline) pemrosesan data AI:
import malevolentslice
# 1. Inisialisasi Pipeline dengan konfigurasi yang diinginkan
pipeline = malevolentslice.Pipeline(
noise_threshold_db=-40.0,
speech_threshold=0.5,
min_silence_duration_ms=400.0,
min_speech_duration_ms=1000.0,
max_speech_duration_ms=12000.0,
chunk_buffer_mb=10.0,
target_sr=16000,
max_depth=3, # Batas kedalaman pencarian subfolder
preserve_structure=False, # Ubah ke True jika ingin memisahkan per subfolder
wav_subfolder="wavs"
)
# 2. Jalankan segmentasi pada direktori atau berkas
summary = pipeline.process(
source="./rekaman_mentah/",
output_dir="./dataset_tts/"
)
# 3. Akses rekapitulasi hasil eksekusi
print(f"Total berkas diproses : {summary.total_files}")
print(f"Segmen dihasilkan : {summary.total_segments}")
print(f"Total durasi wicara : {summary.total_processed_duration:.2f} detik")
print(f"Waktu eksekusi : {summary.elapsed_time:.2f} detik")
print(f"Konsumsi Puncak RAM : {summary.peak_memory_mb:.2f} MB")
Fitur Pencarian Mandiri (Standalone Audio Search)
Anda juga dapat memanfaatkan fungsi pencarian audio bawaan untuk keperluan skrip kustom:
from malevolentslice import find_audio_files
# Mencari seluruh file audio hingga kedalaman 3 tingkat
berkas_audio = find_audio_files("./proyek_audio", max_depth=3)
print(f"Ditemukan {len(berkas_audio)} berkas audio.")
📁 Struktur Direktori Luaran Dataset
1. Struktur Standar LJSpeech (Bawaan)
dataset/
├── wavs/
│ ├── segment_000001.wav
│ ├── segment_000002.wav
│ └── ...
├── metadata.csv
└── processing_audit.log
Format berkas metadata.csv (pemisah | standar korpus LJSpeech):
segment_000001|audio segment 000001|audio segment 000001
segment_000002|audio segment 000002|audio segment 000002
⚠️ Catatan Mengenai Transkripsi Teks:
malevolentsliceberfokus pada tahap segmentasi akustik dan pemotongan audio presisi VAD. Kolom teks padametadata.csvyang dihasilkan adalah kerangka penampung (placeholder template) agar struktur dataset langsung kompatibel dengan format LJSpeech. Sebelum dimasukkan ke tahap pelatihan (training) model TTS, teks tersebut perlu diisi transkrip wicara aslinya (lihat panduan langkah selanjutnya di bawah).
2. Struktur Hierarki Bercermin (--preserve-structure / -p)
dataset/
├── wavs/
│ ├── sesi_01/
│ │ ├── segment_000001.wav
│ │ └── segment_000002.wav
│ └── sesi_02/
│ └── segment_000003.wav
├── metadata.csv
└── processing_audit.log
🔄 Alur Kerja Lengkap Pembuatan Dataset TTS (Next Steps)
Untuk melatih model Text-to-Speech (seperti VITS, FastSpeech 2, atau Piper TTS), alur kerja standar kurasi dataset audio adalah sebagai berikut:
[ Rekaman Audio Mentah ]
│
▼
[ 1. Segmentasi via MalevolentSlice ] ──▶ Menghasilkan folder wavs/ (16kHz PCM) & template metadata.csv
│
▼
[ 2. Transkripsi Otomatis (ASR) ] ──▶ Mengisi teks asli (menggunakan Whisper / anotasi manual)
│
▼
[ 3. Pelatihan Model TTS ] ──▶ Siap dilatih pada VITS, FastSpeech, Coqui TTS, Tacotron
Contoh Mengisi Transkripsi Otomatis Menggunakan OpenAI Whisper:
Setelah malevolentslice selesai memotong audio, Anda dapat memperbarui metadata.csv dengan teks ucapan asli secara otomatis:
import csv, os
import whisper
model = whisper.load_model("base")
metadata_file = "dataset/metadata.csv"
updated_rows = []
with open(metadata_file, "r", encoding="utf-8") as f:
reader = csv.reader(f, delimiter="|")
for row in reader:
seg_id = row[0]
audio_path = os.path.join("dataset", "wavs", f"{seg_id}.wav")
if os.path.exists(audio_path):
result = model.transcribe(audio_path, language="id")
text = result["text"].strip()
updated_rows.append([seg_id, text, text])
with open(metadata_file, "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f, delimiter="|")
writer.writerows(updated_rows)
print("metadata.csv berhasil diperbarui dengan transkrip wicara asli!")
📊 Indikator Pemantau Memori RAM
Sistem secara aktif memantau konsumsi Resident Set Size (RSS) memori fisik komputer melalui pustaka psutil:
STABLE($\le 100\text{ MB}$): Alokasi memori fisik berada dalam batas amplop ideal sistem. Memori dibersihkan secara agresif olehgc.collect()setelah tiap blok selesai diproses, membuktikan alokasi memori konstan $O(1)$.ELEVATED($> 100\text{ MB}$): Penggunaan RAM meningkat melebihi ambang batas 100 MB (misal saat parameter buffer diperbesar).
🧪 Pengujian Unit & Validasi
Jalankan pengujian menggunakan pytest untuk memverifikasi fungsionalitas:
pytest -v
📄 Lisensi
Proyek ini dilisensikan di bawah lisensi MIT.
Release files for malevolentslice 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| malevolentslice-0.1.0.tar.gz | 1.5 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| malevolentslice-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.1 MB
Release files / malevolentslice-0.1.0.tar.gz
| Download URL | malevolentslice-0.1.0.tar.gz |
|---|---|
| Size | 1.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9c7bdcccc3b6cfb5f3d4b396c2a4ceefb282a3a2535f0a8357b60c6c8038b05c
|
|
BLAKE2b-256 checksum How to use checksums |
1aea4346826f25f0d75da4724f15da80b410805f1b14b4f555c45933e3df440c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / malevolentslice-0.1.0-py3-none-any.whl
| Download URL | malevolentslice-0.1.0-py3-none-any.whl |
|---|---|
| Size | 1.6 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8c62c8077b0782cc4366a53cf7502867602edd36409067f7d01529d5eb9b1793
|
|
BLAKE2b-256 checksum How to use checksums |
006e609172dc3a226ceb26a9d430cee204a0758b2b432213a7ceec0bee6c84b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|