====== Oszilloskop, modular====== Hier wurde der Code auf verschiedene Dateien (Module) verteilt. Das Modul `microlistener.py` definiert die Klasse MicroListener (den doc-String lasse ich hier weg, siehe Programmcode) import pyaudio import time class MicroListener(object): def __init__(self,rate,channels,chunk,callback,playback=False): self.p = pyaudio.PyAudio() self.stream = self.p.open(format=pyaudio.paInt16 , channels=channels, rate=rate, input=True, output=playback, stream_callback=callback, frames_per_buffer=chunk) self.stream.start_stream() time.sleep(0.5) def __del__(self): self.stream.stop_stream() self.stream.close() self.p.terminate() Das Modul `plotanzeige.py' definiert die Klasse Anzeige: 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 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: #!/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() Wichtiger aber als die Übersichtlichkeit ist die Tatsache, dass die Module getrennt weiterentwickelt werden können, solange man an der 'Schnittstelle' nichts ändert.