oszilloskop im x-y modus simulieren mit openGL?

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
phiros
User
Beiträge: 1
Registriert: Mittwoch 23. März 2011, 21:33

Hi

ich will ein Oszilloskop(-Display) im x-y Modus mit python und opengl simulieren zwecks analyse von (Stereo ) wav Dateien.
Die Datenpunkte die ich anzeigen möchte liegen in einem numpy Array vor ( die wav Datei wurde mittels scipy.io.wavfile.read ) eingelesen. Das Array sieht so aus:

Code: Alles auswählen

>>> data
array([[0, 0],
       [0, 0],
       [0, 0],
       ..., 
       [0, 0],
       [0, 0],
       [0, 0]], dtype=int16)
(Die ersten und letzten Einträge sind bei den meisten wav files 0 ; Ein später Eintrag wie z.B. data[1000] lautet z.B. "array([-10581, -17808], dtype=int16)" )

Nun hat diese Datei eine samplerate von 44,1 kHz also entsprechen 44100 Array Einträge einer Sekunde Sound.
Da es kaum möglich sein wird 44100 Einträge pro Sekunde zu plotten ( oder doch ?) hatte ich mir gedacht ich Plotte erstmal immer nur 100 Punkte in jedem Frame. Dazu hole ich mir jeden Fünfhundertsten Eintrag aus dem Array und schreibe diesen in einen Ringpuffer ( 100 Einträge; die Zahlen hier sind willkürlich festgelegt worden ) und verwende dann folgendes Konstrukt um den Ringpuffer zu zeichnen
( Ich zeichne kleine Vierecke statt einfach nur ein Punkt zu Zeichnen ):

Code: Alles auswählen

size=0.5
scale=500
b = rbuffer.get()  
for t in b:
    glColor4f(255,0,0,1)
    glRectd(t[0]/scale-size,t[1]/scale-size,t[0]/scale+size,t[1]/scale+size)

pygame.display.flip()


Das Funktioniert auch halbwegs.
Aber eben nur halbwegs weil:

1. Das ganze ist seeeehr langsam bei der Anzeige ( ich weiß ich sollte keine Wunder von einer Skriptsprache erwarten; Aber es gibt doch sicher eine Möglichkeit das ganze zu Beschleunigen; Benutze ich eventuell OpenGL falsch bzw. nicht optimal ? )
2. Weiß ich nicht ob einfach nur Punkte zeichnen der Richtige weg ist um ein Oszilloskop ( im x-y Modus ) zu simulieren
( man sieht die erwarteten Muster teilweise jedoch sieht das ganze mehr aus nach Game of Life wobei das vielleicht auf die langsame Darstellung zurückzuführen ist )
3. Habe ich keine Idee wie ich es hinbekomme soll, dass die Anzeige genauso schnell läuft wie wenn ich die Sounddatei abspielen würde.

Weiß jemand was ich besser machen könnte?

P.S.: Ich möchte noch anmerken, dass ich bis jetzt so gut wie nie etwas mit openGL gemacht habe.
Python ist außerdem auch nicht meine "Hauptsprache" ( Hat aber gute Chancen zur selbigen zu werden; speziell wegen
Paketen wie scipy und matplotlib )
deets

44100 Balken pro Sekunde? Mach doch mal ne kurze Rechnung auf, wieviele Gigabyte deine Kiste pro Sekunde an Bilddaten durch die Gegend jongliert. Da ist das Pillepalle...

Allerdings nur, wenn man's richtig macht. Auf Anhieb fallen mir hier mehrere Dinge ins Auge:

- statt diskreter OpenGL-Objekte (Rectangles, Triangles, whatever) solltest du eine Textur verwenden. Und die kannst du AFAIK auch mit Numpy bauen.

- falls du nicht ueber einen Bildschirm verfuegst, der aus einem schlechten Hacker-Film wie Password Swordfish stammt, dann hat der ne Aufloesung von *maximal* 2000 Pixeln in der Horizontalen. Und ich denke mal, die wirst du wohl kaum alle fuer dich beanspruchen. Sondern vielleicht 200, 300 Spalten, und noch weniger Zeilen. Das heisst, beim sub-sampling kannst du dich daran orientieren, vieviel du wirklich darstellen kannst, und wie weit du in die Zukunft schauen willst. Das bestimmt dann deine Schrittweite. Du solltest natuerlich dafuer sorgen, dass du beim Fortschreiten durch die Daten immer dieselben Schritte machst, sonst gibt das uU komische Flackereien. Damit meine ich, dass du zum Zeitpunkt T_0 mit einer jetzt voellig angenommenen Schrittweite von 10 die Samples 0, 10, 20, 30 usw darstellst.

Wenn dann T_1 = T_0 + 15 waere, dann wuerden ja beim naechsten mal Samples 15, 25, 35 dran sein. Das sieht aber doof aus.

Also stattdessen lieber ein bisschen unpraezise sein und Auf/Abrunden.

HTH
Antworten