C decoder for files encoded in Morse code

This is a discussion on C decoder for files encoded in Morse code within the C Programming forums, part of the General Programming Boards category; Ive used a simple variable length Huffman encoding. As the dot is the most common symbol in morse, we encode ...

  1. #1
    Registered User
    Join Date
    Oct 2004
    Posts
    6

    C decoder for files encoded in Morse code

    Ive used a simple variable length Huffman encoding. As the dot is the most common symbol in morse, we encode as:

    Symbol Encoding
    dot (.) 0
    dash (-) 10
    space ( ) 11

    Thus the letters of hi there are encoded in Morse as:
    .... .. - .... . .-. .
    which then would be encoded in bits as:
    0000110011111110110000110110100110.
    Broken up into bytes, MSB first, and padded with space symbols at the end, this gives
    00001100 11111110 11000011 01101001 10111111
    which in hex is 0x0CFEC369BF

    For simplicity, the encoder program encodes any non-alphabetic character in the input file as
    if it were a space character (ie 111111 in binary).

    Attached is the C source code for a Morse Code encoder using this encoding.
    I can use some of the source code from the encoder in such as opening and writing to a file.

    I want to change the encoding functions to read bytes from that encoded message and look at the bits. And if you get a 0 then its a ".", if you get a 10 its a "-"etc. Then you compare the string you have against the table; so if you have .- then it will be substituted by an A, -... = B etc. Can sompne please help me with this?


    Many Thanks,

    A
    Attached Files Attached Files

  2. #2
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    unless you just want to do it for the sake of learning how to, i suggest not packing 8 'characters' into a byte...it is much quicker to compare bytes rather than comparing bits. of course, on the other hand, you will save a lot of memory doing that.

    look up masking and bitwise operators
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    here...i JUST learned how to do this after reading this post because i was a bit intrigued myself.....this may not be correct but it will give you something to think about.

    i would like to ask more advanced programmers what they think about this code while i'm at it.

    (by the way, cout << a << endl; is the c++ version of
    printf("%d\n",a)

    Code:
    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
      struct lbit
      {
          unsigned a:1;         //create variable the size of one bit
      };
      int mask = 1;              //...0000 0001
      lbit x;                            //declaration of lbit
      int c = 'A';                    //in your case, read sizeof(int) from  file
    
      //loop sizeof(int) times bits (per byte) number of times
      for(int i = 0; i < sizeof(int) * 8; i++)
      {
         x.a = mask & c;                 //0001 & 0001 returns 1
                                                  //0001 & 0000 returns 0
                                                  //since x.a is only 1 bit this will
                                                  //truncate the leading bits
                                                  //preventing a non-zero value
                                                  //caused by higher ordered bits
         cout <<  x.a << endl;       //print out 1 or 0
         c = c >> 1;                       //shift every bit in 'c' one bit to the
                                                 //right. 0010 >> 1 becomes 0001
                                                 
      }    
                              
                                                                              
      system("PAUSE");	
      return 0;
    }
    Last edited by misplaced; 10-21-2004 at 09:16 AM. Reason: commented code
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  4. #4
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    i re-read what you wanted to do...i think this is more what you want...play with it, because like i said, i JUST now starting playing with bits

    (pretend ints are one byte)

    start with
    int dotmask = 0;
    int dashmask = 2;
    int spacemask = 3;

    unsigned int a = 0; //0000 0000
    a += dashmask //0000 0010
    a = a << 2; //0000 1000
    a += spacemask //0000 1011
    a = a << 2; //0010 1100
    a += dashmask //0010 1110

    if you put this in a loop you will need to stop the loop when the int is "full" and keep track of how many 11's you wrote to the last int when you're writing a space
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  5. #5
    Registered User
    Join Date
    Oct 2004
    Posts
    6
    I've managed to come up with the following code so far:

    char *decode_file(char *input, int inputsize, int *outputsize)
    {
    struct encoding encoding_table[27];
    char *outputbuf;
    int inpos; /*where we are in the input buffer*/
    int outpos; /*where we are in the output buffer*/
    char j;
    char k;
    char *a;
    int stepper;
    int i;
    char coded;
    char temp;
    char *decode;
    decode = malloc(10000);
    a = malloc(50);

    build_encoding_table(encoding_table);

    printf ("Start");

    for(inpos = 0; inpos<inputsize; inpos++)
    {
    coded = input[inpos];
    for (stepper = 0; stepper < 8; stepper++)
    {
    if (coded & 128 != 128)
    {
    strcat(a,".");
    printf(".");

    }
    else
    {
    if (stepper != 7)
    {
    temp = coded;
    coded = coded <<1;
    if (coded & 128 !=128)
    {
    strcat(a,"-");
    printf("-");
    }
    else
    {
    strcat (a," ");
    if(a != " " || a != " ")
    {
    for (i=0; i<27; i++)
    {
    if (encoding_table[i].dotdash==a)
    {
    strcat(decode,encoding_table[i].character);
    outpos++;
    }
    }
    a = malloc(50);

    }
    }
    coded = temp;

    }
    else
    {
    if (inpos!=(inputsize-1))
    {
    inpos++;
    temp = coded;
    coded = input[inpos];
    if (coded & 128 != 128)
    {
    strcat(a, "-");
    printf("- last");
    }
    else
    {
    strcat(a," ");
    if (a!= " " || a!= " ")
    {
    for (i=0; i<27; i++)
    {
    if (encoding_table[i].dotdash==a)
    {
    strcat(decode, encoding_table[i].character);
    outpos++;
    }
    }
    a=malloc(50);

    }
    }
    inpos--;
    coded = temp;
    }
    }
    }
    coded = coded<<1;
    }
    }
    *outputsize=outpos++;
    return decode;
    }

    I'm lost in how to decode the byte? To encode I used:

    void encode_byte(char byte, struct encoding* table,
    unsigned short *encoded_byte, int *bitlen)
    {
    int i;
    if (byte >= 'a' && byte <= 'z') {
    byte = (byte - 'a') + 'A';
    } else if (byte >= 'A' && byte <= 'Z') {
    /* do nothing */
    } else {
    byte = ' ';
    }

    /* now encode the byte */
    for (i=0; i<27; i++) {
    if (table[i].character == byte) {
    *encoded_byte = table[i].bits;
    *bitlen = table[i].length;
    return;
    }
    }
    /* can't get here */
    abort();
    }

    But how do I decode a byte?

  6. #6
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    read this before posting anymore code
    << !! Posting Code? Read this First !! >>

    can you make it to where '.' = 00 rather than 0...if so the algorithm will be much more simplified....i'm not even sure you'll be able to get consistent results the way it's encoded..
    you're trying to store 3 unique values, however 0 or 1 only stores 2 values. i don't think there's any (remotely simple) way to tell programmatically whether a zero is by itself or attached to a preceeding 1. therefore you need to create a storage unit that is consistent and will hold 3 unique values. in this case, 2 bits per character...

    if you choose to follow this path, you can also delimit entire words as well...
    00 = '.'
    01 = ' ' word space
    10 = '-'
    11 = ' ' letter space
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 14
    Last Post: 11-23-2005, 08:53 AM
  2. Replies: 1
    Last Post: 10-31-2005, 11:36 AM
  3. how do I morse code converting program
    By panfilero in forum C Programming
    Replies: 17
    Last Post: 10-29-2005, 10:16 PM
  4. Replies: 4
    Last Post: 01-16-2002, 12:04 AM
  5. how convert english to morse code
    By uler in forum C++ Programming
    Replies: 2
    Last Post: 09-12-2001, 08:56 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21