Tree based Morse Code decoder

Share your advanced PureBasic knowledge/code with the community.
RichardL
Enthusiast
Enthusiast
Posts: 532
Joined: Sat Sep 11, 2004 11:54 am
Location: UK

Tree based Morse Code decoder

Post by RichardL »

Hi,
If you have an interest in decoding Morse code here are some Procedures() snipped from some code I wrote.
I've also added a simple exerciser to show how it works. Compile it in Debug mode.

The tree based decoder has some advantages:
1 - There is no need to carry out a linear search when an end-of-character space is detected.
2 - It lends itself to decoding multiple input streams.

In a real-time decoder the characters would not all come in at the same time :D

In a multi channel application the variable *P would be one of an array from Dim *P(NumOfChans) and the channel number at any time probably derived from an FFT bin number, or group thereof.

73
RichardL (G8CDD)

Code: Select all

; This snip illustrates a method of decoding incoming morse code as symbols 
; (Dits and Dahs) are received.

; (C)Richard Leman 2013
; Free to use at your own risk.

;{ Useful docs
; http://www.giangrandi.ch/electronics/radio/morse/morse.html
; http://www.learnmorsecode.com/
;}

Procedure Morse_BuildTree()     ; Make a tree structured morse character table 
; Each node has the address' of the nodes at the next level down and the character
; if this happens to be the last symbol.

; Returns the address of the entry node for use by decoders.
  
  Protected *Table,CharCount,m,n,*P, AddMorse$,AddChar$
  
  ;{- Morse code table
  DataSection
    CodeList:
    Data.s "a", ".-"
    Data.s "b", "-..."
    Data.s "c", "-.-."
    Data.s "d", "-.."
    Data.s "e", "."
    Data.s "f", "..-."
    Data.s "g", "--."
    Data.s "h", "...."
    Data.s "i", ".."
    Data.s "j", ".---"
    
    Data.s "k", "-.-"
    Data.s "l", ".-.."
    Data.s "m", "--"
    Data.s "n", "-."
    Data.s "o", "---"
    Data.s "p", ".--."
    Data.s "q", "--.-"
    Data.s "r", ".-."
    Data.s "s", "..."
    Data.s "t", "-"
    
    Data.s "u", "..-"
    Data.s "v", "...-"
    Data.s "w", ".--"
    Data.s "x", "-..-"
    Data.s "y", "-.--"
    Data.s "z", "--.."
    Data.s "0", "-----"
    Data.s "1", ".----"
    Data.s "2", "..---"
    Data.s "3", "...--"
    
    Data.s "4", "....-"
    Data.s "5", "....."
    Data.s "6", "-...."
    Data.s "7", "--..."
    Data.s "8", "---.."
    Data.s "9", "----."
    Data.s ".", ".-.-.-"
    Data.s ",", "--..--"
    Data.s "?", "..--.."
    Data.s "'", ".----."
    
    Data.s "!", "-.-.--"
    Data.s "/", "-..-."
    Data.s "(", "-.--."
    Data.s ")", "-.--.-"
    Data.s "&", ".-..."
    Data.s ":", "---..."
    Data.s ";", "-.-.-."
    Data.s "=", "-...-"
    Data.s "+", ".-.-."
    Data.s "-", "-....-"
    
    Data.s "_", "..--.-"
    Data.s #DQUOTE$,".-..-."
    Data.s "$", "...-..-"
    Data.s "@", ".--.-."
    
  EndDataSection
  
  Debug "Number of characters = 54"
  CharCount = 54
  ;}
  
  Structure MORSE_NODE
    DitBranch.i
    DahBranch.i
    NormLen.i     
    Char.s
  EndStructure
  Debug "Size of MORSE_NODE = " + Str(SizeOf(MORSE_NODE))
  
  ;- Memory for tree table
  *Table = AllocateMemory((CharCount+12) * SizeOf(MORSE_NODE))
  
  ;- Create start node and first pair of sub-nodes
  *MorseDat.MORSE_NODE = *Table
  *MorseDat\DitBranch  = *Table + SizeOf(MORSE_NODE)
  *MorseDat\DahBranch  = *Table + (2*SizeOf(MORSE_NODE))
  *Empty               = *Table + (3*SizeOf(MORSE_NODE)); Pointer to space for remaining nodes
  
  ;- Build tree
  Restore CodeList
  For m = 1 To CharCount
    Read.s AddChar$ :  Read.s AddMorse$
    
    Debug ""
    Debug Str(m)+"  " + AddChar$+"  "+AddMorse$+"   ("+Str(Len(AddMorse$))+ " Symbols)"
    
    *P = *Table                           ; Entry point to table
    For n = 1 To Len(AddMorse$)
      *MorseDat.MORSE_NODE = *P
      With *MorseDat
        Select Mid(AddMorse$,n,1) 
            
          Case "-"                        ; Got a DAH...
            If \DahBranch = 0             ; If no DAH branch...
              \DahBranch = *Empty         ; use an Empty node...
              *Empty + SizeOf(MORSE_NODE) ; make a new empty node for later
            EndIf
            *P = \DahBranch 
            Debug "DAH  "+Str(*P-*Table)
            
          Case "."                        ; Got a DIT...
            If \DitBranch = 0
              \DitBranch = *Empty
              *Empty + SizeOf(MORSE_NODE)
            EndIf
            *P = \DitBranch 
            Debug "DIT "+Str(*P-*Table)
            
        EndSelect
      EndWith
    Next
    
    *MorseDat.MORSE_NODE = *P
    *MorseDat\Char = AddChar$
    
  Next
  ProcedureReturn *Table
  
EndProcedure
Procedure Morse_GotDit(*K)      ; A DIT has been received, move down the tree from current tree position
  *MorseDat.MORSE_NODE = *K
  *K = *MorseDat\DitBranch
  ProcedureReturn *K
EndProcedure
Procedure Morse_GotDah(*K)      ; A DAH has been received, move down the tree from current tree position
  *MorseDat.MORSE_NODE = *K
  *K = *MorseDat\DahBranch
  ProcedureReturn *K
EndProcedure
Procedure.s Morse_GetChar(*K)   ; An end of char space was detected, get the character at the current tree position
  *MorseDat.MORSE_NODE = *K
  ProcedureReturn *MorseDat\Char
EndProcedure

; Demo
*MorseTable = Morse_BuildTree() ; Build table
*P = *MorseTable                ; Init pointer
Repeat
  k$ = InputRequester("Morse entry","Type a string of Dits and Dahs ('.' and '-')","")
  If k$ = "" : Break : EndIf
   
  For n = 1 To Len(k$) ; For each symbol...
    Select Mid(k$,n,1)
      Case "." : *P=Morse_GotDit(*P) ; It is a '.' so move down the table.
      Case "-" : *P=Morse_GotDah(*P) ; It is a '-' so move down teh table.
      Default  : *P = 0 : Break      ; Typo in input.
    EndSelect
  Next
  
  If *P
    Debug Morse_GetChar(*P)
  EndIf 
  
  *P = *MorseTable ; Re-init pointer ready for next symbol/char
  
ForEver
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Tree based Morse Code decoder

Post by Fangbeast »

Thanks RichardL, consider it snagged:):)

Fangbeast (VK3HAF)
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
RichardL
Enthusiast
Enthusiast
Posts: 532
Joined: Sat Sep 11, 2004 11:54 am
Location: UK

Re: Tree based Morse Code decoder

Post by RichardL »

Hi FangBeast,
Are you on any of the DX bands? VK was open from UK yesterday in the afternoon.
Richard
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Tree based Morse Code decoder

Post by Fangbeast »

RichardL wrote:Hi FangBeast,
Are you on any of the DX bands? VK was open from UK yesterday in the afternoon.
Richard
Hello Richard, my current level of license gives me access to 80m, 40m, 20m, 15m, 10m, 6m, 2m metres and 70cm, 23cm, 13cm and 9cm

Haven't played much on HF due to the location I am in but must admit, it would be good to experiment. Have an 80 metre dipole up above the house I can try out although must admit that an inverted v or a magloop would do better.

Still, let me know if we can experiment one day. Fingers crossed.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Tree based Morse Code decoder

Post by IdeasVacuum »

....I envisaged somebody in a tree receiving Morse signals :shock:
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Tree based Morse Code decoder

Post by Fangbeast »

IdeasVacuum wrote:....I envisaged somebody in a tree receiving Morse signals :shock:

Oi!!! No looking up our monkey bums up the tree!! It's personal when we are fiddling with our bananas!!!
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Tree based Morse Code decoder

Post by IdeasVacuum »

I understand your concern, bananas are delicate things....
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Tree based Morse Code decoder

Post by Fangbeast »

IdeasVacuum wrote:I understand your concern, bananas are delicate things....
After considering that this is a family friendly forum (and snorting tea through both eyeducts), I decided to shaddap my face and wander away:):):)
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Post Reply