Morse Encoder/Decoder Library. Transforms char array to binary array and vice-versa.

A Morse Encoding/Decoding Library \n Transforms char arrays into bool arrays and vice-versa

Morse code taken from http://en.wikipedia.org/wiki/Morse_code Added some more characters :
- : DOT DOT DASH DASH
_ : DASH DASH DASH DOT
. : DASH DASH DASH DASH
/ : DOT DASH DOT DASH
@ : DOT DOT DOT DASH DOT
? : DOT DOT DASH DOT DOT

Here is an quick hello-world that show how to use this library

#include "mbed.h
#include "Morse.h"
    
Serial pc(USBTX, USBRX);
    
int main() {
    int i;
    Morse_data* data;
    char message[] = "Hello World";
    
    data = morse_create(morse_getBoolSize(message));
    morse_encode(message, data);
    for (i=0; i<data->length; i++) pc.printf("%d", data->data[i]);
    
    morse_decode(data, message);
    pc.printf("\nMessage was : %s\n", message);
    
    while(1);
}

MorseEncoder.cpp

Committer:
rominos2
Date:
2014-09-18
Revision:
1:84ef66bf435d
Parent:
0:4648894e0d80

File content as of revision 1:84ef66bf435d:

/* 
    Copyright (c) 2014 Romain Berrada
    
    Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
    and associated documentation files (the "Software"), to deal in the Software without restriction, 
    including without limitation the rights to use, copy, modify, merge, publish, distribute, 
    sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or 
    substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
    BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
    DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Morse.h"

// Definitions of encoder/decoder data and Morse letter definitions
#define DOT  false
#define DASH true

#define MORSE_MN {DOT,  DOT,  DASH, DASH, 0   }
#define MORSE_DO {DASH, DASH, DASH, DASH, 0   }
#define MORSE_SL {DOT,  DASH, DOT,  DASH, 0   }
#define MORSE_0 {DASH, DASH, DASH, DASH, DASH}
#define MORSE_1 {DOT,  DASH, DASH, DASH, DASH}
#define MORSE_2 {DOT,  DOT,  DASH, DASH, DASH}
#define MORSE_3 {DOT,  DOT,  DOT,  DASH, DASH}
#define MORSE_4 {DOT,  DOT,  DOT,  DOT,  DASH}
#define MORSE_5 {DOT,  DOT,  DOT,  DOT,  DOT }
#define MORSE_6 {DASH, DOT,  DOT,  DOT,  DOT }
#define MORSE_7 {DASH, DASH, DOT,  DOT,  DOT }
#define MORSE_8 {DASH, DASH, DASH, DOT,  DOT }
#define MORSE_9 {DASH, DASH, DASH, DASH, DOT }
#define MORSE_IN {DOT,  DOT,  DASH, DOT,  DOT }
#define MORSE_AR {DOT,  DOT,  DOT,  DASH, DOT }
#define MORSE_A {DOT,  DASH, 0,    0,    0   }
#define MORSE_B {DASH, DOT,  DOT,  DOT,  0   }
#define MORSE_C {DASH, DOT,  DASH, DOT,  0   }
#define MORSE_D {DASH, DOT,  DOT,  0,    0   }
#define MORSE_E {DOT,  0,    0,    0,    0   }
#define MORSE_F {DOT,  DOT,  DASH, DOT,  0   }
#define MORSE_G {DASH, DASH, DOT,  0,    0   }
#define MORSE_H {DOT,  DOT,  DOT,  DOT,  0   }
#define MORSE_I {DOT,  DOT,  0,    0,    0   }
#define MORSE_J {DOT,  DASH, DASH, DASH, 0   }
#define MORSE_K {DASH, DOT, DASH,  0,    0   }
#define MORSE_L {DOT,  DASH, DOT,  DOT,  0   }
#define MORSE_M {DASH, DASH, 0,    0,    0   }
#define MORSE_N {DASH, DOT,  0,    0,    0   }
#define MORSE_O {DASH, DASH, DASH, 0,    0   }
#define MORSE_P {DOT,  DASH, DASH, DOT,  0   }
#define MORSE_Q {DASH, DASH, DOT,  DASH, 0   }
#define MORSE_R {DOT,  DASH, DOT,  0,    0   }
#define MORSE_S {DOT,  DOT,  DOT,  0,    0   }
#define MORSE_T {DASH, 0,    0,    0,    0   }
#define MORSE_U {DOT,  DOT,  DASH, 0,    0   }
#define MORSE_V {DOT,  DOT,  DOT,  DASH, 0   }
#define MORSE_W {DOT,  DASH, DASH, 0   , 0   }
#define MORSE_X {DASH, DOT,  DOT,  DASH, 0   }
#define MORSE_Y {DASH, DOT,  DASH, DASH, 0   }
#define MORSE_Z {DASH, DASH, DOT,  DOT,  0   }
#define MORSE_UN {DASH, DASH, DASH, DOT,  0   }

#define MORSE_MN_SIZE 11
#define MORSE_DO_SIZE 15
#define MORSE_SL_SIZE 11
#define MORSE_0_SIZE 19
#define MORSE_1_SIZE 17
#define MORSE_2_SIZE 15
#define MORSE_3_SIZE 13
#define MORSE_4_SIZE 11
#define MORSE_5_SIZE 9
#define MORSE_6_SIZE 11
#define MORSE_7_SIZE 13
#define MORSE_8_SIZE 15
#define MORSE_9_SIZE 17
#define MORSE_IN_SIZE 11
#define MORSE_AR_SIZE 11
#define MORSE_A_SIZE 5
#define MORSE_B_SIZE 9
#define MORSE_C_SIZE 11
#define MORSE_D_SIZE 7
#define MORSE_E_SIZE 1
#define MORSE_F_SIZE 9
#define MORSE_G_SIZE 9
#define MORSE_H_SIZE 7
#define MORSE_I_SIZE 3
#define MORSE_J_SIZE 13
#define MORSE_K_SIZE 9
#define MORSE_L_SIZE 9
#define MORSE_M_SIZE 7
#define MORSE_N_SIZE 5
#define MORSE_O_SIZE 11
#define MORSE_P_SIZE 11
#define MORSE_Q_SIZE 13
#define MORSE_R_SIZE 7
#define MORSE_S_SIZE 5
#define MORSE_T_SIZE 3
#define MORSE_U_SIZE 7
#define MORSE_V_SIZE 9
#define MORSE_W_SIZE 9
#define MORSE_X_SIZE 11
#define MORSE_Y_SIZE 13
#define MORSE_Z_SIZE 11
#define MORSE_UN_SIZE 13

// Array containing the morse letter definitions and the size of each letter (size is in bits) 
// Example: A = DOT-DASH.
// DOT has size 1 and DASH 3. Plus the blank between the DOT and the DASH
// So A has size 1+3+1 = 5
static const unsigned int _morse_values_size[42] = {MORSE_MN_SIZE, MORSE_DO_SIZE, MORSE_SL_SIZE, MORSE_0_SIZE, MORSE_1_SIZE, MORSE_2_SIZE,
                                                    MORSE_3_SIZE, MORSE_4_SIZE, MORSE_5_SIZE, MORSE_6_SIZE, MORSE_7_SIZE, MORSE_8_SIZE,
                                                    MORSE_9_SIZE, MORSE_IN_SIZE, MORSE_AR_SIZE, MORSE_A_SIZE, MORSE_B_SIZE, MORSE_C_SIZE,
                                                    MORSE_D_SIZE, MORSE_E_SIZE, MORSE_F_SIZE, MORSE_G_SIZE, MORSE_H_SIZE, MORSE_I_SIZE,
                                                    MORSE_J_SIZE, MORSE_K_SIZE, MORSE_L_SIZE, MORSE_M_SIZE, MORSE_N_SIZE, MORSE_O_SIZE,
                                                    MORSE_P_SIZE, MORSE_Q_SIZE, MORSE_R_SIZE, MORSE_S_SIZE, MORSE_T_SIZE, MORSE_U_SIZE,
                                                    MORSE_V_SIZE, MORSE_W_SIZE, MORSE_X_SIZE, MORSE_Y_SIZE, MORSE_Z_SIZE, MORSE_UN_SIZE};

static const bool _morse_values[42][5] = {MORSE_MN, MORSE_DO, MORSE_SL, MORSE_0, MORSE_1, MORSE_2,
                                          MORSE_3, MORSE_4, MORSE_5, MORSE_6, MORSE_7, MORSE_8,
                                          MORSE_9, MORSE_IN, MORSE_AR, MORSE_A, MORSE_B, MORSE_C,
                                          MORSE_D, MORSE_E, MORSE_F, MORSE_G, MORSE_H, MORSE_I,
                                          MORSE_J, MORSE_K, MORSE_L, MORSE_M, MORSE_N, MORSE_O,
                                          MORSE_P, MORSE_Q, MORSE_R, MORSE_S, MORSE_T, MORSE_U,
                                          MORSE_V, MORSE_W, MORSE_X, MORSE_Y, MORSE_Z, MORSE_UN};

// Returns the index of the letter in the above arrays. returns -1 if not found
static int _morse_find(char c) {
    int i=-1;
    if (c>='-' && c<='9') i=c-'-';
    else if (c>='?' && c<='Z') i=c-'?'+13;
    else if (c>='a' && c<='z') i=c-'a'+15;
    else if (c=='_') i=41;
    return i;                                             
}

// Add a single char (index array) to the result array at the specified position
static unsigned int _morse_addChar(unsigned int index_value, bool* result, unsigned int place) {
    unsigned char i,j;
    i=0;
    for (j=0; j<_morse_values_size[index_value]; j++) {
        if (_morse_values[index_value][i]==DOT) { // if DOT
            result[place+j] = true; 
        } else { // else DASH
            result[place+j] = true;
            result[place+j+1]=true;
            result[place+j+2]=true;
            j+=2;
        }
        j++; // add a blank
        i++; // next element
    }
    
    return j-1;
}

unsigned int morse_getBoolSize(char* word) {
    unsigned int char_i;
    int morse_i;
    unsigned int size = 0;
    
    for (char_i=0; word[char_i]!='\0'; char_i++) {
        if (word[char_i]!=' ') { // if not space
            morse_i = _morse_find(word[char_i]);
            if (morse_i==-1) continue; // if not found
            
            size += _morse_values_size[morse_i];
            size += 3; // plus the 3 blanks between chars
        }
        else { // else space
            if (char_i==0 || word[char_i-1]==' ') size+=7;
            else size+=4; // if not first letter, already 3 from the last char
        }
    }
    if (word[char_i-1]!=' ') size -= 3; // remove last space between elements (but not if space)
    
    return size;
}
                             
void morse_encode(char* word, Morse_data* data) {
    unsigned int char_i;
    int morse_i;
    unsigned int res_counter;
    
    res_counter = 0;
    for (char_i=0; word[char_i]!='\0'; char_i++) {
        if (word[char_i]!=' ') {
            morse_i = _morse_find(word[char_i]);
            if (morse_i==-1) continue; // if not found
            
            res_counter += _morse_addChar(morse_i, data->data, res_counter); // if not space
            res_counter += 3; // add space between elements
        }
        else { // else space
            if (char_i==0 || word[char_i-1]==' ') res_counter+=7; // if not char last time
            else res_counter += 4;
        }  
    }
    if (word[char_i-1]!=' ') res_counter -= 3; // remove last space between elements (but not if space)
    data->length = res_counter;
}

Morse_data* morse_create(unsigned int length) {
    Morse_data* data = new Morse_data;
    data->length = length;
    data->data = new bool[length]();
    return data;
}
void morse_destroy(Morse_data* data) {
    delete[] data->data;
    delete data;
}