Seite 1 von 1

Tonfolge decodieren

Verfasst: Montag 26. Juni 2006, 12:55
von Damaskus
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

Re: Tonfolge decodieren

Verfasst: Montag 26. Juni 2006, 13:17
von Leonidas
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.

Re: Tonfolge decodieren

Verfasst: Mittwoch 16. August 2006, 23:25
von Talphir
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?

Verfasst: Mittwoch 16. August 2006, 23:29
von Damaskus
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

Verfasst: Mittwoch 16. August 2006, 23:40
von Talphir
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

Verfasst: Mittwoch 16. August 2006, 23:51
von Damaskus
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.

Codebeispiel

Verfasst: Donnerstag 17. August 2006, 07:42
von Talphir
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 :)

Verfasst: Sonntag 20. August 2006, 22:44
von Damaskus
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

Verfasst: Montag 21. August 2006, 13:01
von Talphir
: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 :)

Verfasst: Montag 21. August 2006, 16:11
von Damaskus
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:

Re: Tonfolge decodieren

Verfasst: Samstag 18. Juli 2020, 13:20
von zwick88
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