Upload
others
View
19
Download
0
Embed Size (px)
Citation preview
1
Kapitel 10:
Signalverarbeitung mit Python: Sound
Einführung in die InformatikWintersemester 2007/08
Prof. Bernhard Jung
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Übersicht
Repräsentation von SoundAlgorithmen:
Erhöhen der LautstärkeNormalisierung von SoundRückwärts-SoundKonkatenierung von Sound
Kombination von SoundsAkkordeEcho
Synthetischer SoundFrequenz von Sounds erhöhen / verringern
Hauptlernziele• Repräsentation von digitalem Sound verstehen• Digitalen Sound als eine Art von Messwerten verstehen • Einfache Python-Programme zur Soundverarbeitung entwickeln können• Wdh: Schleifen (for) und bedingte Anweisungen (if … else) verstehen
Signalverarbeitung mit Python: Sound
2
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Akustik – die Lehre vom Schall
Schallwellen sind zyklischFrequenz einer Welle
Anzahl der Zyklen pro Sekundegemessen in Hertz(1 Hz = 1 Zyklus / Sekunde)
Amplitudemaximale Höhe der Welle
Natürlich vorkommende Klänge bestehen aus Überlagerung einer Vielzahl von Schallwellen
Amplitude
1 Zyklus
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Psychoakustik – Wahrnehmung von SchallLautstärke und Tonhöhe
Wahrgenommene Lautstärke korreliert (logarithmisch) mit AmplitudeVerdopplung der Amplitude ca. 3 Dezibel lauterDezibel: Maß für wahrgenommene Lautstärke
0 dB: Schwellwert für Wahrnehmbarkeit von Geräuschen60 dB: Unterhaltungsgespräch80 dB: Schreien
Wahrgenommene Tonhöhe korreliert (logarithmisch) mit FrequenzHöhere Frequenz größere TonhöheVerdopplung der Frequenz 1 Oktave höherMenschliches Gehör: 5 Hz – 20.000 Hz
3
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Digitalisierung von Sound
Sound Samplenumerische Repräsentation der Amplitude zu einem bestimmten Zeitpunkt(Messung des Drucks, den Sound-Welle an Mikrofonmembran erzeugt)
Beschreibung der Sound-Welle durch hinreichende Anzahl von Samples
AD-Wandler (Analog-Digital)
wie viele Samples notwendig?
PCM – Pulse Code Modulation:Digitale Repräsentation eines analogenSignals, bei welcher das Signal in uniformenIntervallen abgetastet wird und die Signal-größe in digitaler Form quantisiert wird
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Theorem von Nyquist
Theorem von Nyquist (bezogen auf Sound):
Sampling Rate: Anzahl der erfassten Samples pro Sekundez.B. Menschliche Stimmen: maximale Frequenz 4000 Hz
8000 Samples pro Sekunde notwendig (Telefon)z.B. Menschliches Gehör: maximale Frequenz ca. 22000 Hz
ca. 44000 Samples pro Sekunde notwendigCD-Qualität: 44.100 Samples / Sekunde3-Minuten Song benötigt 158.760.000 Samples (Stereo × 2)
Zur Repräsentation (und späteren Wiedergabe) von Sound mit maximaler Frequenz n Hertz
müssen mindestens 2n Samples abgenommen werden
4
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Typischerweise jeder Sample-Wert wird durch 2 Byte repräsentiert2 Byte = 16 Bitd.h. 216 = 65.536 verschiedene Zahlen darstellbar
Sample-Werte: -32.768 … 32.767Bem: Viele Varianten möglich, z.B. 8 Bit pro Sample
Digitaler Sound = Feld (Array) von Sound-SamplesAchtung: Komprimierte Speicherung in üblichen Datei-Formaten (z.B. mp3)
Digitale Soundverarbeitung = Manipulation von FeldernÄndern der Sample-WerteÄndern der Feldgröße
Digitaler Sound: Repräsentation von Sound in Computern
59 -111-119 -30 18 18
0 321 4 5 6
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Teil von Microsofts RIFF-Spezifikation für Multimedia DateienRepräsentation von Samplewerten und Formatinformationen größtenteils als "littleendian"z.B. Bytefolge24 17 1e 13repräsentiertHex-Zahl 0x131e1724= 320739108Falls 16 Bits per Sample, werden Samplewerte vorzeichenbehaftet (im Zweierkomplement) gespeichert, d.h. Wertebereich-32768 … 32767
WAVE-Dateiformat
Quelle: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
5
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
WAVE-Dateiformat / Beispiel
0x00000824 = 2084
0x5622 = 22050
Mono = 1, Stereo =2
0x0d1ace11= 219860497
Quelle: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
TUBAFSound.pyFunktionen für die Sound-Verarbeitung
Skript mit Funktionen zur einfachen Verarbeitung von digitalem SoundEinschränkungen an Sound-Dateien
.wav Format16 Bit Sample-Breitemono (laden von Stereo ok)bevorzugte Samplingrate 22050
funktioniert aber auch mitanderen Samplingrates
VerwendungSkript auf Kurs-WebseiteSpeichern im Arbeitsverzeichnis
mit eigenen SkriptenSound-Dateien
Abspielen von Sound nur auf Windows u. Linuxalle Plattformen: Bearbeiteten Sound speichern, dann mit geeignetem Playerabspielen
>>> from TUBAFSound import *>>> sound = makeSound('c4.wav')>>> playSound(sound)>>> saveSound(sound,'c4-copy.wav')
6
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
TUBAF Sound: Funktionen für die Sound-Verarbeitung(Auswahl)
Öffnen von Sound-Dateien makeSound(dateiname) – Erzeugt internes Sound-Objekt
nur .wav Dateien !
Lesen und Setzen von Sample-WertengetSamples(sound) – liefert Liste aller SamplewertesetSamples(sound, samples) – setzt die Samplewerte getSample(sound, index) – liefert Wert eines Samples (als Integer-Zahl)setSample(sound, index, value) – setzt Wert eines SamplesgetLength(sound) bzw len(sound) – liefert Länge des Sounds (Anzahl der Samples)
Speichern / Abspielen von SoundssaveSound(sound, filename) – abspeichern des Sounds als .wav DateiplaySound(sound) – bis jetzt nur Windows und Linux
andere Plattformen: Abspeichern des Sounds, Abspielen mit jeweiligem Audio-Player
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
TUBAF Sound: Beispiele für Sound-Funktionen
>>> from TUBAFSound import *>>> filename = r'C:\Dokumente und Einstellungen\Jung\EigeneDateien\c4.wav' >>> sound = makeSound(filename)>>> print soundSound of length 55125>>> getSample(sound, 0)20>>> getSample(sound, 55124)4225>>> samples = getSamples(sound)>>> print samples[0:10] # ':' ist sog. 'slice'-operator[20, 946, 1948, 2919, 3814, 4748, 5673, 6547, 7333, 8130]>>> playSound(sound) # nur Windows u. Linux>>> saveSound(sound, 'c4-copy.wav') # alle Plattformen
7
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Erinnerung: range() Funktion
>>> range(3)[0, 1, 2]>>> range(1, 3)[1, 2]>>> range(3, 1)[]>>> range(-1, 5)[-1, 0, 1, 2, 3, 4]>>> range(100)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, … 99]
Oft Verwendung in Zählschleifen: for index in range(10): …
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Erinnerung: Bearbeitung von Listen mit Zählschleifen
Beispiel: Verdoppeln aller Listenelemente>>> def verdopple( liste):
for index in range( len(liste) ):wert = liste[index] # Zugriff auf i. Elementliste[index] = wert * 2 # Zuweisung an i. Element
>>> liste = [10,11,12,13,14]>>> verdopple(liste)>>> liste[20, 22, 24, 26, 28]>>> liste = [10,11,12,13,14,15,16,17,18,19]>>> verdopple(liste)>>> liste[20, 22, 24, 26, 28, 30, 32, 34, 36, 38]>>>
Sound-Bearbeitung = Manipulation von Arrays/Listenanalog zu obigem BeispielListen allerdings länger, z.B. 22050 Elemente pro Sekunde des Sounds
8
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
TUBAF Sound: Einfaches Gerüst für Programme zur Sound-Verarbeitung
def manipulateSound(sound):for index in range( getLength(sound) ):
value1 = getSample(sound, index)value2 = value1 # oder sinnvolleren neuen WertsetSample(sound, index, value2)
>>> from TUBAFSound import *>>> filename = "techno_mono.wav" # bzw. andere wav-Datei>>> sound = makeSound(file)>>> manipulateSound(sound)>>> playSound(sound)>>>
Iteration über alle Samples mit for-Schleife !
Benutzung
Python-Skript
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
def increaseVolume(sound):for index in range(getLength(sound)):
value = getSample(sound, index)setSample(sound, index, value*2)
Beispiel: Lautstärke erhöhen
Amplitude des Sounds muss größer werdenalle Sample-Werte z.B. verdoppeln
59 -111-119 -30 18 18
118 -222-238 -60 36 36
alt:
neu:
>>> filename = "techno_mono.wav">>> sound = makeSound(filename)>>> increaseVolume(sound)>>> playSound(sound)>>>
Python-Skript:
Benutzung:
0 321 4 5 6
0 321 4 5 6
9
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Arbeitsweise von increaseVolume():Start der Schleife
for Schleife setzt index = 0
def increaseVolume(sound):for index in range(getLength(sound)):
sample = getSample(sound, index)setSample(sound, index, sample*2)
59 -111-119 -30
0 321 4…
index
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Arbeitsweise von increaseVolume():Ausführung des Blocks
sample erhält den Wert des ersten Samples (d.h. index 0) von sound
Wert des Samples an index wird neu gesetzt (bisheriger Wert mal 2)
def increaseVolume(sound):for index in range(getLength(sound)):
sample = getSample(sound, index)setSample(sound, index, sample*2)
118 -111-119 -30
0 321 4…
sample
index
10
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Arbeitsweise von increaseVolume():Das nächste Sample …
Kontrolle kehrt zum Schleifenanfang zurück;index wird nun inkrementiert und erhält somit den Wert 1
def increaseVolume(sound):for index in range(getLength(sound)):
sample = getSample(sound, index)setSample(sound, index, sample*2)
118 -111-119 -30
0 321 4…
index
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Arbeitsweise von increaseVolume():… verdoppeln des nächsten Samples
nun wird Wert des nun aktuellen Samples (index = 1) gelesen …… und auf den neuen Wert 38 gesetzt
def increaseVolume(sound):
for index in range(getLength(sound)):
sample = getSample(sound, index)
setSample(sound, index, sample*2)
118 -111-138 -30
0 321 4…
sample
index
11
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Arbeitsweise von increaseVolume():… und so weiter für alle Samples
Schleife iteriert über alle Indicessomit sind alle Sample-Werte nun verdoppelt
def increaseVolume(sound):
for index in range(getLength(sound)):
sample = getSample(sound, index)
setSample(sound, index, sample*2)
118 -222-238 -60
0 321 4…
sample
index
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Beispiel: Benutzung von increaseVolume()
>>> sound = makeSound("techno_mono.wav")>>> playSound(sound)>>> increaseVolume(sound)>>> playSound(sound)>>> saveSound(sound, "techno_mono_louder.wav")>>>
original
Amplitude * 2
Zur Erinnerung: Verdopplung Amplitude≠ doppelte Lautstärke(logarithm. Korrelation)
12
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Beispiel: Wiederholtes Erhöhen der Lautstärke
original
Amplitude * 2
Amplitude * 4
Clipping – Physikalische Schallwelle wird aufgrund der Beschränkungauf 16 Bit pro Sample nicht adäquat repräsentiert schlechte Klangqualität
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Test: Extremer Sound
Sound soll nur Samples mit extremen Sample-Werten enthalten:Falls Sample-Wert im Original >= 0, dann neuer Wert = 32767Andernfalls neuer Wert = -32768
Verwendung von if … else
original
extrem
def toTheExtreme(sound):for index in range(len(sound)):
value = getSample(sound, index)if (value>=0):
setSample(sound, index, 32767)else:
setSample(sound, index, -32768)
13
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Normalisierung von Sound
Skalierung der Amplituden in einem Sound, so dass maximaler Sample-Wert = 32767 (und minimaler Sample-Wert = -32768)Schritte:
1.) Maximalen Sample-Wert loudest in Sound ermitteln2.) Ermittlung des Verstärkungsfaktors amp, so dass
amp * loudest = 32767d.h. amp = 32767/loudest
3.) Verstärkung aller Sample-Werte durch Multiplikation mit amp
original
normalisiert
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Normalisierung von Sounddef normalize(sound):
loudest = 0for s in getSamples(sound):
loudest = max(loudest, s ) amp = 32767.0 / loudest
print "Groesster Sample-Wert in Original: ", loudestprint "Verstaerkungsfaktor: ", amp
for index in range( len(sound) ):value = getSample(sound, index)louder = int(amp * value) setSample(sound, index, louder)
>>> sound = makeSound("techno_mono.wav")>>> normalize(sound)Groesster Sample-Wert in Original: 14007Verstaerkungsfaktor: 2.33933033483>>> saveSound(sound,"techno_mono_normalized.wav")>>>
14
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Rückwärts-Sound
Rückwärts-Abspielen von Sound war zu Beatles-Zeiten beliebt …siehe z.B. en.wikipedia.org zu "Revolution 9"
Umsetzung mit digitalem SoundSound-Array einfach umkehren:
“[Revolution] number 9, number 9, number 9”
59 -111-119 -30 18 18
18 -111-3018 -1 19 59
vorwärts:
rückwärts:
0 321 4 5 6
0 321 4 5 6
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Rückwärts-Listen
Vorgehen:Zweite Liste listeRueckwaerts erzeugen, die Ergebnis enthalten sollVerwendung von zwei Indices (Laufvariablen)
indexRueck – läuft von 0, 1, 2, …, n-1, zum Durchlaufen von listeRueckwaertsindexVor – läuft von n-1, n-2, …, 2, 1, 0, zum Durchlaufen der Originalliste
Bei jedem Schleifendurchlauf wirdindexRueck um 1 erhöht, durch range-FunktionindexVor um 1 erniedrigt, per expliziter Zuweisungein Wert von Originalliste in neue Liste listeRueckwaerts kopiert
def rueckwaerts(liste):listeRueckwaerts = [0] * len(liste)indexVor = len(liste) - 1for indexRueck in range( len(liste) ):
wert = liste[indexVor]listeRueckwaerts[indexRueck] = wertindexVor = indexVor - 1
return listeRueckwaerts
Am Ende derListe anfangen
indexVor läuftrückwärts
>>> rueckwaerts([1,2,3])
[3, 2, 1]
Test:>>> rueckwaerts([0,-1,88,7])
[7, 88, -1, 0]
>>> rueckwaerts([])
[]
15
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Rückwärts-Sound
Vorgehen (analog zu Umkehrung von Listen):Kopien des Original-Sounds erzeugen (sound destSound)Verwendung von zwei Indices (Laufvariablen)
destIndex – läuft von 0, 1, 2, …, n-1srcIndex – läuft von n-1, n-2, …, 2, 1, 0
Bei jedem Schleifendurchlauf wirddestIndex um 1 erhöht, durch range-FunktionsrcIndex um 1 erniedrigt, per expliziter Zuweisung
from TUBAFSound import *
def backwards(sound):destSound = copySound(sound)srcIndex = getLength(sound) - 1for destIndex in range( getLength(sound) ):
sample = getSample(sound, srcIndex)setSample(destSound, destIndex, sample)srcIndex = srcIndex - 1
return destSound
Am Ende des Sounds anfangen
srcIndex läuftrückwärts
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Rückwärts-Sound
“number 9, number 9, number 9”
“Turn me on, dead man” ???
def backwards(sound):destSound = copySound(sound)srcIndex = getLength(sound) - 1for destIndex in range( getLength(sound) ):
sample = getSample(sound, srcIndex)setSample(destSound, destIndex, sample)srcIndex = srcIndex - 1
return destSound
16
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Konkatenierung von Sound
Aneinanderhängen von Sounds in zwei Dateien zu Sound in einer Datei
Aneinanderhängen von Sample-Arrays
59 -111-119 -30 18 18
59 -111-119
0 321
-30 1818
0 21
+
=
0 321 4 5 6
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Konkatenierung von Sound
Vorgehen zur Konkatenierung von zwei Sounds:1. Erzeuge neues, leeres Sound-Objekt, das mindestes so lang ist wie beide
Eingabe-Sounds zusammenTUBAF Sound: makeEmptySound(t) – t ist Länge des Sounds in Sekunden
2. Kopiere Sample-Werte von erstem Sound-Objekt an Anfang von neuem Sound-Objekt
3. Kopiere Sample-Werte von zweitem Sound-Objekt in neues Sound-Objekt, beginnend hinter den Samples des ersten Sounds
59 -111-119 -30 18 18
59 -111-1190 321
-30 18180 21+
=0 321 4 5 6
17
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Konkatenierung von Sound
Neues Teilproblem: Berechnung der Dauer eines Sounds in Sekunden
Relevante Funktionen von TUBAFSound:getLength(sound) – Anzahl Samples eines SoundsgetSamplingRate(sound)
z.B. 22050 oder 44100 Samples / Sekunde
Dauer eines Sounds in Sekunden:duration(sound)in TUBAF-Sound enthaltendefiniert als: getLength(sound) / getSamplingRate(sound)Liefert i.d.R. float-Wert, z.B. 3.219
>>> snd = makeSound("techno_mono.wav")>>> duration(snd)3.8552380952380951>>>
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Konkatenierung von Sound
def concatSounds(sound1, sound2):dur = duration(sound1) + duration(sound2) print "Duration:", dursound = makeEmptySound( dur )index = 0for i in range(len(sound1)):
value = getSample(sound1,i)setSample(sound, index, value)index = index + 1
for i in range(len(sound2)):value = getSample(sound2,i)setSample(sound, index, value)index = index + 1
return sound
>>> snd1 = makeSound("InformatikMachtSpass.wav")>>> snd2 = makeSound("meistens.wav")>>> snd3 = concatSounds(snd1,snd2)Duration: 3.26063492063>>> playSound(snd3)>>>
Länge des konkateniertenSounds berechnen(in Sekunden)
Leeren Sounderzeugen
Alle Samples von Sound1kopieren
Alle Samples von Sound2kopieren
18
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Kontext: Manipulation digitaler Medien
… ist einfach: nur Ersetzung von Bytes durch andere Bytes
z.B. Bilder
z.B. Soundechtes Zitat des Dozenten: "Informatik macht Spaß"auch mal gesagt: "meistens"nie gesagt: "Informatik macht Spaß … meistens"
selbst falls Sound-Dateien dieses Inhalts existieren sollten!
www.br-online.de, 2005
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Nachtrag: Sound-Bearbeitung mittels Builtin-Funktionenvon Python für Listen
Eingebaute Funktionen zur Manipulation von Listen in Python, u.a.:sei liste = [1,2,3]Liste rückwärts: liste.reverse() [3,2,1]Konkatenierung von Listen: liste+[4,5] [1,2,3,4,5]Erweitern um zweite Liste: liste.extend([2,1]) [1,2,3,2,1]
def backwards_usingBuiltIns(sound):sound.getSamples().reverse()return sound
def concatSounds_usingBuiltIns(sound1,sound2):sound = makeEmptySound(0)setSamples(sound, getSamples(sound1) + getSamples(sound2))return sound
def concatSounds_usingBuiltIns2(sound1,sound2):sound1.getSamples().extend(sound2.getSamples())return sound1
damit sind vereinfachte Funktionen zur Sound-Manipulation möglich:
19
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Addition von Sound
Natürlich vorkommende Sounds sind oft die Überlagerung mehrerer einfacherer Sounds
Addition digitaler Sounds ist einfach: nur Sample-Werte addieren
AnwendungenMixen von Sound
einfache AkkordeMischen von komplexer Sounds
auch Übergänge (fade-in / fade-out) durch Verändern der Lautstärke
Erzeugen von Echos…
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Addieren von Sound
def addSounds(sound1,sound2):for index in range( getLength(sound1) ):s1Sample = getSample(sound1,index)s2Sample = getSample(sound2,index)setSample(sound1,index,s1Sample+s2Sample)
return sound1
Kombinierter Sound in sound1d.h. sound1 ist nach Funktionsaufruf verändert (sound2 bleibt wie zuvor)
10 403020 50 60 20
1 432 5 6 76 281812 38 -15 -40
16 684832 88 45 -20
0 321 4 5 6
+
20
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Erzeugen von Akkorden durch Mischen von drei Sounds
>>> c4=makeSound("bassoon-c4.wav")>>> e4=makeSound("bassoon-e4.wav")>>> g4=makeSound("bassoon-g4.wav")>>> playSound(c4)>>> addSounds(c4,e4)>>> playSound(c4)>>> addSounds(c4,g4)>>> playSound(c4)>>>
bassoon (engl.): Fagott
>>> c4=makeSound("bassoon-c4.wav")>>> e4=makeSound("bassoon-e4.wav")>>> g4=makeSound("bassoon-g4.wav")>>> playSound( addSounds( addSounds(c4,e4), g4) )>>>
(c4+e4)
(c4+e4) + g4
oder auch:
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Akkord mit Delay
z.B. zweiter Sound mit Delay von 5000 Samplesz.B. dritter Sound mit Delay von 10000 Samples
def makeChord(sound1,sound2,sound3):for index in range( getLength(sound1) ):
s1Sample = getSample(sound1,index)if index > 5000:
s2Sample=getSample(sound2,index-5000)setSample(sound1,index,s1Sample+s2Sample)
if index > 10000:s3Sample = getSample(sound3,index-10000)setSample(sound1,index,s1Sample+s2Sample+s3Sample)
return sound1
>>> makeChord(c4,e4,g4)<TUBAFSound.Sound instance at 0x00C454E0>>>> playSound(c4)>>>
sound1 wirdüberschrieben
21
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Erzeugen von Echos
Idee: Neuer Sample-Wert erhält Anteile des bisherigen Samples + Anteile des Samples, das delay Samples zurück liegt
Zur Vermeidung, dass Amplitude über Maximalwert liegt (d.h. neuer Sample-Wert > 32767) fließen altes und Echo-Sample mit Faktoren < 1 in neuen Sound ein
10 403020 50 60 70
0 321 4 5 6
624+4=28
181230+8=38
36+12=48
42+16=58
0 321 4 5 6
Faktor 0.6Faktor 0.4
Beispiel: Delay 4 (realistisch: 10000-20000)
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Erzeugen von EchosPython-Code
def echo(sound, delay):destSound = copySound(sound)for index in range(delay):
origSample = getSample(sound, index)setSample(destSound,index,int(0.6*origSample))
for index in range(delay, getLength(sound)):origSample = getSample(sound,index)echoSample = getSample(sound,index-delay)newSample = int(0.6*origSample+0.4*echoSample)setSample(destSound,index,newSample)
return destSound
>>> snd = makeSound("InformatikMachtSpass.wav")>>> playSound( echo(snd, 10000) ) >>> playSound( echo(snd, 20000) )
Kopie des Eingabe-Sounds
nur Kopie wird verändert!
22
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Synthetischer Sound
Z.B.Elektrische Orgeln, 1934
Prinzip: Überlagerung mehrerer Sinus-Wellen ("additive Synthese")
Synthesizer, 1964 (Moog)Hörbeispiel: "Popcorn", 1969; erster nur mit Synthesizer eingespielter Pop-Hit
MIDI, 1983"Musical Instrument Digital Interface"Befehle zur Ansteuerung von digitalen Instrumenten bzw. Soundkarten(analog zu Vektorgrafik) Hörbeispiel
Hammond-Orgel, wikipedia.org
Moog-Synthesizerwww.wendycarlos.com
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Innovation
1970er Jahre: "Wall of Synthesizers"Foto: Emerson, Lake & Palmer, 1974 (Moog-Synthesizer)
Moderne SynthesizerFoto: Kraftwerk, www.kraftwerk.com
23
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Synthetischer SoundGenerierung von Sinus-Wellen
Wie viele Zyklen pro Sekunde? Frequenz = Anzahl der Zyklen pro Sekunde
Wie viele Samples pro Zyklus?SamplesPerCycle = SamplingRate / Frequenz
z.B. 22050 / 440 = 50.11Wert des i.-ten Samples (i = 1…22050):
Bereich -1.0 ... +1.0: sin(i / SamplesPerCycle * 2 * pi) Multiplikation mit max. Amplitude!
def sineWave(freq, amplitude = 4000):'''Generate a 1 second sine wave sound'''from math import pi, sinbuildSin = makeEmptySound(1) # make a 1 sec. empty soundsr = getSamplingRate(buildSin) # e.g. 22050samplesPerCycle = float(sr) / freq # e.g. 22050 / 440 = 50.11for pos in range( len(buildSin) ):
rawSample = sin( (pos / samplesPerCycle) * 2 * pi)sampleVal = int( amplitude*rawSample)setSample(buildSin, pos, sampleVal)
return buildSin
π 2π0
1 Zyklus
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Synthetischer SoundGenerierung von Rechteckwellen-Wellen
Rechteckwellen(etwas) komplexerer Klang als Sinuswellen
Generierungfalls Sinus > 0 :Samplewert = Amplitudesonst: Samplewert = -Amplitude
def squareWave(freq, amplitude = 4000):'''Generate a 1 second square wave sound'''from math import pi, sinbuildSquare = makeEmptySound(1) # make a 1 sec. empty soundsr = getSamplingRate(buildSquare) # e.g. 22050samplesPerCycle = float(sr) / freq # e.g. 22050 / 440 = 50.11for pos in range( len(buildSquare) ):
if sin( (pos / samplesPerCycle) * 2 * pi) >= 0:sampleVal = amplitude
else:sampleVal = - amplitude
setSample(buildSquare, pos, sampleVal)return buildSquare
24
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Synthetischer Sound – weitere Wellenformen
http://commons.wikimedia.org/wiki/Image:Waveforms.png
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Ändern der Frequenz von Sounds
Vorige Vorlesung: Ändern der Amplitude von Sounds
Amplitude (logarithmisch) korreliert mit Lautstärke
Jetzt: Ändern der Frequenz von SoundsFrequenz (logarithmisch) korreliert mit TonhöheAuswirkung auf Tonhöhe und Geschwindigkeit
25
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Halbieren der Frequenz von Sounds:Idee
Sample-Werte des Original-Sounds jeweils doppelt in Ziel-Sound kopieren
59 -111-119 -30 18 18
59 191959 -1 -1 -111
0 321 4 5 6
[Besser als doppeltes Kopieren wäre Interpolation der Sample-Werte]
0 321 4 5 6
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Halbieren der Frequenz:Python-Skript
def half(sound):destSound = copySound(sound)
srcIndex = 0.0for destIndex in range( getLength(destSound) ):
sample = getSample(sound, int(srcIndex) )setSample(destSound, destIndex, sample)srcIndex = srcIndex + 0.5
return destSound
>>> snd = makeSound("techno_mono.wav")>>> playSound(snd) >>> snd2 = half(snd)>>> playSound(snd2)>>>
Trace der Laufvariablen je Schleifendurchlauf:destIndex: 0, 1, 2, 3, 4, 5, 6, 7, …srcIndex: 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, …int(srcIndex): 0, 0, 1, 1, 2, 2, 3, 3, 4, …
Konvertierung Float Integerz.B. 1.5 1
Kopie des Sounds erzeugen (und später bearbeiten)
26
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Verringern der Frequenz um beliebigen FaktorPython-Skript (fast identisch mit vorigem Skript)
def slower(sound, rate):"make the sound slower, rate should be at most 1.0"destSound = copySound(sound)
srcIndex = 0.0for destIndex in range( getLength(destSound) ):
sample = getSample(sound, int(srcIndex) )setSample(destSound, destIndex, sample)srcIndex = srcIndex + rate
return destSound
>>> snd = makeSound("techno_mono.wav")>>> snd2 = slower(snd, 0.8) >>> playSound(snd2)
Trace der Laufvariablen je Schleifendurchlauf bei rate = 0.8:destIndex: 0, 1, 2, 3, 4, 5, 6, 7, …srcIndex: 0.0, 0.8, 1.6, 2.4, 3.2, 4.0, 4.8, 5.6, …int(srcIndex): 0, 0, 1, 2, 3, 4, 4, 5, …
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Verdoppeln der Frequenz von Sounds: Idee
Nur jedes zweite Sample des Original-Sounds in Ziel-Sound kopieren
Falls Ziel-Sound (formal) gleiche Länge wie Original haben soll: zweite Hälfte des Ziel-Sounds: z.B. mit Nullen füllen
59 -111-119 -30 18 18
59 18-30-1
0 321 4 5 6
0 0 0
0 321 4 5 6
27
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Verdoppeln der Frequenz:Python-Skript
def double(sound):destSound = copySound(sound)destIndex = 0for sourceIndex in range(0, len(sound), 2):
value = getSample(sound, sourceIndex)setSample( destSound, destIndex, value)destIndex = destIndex + 1
# Zero out the rest of the target sound -- it's only half full!# Zeros are silent.for secondHalf in range(len(destSound)/2, len( destSound)):
setSample(destSound, destIndex, 0)destIndex = destIndex + 1
return destSound
>>> snd = makeSound("techno_mono.wav")>>> snd2 = double(snd) >>> playSound(snd2)
Trace der Laufvariablen je Schleifendurchlauf:sourceIndex: 0, 2, 4, 6, 8 …destIndex: 0,1, 2, 3, 4, 5, …
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Verdoppeln der Frequenz OHNE Auffüllen des Ziel-Sounds mit Nullen
def doubleNoClear(sound):destSound = copySound(sound)destIndex = 0for sourceIndex in range(0, getLength(sound), 2):
value = getSample(sound, sourceIndex)setSample( destSound, destIndex, value)destIndex = destIndex + 1
return destSound
>>> snd = makeSound("techno_mono.wav")>>> snd2 = doubleNoClear(snd) >>> playSound(snd2)
2. Hälfte des neuen Sounds wie Original-Sound
28
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Beliebiges Verändern der Frequenz von Soundsbasiert auf slower-Skript
def changeFreq(sound, rate):destSound = copySound(sound)
srcIndex = 0.0for destIndex in range( len(destSound) ):
if srcIndex <= getLength(sound):sample = getSample(sound, int(srcIndex) )
else: # possibly fill end of sound with zerossample = 0
setSample(destSound, destIndex, sample)srcIndex = srcIndex + rate
return destSound
>>> playSound( changeFreq(snd, 0.8) ) # langsamer>>> playSound( changeFreq(snd, 1.3) ) # schneller
wie slower-Skript, aber mit Auffüllen von Nullen, falls notwendig
Prof. B. Jung Einführung in die Informatik, WS 2007/08 TU Bergakademie Freiberg
Singender Eisberg entdeckt
Ein Lied von Kälte und EinsamkeitEigentlich wollten Forscher des Bremerhavener Alfred-Wegener-Instituts für Polar- und Meeresforschung seismische Signale in der Antarktis untersuchen. Als sie die Aufnahmen auswerteten, entdeckten sie völlig unerwartet ein neues Talent: ein Eisberg, der musikalisch anmutende Klänge erzeugt.Mit einer Frequenz von 0,5 Hertz ist der von den Forschern als "harmonischer Tremor" beschriebene Ton für das menschliche Ohr zwar nicht wahrnehmbar. Auf schnellerer Geschwindigkeit abgespielt hört er sich jedoch an wie ein Bienenschwarm oder ein sich warmspielendes Orchester, berichteten die Forscher. Redaktionsmitglieder von tagesschau.de fühlten sich eher an die Geräuschkulisse eines Formel-1-Rennens oder sogar an Celine Dions Lied "My Heart will go on" aus dem Film Titanic erinnert. …
www.tagesschau.de, 25.11.2005
eisberg.wav