Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1415:ton_zu_bild

Ton zu Bild

Projektmitglieder

  • Claire Melchior
  • Mascha Pachael
  • Laila Kulsvehagen
  • Lenny Leass

Ziel

Wir wollen Tonsignale in Bilder umwandeln. Hierbei ist es uns am wichtigsten, dass die entstehenden Bilder ästhetisch interessant sind.

Ansätze

Zuerst müssen die Tonsignale in Daten umgewandelt werden, die dann in unserem Programm verarbeitet werden können. Diese Daten können dann auf verschiedene Arten verwendet werden, um Bilder zu generieren.

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.

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:

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

Den numpy-array, den wir hierdurch erhalten, können wir uns mit matplotlib anzeigen lassen, z.B. so:

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()

Wenn wir nun auch die Fourier-Analyse ins Spiel bringen, können wir noch interessantere Bilder erzeugen:

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()

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:

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)

Dann erstellen wir eine callback-funktion, welche unser Anzeige-objekt sich mit neuen Daten aktualisieren lässt:

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)

Nun wird ein Audiostream gestartet, welcher, immer wenn CHUNK frames vom Mikrophon gelesen wurden, unsere callback-funktion aufruft:

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)

Schließlich startet unsere Hauptschleife, welche das Anzeige-objekt so lange darstellt, wie der Stream aktiv ist:

while stream.is_active():
	anzeige.fig.canvas.draw()
	anzeige.fig.canvas.flush_events()
 
 

Das Endprodukt

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