|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Nils
Anmeldungsdatum: 24.03.2006 Beiträge: 191
|
Verfasst am: 27.11.2019, 20:18 Titel: Audio MorseZeichen in Schrift Morsezeichen übersetzen |
|
|
Hi!
Ich lerne gerade morsen. Also ich versuch's mal.
Dazu gibt es Audiodateien(.mp3), die die Morsezeichen [langer Ton. kurzer Ton, Pause] einem Vorspielen. [Da wird dann dazwischen auch gesprochen. Üblicherweise werden Gruppen zu fünf Buchstaben 'gegeben'. Zw. 2 Buchstaben je eine Pause.]
Ich suche eine Möglichkeit dieses Audiodatei-Morsezeichen in kurz-lang-pause Schriftdarstellung zu konvertieren.
Bsp.: Ein "q" besteht aus den 4 Tönen [pause,] lang, lang, kurz, lang[, pause]. Die sollen übersetzt werden in [p]-[p] und in einer Datei abgelegt werden.
qb hiesse so: [p]- -...[p]
Geht so etwas mit QB?
Wie macht man das?
Gibt es das schon Beispielcodes?
Hat da jemand im Forum eine Idee?
ps. link zu einer solchen Audiodatei: https://dj1kn.darc.de/morsenlernen001.htm
pps Woher kommt jetzt der blaue Smiley? dann eben so.
b: l l k l
qb: l k k k _________________ Kontrolliert die Politik! Laßt nicht die Politik Euch kontrollieren! Das sind Eure Angestellten! Lasst Sie das spüren!!! |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 27.11.2019, 21:34 Titel: |
|
|
Hmm, das wäre ein schönes Thema für ein kleines Weihnachtsprojekt.
So ganz spontan fällt mir dazu folgender Lösungansatz ein: Zuerst wird die Audiodatei zwecks besserer Analysierbarkeit von mp3 nach wav konvertiert. Anschließend wird die Datei in Abschnitte von (beispielsweise) 1 ms zerlegt und jeder Abschnitt auf "Ton" (= 1) oder "kein Ton" (= 0) untersucht. Dabei ergibt sich eine Folge von Nullen und Einsen, die schon recht genau den Punkten und Strichen entspricht.
Das Programm müsste dann nur noch auf statistischem Weg herausfinden, was "Punkt", "Strich", "Pause zwischen Tönen" und "Pause zwischen Zeichen" ist und die Tonfolgen den passenden Zeichen zuordnen. Eigentlich ganz simpel, zumindest bei konstanter Geschwindigkeit und wenig Störgeräuschen.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
Nils
Anmeldungsdatum: 24.03.2006 Beiträge: 191
|
Verfasst am: 27.11.2019, 22:05 Titel: |
|
|
qgrindstone:
Oh, Mann, das klingt ja echt unüberwindlich.
hardwaremäßig hab ich so etwas gefunden > https://www.youtube.com/watch?v=G0AWScXzz6A
Aber auch das scheint echt schwer!
cu _________________ Kontrolliert die Politik! Laßt nicht die Politik Euch kontrollieren! Das sind Eure Angestellten! Lasst Sie das spüren!!! |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 28.11.2019, 17:58 Titel: |
|
|
Nils hat Folgendes geschrieben: | Oh, Mann, das klingt ja echt unüberwindlich. | Ganz und gar nicht (und das ist jetzt nicht ironisch gemeint). Mit QB -insofern hast du schon recht- ist das allerdings nicht zu machen, aber es gibt ja noch FB.
Für die ersten beiden Arbeitsschritte (herunterladen und konvertieren) habe ich schon eine fertige Lösung (nur mal als kleines Appetithäppchen): Code: | Function herunterladen(url As String, datei As String, pfad As String, tout As Double = 10.0) As Integer
Dim As libvlc_instance_t Ptr vlcInstance
Dim As libvlc_media_player_t Ptr mp
Dim As libvlc_media_t Ptr media
Dim As String vmem_options, myMediaFile
Dim As Single dlpos
Dim As Double timeout
Dim As Integer flag, ff
vmem_options = "#transcode{acodec=fl32}:std{mux=wav,access=file,dst=""" + _
pfad + "temp.wav""}"
Dim As Any Ptr vlc_args(0 To ...) = { @"--quiet", _
@"--sout", _
StrPtr(vmem_options) }
vlcInstance = libvlc_new (UBound(vlc_args) + 1, @vlc_args(0))
media = libvlc_media_new_location(vlcInstance, url)
mp = libvlc_media_player_new_from_media(media)
libvlc_media_player_play(mp)
libvlc_media_release(media)
Print
timeout = Timer + tout
dlpos = 0
Locate CsrLin-1,1,0
Print Int(dlpos * 100);"% (abbrechen mit ESC) "';toutzaehler
Do
If dlpos <> libvlc_media_player_get_position(mp) Then
dlpos = libvlc_media_player_get_position(mp)
timeout = Timer + 1
Locate CsrLin-1,1,0
Print Int(dlpos * 100);"% (abbrechen mit ESC) "';toutzaehler
EndIf
If InKey = Chr(27) Then
libvlc_media_player_stop(mp)
libvlc_media_player_release(mp)
libvlc_release(vlcInstance)
Return 1
EndIf
Sleep 1
Loop While timeout > Timer
If dlpos < .5 Then 'kein download
ff = FreeFile
Open pfad + "url.txt" For Append As #ff
Print #ff, url
Close ff
EndIf
Locate CsrLin-1,6
Print " "
Sleep 500
libvlc_media_player_stop(mp)
libvlc_media_player_release(mp)
libvlc_release(vlcInstance)
If FileLen(pfad + "temp.wav") Then
If Name (pfad + "temp.wav", pfad + datei + ".wav") Then
datei = erlzeichen(datei)
If Name (pfad + "temp.wav", pfad + datei + ".wav") Then
Print pfad + datei + ".wav";" >>> Umbenennen fehlgeschlagen"';toutzaehler
Sleep 1000
Return 2
EndIf
EndIf
Else
Return 3
EndIf
FileCopy(pfad + datei + ".wav", erpfad + "NEU\" + datei + ".wav")
Return 0
End Function | Die eigentliche Arbeit erledigt dabei libvlc, die eierlegende Wollmilchsau unter den Open Source - Mediaplayern.
Die obige Function ist Teil eines Programms, mit dem ich unter anderem einmal in der Woche neu erschienene Folgen von Der kleine Erziehungsratgeber herunterlade, für meine persönliche Sammlung.
Der erste Analyseschritt "Ton" oder "kein Ton" in 1-ms-Schritten ist auch nicht besonders schwierig. Jede wav - Datei hat einen Header, aus dem sich u.a. der Wert "Samples pro Sekunde je Kanal" ablesen lässt (ja, auch dafür habe ich eine fertige Funktion ). Dieser Wert durch 1000 geteilt mal Anzahl der Kanäle ergibt die Anzahl der Samples pro Millisekunde, und die Größe und Art der Samples ist von der vorherigen Konversion her bekannt (hier 32bit float = Variablentyp "Single"). Es werden nun jeweils so viele Samples von der Datei gelesen wie sie 1 ms Dauer entsprechen und die Absolutwerte der Samples aufaddiert. Diese Summe wird anschließend mit einem (experimentell zu ermittelnden) Schwellwert verglichen und entschieden, ob es gerade piepst oder nicht.
Die resultierenden Werte werden als "0" oder "1" in eine Datei geschrieben und weiter analysiert. Wie genau, darüber muß ich auch erst noch ein wenig grübeln.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 29.11.2019, 15:52 Titel: |
|
|
Ganz so kompliziert muss man es eigentlich nicht machen.
"Zeit" Spielt bei der Analyse nur eine untergeordnete Rolle, da auch das "Gebertempo" variieren kann.
Am Besten wandelst du, wie schon angesprochen, die Datei in WAV um.
Anschließend findest du heraus, wieviele Byte's die WAV pro Sampel benötigt. Dann kannst du einfach die Datei, Byte für Byte bzw. Sampel für Sampel einlesen. Mit einer einfachen For-Next schleife brauchst du dann nur noch die "Sampelabstände" zwischen einem "Ton" und "keine Ton" sowie zwischen einem "Ton" und dem "nächsten Ton" in ein Array speichern.
Im Anschluß kennst du dann sowohl die Zeitlichen Abstände zwischen den Einzelnen Signalen sowie die Signallängen.
Am einfachsten gehst du dann das ganze Array durch und ermittelst die Längen der einzelnen Tonabstände, um sowohl das "did" als auch das "da" durch die "sampellänge" zu definieren.
Zum schluß noch die abstände zwischen den einzelnen tönen um buchstabe und satzende zu erkennen.
Jetzt kannst du mit den Längenangaben / zeitabstände bzw. sämpelabstände die signale in buchstaben umsetzen und ausgeben.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 29.11.2019, 17:17 Titel: |
|
|
ThePuppetMaster hat Folgendes geschrieben: | Dann kannst du einfach die Datei, Byte für Byte bzw. Sampel für Sampel einlesen. Mit einer einfachen For-Next schleife brauchst du dann nur noch die "Sampelabstände" zwischen einem "Ton" und "keine Ton" sowie zwischen einem "Ton" und dem "nächsten Ton" in ein Array speichern. | Das funktioniert so nicht, weil die Werte der Samples den Wellenverlauf des Audiosignals abbilden und das einzelne Sample nichts über den Signalpegel aussagt. Um den Signalpegel zu ermitteln, muss der Mittelwert über eine größere Anzahl von Samples gebildet werden, d.h. Summe der Absolutwerte aller Samples durch Anzahl der Samples. Das Teilen durch die Anzahl der Samples können wir uns hier sparen, da diese für ein 1-ms-Intervall immer gleich ist und als Faktor in den Schwellwert einfliesst.
Die Auswertung hatte ich mir so gedacht, daß ein Zähler die aufeinanderfolgenden "Ton"- bzw. "kein Ton" - Intervalle mitzählt und bei jedem Wechsel die Anzahl in ein -da bin ich ganz bei dir- Array schreibt, und zwar "Ton" als positiven und "kein Ton" als negativen Wert. Diese Werte sind dann quasi direkte Zeitangaben.
Das Array wird über zwei Zeiger (einer zum Schreiben für die hereinkommenden Werte und einer zum Auslesen für die Auswertung) als FIFO-Register organisiert, so daß dessen Größe überschaubar bleibt.
Über das genaue Vorgehen bei der Auswertung muß ich noch ein wenig grübeln...
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 29.11.2019, 18:29 Titel: |
|
|
grindstone hat Folgendes geschrieben: | Das funktioniert so nicht, weil die Werte der Samples den Wellenverlauf des Audiosignals abbilden und das einzelne Sample nichts über den Signalpegel aussagt. Um den Signalpegel zu ermitteln, muss der Mittelwert über eine größere Anzahl von Samples gebildet werden, d.h. Summe der Absolutwerte aller Samples durch Anzahl der Samples. Das Teilen durch die Anzahl der Samples können wir uns hier sparen, da diese für ein 1-ms-Intervall immer gleich ist und als Faktor in den Schwellwert einfliesst. |
Normalerweise würde ich dir recht geben. ABER ... da es hier um morsezeichen geht, welche durch einen definierten ton gesampelt werden, braucht es glücklicherweise kein FFT und auch keine anderweitige komplexe analyse ... DENN ... der bezug ist folgender: Schwingungsabstand vs. Signalabstand.
Es ist unerheblich, welcher Wert das Byte definiert, da die schwingung der frequenz kleiner ist als die der Signalinformation, und dadurch gefiltert bzw. auch gezählt werden kann.
Code: |
c = 0
for x as bla
c += 1
if value > 10 then 'schwellwert für frequenzsignal
if c > 100 then 'schwellwert für tonsignal
'... usw.
c = 0
end if
end if
next
|
sobald allerdings die frequenz variieren sollte, oder andere hochamplituriierte störgeräuscht mit in der wav enthalten sind, funktioniert mein beispiel nicht. Aber, einfache klassische morsedec. funzt hiermit hervorragend.
EDIT:
Klicken zum vergrößern
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Zuletzt bearbeitet von ThePuppetMaster am 30.11.2019, 18:38, insgesamt 2-mal bearbeitet |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 30.11.2019, 16:12 Titel: |
|
|
Wer bindet denn da schon wieder so große Bilder ein, dass ich beim Lesen seitwärts scrollen muss?
Edit: Danke, sehr viel angenehmer. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|