Strumień bajtów mikrofon

0

Chciałbym napisać/zrobić własny oscyloskop. Do próbkowania wykorzystał bym wejście na na mikron, ma ono częstotliwość próbkowania 44kHz, takie rzeczy już istnieją więc to nie jest science fiction. Problem jest taki że w językach wyższego poziomy garbacz kolektor się miesza we wszytko i powoduje utratę części danych próbek, i zastanawiam się czy w C/C++ istnieje możliwość pewnej rejestracji danych z mikrofonu. Pewnej znaczy żeby nie tracić próbek i nie mieszać kolejności, szybkość nie jest istotna nie potrzebuje ich real time. I drugie czy dało by rade pewnie wysłać te dane do innego programu, dużo szybciej można zrobić UI javie czy C# niz w c/c++.

0

Jaki system operacyjny? Prawdopodobnie, aby mieć pewność, że wszystko odczytujesz, będziesz musiał dostać się do urządzenia bezpośrednio. W przypadku linux'a dostajesz się przez plik w /dev, oraz konfigurujesz różne ustawienia ioctl'em.
W windowsie jeżeli nic takiego nie istniej co pozwala na dostęp, prawdopodobnie będziesz musiał napisać własną wersję drivera?
Nie znam się na windowsach i ich budowie, ale co mogę Ci powiedzieć, to to, że w przypadku linux'a sprawę masz praktycznie załatwioną. Różna może być nazwa urządzenia dla róznych systemów, natomiast sama implementacja sprzętowa, programowa (niskiego poziomu), kompletnie Cię nie interesuje.

3
topik92 napisał(a):

Problem jest taki że w językach wyższego poziomy garbacz kolektor się miesza we wszytko i powoduje utratę części danych próbek

Że co? Coś ci się miesza, albo przeczytałeś jakąś bzdurę w internecie.
Albo jakiś programisty mądry inaczej, w ten sposób umywa rączki od bug-a w swoim kodzie.

0

Przeczytałem :(. Moze to dotyczyło tylko ich Api, moze ktoś to zmyślił, moze to prawda, nie wiem :(

0

z GC jest taki problem, że w nieprzewidywalnym momencie może odpalić przerywając działanie programu, i próbki w tym czasie nadchodzące rzeczywiście mogą być tracone, bo nie będą odbierane na czas.
I wcale nie chodzi tu o bugi w kodzie.
Chociaż nowsze wersje .NETa (od 4 w górę) podobno są pod tym względem lepsze.
Można też zmniejszyć prawdopodobieństwo odpalenia kolektora nie alokując żadnych nowych obiektów podczas próbkowania.

Z drugiej strony 44 kHz to nie jest jakoś strasznie dużo i myślę że wyolbrzymiasz problem.

zastanawiam się czy w C/C++ istnieje możliwość pewnej rejestracji danych z mikrofonu

Oczywiście.

0

Jak chcesz się bawić czymś nowym (i mniej błędogennym niż C/C++) to masz https://github.com/RustAudio/rust-portaudio

0

Według mnie jedyny przypadek kiedy w takim programie GC może coś bruździć, to generowanie sygnału na karcie dźwiękowej, przepuszczanie go przez badany układ elektroniczny i analizowanie sygnału jaki dociera do wejścia mikrofonowego.
Jeśli program nie zdąży wygenerować danych wyjściowych to wtedy faktycznie jest problem, ale wtedy brakuje próbek dla karty dźwiękowej, a nie dla programu.
Natomiast w przypadku próbek wejściowych problemu nie powinno być, bo próbki powinny być zbuforowane w czasie gdy działa GC.

0

Okazało się że przez braki dokładności przy pomiarze czasu nie da rady dobrze zaimplementować jednej fikcjonalności <3

1
topik92 napisał(a):

Okazało się że przez braki dokładności przy pomiarze czasu nie da rady dobrze zaimplementować jednej fikcjonalności <3

?
Dziwne. Można pobrać częstotliwość próbkowania karty dźwiękowej i uznać, że czas między próbkami jest stały, nie wiem po co ci jakieś dodatkowe pomiary czasu.

0

Okazało się że przez braki dokładności przy pomiarze czasu nie da rady dobrze zaimplementować jednej fikcjonalności

„fikcjonalności” to chyba rzeczywiście nie :-)

Może napisz do czego ci pomiar czasu. QueryPerformanceTimer/QueryPerformanceFrequency przy próbkowaniu 44 kHz powinno wystarczyć aż nadto.

0

W telegraficznym skrócie powiedzmy że ambitnie chce wyświetlić sygnał o częstotliwości 1kHz(okres 1ms) 44,1 próbki wiec jakość będzie to wyglądać. Oscyloskop ma taką opcje że wyświetla że wyświetla x ms potem kolejne i jak trafi się w okres to robi się stan quasi-ustalony sygnał "stoi" lub lekko płynie. Monitor mogę odświeżać tylko 60 razy na sekundę(16 ms-16 okresów). więc muszę sobie wartości kolejnych próbek do wyrzucenia na monitor estymować. Żeby przewidzieć co trzeba z dokładnością 1% bład na okres musi być mniejszy niż 0,000625 ms. 44,1 próbek na ms "to taka sobie "wartość więc muszę uwzględniać dt na początku i na końcu okresu żeby obraz nie skakał i uwzględniać je przy kolejnych estymacjach. Z biblioteki która Jest(i innej nie mam) mogę odbierać dane w postaci tablicy co ~100 ms. Dziesiąte części sekundy mają się tak do milionowych części sekundy że o pomiarze czasu jakimkolwiek timerem nie ważne jak dokładnym, mogę zapomnieć. Uroku dodaje fakt że kontrolka z wykresem jest w UI thread, i nie mogę jej od tak zmieniać z innego wątku, i odświeżam ją winformsowym timerem o rozdzielczości ~16ms :D.

Syzyfowa robota zamiast tego wykrywam zbocze narastające, i przejście przez 0 :P

1

Używałeś kiedyś oscyloskopu? Rozumiesz jak działa? Wygląda na to, że nie.
To, że sygnał "robi się stan quasi-ustalony" to jest wynik ustawienie właściwego trigera na oscyloskopie. Oscyloskop nie wyświetla wszystkiego jak leci, ale tylko wybrane ramki czsowe, które zostaną wykryte przez "triger".
Chodzi mi o to, że nie masz wyświetlać wszystkich próbek. Nie jest ci to potrzebne (jeśli ma się to zachowywać jak oscyloskop).
Równocześnie musisz napisać mechanizm, który będzie odtwarzał zachowanie trigera (np przejście w "góre" do jakiejś wartości wyznacza ci jakiś moment na osi czasowej).

0

Oscyloskop ma taką funkcje jak napisałem, z reguły korzysta sie z wyzwalaczy bo są bardziej praktyczne, ale MA taką funkcje. Możesz sprawdzić w pisując oscilloscope free running mode, w google

Nie pisałem też o wyświetlaniu wszystkich próbek, wręcz przeciwnie, tylko o wyświetlaniu tylko tego co trzeba czyli okna czasowego co 16ms czyli 60hz czyli tyle żeby "ekran chodził płynnie".

Poza tym o wykrywaniu przejścia przez 0 i zbocza narastającego pisałem, na dole tam tego postu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1