Cara termudah untuk mendeteksi di mana amplop audio mulai dan berhenti


43

Di bawah ini adalah sinyal yang mewakili rekaman seseorang berbicara. Saya ingin membuat serangkaian sinyal audio yang lebih kecil berdasarkan ini. Idenya adalah untuk mendeteksi kapan suara 'penting' dimulai dan diakhiri dan gunakan itu untuk spidol untuk membuat potongan audio baru. Dengan kata lain, saya ingin menggunakan keheningan sebagai indikator kapan audio 'chunk' mulai atau berhenti dan membuat buffer audio baru berdasarkan ini.

Jadi misalnya, jika seseorang mencatat dirinya berkata

Hi [some silence] My name is Bob [some silence] How are you?

maka saya ingin membuat tiga klip audio dari ini. Satu yang mengatakan Hi, satu yang mengatakan My name is Bobdan satu lagi yang mengatakan How are you?.

Ide awal saya adalah menjalankan buffer audio terus-menerus memeriksa di mana ada area amplitudo rendah. Mungkin saya bisa melakukan ini dengan mengambil sepuluh sampel pertama, rata-rata nilainya dan jika hasilnya rendah maka label sebagai diam. Saya akan melanjutkan buffer dengan memeriksa sepuluh sampel berikutnya. Semakin bertambah dengan cara ini saya bisa mendeteksi di mana amplop mulai dan berhenti.

Jika ada yang punya saran tentang cara yang baik, tetapi sederhana untuk melakukan ini, itu akan bagus. Untuk tujuan saya solusinya bisa sangat sederhana.

Saya bukan pro di DSP, tetapi mengerti beberapa konsep dasar. Juga, saya akan melakukan ini secara terprogram sehingga akan lebih baik untuk berbicara tentang algoritma dan sampel digital.

Terima kasih atas semua bantuannya!

masukkan deskripsi gambar di sini


EDIT 1

Sejauh ini tanggapan luar biasa! Hanya ingin mengklarifikasi bahwa ini bukan pada audio langsung dan saya akan menulis sendiri algoritma di C atau Objective-C sehingga solusi apa pun yang menggunakan perpustakaan bukan pilihan.


1
Sepertinya Anda mencoba untuk memecahnya menggunakan periode keheningan sebagai titik istirahat. Mengapa tidak menggunakan power thresholding untuk menentukan "keheningan", dan memiliki waktu ambang untuk menentukan apakah itu cukup lama untuk membentuk jeda?
Jim Clay

@ Jimclay Ya, itulah yang saya coba lakukan. Saya belum pernah mendengar tentang power thresholding, tetapi sepertinya sesuatu yang bisa saya gunakan. Apakah ini rumit? Bisakah Anda mengembangkannya sedikit?
Eric Brotto

@EricBrotto Mungkin Anda harus memberi tahu kami sedikit tentang kemampuan apa yang Anda miliki di perpustakaan Anda. Itu akan memungkinkan kami untuk memijat metodologi yang sebenarnya untuk Anda lebih baik.
Spacey

pendekatan untuk deteksi keheningan ini lebih baik ?? apa yang seharusnya menjadi level selain dari 0,05 x = wavread ('s1.wav'); i = 1; sementara abs (x (i)) <0,05% Pendeteksian senyap i = i + 1; end x (1: i) = []; x (6000: 10000) = 0;
zeee

Jawaban:


26

Ini adalah masalah klasik deteksi wicara . Hal pertama yang harus dilakukan adalah konsep Google. Ini banyak digunakan dalam komunikasi digital dan sudah ada banyak penelitian yang dilakukan pada subjek dan ada makalah yang bagus di luar sana.

Secara umum, semakin banyak kebisingan latar belakang Anda harus berurusan dengan metode pendeteksian bicara Anda yang lebih rumit. Jika Anda menggunakan rekaman yang diambil di ruangan yang sunyi, Anda dapat melakukannya dengan sangat mudah (lebih belakangan). Jika Anda memiliki semua jenis kebisingan saat seseorang berbicara (truk lewat, anjing menggonggong, menghancurkan piring, alien menyerang), Anda harus menggunakan sesuatu yang jauh lebih pintar.

Melihat bentuk gelombang yang Anda pasang, kebisingan Anda minimal, jadi saya sarankan yang berikut:

  1. Ekstrak amplop sinyal
  2. Pilih ambang batas yang baik
  3. Mendeteksi tempat di mana besarnya amplop melebihi ambang batas

Apa artinya semua ini? Sebuah amplop dari sinyal adalah kurva yang menggambarkan besarnya dari waktu ke waktu, secara independen dari bagaimana konten frekuensi membuatnya terombang-ambing (lihat gambar di bawah).

masukkan deskripsi gambar di sini

Ekstraksi amplop dapat dilakukan dengan membuat sinyal baru yang berisi nilai absolut dari sinyal asli Anda, misalnya menjadi , dan kemudian low-pass memfilter hasilnya. Filter low-pass paling sederhana dapat diimplementasikan dengan mengganti setiap nilai sampel dengan rata-rata tetangga N -nya di kedua sisi. Nilai N terbaik dapat ditemukan secara eksperimental dan dapat bergantung pada beberapa hal seperti laju sampling Anda.{ 1 , 45 , 6 , 2 , 43 , 2 ... }{1,45,6,2,43,2}{1,45,6,2,43,2}

Anda dapat melihat dari gambar bahwa Anda tidak memiliki banyak noise, amplop sinyal Anda akan selalu berada di atas ambang batas tertentu (tingkat kenyaringan suara), dan Anda dapat mempertimbangkan daerah-daerah itu sebagai daerah yang terdeteksi ucapan .


3
Saya sebenarnya menerapkan ini sebagai salah satu plug-in di winamp good'ol. Apa yang Anda gambarkan itu baik tetapi tidak cukup. Biasanya ada suara bersuara (vokal) dan suara tidak bersuara (konsonan). Jika hanya ada suara bersuara, apa yang Anda gambarkan akan bekerja - tetapi suara tidak bersuara adalah energi yang sangat rendah dan mereka tidak dapat dibedakan dari kebisingan umum. Dan kondisi tanpa kebisingan juga sangat jarang bahkan di studio.
Dipan Mehta

bagaimana mencapai ini dengan python?
kRazzy R

26

Apa yang benar-benar ingin Anda lakukan pada dasarnya disebut sebagai Deteksi Aktivitas Suara atau deteksi ucapan.

Pada dasarnya setiap sinyal ucapan murni (yang tidak mengandung musik) memiliki tiga bagian.

  1. Suara yang disuarakan - yang pada dasarnya disebabkan oleh Vokal
  2. Suara tidak disuarakan - yang berisi konsonan.

Karakteristik suara manusia sedemikian rupa sehingga sementara banyak energi digunakan dalam suara bersuara, informasi nyata terkandung dalam konsonan. Juga, suara bersuara biasanya frekuensi yang lebih rendah di mana suara tidak bersuara adalah frekuensi yang lebih tinggi. [Lebih tepatnya semua suara yang disuarakan beresonansi lebih atau kurang dari frekuensi konstan untuk orang tertentu yang merupakan titinanya].

Sekarang, karena sistem apa pun ada kebisingan. Suara yang disuarakan biasanya cukup kuat sehingga dapat dibedakan terlihat. Ketika Anda menerapkan pemfilteran frekuensi yang lebih rendah, namun dimungkinkan untuk mengumpulkan suara dengan suara berskala besar yang baik, suara yang tidak disuarakan (dengan semua informasi yang kaya) akan hilang.

Datang ke pertanyaan bagaimana menyelesaikannya:

Triknya terletak pada fakta bahwa suara tidak bersuara masih berasal dari sumber beresonansi; dan secara inheren dibatasi pada frekuensi tertentu. Padahal, suaranya agak seragam. Jadi ukuran sederhana yang membedakan ketiganya adalah "kekuatan lokal" atau sebagai alternatif tetapi setara adalah dengan mengambil korelasi otomatis berjendela.

Jika Anda mengambil pada suatu waktu katakan 100 sampel - dan otomatis berkorelasi sendiri, jika hanya mengandung noise hasilnya akan hampir nol (ini adalah properti dari white noise) di mana sebagai sinyal suara, besarnya ini akan dapat diamati karena sinyal masih memiliki struktur yang lebih baik. Ini berhasil bagi saya di masa lalu.

VAD telah menjadi area penelitian aktif - karena hampir semua komunikasi telepon seluler ingin mendeteksi bagian yang tidak dapat berbicara dan menghapusnya dari pengodean. Tetapi jika mereka akan menghapus ucapan tidak bersuara, ini akan membuat telepon menjadi tidak berguna.

Standar G.729 menghitung VAD berdasarkan pada fitur-fitur seperti: frekuensi spektral garis, energi pita penuh, energi pita rendah (<1 kHz), dan laju penyilangan nol.

Standar GSM berfungsi sebagai berikut: Opsi 1 menghitung SNR dalam sembilan pita dan menerapkan ambang batas untuk nilai-nilai ini. Opsi 2 menghitung parameter yang berbeda: daya saluran, metrik suara, dan daya derau. Kemudian ambang metrik suara menggunakan ambang yang bervariasi sesuai dengan perkiraan SNR. (dari wikipedia)

Untuk teknik yang lebih maju saya daftar beberapa referensi tentang hal ini

  1. Referensi yang paling sering dicari : Jongseo Sohn; Nam Soo Kim; Wonyong Sung; "Deteksi aktivitas suara berbasis model statistik" Signal Processing Letters, IEEE, Jan 1999, Volume: 6 Masalah: 1 pp: 1-3

  2. Paling relevan untuk Anda: Mark Marzinzik dan Birger Kollmeier "Deteksi Jeda Pidato untuk Estimasi Spektrum Bising dengan Menelusuri Dinamika Amplop Daya" TRANSAKSI IEEE PADA PENGOLAHAN SPEECH DAN AUDIO, VOL. 10, TIDAK. 2, FEBRUARI 2002 hal.109

  3. Ramírez, J .; JM Górriz, JC Segura (2007). "Deteksi Aktivitas Suara. Fundamentals dan Robustness System Recognition Speech". Dalam M. Grimm dan K. Kroschel. Pengakuan dan Pemahaman Bicara yang Kuat. hlm. 1–22. ISBN 978-3-902613-08-0.

  4. Pendahuluan: Jonathan Kola, Carol Espy-Wilson dan Tarun Pruthi "Deteksi Aktivitas Suara"


bagaimana mencapai ini dengan python?
kRazzy R

9

Saya akan benar-benar mendukung Jim Clay dalam pendekatannya, tetapi sedikit memvariasikan rasanya menggunakan amplop:

Kita tahu bahwa bicara terutama terjadi sekitar 1-2kHz. Pengambilan sampel data Anda kemungkinan 44kHz (ini tergantung pada perangkat rekaman Anda). Jadi apa yang akan saya lakukan pertama adalah rata-rata bergerak dari sinyal kuadrat secara real time di 10 titik, untuk memiliki amplop kekuatan sinyal. Itu akan menyebabkan keterlambatan dalam deteksi, sehingga Anda ingin tetap rendah.

Kemudian, saya akan menambahkan fase kalibrasi pada sistem Anda: minta pengguna untuk tetap diam, tekan tombol, dan rekam kebisingan latar belakang selama 10 detik. Ambil amplitudo rata-rata atau rata-rata amplop, kalikan dengan 2 untuk mendapatkan keamanan, dan itu akan memberi Anda ambang yang telah dibicarakan oleh Jim, secara otomatis.

Jika ini bukan perekaman real-time, Anda mungkin menemukan berguna untuk menggunakan rata-rata bergerak 0-fase untuk mengurangi gangguan yang disebabkan oleh penundaan. Beri tahu kami jika itu berhasil untuk Anda.


9

Eric,

Jika Anda benar-benar mencari sesuatu yang cepat dan kotor, hal pertama yang harus Anda dapatkan adalah amplop, dan saya akan melakukan ini secara sederhana (dalam MATLAB) dengan:

 envelope = abs(hilbert(yourSignal));

Pada titik itu, saya hanya akan ambang, dan 'suara ada' jika Anda berada di atas ambang batas tertentu.

Ini adalah solusi yang sangat sederhana, tetapi mungkin berhasil untuk Anda.


1
+1. Mungkin Anda bisa menguraikan metode di balik baris kode ini? Saya yakin OP tidak terbiasa dengan ekstraksi amplop melalui Hilbert Transform.
Phonon

@Mohammad, terima kasih! Tapi tolong lihat EDIT 1. Saya pasti ingin yang cepat dan kotor, tetapi juga perlu melakukan algoritma sendiri :)
Eric Brotto

@EricBrotto Ah ok, well, saya bisa memberi tahu Anda cara menerapkan transformator hilbert, tapi saya berasumsi Anda memiliki kemampuan untuk melakukan FFT di perpustakaan C / Obj-C Anda? Jika tidak, itu akan menjadi masalah ... :-)
Spacey

bagaimana mencapai ini dengan python?
kRazzy R

Tuan / Nyonya yang Baik, bisakah Anda mengarahkan saya ke sumber tentang bagaimana hilbert ini diimplementasikan dalam Python?
kRazzy R

6

Saya berasumsi bahwa Anda berurusan dengan sinyal nyata, bukan kompleks - jika itu tidak terjadi, beri tahu saya dan saya dapat mengubah jawabannya.

Daya didefinisikan sebagai kuadrat dari sinyal (yaitu sampel sinyal dikalikan sendiri). Anda dapat membandingkan kekuatan dengan beberapa ambang batas untuk menentukan apakah ada ucapan atau tidak. Anda mungkin perlu melakukan beberapa pengukuran pada rekaman Anda untuk secara empiris menemukan ambang batas yang baik.

Jika rekaman Anda "bersih" (yaitu tidak banyak suara), saya mungkin akan sesederhana mungkin dengan membandingkan daya sesaat (yaitu sampel tunggal) ke ambang batas. Ini berarti bahwa Anda bahkan tidak perlu mengkuadratkannya jika Anda tidak mau, Anda hanya perlu nilai absolut dan membandingkannya dengan akar kuadrat dari batas daya, yang dapat dikomputasi sebelumnya. Ketika Anda mendeteksi ucapan, ambil dan jumlah rekaman sebelum itu, untuk memastikan Anda mendapatkan semua pidato (mungkin 1/10 per detik?). Terus sampai Anda menemukan periode berkepanjangan tidak ada sampel yang melebihi ambang batas. Sekali lagi, panjang periode perlu ditentukan secara empiris.

Bilas dan ulangi.


4

Saya telah menulis kelas pendeteksi aktivitas di Jawa. Itu bagian dari koleksi Java DSP open-source saya . Anda dapat menggunakan program uji WavSplitter.java untuk memeriksanya dengan file WAV sebagai input.


Ingatlah OP secara khusus mengatakan dia perlu menulis sendiri algoritme dalam C.
Sam Maloney

Sangat mudah untuk mengonversi algoritme semacam itu dari Jawa ke C.
Christian d'Heureuse

Pak, bagaimana mencapainya dengan python?
kRazzy R
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.