Tonfolge decodieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Damaskus
Administrator
Beiträge: 995
Registriert: Sonntag 6. März 2005, 20:08
Wohnort: Schwabenländle

Hi,
kann mir jemand Anhaltspunkte oder Ideen geben wie ich ein Tonfolge decodieren kann. Also folgende Punkte muss ich irgendwie realisieren

- alle 0,5 Sekunden zugriff auf die Soundkarte und abholen der Daten auf dem Line In / Mikrofon In Port

- Die Tonfolge decodieren nach den Frequenzen. http://de.wikipedia.org/wiki/5-Ton-Folge

Für sämtliche Anregungen bin ich euch echt Dankbar.

Mfg
Damaskus
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Damaskus hat geschrieben:- alle 0,5 Sekunden zugriff auf die Soundkarte und abholen der Daten auf dem Line In / Mikrofon In Port
Vermute mal, dass man das mit pySonic realisieren kann.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Talphir
User
Beiträge: 5
Registriert: Mittwoch 16. August 2006, 22:45

Unter Linux gibt es für den Zugriff auf die Soundkarte das Modul "ossaudiodev". Bei anderen Betriebssystem bin ich leider unwissend :?

Sind die Daten erstmal vorhanden, ist die Vearbeitung mit "numpy" oder "numarray" wahrscheinlich am einfachsten (z.B. mit den FFT-Funktionen).

http://numeric.scipy.org/ (numpy)
http://www.stsci.edu/resources/software ... e/numarray (numarray)

Hast Du für die Decodierung schon an einen bestimmten Algorithmus gedacht, oder ist das noch unklar?
Zuletzt geändert von Talphir am Mittwoch 16. August 2006, 23:29, insgesamt 1-mal geändert.
Benutzeravatar
Damaskus
Administrator
Beiträge: 995
Registriert: Sonntag 6. März 2005, 20:08
Wohnort: Schwabenländle

Na ich dachte da so an 5Ton ZVEI für den Anfang und später an POCSAQ.
Allerdings hab ich davon bisher noch keine wirkliche Ahnung wie die Aufgebaut sind.

Gruß
Damaskus
Talphir
User
Beiträge: 5
Registriert: Mittwoch 16. August 2006, 22:45

Hmm, also die genauen Standards kenne ich jetzt auch nicht.

Ich nehme mal an "5Ton ZVEI" ist dieses typische Gefiepse, das man z.B. von den Taxis kennt. (ich gehe da mal ganz nach Gehör :) )
Das ist relativ leicht zu dekodieren, entweder mit Fouriertransformation oder sogar nur mit Nullstellenzählung. Ob man das in reinem Python realiseren kann oder dazu "numpy"/"numarray" braucht, müsste man erstmal testen...

POCSAG scheint mir eine wesentlich höhere Datenrate zu verwenden, das wird somit schwieriger. Vielleicht gibt es bereits von den Amateurfunkern externe Tools, die das Paket einfach auf der Konsole ausgeben.

Gruß
Talphir
Benutzeravatar
Damaskus
Administrator
Beiträge: 995
Registriert: Sonntag 6. März 2005, 20:08
Wohnort: Schwabenländle

Stimmt :)
5-Ton ist das was du im Taxi hörst.
Pocsaq ist Digital und hat eine höhere Datendichte.

Also in Java gibts einige Implementierungen und was in Java möglich ist muss doch auch in Python gehen.

Mich würde halt das gesamte interresieren nicht nur "einfach" ein fertiges Auswertungs Modul nehmen und die Ausgaben formatieren, sondern das ganze komplett selbst aufzusetzten.
Ich vermute mal das das auch nicht wirklich ganz einfach ist. Aber probieren will ichs trotzdem mal.
Talphir
User
Beiträge: 5
Registriert: Mittwoch 16. August 2006, 22:45

Hier mal eine Version in reinem Python, um die einzelnen Symbole im 5-Ton zu detektieren.

Code: Alles auswählen

import wave
import struct
from math import sin, cos, pi, sqrt

## frequencies of ZVEI coding
freqs = (    
    (1060, "1"), (1160, "2"), (1270, "3"),
    (1400, "4"), (1530, "5"), (1670, "6"),
    (1830, "7"), (2000, "8"), (2200, "9"),
    (2400, "0"),
    (2600, "R")
)

## seconds per digit
period = 0.07

## open sample stream from file
stream = wave.open("5ton.wav")
srate = stream.getframerate()
assert stream.getnchannels() == 1    ## is mono 
assert stream.getsampwidth() == 2   ## is 16-bit

## get chunk size for analysis in samples
subdivide = 2
chunklen = int(period*srate/subdivide)

## print header
for freq, digit in freqs:
    digit = "[" + digit + "]"
    print digit.ljust(4),

print
print "---- " * len(freqs)

## process
while 1:
    data = stream.readframes(chunklen)
    if len(data) < chunklen*2:
        break

    ## unpack 16-bit data into tuple of numbers
    format = str(chunklen) + "h"
    samples = struct.unpack(format, data)    

    ## look for each frequency separately
    for freq, digit in freqs:
        omega = freq/44100.0 * 2 * pi

        ## discrete fourier transformation
        tsin = 0; tcos = 0; phi = 0
        for sample in samples:
            tsin += sample * sin(phi)
            tcos += sample * cos(phi)
            phi += omega

        ## output of each frequency amplitude
        amplitude = sqrt(tsin*tsin + tcos*tcos)
        amplitude = int(amplitude / chunklen) / 100
        print str(amplitude).ljust(4), 

    print
Mit dem Beispiel von http://de.wikipedia.org/wiki/5-Ton-Folge konvertiert in ein Mono-WAVE ergibt sich:

Code: Alles auswählen

# sox 5-Ton-Folge-88022.wav -c1 5ton.wav
# python ZVEI-dec.py 

[1]  [2]  [3]  [4]  [5]  [6]  [7]  [8]  [9]  [0]  [R] 
---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
0    0    0    0    0    0    0    0    0    0    0   
0    0    0    0    0    0    0    0    0    0    0   
0    1    1    0    2    2    0    97   0    0    0   
0    1    1    0    1    3    1    104  1    0    0   
0    0    0    0    1    1    0    0    0    2    112 
0    0    0    0    1    1    0    0    0    3    120 
0    0    0    0    1    1    0    0    0    132  1   
1    0    1    0    1    1    1    1    1    136  1   
12   153  6    6    0    1    2    2    1    1    1   
14   159  6    6    1    0    2    2    1    1    1   
0    0    1    0    0    1    0    0    1    2    152 
0    1    1    0    1    1    0    0    0    2    157 
0    0    0    0    0    0    0    0    0    0    0   
0    0    0    0    0    0    0    0    0    0    0   
Jede Zeile entspricht einer halben (!) Symbollänge und jede Spalte den Amplituden der einzelnen Frequenzen im 5-Ton ZVEI. Man erkennt sehr schön 8R02R, also 88022. (der Algorithmus benutzt die halbe Symbollänge, da die Zeitraster ja nicht unbedingt so schön wie im Beispiel aufeinander passen)

Allerdings: für die 1,4 Sekunden lange Aufnahme braucht mein 1,2 Ghz Celeron schon 3 Sekunden! Für Echtzeit-Signalverarbeitung auf Sampleebene ist Python leider fast immer zu langsam. Beim Experimentieren ist es hingegen sehr hilfreich -- ich habe schon öfters bewährte Prototypen in Pyrex oder C++ übersetzt.

Es gibt natürlich noch zig andere Algorithmen für obiges Problem. Von der hier fehlenden Auswertung mal zu schweigen :)
Benutzeravatar
Damaskus
Administrator
Beiträge: 995
Registriert: Sonntag 6. März 2005, 20:08
Wohnort: Schwabenländle

Hi,
ich hab mich mal in dein Codeschnippsel reingearbeitet.
So ganz langsam wird mir klar wie das Decodieren erfolgen muss.

Ich hab mich jetzt mal noch an die Auswertung gemacht und verwende dazu ein knapp 3 Sekunden langes File.

Mit Python 2.5 RC1 ist es sogar noch etwas schneller als mit 2.4
Python 2.4 hat geschrieben:
0
----
2000
----
2600
----
2400
----
1160
----
2600
----
0
----
2000
----
2600
----
2400
----
1160
----
2600
----
----------------------------------------------------------------------
Ran 1 test in 1.140s

OK
Python 2.5 hat geschrieben: ----------------------------------------------------------------------
Ran 1 test in 1.032s

OK
Jetzt muss ich nur noch den Mikrofon Eingang Streamen und ich hab eine "Live Auswertung" :wink:

Gruß
Damaskus
Talphir
User
Beiträge: 5
Registriert: Mittwoch 16. August 2006, 22:45

:D Dein Rechner ist ja 3x so schnell wie meiner.
Oder vielleicht verwendest Du eine niedrigere Abtastrate, 8kHz sollten ja auch reichen. Versuch auch mal, ob "psyco" noch mehr Performance bringt. In diesem speziellen Fall sollte es ziemlich gut anschlagen... (ich hab's gerade nicht installiert)

Übrigens, die verwendete Technik des Durchmultiplizierens mit der Sinus- und Kosinusfunktion findet bei Softwaremodems dieser Art häufig Anwendung. Da kann man auch noch viel am Algorithmus selbst optimieren, ist dann halt nicht mehr so schön gerade heraus.

Weiterhin viel Erfolg beim Experimentieren :)
Benutzeravatar
Damaskus
Administrator
Beiträge: 995
Registriert: Sonntag 6. März 2005, 20:08
Wohnort: Schwabenländle

Hi,
als Abtastrate hab ich 11Khz bei 16 Bit / mono verwendet.
Aber ich sitz hier auch an einem P4 3Ghz Dual Core, der sollte auch etwas schneller rechnen. :wink:
zwick88
User
Beiträge: 1
Registriert: Samstag 18. Juli 2020, 13:19

Hallo Zusammen,

hat jemand eine Lösung für micht, dass ich in Echtzeit den Mikrofoneingang Streame, damit ich eine Zvei Alarmierung auswerten kann? Oder gibts für einen Raspberry PI eine alternative?

Danke für eure Unterstützung

Alexander
Antworten