I've written a small program to help learning morse code.
It's not finished, but usablel. It's missing special characters like Á...
Future versions will be edited inside this post here.
It features a REPL (read eval print loop - shell alike) for recognizing commands and text to morse.
It doesn't show you the -.--, instead it shows you the actual character or shorthand while you hear it!
In the end, after using this program for a longer time you should be able to write down what you hear (the morse) without thinking.
Start with only 2-3 chars each day for about 15m. After about 1-3 months (depends on your brain, hehe) you should be able to "see" heard morse code in your head.
If you can write it down on paper without thinking finally, you will be able to morse too. Believe it or not
A special learning modus will be implemented later (dictionary, speed independent,...)
1) get SoundEasy.pbi from http://forum.purebasic.com/english/view ... 12&t=53646
I used it from the very first post in that thread. Thank you BasicallyPure!
2) save the following code aside the pbi and read the comments at the beginning
Code: Select all
; Title: Minimorse
; Author: Gekkonier
; Date: 2016-05-13
; Version: 0.2
; OS: Windows tested
; Linux and OSX not tested!
; PB ver. 5.42 LTS (x64)
;
; LICENSE:
;
; Do what you want with it, but don't blame me if your ears fall apart or your
; computer starts to act weird!
; This program uses SoundEasy.pbi
; you can find this include here:
; http://forum.purebasic.com/english/viewtopic.php?f=12&t=53646
; I don't know the terms of this include.
;
; Thank you, BasicallyPure for this awesome code!
;
;
; primary purpose:
; this program should help you to learn to correctly hear morse code (ITU)
;
; features:
; repl with help
; you enter text, it displays the transformed text (what is defined as code),
; and then shows you code after code the text and plays the corresponding sequence
; it doesn't show you the actual morse code, it distracts while learning!
;
;
; planned features:
; - change volume, speed and soundfrequency inside repl
; - argc, argv for:
; minimorse for repl
; minimorse -vol:XX -speed:XX -freq:xx
; minimorse -say hello world! for direct playing of strings
; minimorse -play filename for playback of a file
; minimorse hello world! garbage, abort!
; - in a galaxy far, far away:
; minimorse -learn and &learn command for a dedicated learning modus
; you hear morse code, and have to write it down
; but i think i will do this as a gui app
; so i can implement sound or optical morsing
; a simple error "handler"
Procedure handle(value.i, message.s)
If value = 0
MessageRequester("ERROR!", message)
End
EndIf
EndProcedure
handle(InitSound(), "Could not initialize Sound System!")
; the SoundEasy.pbi is not EnableExplicit compatible!
IncludeFile "SoundEasy.pbi"
; but now we can use it!
EnableExplicit
; speed and freqency settings for the soundoutput
#SPEED = 0.09
#SPEEDMS = #SPEED * 1000
#AMP = 25
#FREQUENZY = 1000
; dit and dah sounds are created with SoundEasy.pbi
Global ditsnd.i = CreateSound(#PB_Any, #FREQUENZY, #SPEED, #AMP, 0, #WF_SineWave, 0, 1)
Global dahsnd.i = CreateSound(#PB_Any, #FREQUENZY, #SPEED * 3, #AMP, 0, #WF_SineWave, 0, 1)
; this is the "AST"
Global NewList Tokens.s()
; these are the morse code values for the different token types
; these values are copied from our glory interwebs.
; missing: accents
; ä, ö, ü, ß are there, because german.
Global NewMap Token.s()
Token(" ") = " "
Token("A") = ".-"
Token("B") = "-..."
Token("C") = "-.-."
Token("D") = "-.."
Token("E") = "."
Token("F") = "..-."
Token("G") = "--."
Token("H") = "...."
Token("I") = ".."
Token("J") = ".---"
Token("K") = "-.-"
Token("L") = ".-.."
Token("M") = "--"
Token("N") = "-."
Token("O") = "---"
Token("P") = ".--."
Token("Q") = "--.-"
Token("R") = ".-."
Token("S") = "..."
Token("T") = "-"
Token("U") = "..-"
Token("V") = "...-"
Token("W") = ".--"
Token("X") = "-..-"
Token("Y") = "-.--"
Token("Z") = "--.."
Token("1") = ".----"
Token("2") = "..---"
Token("3") = "...--"
Token("4") = "....-"
Token("5") = "....."
Token("6") = "-...."
Token("7") = "--..."
Token("8") = "---.."
Token("9") = "----."
Token("0") = "-----"
Token("Ä") = ".-.-"
Token("Ö") = "---."
Token("Ü") = "..--"
Token("ß") = "...--.."
Token("CH") = "----"
Token(".") = ".-.-.-"
Token(",") = "--..--"
Token(":") = "---..."
Token(";") = "-.-.-."
Token("?") = "..--.."
Token("&") = ".-..."
Token("-") = "-....-"
Token("_") = "..--.-"
Token("(") = "-.--."
Token(")") = "-.--.-"
Token("'") = ".----."
Token("=") = "-...-"
Token("+") = ".-.-."
Token("/") = "-..-."
Token("@") = ".--.-."
; shorthands
Token("STARTING SIGNAL") = "-.-.-"
Token("ENDING SIGNAL") = ".-.-."
Token("INVITATION TO TRANSMIT") = "-.-"
Token("UNDERSTOOD") = "...-."
Token("PAUSE") = "-...-"
Token("WAIT") = ".-..."
Token("ERROR") = "........"
Token("NEW PAGE SIGNAL") = ".-.-."
Token("END OF WORK") = "...-.-"
; this can only play one morse symbol
; morse symbols are . - and <space>
Procedure playsymbol(symbol.s)
Select symbol
Case "."
PlaySound(ditsnd)
Delay(#SPEEDMS * 2)
Case "-"
PlaySound(dahsnd)
Delay(#SPEEDMS * 4)
Case " "
Delay(#SPEEDMS * 7)
EndSelect
EndProcedure
; this uses playsymbol to play a sequence of morse symbols
Procedure playcode(morsecode.s)
Define i.i
For i = 1 To Len(morsecode)
playsymbol(Mid(morsecode, i, 1))
Next
EndProcedure
; this feeds the Tokens() List, if the UCase of a char is in the Token() Map
Procedure tokenize(text.s)
text = UCase(text)
ClearList(Tokens())
Define textlength.i = Len(text)
If textlength = 1
If Token(text) <> ""
AddElement(Tokens())
Tokens() = text
EndIf
EndIf
If textlength > 1
Define currentchar.s
Define nextchar.s
Define i.i
For i = 1 To textlength - 1
currentchar = Mid(text, i, 1)
nextchar = Mid(text, i + 1, 1)
If currentchar = "C" And nextchar = "H"
AddElement(Tokens())
Tokens() = "CH"
i = i + 1
Else
AddElement(Tokens())
Tokens() = currentchar
EndIf
Next
If i = textlength
AddElement(Tokens())
Tokens() = Mid(text, i, 1)
EndIf
EndIf
EndProcedure
; this returns the Tokens() List as a combined string
; for debugging purposes or to see what the process(text.s) will work on
Procedure.s tokens2text()
Define tokencount = ListSize(Tokens())
Define text.s
If tokencount > 0
Define i.i
For i = 0 To tokencount - 1
SelectElement(Tokens(), i)
text = text + Tokens()
Next
EndIf
ProcedureReturn text
EndProcedure
; print a help for the repl
Procedure help()
PrintN("")
PrintN("&help = this text")
PrintN("&quit = quit program")
;PrintN("&faster, &slower = change speed")
;PrintN("&louder, &lower = change amp")
PrintN("")
PrintN("-- shorcuts --")
PrintN("&start = starting signal")
PrintN("&inv = invitation to transmit")
PrintN("&ok = understood")
PrintN("&wait = wait")
PrintN("&pause = pause")
PrintN("&error = error")
PrintN("&np = new page")
PrintN("&eow = end of work")
PrintN("")
EndProcedure
; repl processor - this iterates over the given text.
; first it creates the tokens
; if the tokens2text() returns a commando it will execute that
; if not:
; it prints the token and playes the morsecode of it.
Procedure process(text.s)
Repeat
tokenize(text)
; special repl syntax
Select tokens2text()
; end the program
Case "&QUIT"
CloseConsole()
End
; print a help
Case "&HELP"
help()
Break
; from here: shorthands
Case "&START"
Print("STARTING SIGNAL")
playcode(Token("STARTING SIGNAL"))
PrintN("")
Break
Case "&INV"
Print("INVITATION TO TRANSMIT")
playcode(Token("INVITATION TO TRANSMIT"))
PrintN("")
Break
Case "&OK"
Print("UNDERSTOOD")
playcode(Token("UNDERSTOOD"))
PrintN("")
Break
Case "&WAIT"
Print("WAIT")
playcode(Token("WAIT"))
PrintN("")
Break
Case "&PAUSE"
Print("PAUSE")
playcode(Token("PAUSE"))
PrintN("")
Break
Case "&ERROR"
Print("ERROR")
playcode(Token("ERROR"))
PrintN("")
Break
Case "&NP"
PrintN("NEW PAGE")
playcode(Token("NEW PAGE SIGNAL"))
PrintN("")
Break
Case "&EOW"
PrintN("END OF WORK")
playcode(Token("END OF WORK"))
PrintN("")
Break
EndSelect
; if no command do your job
; this needs to be improoved.... spaghetti and silly checks
Define tokencount.i = ListSize(Tokens())
Select tokencount
Case 0
Break
Case 1
FirstElement(Tokens())
Print(Tokens())
playcode(Token(Tokens()))
PrintN("")
Break
Default
PrintN(tokens2text())
Define i.i
For i = 0 To tokencount - 1
SelectElement(Tokens(), i)
Print(Tokens())
playcode(Token(Tokens()))
Delay(#SPEEDMS)
Next
PrintN("")
Break
EndSelect
ForEver
EndProcedure
; our main loop
Procedure repl()
Define input.s
OpenConsole()
PrintN("Welcome to Minimorse")
PrintN(".-.-.-.-.-.-.-.-.-.-")
help()
Repeat
Print("input: ")
input = Input()
process(input)
ForEver
EndProcedure
repl()