import argparse import tempfile from pathlib import Path import joblib from audio_utils import SUPPORTED_AUDIO_EXTENSIONS, convert_to_wav from features import LABEL_PD, LABEL_TPD, extract_features BASE_DIR = Path(__file__).resolve().parent MODEL_PATH = BASE_DIR / "models" / "svm_voice_confidence_model.joblib" CONFIDENCE_THRESHOLD = 0.60 LABEL_DESCRIPTION = { LABEL_PD: "Percaya Diri", LABEL_TPD: "Tidak Percaya Diri", } def prepare_audio_for_prediction(audio_path): """ Menyiapkan audio prediksi menjadi WAV mono 22050 Hz. Path hasil konversi dikembalikan bersama flag apakah file temporer perlu dihapus. """ audio_path = Path(audio_path) extension = audio_path.suffix.lower() if extension not in SUPPORTED_AUDIO_EXTENSIONS: allowed = ", ".join(sorted(SUPPORTED_AUDIO_EXTENSIONS)) raise ValueError(f"Format audio tidak didukung: {extension}. Format yang didukung: {allowed}") temp_wav_path = Path(tempfile.NamedTemporaryFile(delete=False, suffix=".wav").name) convert_to_wav(audio_path, temp_wav_path) return temp_wav_path def predict_audio(audio_path, model_path=MODEL_PATH): """ Memprediksi satu file audio. Audio diproses dengan preprocessing dan ekstraksi fitur yang sama seperti training. """ model = joblib.load(model_path) temp_wav_path = prepare_audio_for_prediction(audio_path) try: features = extract_features(temp_wav_path).reshape(1, -1) predicted_label = model.predict(features)[0] probabilities = model.predict_proba(features)[0] class_probabilities = dict(zip(model.classes_, probabilities)) confidence = class_probabilities[predicted_label] finally: temp_wav_path.unlink(missing_ok=True) return predicted_label, LABEL_DESCRIPTION[predicted_label], confidence, class_probabilities def main(): parser = argparse.ArgumentParser(description="Prediksi tingkat percaya diri dari audio") parser.add_argument("audio_path", help="Path file audio yang ingin diprediksi") args = parser.parse_args() audio_path = Path(args.audio_path) if not audio_path.exists(): raise FileNotFoundError(f"File tidak ditemukan: {audio_path}") label, description, confidence, probabilities = predict_audio(audio_path) probability_pd = probabilities.get(LABEL_PD, 0.0) probability_tpd = probabilities.get(LABEL_TPD, 0.0) print("=== Hasil Prediksi ===") print(f"File : {audio_path}") print(f"Prediksi : {label}") print(f"Keterangan : {description}") print(f"Confidence : {confidence * 100:.2f}%") print(f"Probabilitas PD : {probability_pd * 100:.2f}%") print(f"Probabilitas TPD : {probability_tpd * 100:.2f}%") if confidence < CONFIDENCE_THRESHOLD: print( "Peringatan : Model belum yakin, suara perlu direkam ulang " "atau data training perlu ditambah." ) if __name__ == "__main__": main()