Benutzer-Werkzeuge

Webseiten-Werkzeuge


ws1415:ton_zu_bild

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
ws1415:ton_zu_bild [2015/02/28 14:33]
lennyleass
ws1415:ton_zu_bild [2016/05/10 14:46] (aktuell)
Zeile 22: Zeile 22:
 ===Theoretischer Hintergrund=== ===Theoretischer Hintergrund===
  
-Zuerst mussten wir uns damit auseinandersetzen,​ wie Schall mathematisch beschrieben werden kann. Wir haben uns die Begriffe Periode, Frequenz, Amplitude etc. noch einmal vergegenwärtigt. Grundlage für die Verarbeitung und Analyse von Tonsignalen ist die Fourier-Analyse. Sie bietet eine Möglichkeit,​ Schallsignale in ihre Teilfrequenzen zu zerlegen. Somit kann man z.B. Grundtöne bestimmen, Obertonspektren vergleichen,​ und vieles mehr - so weit sind wir aber noch nicht gekommen.+Zuerst mussten wir uns damit auseinandersetzen,​ wie Schall mathematisch beschrieben werden kann. Wir haben uns die Begriffe Periode, Frequenz, Amplitude etc. noch einmal vergegenwärtigt. ​
  
-[[Protokolle]]+==Fourier-Analyse==
  
 +Grundlage für die Verarbeitung und Analyse von Tonsignalen ist die Fourier-Analyse. ​
  
 +Sie bietet eine Möglichkeit,​ Schallsignale in ihre Teilfrequenzen zu zerlegen. Somit kann man z.B. Grundtöne bestimmen, Obertonspektren vergleichen,​ und vieles mehr.
 +
 +
 +===Unser Programm===
 +
 +Um Töne  aufnehmen deren Daten verarbeiten zu können, verwenden wir das Modul pyaudio.
 +Für die Verarbeitung der Daten verwenden wir das Modul numpy. ​
 +Für die Generierung und Darstellung der Bilder verwenden wir das Modul matplotlib.
 +
 +Ein Funktion zum Aufnehmen von Tönen kann z.B. so aussehen:
 +
 +<code python>
 +
 +from __future__ import division
 +import pyaudio
 +import numpy as np
 +
 +
 +def recordsnd(filename,​ time):
 + '''​
 + Nimmt eine  time  Sekunden lange Schallsequenz
 + auf (mit der Samplerate 44100 Hz) auf,
 + speichert sie in der Datei filename und gibt die
 + Aufnahme als numpy-array mit Werten zwischen -1 und 1 zurück
 + '''​
 +        CHANNELS = 1
 +        RATE = 44100
 + DAUER=time
 + ANZAHL=int(RATE*DAUER)
 +
 +
 + p = pyaudio.PyAudio()
 + raw_input("​Aufnehmen ​ "​+str(time)+ " Sekunden): Eingabetaste drücken..."​)
 +
 + stream = p.open(format =pyaudio.paInt16 ,
 +                channels = CHANNELS,
 +                 rate = RATE,
 +                 input = True,
 +                 frames_per_buffer = 1024)#​ANZAHL)
 +
 +
 + yy=stream.read(ANZAHL)
 + y=np.fromstring(yy,​dtype=np.short)
 + if CHANNELS==2:​
 + y=y.reshape((y.shape[0]//​2,​2))
 +
 + print("​Aufgenomen:​ " + str(ANZAHL) + " Frames"​)
 + stream.close()
 + p.terminate()
 + yy=np.array(y,​dtype='​d'​)/​32768.0
 + if filename!=None:​
 + wavwrite(filename,​ yy)
 +
 + return yy
 +
 +</​code>​
 + 
 +Den numpy-array,​ den wir hierdurch erhalten, können wir uns mit matplotlib anzeigen lassen, z.B. so:
 +
 +<code python>
 +import matplotlib.pyplot as plt
 +
 +y = recordsnd(None,​1)
 +y = y[:2000]
 +y = y.reshape(len(y),​ 1) + y.reshape(1,​ len(y))
 +ax = plt.axes()
 +ax.imshow(y)
 +plt.show()
 +
 +</​code>​
 +
 +Wenn wir nun auch die Fourier-Analyse ins Spiel bringen, können wir noch interessantere Bilder erzeugen:
 +
 +<code python>
 +
 +y = recordsnd(None,​1)
 +y = y[:512]
 +y = np.abs(np.fft.fft(y))
 +y = np.concatenate((y[-50:​],​y[:​50]),​axis=0)
 +y = y.reshape(len(y),​1) + y.reshape(1,​len(y))
 +ax = plt.axes()
 +ax.imshow(y)
 +plt.show()
 +
 +
 +</​code>​
 +
 +
 +Nun brauchen wir eine Methode, um Tondaten kontinuierlich verarbeiten und anzeigen zu lassen. ​
 +Zunächst erstellen wir ein Anzeigeobjekt,​ zusammen mit einer Methode, wie sich dieses aktualisiert:​
 +
 +<code python>
 +
 +class Anzeige(object):​
 +
 + def __init__(self,​chunk,​rate):​
 + self.chunk=chunk
 + self.pixels = np.random.rand(chunk,​chunk)
 + plt.pause(0.001)
 + self.rate=rate
 + self.fig = plt.figure()
 + self.ax = self.fig.add_axes((0,​0.25,​0.5,​0.5))
 + plt.axis("​off"​)
 + self.ax2 = self.fig.add_axes((0.5,​0.25,​0.5,​0.5))
 + plt.axis("​off"​)
 + #​self.image = self.ax.imshow(self.pixels)
 + self.fig.canvas.draw()
 + self.noch_kein_erstes_bild_da=True
 +
 +
 + def update(self,​data):​
 + l=len(data)
 + self.fourier = np.abs(np.fft.fft(data,​ axis=0))
 + self.fourier = np.concatenate((self.fourier[-50:,​0],​self.fourier[:​50,​0]),​axis=0)
 + l2 = len(self.fourier)
 + self.fourier2 = self.fourier.reshape((l2,​1))+self.fourier.reshape((1,​l2))
 +
 + self.pixels=data.reshape((l,​1))+data.reshape((1,​l))
 + if self.noch_kein_erstes_bild_da:​
 + self.image = self.ax.imshow(self.pixels)
 + self.image.set_cmap("​spectral"​)
 + self.fourier_image = self.ax2.imshow(self.fourier2)
 + self.fourier_image.set_cmap("​spectral"​)
 + self.noch_kein_erstes_bild_da=False
 + self.fig.canvas.draw()
 + plt.pause(0.05)
 + self.image.set_data(self.pixels)
 + self.fourier_image.set_data(self.fourier2)
 +
 +
 +anzeige=Anzeige(CHUNK,​RATE)
 +
 +</​code>​
 +
 +
 +Dann erstellen wir eine callback-funktion,​ welche unser Anzeige-objekt sich mit neuen Daten aktualisieren lässt:
 +
 +<code python>
 +
 +def micro_callback(in_data,​ frame_count,​ time_info, status):
 +
 + if CHANNELS==2:​
 + y=y.reshape((y.shape[0]//​2,​2))
 + else:
 + y=y.reshape((y.shape[0],​1))
 + anzeige.update(y)
 + return (in_data, pyaudio.paContinue)
 +
 +</​code>​
 +
 +Nun wird ein Audiostream gestartet, welcher, immer wenn CHUNK frames vom Mikrophon gelesen wurden, unsere callback-funktion aufruft:
 +
 +<code python>
 +
 +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)
 +
 +</​code>​
 +
 +Schließlich startet unsere Hauptschleife,​ welche das Anzeige-objekt so lange darstellt, wie der Stream aktiv ist:
 +
 +<code python>
 +
 +while stream.is_active():​
 + anzeige.fig.canvas.draw()
 + anzeige.fig.canvas.flush_events()
 +
 +    ​
 +</​code>​
 +
 +===Das Endprodukt===
 +
 +{{ws1415:​projekte_im_wintersemester_2014_15:​bild2.png}}
 +
 +[[Protokolle]]
ws1415/ton_zu_bild.1425130412.txt.gz · Zuletzt geändert: 2016/05/10 14:46 (Externe Bearbeitung)