Ini detektor pendengkur saya lagi.
Saya sudah cukup baik dalam mendeteksi sinyal ketika ada sesuatu di sana - dapat melacak dari mendengkur dinding ke bernafas Anda bahkan tidak dapat mendengar dalam rekaman. Masalahnya adalah, saya tidak tahu kapan sinyalnya turun di bawah level yang dapat dideteksi dan aplikasinya hanya "mendengar hal-hal". Dan, sayangnya, mendengkur / bernafas sering tidak teratur sehingga autokorelasi sederhana atau skema pengaturan waktu yang serupa tidak akan banyak membantu. (Dan sebenarnya ada kemungkinan bahwa dalam beberapa kasus kebisingan lebih teratur daripada pernapasan.)
Jadi, apakah ada trik yang saya lewatkan untuk mencari tahu ketika tidak ada sinyal? Sepertinya saya menentang tempat yang keras di sini, mengingat "sinyal" begitu berisik.
(Dan mungkin ini terkait dengan masalah lain yang saya alami: Anehnya, saya tidak dapat secara akurat (atau bahkan kurang lebih) mengukur level sinyal bahkan ketika cukup keras. Karena saya perlu menggunakan rolling average dan rasio untuk mendeteksi sinyal, jenis informasi level hilang. Saya mencari beberapa trik untuk menyusunnya kembali.)
Teknik dasar
(Untuk Yoda)
Sinyal audio diambil sampelnya (umumnya pada 8000Hz, karena berbagai alasan), kemudian FFT dalam 1024 blok. (Dalam eksperimen saya, filter Hamming dan blok yang tumpang tindih tampaknya memiliki sedikit pengaruh, meskipun itu mungkin ditinjau kembali nanti.)
FFT dibagi menjadi "band" (saat ini 5, sedikit miring dalam ukuran untuk menempatkan lebih detail pada ujung bawah) dan "perbedaan spektral" dan tingkat masing-masing band dijumlahkan. Rata-rata jangka panjang dari nilai-nilai puncak-terbatas digunakan sebagai "ambang", dan penyesuaian bias lebih lanjut digunakan untuk mempertahankan tingkat sekitar 20% "melampaui ambang batas".
Setiap nilai "melebihi ambang batas" diberi bobot 1 (di bawah ambang diberi bobot 0), tetapi kemudian bobot itu disesuaikan dengan "variabilitas" yang tampak (sekitar 2Hz) dalam pita, untuk memberikan bobot lebih kepada pita yang membawa sinyal lebih jelas.
Bobot band dirangkum dan kemudian bobot dijumlahkan dari blok berikutnya dijumlahkan sekitar satu detik untuk menghasilkan "skor" berjalan. Ini lagi dibandingkan dengan ambang rata-rata berjalan (ditambah beberapa heuristik) untuk mendeteksi onset / offset mendengkur.
Memperbarui
Tiba-tiba terpikir oleh saya bahwa jika algoritma saya secara efektif mempertahankan sinyal level konstan (per masalah level sinyal saya), cara untuk mengukur SNR secara efektif adalah dengan mengukur noise ketika tidak ada sinyal.
Nyaman, mendengkur berselang-seling, dengan banyak "udara mati" di antaranya. Dan saya sudah mendeteksi amplop mendengkur. Jadi segala sesuatu di luar amplop (antara akhir satu dengkuran dan permulaan yang berikutnya) mungkin berisik! Ini saya dapat (dengan beberapa tingkat akurasi / pengulangan). (Butuh tiga kali percobaan untuk menghasilkan algoritma yang layak setengah jalan, tentu saja - kenyataan tidak pernah cocok dengan teorinya.)
Jadi saya belum memiliki jawaban lengkap, tetapi saya telah membuat kemajuan.
(Walaupun teknik di atas memberi saya proksi yang cukup baik untuk SNR, saya masih mengalami kesulitan memperkirakan tingkat sinyal aktual. Indikasi "level relatif" saya bisa keluar dari skala untuk nafas yang nyaris tak terdengar dan begitu-begitu untuk pengadu jendela. Saya perlu semacam proxy untuk level absolut.)