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++.
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.
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.
Przeczytałem :(. Moze to dotyczyło tylko ich Api, moze ktoś to zmyślił, moze to prawda, nie wiem :(
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.
Jak chcesz się bawić czymś nowym (i mniej błędogennym niż C/C++) to masz https://github.com/RustAudio/rust-portaudio
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.
Okazało się że przez braki dokładności przy pomiarze czasu nie da rady dobrze zaimplementować jednej fikcjonalności <3
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.
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.
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
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).
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.