Bagaimana kami menguji sistem mikrofon pada STM32: pengalaman pengembang perangkat Yandex



Hai, saya Gennady "Crail" Kruglov dari tim solusi perangkat keras Yandex.

Pemilihan mikrofon untuk matriks mikrofon adalah bagian yang kompleks dan menarik dari pekerjaan kami: kami menguji model dengan berbagai parameter, bereksperimen dengan berbagai konfigurasi matriks, dan meningkatkan algoritma pemrosesan suara.

Sangat nyaman bagi pengembang yang membuat algoritma pengurangan gema dan kebisingan untuk tidak hanya memproses data mentah yang sebelumnya diambil dari perangkat di laboratorium, tetapi juga untuk berinteraksi, misalnya, dengan matriks mikrofon baru secara real time dengan menghubungkannya ke laptop mereka.

Tampaknya sederhana hanya pada pandangan pertama. Pada artikel ini saya akan menjelaskan bagaimana kami memecahkan masalah mentransfer suara dari tujuh mikrofon dengan antarmuka PDM ke komputer melalui USB, nuansa perangkat keras dan perangkat lunak apa yang kami temui dan bagaimana cara mengatasinya (spoiler: pendekatan ini dapat disesuaikan untuk matriks dengan jumlah mikrofon โ‰ค 8 ) Di akhir posting saya akan membagikan tautan ke stream, tempat saya menunjukkan proses pengembangan pada mikrokontroler STM32, dan berbicara tentang seri selanjutnya.

Perumusan masalah


Sedikit latar belakang: untuk membuat berkas kepekaan yang terkontrol, untuk Yandex.Station pertama, rangkaian dengan tujuh mikrofon (analog) dipilih, untuk versi Mini - dengan empat (sudah digital). Untuk produk lain, berbagai konfigurasi dipertimbangkan, tetapi tetap matriks tujuh-mikrofon bagi kami adalah dasar, klasik.

Jadi, diberikan: tujuh mikrofon digital, kebutuhan untuk mengujinya. Temukan: tidak terlalu sulit untuk diterapkan dan cara fleksibel untuk berinteraksi dengan mereka. Adalah logis untuk membagi tugas menjadi dua:

1. Dapatkan data dari mikrofon.

2. Kirim mereka ke komputer.

Pada perangkat yang sudah jadi, ketika pengguna menghubungi Alice, sinyal dari mikrofon digital dikirim langsung ke prosesor pusat (lebih tepat menyebutnya SOC - System-on-Chip, tetapi "prosesor" lebih akrab dan nyaman), ia memiliki kekuatan yang cukup untuk memprosesnya. Tetapi untuk algoritma debugging, jauh lebih mudah untuk mendapatkan data ini langsung ke komputer pengembang. Cara termudah adalah terhubung melalui USB: dengan demikian, board harus memiliki mikrokontroler dengan unit yang sesuai. Kami menyukai pengontrol STM32, tetapi tidak mungkin mengirim aliran suara langsung dari mikrofon ke sana: tidak ada unit penerimaan sinyal PDM (modulasi kepadatan pulsa) - antarmuka keluaran mikrofon digital.

Pilihan lain adalah menghubungkan papan mikrofon ke papan debug dari pabrikan SoC yang digunakan. Tetapi keputusan ini terkait dengan Linux alsamixer, dan parameternya sangat mempengaruhi hasil konversi PDM ke PCM. Blok ini mungkin berbeda tidak hanya untuk prosesor dari pabrikan yang berbeda, tetapi bahkan untuk dua model dari vendor yang sama. Saya mengingatkan Anda bahwa kami membutuhkan solusi sederhana, transparan dan dapat diprediksi.

Solusi perangkat keras


Terima ketidakmampuan STM32 untuk menerima PDM multi-saluran. Seseorang dapat menggunakan blok SPI untuk menerima sinyal PDM, tetapi hanya satu mikrofon yang dapat dihubungkan ke satu bus SPI. Kami bekerja dengan pengontrol STM32L476RC, di mana hanya ada tiga bus seperti itu. Kompleksitas tambahan: sinyal PDM memiliki frekuensi cukup tinggi, perlu melakukan penipisan, rata-rata, pemrosesan, pemfilteran - untuk tujuh mikrofon, tugas ini cukup rumit.

Karena kita berbicara tentang papan debug, dan bukan prototipe untuk produksi massal, kami akan fokus pada chip khusus TSDP18xx. Itu melakukan semua yang diperlukan: itu menghasilkan frekuensi dan sinyal yang diperlukan untuk PDM, rata-rata dan proses sinyal PDM, mengubah semuanya menjadi sinyal I2S. Lebih tepatnya, TDM (Time Division Multiplexing), karena I2S-bus mengasumsikan dua saluran, dan jika Anda berkendara lebih banyak melalui kabel yang sama, tidak lagi benar untuk menyebutnya I2S.

Keuntungan dari pendekatan ini adalah bahwa semua pekerjaan persiapan dan rata-rata dilakukan oleh TSDP. Minus - semua algoritma terhubung dengan kabel di dalam sirkuit mikro ini, dan tidak dapat diubah. Secara khusus, Anda tidak dapat menyesuaikan volume dengan memodifikasi parameter rata-rata. Tetapi untuk debugging, ini tidak penting.

Awasi tangan Anda: ada tujuh mikrofon, delapan saluran di sirkuit mikro. Yang tidak digunakan, output masih ada, jadi di masa depan untuk kesederhanaan saya akan berbicara tentang aliran audio delapan saluran.

Jadi, kami menaikkan TDM delapan saluran ke STM32, kami mendapatkan aliran audio delapan saluran. Bagaimana data bergerak:



SAI - STM32 perangkat keras untuk bekerja dengan I2S / TDM. Ini sangat fleksibel dan memungkinkan Anda untuk mengimplementasikan banyak opsi protokol. Tetapi karena ini, mudah untuk bingung dalam persyaratan untuk frekuensi.

Pohon jam layak untuk dilihat lebih dekat. Sebuah resonator kuarsa 12 MHz terhubung ke mikrokontroler. Kami membagi frekuensi ini sebelum menerapkan ke blok PLL dengan 3 dan mendapatkan 4 MHz. Maka kerjanya seperti ini:

1. Alangkah baiknya untuk membuat frekuensi inti lebih tinggi untuk mengikuti semuanya: misalnya, maksimum untuk pengontrol ini adalah 80 MHz. Kami menggunakan blok PLL pertama: kami mengalikan 4 MHz dengan 40 dan membaginya dengan 2.

2. USB membutuhkan 48 MHz. Untuk melakukan ini, gunakan blok PLL kedua: kalikan 4 MHz dengan 24 dan bagi dengan 2.

3. Tentang mikrofon. Papan uji kami menggunakan frekuensi sampling Fs = 16 kHz, standar yang diadopsi di bidang pengenalan ucapan. Dari frekuensi awal 4 MHz Anda perlu mendapatkan sesuatu yang dapat diubah menjadi frekuensi frame bus TDM 16 kHz (alias LRCK, alias FCK, alias FrameSync). Dalam hal ini:

[frekuensi sinkronisasi bit (BCLK, BitClk, Sync, SCK)] = Fs โˆ™ [jumlah saluran] โˆ™ [jumlah bit per saluran]

Yaitu: SCK = 16 kHz โˆ™ 8 โˆ™ 16 = 2048 kHz.

4. Lembar data menunjukkan bahwa rasio antara Master Clock dan laju sampling Fs adalah sebagai berikut: MasterClock = 16 kHz โˆ™ Pembagi MCLK โˆ™ 256. Di sini 256 adalah konstanta, dan pembagi dapat diatur dalam register. Mari kita periksa skema - untuk fungsionalitas yang diperlukan ada koefisien untuk membagi frekuensi PLL dengan 7 atau 17:



Untuk meringkas masalah: Anda perlu memilih seperangkat faktor PLL dan SAI dan pembagi untuk mendapatkan frekuensi sampling 16 kHz dan frekuensi bit 128 kali lebih banyak. Karena set memiliki pembagi wajib oleh 7 (atau 17), itu tidak berfungsi untuk mendapatkan hasil yang diinginkan. Saya harus membuat tabel pengganda dan pembagi untuk mendapatkan 24.571 MHz. Membagi frekuensi ini dengan 6 (MCLK Divider), dan kemudian 256 (konstan), akhirnya, kami mendapatkan angka yang cukup dekat hingga 16 kHz. Sekarang saya akan menjelaskan mengapa ini sangat penting.

Operasi USB


USB menggunakan jenis transfer isochronous untuk bekerja dengan data multimedia: dalam hal ini, bandwidth dan nilai penundaan tertentu dijamin pada bus USB. Pengiriman data tidak dijamin: jika suatu paket datang dengan kegagalan, maka itu akan dianggap hilang. Ini karena batas waktu yang ketat: tidak ada cara untuk bertanya lagi.

Dengan jenis transfer isochronous pada kecepatan USB FullSpeed โ€‹โ€‹(12 Mbit / s; pada kecepatan inilah blok USB STM32 dapat bekerja) komputer datang ke perangkat untuk data setiap milidetik: setelah periode waktu ini, ia harus mengumpulkan data yang terakumulasi. Biarkan saya mengingatkan Anda yang pengantar: frekuensi sampling adalah 16 kHz, 8 saluran, masing-masing saluran membutuhkan dua byte, karena suara enam belas-bit. Total 16000 โˆ™ 2 โˆ™ 8/1000 = 256 byte per milidetik. Ukuran satu paket untuk jenis transmisi isochronous dapat mencapai 1023 byte, sehingga tidak ada masalah pada saat ini.

Jadi, ukuran paket adalah 256 byte. Tampaknya semuanya baik-baik saja. Enam belas kali menerima data pada TDM, dimasukkan ke buffer, USB datang, kami berikan paket, kami ulangi ... Tapi ini hanya terjadi di dunia yang ideal. Masalahnya adalah bahwa di satu sisi kita memiliki 16 kHz tidak sempurna (sedikit kurang), dan sebagai hasilnya, data datang sedikit kurang dari sekali setiap milidetik. Di sisi lain, milidetik komputer juga mengapung, karena sibuk: ketika bisa, maka itu datang. Artinya, frekuensi pengambilan sampel mikrofon berbeda dari 16 kHz (tetapi selalu sama), dan milidetik USB juga berbeda panjangnya (perbedaannya kemungkinan besar mengambang: ternyata sedikit lebih banyak, kemudian sedikit kurang dari satu milidetik ideal).

Mengapa ini menjadi masalah? Anda bisa kehilangan paket. Mungkin tidak perlu dijelaskan bahwa data lengkap diperlukan untuk debugging yang benar dari algoritma. Bagaimana paket tersebut hilang: mereka mengumpulkan 256 byte hasil, menempatkannya di buffer, dan melanjutkan pengukuran. Komputer datang, mengambil 256 pertama, kami masih terus mengukur. Komputer datang lagi, tetapi pengukuran belum selesai - komputer pergi dengan paket kosong. Kemudian kami selesai mengisi buffer dan mulai mengisi yang lain, yang berikutnya, sampai komputer datang lagi. Komputer hanya mengambil paket terakhir, sebagai hasilnya, satu paket hilang.



Masalahnya, sebenarnya, diketahui. Ada tiga pendekatan untuk menghadapinya:

  • . USB. โ€” . ยซยป โ€” . USB . , , ( , 16 ), . , .
  • . .
  • Asynchronous adalah yang terbaik untuk tugas ini. Perangkat ini memiliki generator frekuensi yang stabil. Kecepatan pengambilan sampel dipertahankan persis sama tanpa merujuk ke USB. Dalam hal ini, Anda perlu mentransfer data ke perangkat sehingga tidak ada perbedaan yang signifikan.

Semua ini telah dibahas lebih dari satu kali di Internet untuk kasus pemutaran dari komputer ke speaker melalui perangkat dengan digital-to-analog coder, di mana perangkat sebagai umpan balik memberitahu Anda berapa banyak periode pengambilan sampel telah datang sejak paket terakhir diterima.



Tetapi tugas kami adalah sebaliknya, debugging membutuhkan penerimaan data dari mikrofon ke komputer, dan pertanyaan tentang merekam sinyal dari mikrofon ke komputer hanya disebutkan yang terbaik. Mengapa tidak melakukan hal yang sama: masukkan umpan balik dari komputer? Ada opsi yang lebih mudah.

Itu dia


Kami sering menggunakan penambahan sampel dan dua buffer untuk menyimpan data untuk pengiriman. 16 kali per milidetik, kami menambahkan ke buffer terpilih sampel berikutnya. Pada titik waktu tertentu, terjadi gangguan: USB mengambil paket sebelumnya. Jika buffer No. 1 penuh, ia beralih ke buffer No. 2. Ketika USB tiba untuk paket berikutnya, ia sudah disiapkan. Kirim nomor penyangga 2 dan kembali ke nomor 1.



USB datang untuk data di berbagai titik waktu, paket menyertakan jumlah sampel yang berbeda. Itu bisa berubah menjadi lebih dan kurang dari enam belas, sehingga ada peluang untuk melebihi paket dengan ukuran 256 byte, lebih baik untuk meninggalkan ruang untuk bermanuver. Biarkan 384 = 256 + 128: ini akan memberikan margin setengah milidetik, yaitu, ia akan memaafkan fase berenang dari sinyal USB sebesar 50% - margin seperti itu harus lebih dari cukup. Total: kadang-kadang lebih atau kurang 256 byte dikirim, tetapi tidak pernah paket kosong, yang menghindari kehilangan data. Artinya, masalah ketidakseimbangan diselesaikan dengan meningkatkan paket, dengan biaya meningkatkan bagian dari bandwidth bus yang dialokasikan untuk perangkat kami dan mengurangi bagian ini untuk perangkat lain.

Tentang ini, pengiriman data ke komputer berakhir. Pengembang dapat didebug, dan Anda dapat mengajukan pertanyaan di komentar jika beberapa jenis paket data tidak cukup untuk pemahaman yang lengkap.

Streaming saya dan episode berikutnya


Akhir-akhir ini saya mengalir dua kali dari lab solder rumah saya. Pada awalnya saya hanya menunjukkan proses penyolderan dan memberi tahu perangkat mana yang saya gunakan. Seri kedua hanya ditujukan untuk pengembangan pada STM32.

Streaming berlanjut. Jumat ini pukul 19.00, kolega saya dari tim pengembangan solusi perangkat keras Andrey Laptev akan mengatur analisis online Yandex.Stations Mini - tunjukkan bagian dalamnya dan bagikan sejarah produksi. Untuk lebih menyenangkan, Andrey akan mengacaukan baterai ke kolom - tidak semua sama, bekerja dari kawat. Di final, Anda akan menerima panduan yang memungkinkan Anda mengulangi pengalaman ini sendiri atau menghasilkan desain yang lebih menarik.

Daftaruntuk menonton arus. Anda akan menerima surat dengan file untuk kalender dan pengingat pada hari udara. Terima kasih telah membaca!

All Articles