Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1415:2._variante_oszilloskop

2. Variante Oszilloskop

Es gibt verschiedene graphische Benutzeroberflächen, die abhängig von Ereignissen andere Programme aufrufen können. Hier habe ich mich für gtk entschieden, es gibt noch Qt, tk und wx (komische Namen). Man kann matplotlib mitteilen, welche dieser Oberflächen er verwenden soll. Nur darin unterscheidet sich der Vorspann des Programms von der 1. Variante:

#!/usr/bin/python
# coding=utf8
 
from __future__ import division
 
### Audio-Modul
 
import pyaudio
 
##############
 
# Graphik und Berechnungen
 
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
 
###  Zeit
 
import time
 
 
###########################
 
### GLOBALE VARIABLEN
 
CHANNELS=1
RATE=44100
DAUER=1
ANZAHL=DAUER*RATE # ANZAHL der Frames,
CHUNK=2**11
 
# globale Variablen, schlechter Programmierstil, hier aber ganz
# praktisch: Nach Aufnahme oder Lesen werden diese Variablen 
# entsprechend gesetzt.

Der für die graphische Anzeige zuständige Teil unterscheidet sich nur wenig, aber in bedeutsamer Weise von der 1. Variante. Die Klasse `Anzeige` hat nun eine weitere Methode `zeichnen`. Die zeichnen-Methode des globalen Anzeige-Objekts wird mit dem so genannten `idle`-Event verknüpft, d.h. immer dann aufgerufen, wenn sonst nichts zu tun ist.

 
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.fig,self.ax=plt.subplots(1,1)  
		self.ax = plt.axes(ylim=(-1,1),xlim=(0,chunk/RATE))
		self.xwerte=np.arange(chunk)/RATE
 
		self.kurve, = self.ax.plot(self.xwerte,np.zeros(chunk), lw=2)
		self.fig.canvas.draw()
		plt.pause(0.001)
		self.chunk=chunk
 
 
	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
 
##################
 
### Anzeige setup, hier wird das 'idle'-Event (=nichts weiter
### zu tun) mit dem Zeichnen des momentanen Plots verbunden
 
 
anzeige=Anzeige(CHUNK,RATE)
gobject.idle_add(anzeige.zeichnen)

Der Audio-Teil unterscheidet sich nicht von der 1. Variante, siehe dort. Das Hauptprogramm tut nun nichts anderes mehr, als die beiden unabhängigen Prozesse (Mikrophon auslesen, Bild anzeigen) nebeneinander laufen zu lassen. Die Prozesse sind nicht synchron. Es kann sein, dass die Bilder sehr viel häufiger neu gezeichnet werden als neue Audio-Daten kommen. Das macht aber nichts. Da beide Prozesse schon gestartet wurden, muss nur dafür gesorgt werden, dass das Programm nicht beendet wird und die graphische Oberfläche aktiv bleibt:

plt.show()

Dieser Methodenaufruf wird erst beendet, wenn man das Graphikfenster schließt. Anschließend kann man wieder, wie in der 1. Variante, die beiden Prozesse sauber beenden.

ws1415/2._variante_oszilloskop.txt · Zuletzt geändert: 2016/05/10 14:46 (Externe Bearbeitung)