Benutzer-Werkzeuge

Webseiten-Werkzeuge


ss15:tonverarbeitung

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
ss15:tonverarbeitung [2015/10/04 21:45]
m.schramm [3.2 Decodierung für Taktrückgewinnung 1.2]
ss15:tonverarbeitung [2016/05/10 14:46] (aktuell)
Zeile 1: Zeile 1:
 ====== Tonverarbeitung ====== ====== Tonverarbeitung ======
 ===== 1. Aufbau ===== ===== 1. Aufbau =====
-Die Tonverarbeitung besteht aus den zwei Komponenten Taktrückgewinnung und Decodierung. Die Taktrückgewinnung muss dabei zuerst ablaufen, da sie aus dem gesendeten Taktsignal den Sendetakt rekonstruiert,​ der enorm wichtig für die Decodierung ist, weil diese immer taktweise stattfindet. Die Taktrückgewinnung liefert den ermittelten zugrunde liegenden Sendetakt an die Decodierungsfunktion. Diese übersetzt nun den aufgenommenen Schall mithilfe des übermittelten Taktes in eine Liste von Nullen und Einsen, welche dann noch weiter verarbeitet werden kann.+Die Tonverarbeitung besteht aus den zwei Komponenten ​**Taktrückgewinnung** und **Decodierung**. Die Taktrückgewinnung muss dabei zuerst ablaufen, da sie aus dem gesendeten Taktsignal den Sendetakt rekonstruiert,​ der enorm wichtig für die Decodierung ist, weil diese immer taktweise stattfindet. Die Taktrückgewinnung liefert den ermittelten zugrunde liegenden Sendetakt an die Decodierungsfunktion. Diese übersetzt nun den aufgenommenen Schall mithilfe des übermittelten Taktes in eine Liste von Nullen und Einsen, welche dann noch weiter verarbeitet werden kann. Eine dritte neu hinzu gekommene Komponente ist die **Queue**. Deren Aufgabe ist es kontinuierlich,​ aber kontrolliert stückweise Audio-Daten von der Soundkarte zu liefern, die dort vom Mikrofon ankommen. Diese zusätzliche Komponente ist nötig um eine ständige Aufnahme zu ermöglichen,​ bei der automatisch erkannt wird wann etwas gesendet wird und das Gesendete sofort decodiert wird.
 ===== 2. Taktrückgewinnung ===== ===== 2. Taktrückgewinnung =====
   * [[Taktrückgewinnung 1.0]] (verworfen)   * [[Taktrückgewinnung 1.0]] (verworfen)
Zeile 14: Zeile 14:
  tdauer = 0.05 # Taktlänge in Sekunden  tdauer = 0.05 # Taktlänge in Sekunden
  tl = tdauer*RATE # Taktlänge in Samples  tl = tdauer*RATE # Taktlänge in Samples
- f_0 = 12900*tdauer # Frequenz zur codierung der 0 umgerechnet für das Frequenz-Spektrum in f+ f_0 = 13000*tdauer # Frequenz zur codierung der 0 umgerechnet für das Frequenz-Spektrum in f
  f_1 = 12800*tdauer # Frequenz zur codierung der 1 umgerechnet für das Frequenz-Spektrum in f  f_1 = 12800*tdauer # Frequenz zur codierung der 1 umgerechnet für das Frequenz-Spektrum in f
  
Zeile 44: Zeile 44:
  return l  return l
 </​code>​ </​code>​
 +{{:​ss15:​taktverschiebung.png?​direct&​500 |Signale mit Takteinteilung und Taktverschiebung}}
 ==== 3.2 Decodierung für Taktrückgewinnung 1.2 ==== ==== 3.2 Decodierung für Taktrückgewinnung 1.2 ====
 Diese Decodierungs-Funktion gleicht überwiegend der vorigen. Allerdings wird hier keine Taktverschiebung übergeben, sondern eine Liste ''​idx''​ mit konkreten Indizes zur Einteilung in Abschnitte. Nun werden die Indizes vom ersten bis zum vorletzen durchgegangen und die [[https://​de.wikipedia.org/​wiki/​Diskrete_Fourier-Transformation|Diskrete Fourier-Transformation]] auf den Abschnitt vom jeweils aktuellen bis zum nächsten Index angewendet. Weiter geht es äquivalent zur anderen decode-Funktion. Diese Decodierungs-Funktion gleicht überwiegend der vorigen. Allerdings wird hier keine Taktverschiebung übergeben, sondern eine Liste ''​idx''​ mit konkreten Indizes zur Einteilung in Abschnitte. Nun werden die Indizes vom ersten bis zum vorletzen durchgegangen und die [[https://​de.wikipedia.org/​wiki/​Diskrete_Fourier-Transformation|Diskrete Fourier-Transformation]] auf den Abschnitt vom jeweils aktuellen bis zum nächsten Index angewendet. Weiter geht es äquivalent zur anderen decode-Funktion.
Zeile 49: Zeile 50:
 def decode(y, idx): def decode(y, idx):
  '''​erzeugt aus der Aufnahme y eine Liste der übertragenen Bits'''​  '''​erzeugt aus der Aufnahme y eine Liste der übertragenen Bits'''​
- f_0 = 12900*tdauer # Frequenz zur codierung der 0+ f_0 = 13000*tdauer # Frequenz zur codierung der 0
  f_1 = 12800*tdauer # Frequenz zur codierung der 1  f_1 = 12800*tdauer # Frequenz zur codierung der 1
  f = []  f = []
Zeile 86: Zeile 87:
  else:  else:
  l.append(1)  l.append(1)
 +</​code>​
 +{{:​ss15:​decode.png?​direct&​500 |Signalintensitäten abschnittsweise und Schranken}}
 +===== 4. Queue =====
 +Die Umsetzung der Queue basiert auf ''​microlistener_queue.py''​ von Stefan. Wir haben noch die Funktionen ''​get_frames''​ und ''​set_frames''​ ergänzt. Über diese Klasse können wir Objekte erzeugen, die einen Stream von der Soundkarte erhalten und diesen kontinuierlich in die ''​queue''​ schreiben. Über ''​get_frames''​ kann man sich daraus immer ''​n''​ Frames zur Weiterverarbeitung holen, die dann zuerst zur Taktrückgewinnung kommen. Mit der Funktion ''​set_frames''​ werden Frames zurück in die ''​queue''​ geschrieben,​ die bei der Weiterverarbeitung übrig geblieben sind und beim nächsten Aufruf von ''​get_frames''​ verarbeitet werden. Leider haben wir das gesamte Programm bisher noch nicht mit Verwendung der Queue zum fehlerfreien Laufen gebracht.
 +<code python>
 +#​!/​usr/​bin/​python
 +# coding=utf8
 +
 +from __future__ import division
 +
 +import pyaudio
 +import time
 +import numpy as np
 +
 +# GLOBALE VARIABLEN
 +
 +CHANNELS=1
 +RATE=44100
 +CHUNK=2**11
 +
 +
 +### Diese Klasse wird im Modul microlistener definiert.
 +### Sie kann in allen Projekten verwendet werden, die eine
 +### kontinuierliche Audio-Eingabe brauchen.
 +
 +
 +class MicroListener(object):​
 +
 + def __init__(self,​rate,​channels,​chunk,​playback=False):​
 + '''​kreiert einen Stream, der mit der Samplerate '​rate'​
 + und '​channels'​ Kanälen über das Microphon Audio aufnimmt.
 + Nach jeweils '​chunk'​ Frames wird die callback-Funktion
 + aufgerufen. ​
 +
 + Die Callback-Funktion hängt die neuesten Daten an das
 + numpy-Array queue an (es ist ein Nx1-Array für 1-Kanal-Aufnahmen
 + und ein Nx2-Array für 2-Kanal-Aufnahmen.) ​
 +
 + Falls playback==True,​ werden die Daten an den Lautsprecher
 + durchgereicht.
 + '''​
 +
 + self.p = pyaudio.PyAudio()
 + self.stream = self.p.open(format=pyaudio.paInt16 ,
 +                channels=channels,​
 +                rate=rate,
 +                input=True,
 +                output=playback,​
 +                stream_callback=self.micro_callback,​
 +                frames_per_buffer=chunk)
 + self.queue=np.zeros((0,​CHANNELS))
 + self.stream.start_stream()
 + time.sleep(0.5)
 +
 + def micro_callback(self,​ 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.array(np.fromstring(in_data,​dtype=np.short),​dtype=np.float)
 + if CHANNELS==2:​
 + y=y.reshape((y.shape[0]//​2,​2))
 + else:
 + y=y.reshape((y.shape[0],​1))
 + #### Eine Art Lautstärkeanzeige,​ nur zu Testzwecken,​ sonst
 + #### auskommentieren:​
 + # print int(np.linalg.norm(y[:,​0])/​2000.)*'​*'  ​
 + self.queue=np.concatenate((self.queue,​y),​axis=0)
 + return (in_data, status)
 +
 + def __del__(self):​
 + self.stream.stop_stream()
 + self.stream.close()
 + self.p.terminate()
 +
 + def get_frames(self,​ n):
 + while self.queue.shape[0] < n:
 + time.sleep(0.001)
 + y = self.queue[:​n+1,:​]
 + self.queue = self.queue[n+1:,:​]
 + return y
 +
 + def set_frames(self,​ r):
 + self.queue = np.concatenate(r,​ self.queue)
 </​code>​ </​code>​
ss15/tonverarbeitung.1443987906.txt.gz · Zuletzt geändert: 2016/05/10 14:46 (Externe Bearbeitung)