123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /****************************************************************************
- * Copyright: (C) 2005 - 2017 by Dipl.-Ing. Stefan Heesch
- * callsign: HB9TWS
- * email: radio@heesch.net
- ****************************************************************************/
- #include "morse.h"
- static int DurationPoint;
- static char RawBuffer[PATTERN_SIZE + 1];
- static char FailedBuffer[PATTERN_SIZE + 1];
- const morse(MorseCode[]) PROGMEM =
- {
- { 'A',".-" }, { 'B',"-..." }, { 'C',"-.-." }, { 'D',"-.." },
- { 'E',"." }, { 'F',"..-." }, { 'G',"--." }, { 'H',"...." },
- { 'I',".." }, { 'J',".---" }, { 'K',"-.-" }, { 'L',".-.." },
- { 'M',"--" }, { 'N',"-." }, { 'O',"---" }, { 'P',".--." },
- { 'Q',"--.-" }, { 'R',".-." }, { 'S',"..." }, { 'T',"-" },
- { 'U',"..-" }, { 'V',"...-" }, { 'W',".--" }, { 'X',"-..-" },
- { 'Y',"-.--" }, { 'Z',"--.." },
- { '1',".----" }, { '2',"..---" }, { '3',"...--" }, { '4',"....-" },
- { '5',"....." }, { '6',"-...." }, { '7',"--..." }, { '8',"---.." },
- { '9',"----." }, { '0',"-----" },
- { ',',"--..--" }, { '.',".-.-.-" }, { '?',"..--.." }, { '/',"-..-." },
- { '=',"-...-" }, { '-',"-....-" }, { ':',"---..." }, { ';',"-.-.-." },
- { '(',"-.--." }, { ')',"-.--.-" }, { '\'',".----." },
- { '\"',".-..-." }, { '@',".--.-." }, { '#',"........" },
- { 'k',"-.-.-" }, // KA
- { 'a',".-.-." }, // AR
- { 's',"...-.-" }, // SK
- { '\0',"\0" }
- };
- /* ----------------------------------------------------------------------
- * Function Name: pgm_read_morse( morse* in, morse* out )
- * Description: Read cw pattern from program memore
- * Parameters: morse* in, morse* out
- * Return: void
- * ---------------------------------------------------------------------- */
- void pgm_read_morse(morse* in, morse* out)
- {
- out->letter = pgm_read_byte((PGM_P)in);
- for (int i = 0; i<PATTERN_SIZE; i++)
- out->pattern[i] = pgm_read_byte((PGM_P)in + i + 1);
- }
- /* ----------------------------------------------------------------------
- * Function Name: decode_letter( void )
- * Description: Decode cw pattern in variable RawBuffer and return a char
- * Parameters: void
- * Return: char; =0
- * ---------------------------------------------------------------------- */
- char decode_letter(void)
- {
- if (RawBuffer[0] == 0) return 0;
- char result = DECODING_ERROR;
- morse code;
- int i = 0;
- do
- {
- pgm_read_morse(const_cast<morse*>(&MorseCode[i]), &code);
- if (strcmp(RawBuffer, code.pattern) == 0)
- {
- result = code.letter;
- break;
- }
- i++;
- } while (code.letter);
- if (result == DECODING_ERROR)
- memcpy(FailedBuffer, RawBuffer, PATTERN_SIZE);
- return result;
- }
- /****************************************************************************
- *
- * Function Name: decode_tone( int duration )
- *
- * Description: Decode cw tone ( key pressed )
- *
- * Parameters: int duration
- *
- * Return: void
- *
- ***************************************************************************/
- void decode_tone(int duration)
- {
- char s = '.';
- if (duration > 2 * DurationPoint)
- {
- s = '-';
- }
- int i;
- for (i = 0; i < PATTERN_SIZE; ++i)
- {
- if (RawBuffer[i] == 0)
- {
- RawBuffer[i] = s;
- break;
- }
- }
- } /* decode_tone */
- /* ----------------------------------------------------------------------
- * Function Name: decode_pause( int duration )
- * Description: Decode cw pause ( key not pressed )
- * Parameters: int duration
- * Return: char
- * ---------------------------------------------------------------------- */
- char decode_pause(int duration)
- {
- char result = 0;
- if (duration > 2 * DurationPoint)
- {
- /* letter is complete, decode it and initialise buffer */
- result = decode_letter();
- memset(RawBuffer, 0, PATTERN_SIZE);
- }
- return result;
- }
- /* ----------------------------------------------------------------------
- * Function Name: morse_decode( cw input )
- * Description: Decode cw input
- * Parameters: cw input
- * Return: char
- * ---------------------------------------------------------------------- */
- char morse_decode(cw input)
- {
- char result = 0;
- if (input.level == 0)
- result = decode_pause(input.duration);
- else
- decode_tone(input.duration);
- return result;
- }
- /****************************************************************************
- *
- * Function Name: morse_speed( void )
- *
- * Description: speed in letters per minute
- *
- * Parameters: void
- *
- * Return: int
- *
- ***************************************************************************/
- int morse_speed(void)
- {
- return 6000 / DurationPoint;
- } /* morse_speed */
- /****************************************************************************
- *
- * Function Name: morse_timeout( void )
- *
- * Description: return timeout value for decoding
- *
- * Parameters: void
- *
- * Return: int
- *
- ***************************************************************************/
- int morse_timeout(void)
- {
- return 8 * DurationPoint;
- } /* morse_timeout */
- /****************************************************************************
- *
- * Function Name: morse_init( int speed )
- *
- * Description: Initialize morse decoder
- *
- * Parameters: int speed
- *
- * Return: void
- *
- ***************************************************************************/
- void morse_init(int speed)
- {
- memset(RawBuffer, 0, PATTERN_SIZE + 1);
- memset(FailedBuffer, 0, PATTERN_SIZE + 1);
- if (speed > 0 && speed < 120)
- {
- DurationPoint = 6000 / speed;
- }
- else
- {
- DurationPoint = 6000 / 50;
- }
- } /* morse_init */
- /****************************************************************************
- *
- * Function Name: morse_check( cw input )
- *
- * Description: Check for speed and new word (spacing)
- *
- * Parameters: cw input
- *
- * Return: char
- *
- ***************************************************************************/
- char morse_check(cw input)
- {
- char result = 0;
- if (input.level == 0)
- {
- if (input.duration > 6 * DurationPoint)
- {
- /* start a new block or word
- */
- result = ' ';
- }
- }
- else
- {
- /* Adopt speed
- */
- if (input.duration > 3 * DurationPoint + 15)
- {
- DurationPoint += 5;
- }
- else if (input.duration < DurationPoint - 10)
- {
- DurationPoint -= 5;
- }
- if (DurationPoint < MIN_DURATION)
- {
- DurationPoint = MIN_DURATION;
- }
- }
- return result;
- } /* morse_check */
- /****************************************************************************
- *
- * Function Name: morse_failed( void )
- *
- * Description: Return pattern that couldn't be decoded
- *
- * Parameters: void
- *
- * Return: char*
- *
- ***************************************************************************/
- char* morse_failed(void)
- {
- return FailedBuffer;
- } /* morse_failed */
|