Back to the WFC main page

CReedSolomonErrorCorrectionCode

$Revision: 16 $

Description

This class makes it easy to add forward error correction (FEC) to data. This classes uses the Reed-Solomon method.

Data Members

None.

Methods

int Decode( const CByteArray& encoded_data, CByteArray& decoded_data )
Decodes the data and fixes any transmission errors. The return code will be the number of errors corrected on success or -1 on failure.
BOOL Encode( const CByteArray& data, CByteArray& encoded_data )
Adds the Reed-Solomon encoding to the data.

Notes

This algorithm generates a parity of 1 bit per byte. Output data is padded to blocks of 255 bytes. The input is blocked into data chunks of 222 bytes. This allows for a 1 byte block length. This given, if you need to add forward error correction to a packet of data that is 250 bytes long, the resulting encoded data packet will be 510 bytes long.

Example

#include <wfc.h>
#pragma hdrstop

void test_CReedSolomonErrorCorrectionCode( void )
{
   WFCTRACEINIT( TEXT( "test_CReedSolomonErrorCorrectionCode()" ) );

   CReedSolomonErrorCorrectionCode transmitter;

   CByteArray data;

   data.Add( 'A' );

   data.InsertAt( 0, 'A', 220 );

   CByteArray encoded_data;

   if ( transmitter.Encode( data, encoded_data ) == FALSE )
   {
      _tprintf( TEXT( "Can't encode\n" ) );
      return;
   }

   // We have encoded the data. Time to transmit it.

   // Now the parity for the data is computed. Let's muck with the data

   // Here's our sloppy communications path. It adds errors to the data

   CRandomNumberGenerator random_number;
   
   // Add some errors

   int number_of_errors_to_introduce = encoded_data.GetSize() / 16;
   int error_number = 0;

   _tprintf( TEXT( "Adding %d errors to the data\n" ), number_of_errors_to_introduce );

   int index = 0;

   BYTE random_value = 0;

   DWORD value = 0;

   while( error_number < number_of_errors_to_introduce )
   {
      value = random_number.GetInteger();
      random_value = value % 256;

      // Make sure we're introducing an error

      while( random_value == 'A' )
      {
         value = random_number.GetInteger();
         random_value = value % 256;
      }

      index = random_number.GetInteger() % encoded_data.GetSize();

      _tprintf( TEXT( "Setting data.ElementAt( %d ) to %02X\n" ), index, (int) random_value );

      encoded_data.ElementAt( index ) = random_value;

      error_number++;
   }

   // We would now transmit data to the receiver

   CReedSolomonErrorCorrectionCode receiver;

   CByteArray decoded_data;

   int number_of_errors_corrected = receiver.Decode( encoded_data, decoded_data );

   if ( number_of_errors_corrected != (-1) )
   {
      // SUCCESS!

      _tprintf( TEXT( "Decoded!\n" ) );
   }

   _tprintf( TEXT( "Number of errors corrected %d\n" ), number_of_errors_corrected );
   _tprintf( TEXT( "Number of bytes in decoded data %d\n" ), decoded_data.GetSize() );

   if ( data.GetSize() != decoded_data.GetSize() )
   {
      _tprintf( TEXT( "FAILED length test\n" ) );
      _tprintf( TEXT( "Original length was %d" ), data.GetSize() );
      _tprintf( TEXT( "Decoded length was %d\n" ), decoded_data.GetSize() );
      return;
   }

   index = 0;

   while( index < decoded_data.GetSize() )
   {
      if ( data.GetAt( index ) != decoded_data.GetAt( index ) )
      {
         WFCTRACEVAL( TEXT( "Comparison failed at byte %d\n" ), index );
      }

      index++;
   }
}

Copyright, 2000, Samuel R. Blackburn
$Workfile: CReedSolomonErrorCorrectionCode.cpp $
$Modtime: 1/17/00 9:12a $