Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ws1415:3._variante_oszilloskop [2014/12/09 12:26] stefanborn angelegt |
ws1415:3._variante_oszilloskop [2016/05/10 14:46] (aktuell) |
||
---|---|---|---|
Zeile 27: | Zeile 27: | ||
self.p.terminate() | self.p.terminate() | ||
- | </code python> | + | </code> |
+ | Das Modul `plotanzeige.py' definiert die Klasse Anzeige: | ||
+ | <code python> | ||
+ | import matplotlib | ||
+ | ### Wir müssen uns hier für ein Graphik-System ('backend') entscheiden, | ||
+ | ### wenn wir dieses die Ereigniskontroll übernehmen lassen wollen: 'gtk' | ||
+ | |||
+ | matplotlib.use('GTKAgg') | ||
+ | import gobject | ||
+ | import matplotlib.pyplot as plt | ||
+ | import numpy as np | ||
+ | |||
+ | |||
+ | |||
+ | class Anzeige(object): | ||
+ | '''Anzeige-Objekt, zeigt 'chunk' frames | ||
+ | an, x-Achse beschriftet mit den korrekten Zeiten. | ||
+ | Das zweite Argument ist die Sample-Rate''' | ||
+ | def __init__(self,chunk,rate): | ||
+ | self.chunk=chunk | ||
+ | self.rate=rate | ||
+ | self.fig,self.ax=plt.subplots(1,1) | ||
+ | self.ax = plt.axes(ylim=(-1,1),xlim=(0,chunk/self.rate)) | ||
+ | self.xwerte=np.arange(chunk)/self.rate | ||
+ | |||
+ | self.kurve, = self.ax.plot(self.xwerte,np.zeros(self.chunk), lw=2) | ||
+ | self.fig.canvas.draw() | ||
+ | plt.pause(0.001) | ||
+ | gobject.idle_add(self.zeichnen) | ||
+ | |||
+ | def update(self,data): | ||
+ | '''Plottet 'data' ''' | ||
+ | self.kurve.set_data(self.xwerte,data/2**16) | ||
+ | |||
+ | def zeichnen(self,*args): | ||
+ | self.fig.canvas.draw() | ||
+ | return True | ||
+ | </code> | ||
+ | |||
+ | Jedes der Module enthält auch noch einen Testteil, der nur ausgeführt wird, wenn das Modul als Hauptprogramm durchgeführt wird, nicht aber, wenn man es importiert. Das könnte ihr im Code nachsehen. | ||
+ | |||
+ | Das Hauptprogramm wird damit sehr übersichtlich: | ||
+ | |||
+ | <code python> | ||
+ | #!/usr/bin/python | ||
+ | # coding=utf8 | ||
+ | from __future__ import division | ||
+ | |||
+ | from microlistener import MicroListener, pyaudio | ||
+ | from plotanzeige import Anzeige,plt | ||
+ | |||
+ | ## plt ist das dort bereits importierte pyplot | ||
+ | |||
+ | import numpy as np | ||
+ | import time | ||
+ | |||
+ | ## GLOBALE VARIABLEN | ||
+ | |||
+ | CHANNELS=1 | ||
+ | RATE=44100 | ||
+ | DAUER=1 | ||
+ | ANZAHL=DAUER*RATE # ANZAHL der Frames, | ||
+ | CHUNK=2**11 | ||
+ | |||
+ | ### | ||
+ | |||
+ | anzeige=Anzeige(CHUNK,RATE) | ||
+ | |||
+ | def micro_callback(in_data, frame_count, time_info, status): | ||
+ | '''callback Funktion: wird vom PyAudio-Objekt aufgerufen, | ||
+ | wenn CHUNK Frames von der Soundkarte (Mikrophon) gelesen wurden''' | ||
+ | y=np.array(np.fromstring(in_data,dtype=np.short),dtype=np.float) | ||
+ | if CHANNELS==2: | ||
+ | y=y.reshape((y.shape[0]//2,2)) | ||
+ | else: | ||
+ | y=y.reshape((y.shape[0],1)) | ||
+ | anzeige.update(y[:,0]) | ||
+ | return (in_data, pyaudio.paContinue) | ||
+ | |||
+ | listener=MicroListener(RATE,CHANNELS,CHUNK,micro_callback) | ||
+ | |||
+ | ### 'Hauptprogramm' | ||
+ | |||
+ | plt.show() | ||
+ | </code> | ||
+ | |||
+ | Wichtiger aber als die Übersichtlichkeit ist die Tatsache, dass die Module getrennt weiterentwickelt werden können, solange man an der 'Schnittstelle' nichts ändert. |