Przeszukaj forum
Pokazywanie wyników dla tagów 'I2S'.
Znaleziono 2 wyniki
-
Cześć, rozbudowując wcześniejszy projekt Akwizycja danych sensorycznych postanowiłem pobierać również danych z mikrofonów. Po długiej walce z konfiguracją interfejsu SAI, doszedłem do etapu konwersji sygnałów PDM na PCM w użyciem biblioteki pdm2pcm. Czy ktokolwiek z Was korzystał z niej wcześniej? Niby producent dostarcza sporo materiałów informacyjnych, ale nawet po kilkukrotnym ich obejrzeniu stanąłem w miejscu. Parametry systemu: - 4 mikrofony PDM podłączone do 1 linii SCK (3.072 MHz) i dwóch linii danych (2 pary po 2 mikrofony) - długość ramki 32 bity (w ramce dane z wszystkich 4 mikrofonów) - sampling rate 48 kHz (akwizycja dźwięku do 24 kHz) - decimation factor 64 - wykorzystanie DMA. Moim celem jest przerobienie danych PDM na PCM. Chciałbym mieć 4 osobne tablice PCM, każda zawierająca dane z innego mikrofonu (oczywiście może być też 1 tablica, którą sobie "ręcznie" rozdzielę). Na razie chodzi mi o zarejestrowanie kilkuminutowej ścieżki audio i jej zapis na kartę pamięci w sposób umożliwiający rozdzielenie 4 ścieżek z różnych mikrofonów. Jakich wielkości buforów na dane PDM oraz PCM powinienem użyć? W CubeIDE przy pdm2pcm ustawić 1 kanał czy 4? in_ptr_channels powinno być równe 4? out_ptr_channels powinno być równe 1 czy 4? Jaką wartość output_samples_number wybrać? Producent podaje, że w PDM_filter_handler powinien być skonfigurowany dla każdego mikrofonu osobno, natomiast w CubeIDE generuje mi się tylko 1 handler w pliku pdm2pcm.c (jeżeli liczba kanałów jest równa 1). Czy zatem How many channel do you use? ustawić mam na 4? Jeżeli ktokolwiek miał z tym do czynienia lub po prostu jest w stanie pomóc, proszę o informację.
-
Za chwilę mnie coś strzeli... Program najprostszy chyba z możliwych (bez żadnych bibliotek): #include <Arduino.h> #include <i2s_reg.h> #include <i2s.h> int g_samrate = 8000; uint32_t last_micro_call; uint32_t idle_micros = 100000; void init_audio() { i2s_begin(); i2s_set_rate(g_samrate); last_micro_call = micros(); } void put_sample(int16_t sample) { uint32_t usample; usample = sample & 0x0000ffff; usample |= usample << 16; if (micros() - last_micro_call > idle_micros) { last_micro_call = micros(); yield(); } // wersja 1 najprostsza - działa źle i2s_write_sample(usample); /* // wersja 2 - to samo while (i2s_is_full()) { delay(1); last_micro_call = micros(); }*/ /* // wersja 3 - to samo while (!i2s_write_sample_nb(usample)) { delay(1); last_micro_call = micros(); }*/ } void finalize_audio() { for (int i=0; i<1000 && !i2s_is_full(); i++) i2s_write_sample_nb(0); i2s_end(); } void setup(void) { } void loop(void) { int i; init_audio(); for (i=0;i<4000;i++) { float a = i * (3.141592/10); int16_t s = sin(a) * 4096; put_sample(s); } finalize_audio(); delay(500); } Efekt działania: co prawda pika sobie bardzo ładnie, ale mniej więcej połowa (całkowicie losowo) "piknięć" jest głośniejsza i zniekształcona - tak jakby wejściowa próbka przesunęła się o bit w lewo. Miałem podobny efekt kiedyś gdy próbowałem coś zrobić z TDA1543 ale uznałem, że to pewnie wina połączeń na paszczatej płytce stykowej albo 8kHz to dla niego za mało... Co ciekawsze - podobny program, ale używający hacku PWM działa ślicznie... Ktoś coś... jakieś pomysły? Bo mi się skończyły 😞 Po sprawdzeniu: zamiana na bibliotekę ESP8266Audio i użycie AudioOutputI2S nic nie zmienia.