Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1415:1._variante_oszilloskop

1. Variante Oszilloskop

Der Anfang besteht nur aus einigen Imports und Definitionen:

#!/usr/bin/python
# coding=utf8
 
from __future__ import division
 
### Audio-Modul
 
import pyaudio
 
##############
 
# Graphik und Berechnungen
 
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.

Dann kommt der Code-Teil, der die für die Anzeige relevanten Strukturen erzeugt. Ein Anzeige-Objekt erzeugt einen Plot, der sich mit einer 'update'-Methode an veränderte Daten anpassen lässt.

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)
 
 
anzeige=Anzeige(CHUNK,RATE)

Nun der für die Audioverarbeitung zuständige Teil. Dabei wird ein so genannter stream erzeugt, der mit einer callback-Funktion ausgestattet ist. Der stream ist ein unabhängig vom weiteren Programm laufender Prozess, der die Audiodaten liest (man könnte ihn ebenso zum Schreiben verwenden). Immer wenn eine gewisse Menge von Daten zusammengekommen ist (genauer: CHUNK Samples), ruft dieser Prozess die callback-Funktion, die bei seiner Erzeugung angegeben wurde. Diese callback-Funktion aktualisiert hier nur die beim Plotten verwendeten Daten, ohne selbst zu plotten. (Sie könnte ebenso gut eine komplizierte Transformation der Daten durchführen und sie an ein anderes Programm durchreichen.)

### Audio setup ###########################################
 
###  Hier wird ein 'Audio-Stream' gestartet, der immer, wenn
### CHUNK  Frames aus dem Mikrophon gelesen wurden, die Funktion
### micro_callback aufruft, die diese Daten dann in den Plot
### 'anzeige' schreibt. Stattdessen könnte man die Daten auch 
### erste bearbeiten und irgendwoanders hin schreiben.
### Dieser Audiostream läuft unabhängig vom weiteren Programm.
### Die Daten in anzeige.kurve sind also stets aktuell.
### Ums Anzeigen kümmert sich dann die 'Hauptschleife unten.
 
##############################################################
 
 
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.fromstring(in_data,dtype=np.short)
	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)
 
 
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16 ,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                output=False,
                stream_callback=micro_callback,
                frames_per_buffer=CHUNK)
 
stream.start_stream()
time.sleep(0.5)

Das Hauptprogramm kümmert sich nur darum, den Plot mit den aktuellen Daten neu zu zeichnen:

### 'Hauptschleife' 
 
while stream.is_active():
	anzeige.fig.canvas.draw()
	time.sleep(0.05)
 
#### Alles wieder schließen, was geöffnet wurde
 
 
stream.stop_stream()
stream.close()
p.terminate()

Diese Hauptschleife ist keine sehr elegante Lösung. Besser wäre es, der Plot kümmert sich 'selbst' darum, wann er gezeichnet wird, ebenso wie sich der Audio-Stream selbst um die Aktualisierung der Daten kümmert. Das ist aber gerade die 2. Variante.

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