Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1314:audio

Audio

Töne selbst erzeugen

Bei uns ging es zunächst darum Töne zu erzeugen, was hauptsächlich über die Erzeugung von Sinuskurven mit verschiedenen Frequenzen und Amplituden realisierbar ist.

Eigene Variante

Eine Sinuskurve allgemein mit variabler Frequenz und Amplitude zu erzeugen ist mit dem Modul Numpy relativ einfach.

def erzeuge_sinus(f,T):
	global RATE
	yy=np.zeros(int(T*RATE))
	for i in range(0,len(yy)):
		yy[i]=np.sin(2*np.pi*f*i/float(RATE))
	return yy

Mit diesem Code kann man einzelne Sinuskurven generieren. Ebenso kann man die Sinuskurve durch verschiedene periodische Funktionen begrenzen, wodurch sich die Töne ebenfalls modellieren lassen. Als Beispiel haben wir eine Dreiecksperiode:

def erzeuge_dreieckhk(T0,T1,T=2.):
	global RATE
	yy=np.zeros(int(T*RATE))
	for i in range(0,len(yy)):
		t=i/float(RATE)
		if 0<=t<=T0:
			yy[i]=t/float(T0)
		elif T0<t<=T1:
			yy[i]=-t/float(T1-T0)+T1/float(T1-T0)
	return yy
 
def erzeuge_dreieckperiode(frq,T=2.):
	global RATE
	T_periode=1./frq
	ya=erzeuge_dreieckhk(T_periode/2.,T_periode/2.,T=T_periode)
	y=ya.copy()
	for i in range(0,int(T*frq)):
		y=np.concatenate((y,ya))
	return y	

Mit Stefans Hilfe

Da wir allerdings mehrere Sinuskurven mit unterschiedlichen Frequenzen und Amplituden aneinanderreihen wollten, mussten wir uns Gedanken machen, wie wir das Umsetzen. Da dies und das erstellen eines Interface über unseren Fähigkeiten lag, hat Stefan uns bei der Lösung dieser Probleme ausgeholfen. Hierbei entstand folgender krasser Code:

#### Sinusgenerator-Klasse
class sinus_generator(generator):
	'''Sinus-Tongenerator'''
	def __init__(self,freq=440):
		self.freq=freq
		self.phaseshift=0.0
 
	def generate(self,T):
		'''Erzeugt einen Sinusklang der Dauer T.
		Damit Stücke ohne Knacksen verbunden werden,
		können, merkt sich die Funktion die Phasenverschiebung
		am Ende des letzten Stücks'''
		yy=np.fromfunction(lambda i: i, (int(T*RATE),),dtype=int)*2*np.pi*self.freq/RATE\
		+self.phaseshift*np.ones(int(T*RATE))
		yy=np.sin(yy)
		self.phaseshift+=T*2*np.pi*self.freq		
		return yy.copy()
 
 
class fm_generator(generator):
	'''FM-Generator'''
	def __init__(self,freq1=440, freq2=110, I=3.):
		self.freq1=freq1
		self.freq2=freq2
		self.I=I
		self.T=0.0
 
	def generate(self,T):
		'''Erzeugt ein FM-Synthese der Dauer T.
		Damit Stücke ohne Knacksen verbunden werden,
		können, merkt sich Zeit am Ende des letzten Stücks'''
		y1=np.fromfunction(lambda i: i, (int(T*RATE),),dtype=int)
		y2=np.sin(y1*2*np.pi*self.freq1/RATE\
		+self.T*2*np.pi*self.freq1*np.ones(int(T*RATE)))
		yy=np.sin(y1*2*np.pi*self.freq2/RATE\
		+self.T*2*np.pi*self.freq2*np.ones(int(T*RATE))
		+self.I*y2)
		self.T+=T
		return yy.copy()
 
#### Der 'große Generator', der aus Verknüpfung von anderen besteht:
 
class klang1(generator):
 
	def __init__(self):
		self.gen=[]
		self.vol=[]
		# Alle Generatoren und zugehörigen Volumina in die Liste
		# einfügen. Durch entsprechende Gewichte und Frequenzen  -- Fourier! --
		# kannn man Tongeneratoren ganz verschiedener Charakteristiken 
		# erzeugen.
 
		self.gen.append(sinus_generator(440))
		self.gen.append(sinus_generator(1.5*440))
		self.vol.append(0.2)
		self.vol.append(0.2)
		frq0=440*1.5
		for i in range(15):
			frq0=frq0*(i+4)/(i+3)
			self.gen.append(sinus_generator(frq0))
			#self.vol.append(1/(i+2)**2)
			self.vol.append(1/i)

Fourier Transformation

Mit der Fourier Transformation lassen sich unter anderem bereits existente Töne analysieren und in Daten umwandeln, sodass man sie modellieren kann.

Diskret

Zunächst haben wir probiert selbst einen Code für die Diskrete Fourier Transformation zu implementieren. Dieser sieht folgendermaßen aus:

 

Fast

Da wir hier leider auf Speicher Probleme stießen, mussten wir doch auf den in Numpy vorhandenen Fast-Fourier-Transformation Code zurückgreifen:

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