diff --git a/modem/Makefile b/modem/Makefile deleted file mode 100644 index fbb12b6..0000000 --- a/modem/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# Makefile for qo100modem -# ======================= - -CFLAGS=-O3 -Wall -LDLIBS= -L. -lpthread -lfftw3 -lm -lzip -lfftw3_threads -lsndfile -lasound -lbass -lliquid -CC=c++ -PROGNAME=qo100modem -OBJ=qo100modem.o main_helper.o udp.o frame_packer.o scrambler.o crc16.o fec.o fft.o constellation.o arraysend.o audio.o liquid_if.o - -all: qo100modem - -qo100modem: $(OBJ) - $(CC) -g -o $@ $^ $(LDFLAGS) $(LDLIBS) - -clean: - rm -f *.o qo100modem diff --git a/modem/arraysend.c b/modem/arraysend.c deleted file mode 100644 index 1859e03..0000000 --- a/modem/arraysend.c +++ /dev/null @@ -1,230 +0,0 @@ -/* -* High Speed modem to transfer data in a 2,7kHz SSB channel -* ========================================================= -* Author: DJ0ABR -* -* (c) DJ0ABR -* www.dj0abr.de -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -*/ - -#include "qo100modem.h" - -int AddHeader(uint8_t *data, int len, char *filename); -uint8_t *zipArray(uint8_t *data, int length, int *ziplen); - -#define ZIPPED -#define TXMAXSIZE 200000 -uint8_t TXarray[TXMAXSIZE]; -int txlen; // total length of TXarray -int txpos; // current position in TXarray -uint8_t txtype = 0; // file type (from GUI) -uint8_t filestat = 0; // 0=first frame, 1=next frame, 2=last frame - -/* -* start sending a named byte array -* data ... contents of the Byte array -* length ... length of the Byte array -* type ... type of the file (see statics) -* filename ... description of the file or its name which is send with the data -*/ - - -int arraySend(uint8_t *data, int length, uint8_t type, char *filename) -{ - if((length+55) >= TXMAXSIZE) - { - printf("file TOO long. Max is %d byte\n",TXMAXSIZE); - return 0; - } - - txtype = type; - txpos = 0; - filestat = 0; - - // if it is an ASCII, HTML or binary file, zip it - if(type == 3 || type == 4 || type == 5) - { - #ifdef ZIPPED - int ziplen = 0; - printf("orig len:%d\n",length); - uint8_t *zipdata = zipArray(data,length,&ziplen); - if(zipdata==NULL) return 0; - printf("zipped len:%d\n",ziplen); - // add a file header and copy to txdata for transmission - txlen = AddHeader(zipdata,ziplen,filename); - #else - txlen = AddHeader(data,length,filename); - #endif - printf("txlen:%d\n",txlen); - } - else - { - // add a file header and copy to txdata for transmission - txlen = AddHeader(data,length,filename); - } - - // marker, we are sending - setSending(1); - return 1; -} - -int AddHeader(uint8_t *data, int len, char *filename) -{ - // make a unique ID number for this file - // we simply calc the CRC16 of the filename - uint16_t fncrc = Crc16_messagecalc(CRC16FILE, (uint8_t *)filename,strlen(filename)); - - // create the file header - // 50 bytes ... Filename (or first 50 chars of the filename) - // 2 bytes .... CRC16 od the filename, this is used as a file ID - // 3 bytes .... size of file - - int flen = strlen(filename); - if (flen > 50) flen = 50; - memcpy(TXarray,filename,flen); - - TXarray[50] = (uint8_t)((fncrc >> 8)&0xff); - TXarray[51] = (uint8_t)(fncrc&0xff); - - TXarray[52] = len >> 16; - TXarray[53] = len >> 8; - TXarray[54] = len; - - memcpy(TXarray+55,data,len); - - return len+55; -} - -// called from main() in a loop -// sends an array if specified by arraySend(..) -void doArraySend() -{ - if(getSending() == 0) return; - - if(filestat == 0) - { - // send first frame - printf("Start Array Send %d\n",getSending()); - - // preamble - int numframespreamble = 3* ((caprate/txinterpolfactor) * bitsPerSymbol / 8) /258 + 1; - for(int i=0; i= AUDIO_CAPTURE_BUFLEN) cap_wridx = 0; - CAP_UNLOCK; -} - -int cap_read_fifo(float *data) -{ - CAP_LOCK; - - if (cap_rdidx == cap_wridx) - { - // Fifo empty, no data available - CAP_UNLOCK; - return 0; - } - - *data = cap_buffer[cap_rdidx]; - if(++cap_rdidx >= AUDIO_CAPTURE_BUFLEN) cap_rdidx = 0; - CAP_UNLOCK; - - return 1; -} -*/ -void pb_write_fifo(float sample) -{ - PB_LOCK; - - // check if there is free space in fifo - if(pb_fifo_freespace(1) == 0) - { - PB_UNLOCK; - printf("************* pb fifo full\n"); - return; - } - - pb_buffer[pb_wridx] = sample; - if(++pb_wridx >= AUDIO_PLAYBACK_BUFLEN) pb_wridx = 0; - PB_UNLOCK; - //printf("write: pbw:%d pbr:%d\n",pb_wridx,pb_rdidx); -} - -int pb_fifo_freespace(int nolock) -{ -int freebuf = 0; - - if(nolock == 0) PB_LOCK; - - /*freebuf = AUDIO_PLAYBACK_BUFLEN - ((pb_wridx+AUDIO_PLAYBACK_BUFLEN+1 - pb_rdidx)%AUDIO_PLAYBACK_BUFLEN); - freebuf %= AUDIO_PLAYBACK_BUFLEN;*/ - - int elemInFifo = (pb_wridx + AUDIO_PLAYBACK_BUFLEN - pb_rdidx) % AUDIO_PLAYBACK_BUFLEN; - freebuf = AUDIO_PLAYBACK_BUFLEN - elemInFifo; - - if(nolock == 0) PB_UNLOCK; - - //printf("fifolen:%d check: pbw:%d pbr:%d freebuf:%d\n",AUDIO_PLAYBACK_BUFLEN,pb_wridx,pb_rdidx,freebuf); - - return freebuf; -} - -// read elements floats from fifo or return 0 if not enough floats are available -int pb_read_fifo(float *data, int elements) -{ - //printf("pb read fifo: %d\n",elements); - PB_LOCK; - - int e = AUDIO_PLAYBACK_BUFLEN - pb_fifo_freespace(1); - //if (pb_rdidx == pb_wridx) - if(e < elements) - { - // Fifo empty, no data available - PB_UNLOCK; - //printf("pb fifo empty, need:%d have:%d size:%d\n",elements,e,AUDIO_PLAYBACK_BUFLEN); - return 0; - } - - for(int i=0; i= AUDIO_PLAYBACK_BUFLEN) pb_rdidx = 0; - } - //printf("read %d floats\n",elements); - - PB_UNLOCK; - return 1; -} diff --git a/modem/bass.h b/modem/bass.h deleted file mode 100644 index e6f2416..0000000 --- a/modem/bass.h +++ /dev/null @@ -1,1160 +0,0 @@ -/* - BASS 2.4 C/C++ header file - Copyright (c) 1999-2019 Un4seen Developments Ltd. - - See the BASS.CHM file for more detailed documentation -*/ - -#ifndef BASS_H -#define BASS_H - -#ifdef _WIN32 -#include -typedef unsigned __int64 QWORD; -#else -#include -#define WINAPI -#define CALLBACK -typedef uint8_t BYTE; -typedef uint16_t WORD; -typedef uint32_t DWORD; -typedef uint64_t QWORD; -#ifdef __OBJC__ -#include -#else -typedef int BOOL; -#endif -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif -#define LOBYTE(a) (BYTE)(a) -#define HIBYTE(a) (BYTE)((a)>>8) -#define LOWORD(a) (WORD)(a) -#define HIWORD(a) (WORD)((a)>>16) -#define MAKEWORD(a,b) (WORD)(((a)&0xff)|((b)<<8)) -#define MAKELONG(a,b) (DWORD)(((a)&0xffff)|((b)<<16)) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define BASSVERSION 0x204 // API version -#define BASSVERSIONTEXT "2.4" - -#ifndef BASSDEF -#define BASSDEF(f) WINAPI f -#else -#define NOBASSOVERLOADS -#endif - -typedef DWORD HMUSIC; // MOD music handle -typedef DWORD HSAMPLE; // sample handle -typedef DWORD HCHANNEL; // playing sample's channel handle -typedef DWORD HSTREAM; // sample stream handle -typedef DWORD HRECORD; // recording handle -typedef DWORD HSYNC; // synchronizer handle -typedef DWORD HDSP; // DSP handle -typedef DWORD HFX; // DX8 effect handle -typedef DWORD HPLUGIN; // Plugin handle - -// Error codes returned by BASS_ErrorGetCode -#define BASS_OK 0 // all is OK -#define BASS_ERROR_MEM 1 // memory error -#define BASS_ERROR_FILEOPEN 2 // can't open the file -#define BASS_ERROR_DRIVER 3 // can't find a free/valid driver -#define BASS_ERROR_BUFLOST 4 // the sample buffer was lost -#define BASS_ERROR_HANDLE 5 // invalid handle -#define BASS_ERROR_FORMAT 6 // unsupported sample format -#define BASS_ERROR_POSITION 7 // invalid position -#define BASS_ERROR_INIT 8 // BASS_Init has not been successfully called -#define BASS_ERROR_START 9 // BASS_Start has not been successfully called -#define BASS_ERROR_SSL 10 // SSL/HTTPS support isn't available -#define BASS_ERROR_ALREADY 14 // already initialized/paused/whatever -#define BASS_ERROR_NOTAUDIO 17 // file does not contain audio -#define BASS_ERROR_NOCHAN 18 // can't get a free channel -#define BASS_ERROR_ILLTYPE 19 // an illegal type was specified -#define BASS_ERROR_ILLPARAM 20 // an illegal parameter was specified -#define BASS_ERROR_NO3D 21 // no 3D support -#define BASS_ERROR_NOEAX 22 // no EAX support -#define BASS_ERROR_DEVICE 23 // illegal device number -#define BASS_ERROR_NOPLAY 24 // not playing -#define BASS_ERROR_FREQ 25 // illegal sample rate -#define BASS_ERROR_NOTFILE 27 // the stream is not a file stream -#define BASS_ERROR_NOHW 29 // no hardware voices available -#define BASS_ERROR_EMPTY 31 // the MOD music has no sequence data -#define BASS_ERROR_NONET 32 // no internet connection could be opened -#define BASS_ERROR_CREATE 33 // couldn't create the file -#define BASS_ERROR_NOFX 34 // effects are not available -#define BASS_ERROR_NOTAVAIL 37 // requested data/action is not available -#define BASS_ERROR_DECODE 38 // the channel is/isn't a "decoding channel" -#define BASS_ERROR_DX 39 // a sufficient DirectX version is not installed -#define BASS_ERROR_TIMEOUT 40 // connection timedout -#define BASS_ERROR_FILEFORM 41 // unsupported file format -#define BASS_ERROR_SPEAKER 42 // unavailable speaker -#define BASS_ERROR_VERSION 43 // invalid BASS version (used by add-ons) -#define BASS_ERROR_CODEC 44 // codec is not available/supported -#define BASS_ERROR_ENDED 45 // the channel/file has ended -#define BASS_ERROR_BUSY 46 // the device is busy -#define BASS_ERROR_UNSTREAMABLE 47 // unstreamable file -#define BASS_ERROR_UNKNOWN -1 // some other mystery problem - -// BASS_SetConfig options -#define BASS_CONFIG_BUFFER 0 -#define BASS_CONFIG_UPDATEPERIOD 1 -#define BASS_CONFIG_GVOL_SAMPLE 4 -#define BASS_CONFIG_GVOL_STREAM 5 -#define BASS_CONFIG_GVOL_MUSIC 6 -#define BASS_CONFIG_CURVE_VOL 7 -#define BASS_CONFIG_CURVE_PAN 8 -#define BASS_CONFIG_FLOATDSP 9 -#define BASS_CONFIG_3DALGORITHM 10 -#define BASS_CONFIG_NET_TIMEOUT 11 -#define BASS_CONFIG_NET_BUFFER 12 -#define BASS_CONFIG_PAUSE_NOPLAY 13 -#define BASS_CONFIG_NET_PREBUF 15 -#define BASS_CONFIG_NET_PASSIVE 18 -#define BASS_CONFIG_REC_BUFFER 19 -#define BASS_CONFIG_NET_PLAYLIST 21 -#define BASS_CONFIG_MUSIC_VIRTUAL 22 -#define BASS_CONFIG_VERIFY 23 -#define BASS_CONFIG_UPDATETHREADS 24 -#define BASS_CONFIG_DEV_BUFFER 27 -#define BASS_CONFIG_REC_LOOPBACK 28 -#define BASS_CONFIG_VISTA_TRUEPOS 30 -#define BASS_CONFIG_IOS_SESSION 34 -#define BASS_CONFIG_IOS_MIXAUDIO 34 -#define BASS_CONFIG_DEV_DEFAULT 36 -#define BASS_CONFIG_NET_READTIMEOUT 37 -#define BASS_CONFIG_VISTA_SPEAKERS 38 -#define BASS_CONFIG_IOS_SPEAKER 39 -#define BASS_CONFIG_MF_DISABLE 40 -#define BASS_CONFIG_HANDLES 41 -#define BASS_CONFIG_UNICODE 42 -#define BASS_CONFIG_SRC 43 -#define BASS_CONFIG_SRC_SAMPLE 44 -#define BASS_CONFIG_ASYNCFILE_BUFFER 45 -#define BASS_CONFIG_OGG_PRESCAN 47 -#define BASS_CONFIG_MF_VIDEO 48 -#define BASS_CONFIG_AIRPLAY 49 -#define BASS_CONFIG_DEV_NONSTOP 50 -#define BASS_CONFIG_IOS_NOCATEGORY 51 -#define BASS_CONFIG_VERIFY_NET 52 -#define BASS_CONFIG_DEV_PERIOD 53 -#define BASS_CONFIG_FLOAT 54 -#define BASS_CONFIG_NET_SEEK 56 -#define BASS_CONFIG_AM_DISABLE 58 -#define BASS_CONFIG_NET_PLAYLIST_DEPTH 59 -#define BASS_CONFIG_NET_PREBUF_WAIT 60 -#define BASS_CONFIG_ANDROID_SESSIONID 62 -#define BASS_CONFIG_WASAPI_PERSIST 65 -#define BASS_CONFIG_REC_WASAPI 66 -#define BASS_CONFIG_ANDROID_AAUDIO 67 - -// BASS_SetConfigPtr options -#define BASS_CONFIG_NET_AGENT 16 -#define BASS_CONFIG_NET_PROXY 17 -#define BASS_CONFIG_IOS_NOTIFY 46 -#define BASS_CONFIG_LIBSSL 64 - -// BASS_CONFIG_IOS_SESSION flags -#define BASS_IOS_SESSION_MIX 1 -#define BASS_IOS_SESSION_DUCK 2 -#define BASS_IOS_SESSION_AMBIENT 4 -#define BASS_IOS_SESSION_SPEAKER 8 -#define BASS_IOS_SESSION_DISABLE 16 - -// BASS_Init flags -#define BASS_DEVICE_8BITS 1 // 8 bit -#define BASS_DEVICE_MONO 2 // mono -#define BASS_DEVICE_3D 4 // enable 3D functionality -#define BASS_DEVICE_16BITS 8 // limit output to 16 bit -#define BASS_DEVICE_LATENCY 0x100 // calculate device latency (BASS_INFO struct) -#define BASS_DEVICE_CPSPEAKERS 0x400 // detect speakers via Windows control panel -#define BASS_DEVICE_SPEAKERS 0x800 // force enabling of speaker assignment -#define BASS_DEVICE_NOSPEAKER 0x1000 // ignore speaker arrangement -#define BASS_DEVICE_DMIX 0x2000 // use ALSA "dmix" plugin -#define BASS_DEVICE_FREQ 0x4000 // set device sample rate -#define BASS_DEVICE_STEREO 0x8000 // limit output to stereo -#define BASS_DEVICE_HOG 0x10000 // hog/exclusive mode -#define BASS_DEVICE_AUDIOTRACK 0x20000 // use AudioTrack output -#define BASS_DEVICE_DSOUND 0x40000 // use DirectSound output - -// DirectSound interfaces (for use with BASS_GetDSoundObject) -#define BASS_OBJECT_DS 1 // IDirectSound -#define BASS_OBJECT_DS3DL 2 // IDirectSound3DListener - -// Device info structure -typedef struct { -#if defined(_WIN32_WCE) || (WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) - const wchar_t *name; // description - const wchar_t *driver; // driver -#else - const char *name; // description - const char *driver; // driver -#endif - DWORD flags; -} BASS_DEVICEINFO; - -// BASS_DEVICEINFO flags -#define BASS_DEVICE_ENABLED 1 -#define BASS_DEVICE_DEFAULT 2 -#define BASS_DEVICE_INIT 4 -#define BASS_DEVICE_LOOPBACK 8 - -#define BASS_DEVICE_TYPE_MASK 0xff000000 -#define BASS_DEVICE_TYPE_NETWORK 0x01000000 -#define BASS_DEVICE_TYPE_SPEAKERS 0x02000000 -#define BASS_DEVICE_TYPE_LINE 0x03000000 -#define BASS_DEVICE_TYPE_HEADPHONES 0x04000000 -#define BASS_DEVICE_TYPE_MICROPHONE 0x05000000 -#define BASS_DEVICE_TYPE_HEADSET 0x06000000 -#define BASS_DEVICE_TYPE_HANDSET 0x07000000 -#define BASS_DEVICE_TYPE_DIGITAL 0x08000000 -#define BASS_DEVICE_TYPE_SPDIF 0x09000000 -#define BASS_DEVICE_TYPE_HDMI 0x0a000000 -#define BASS_DEVICE_TYPE_DISPLAYPORT 0x40000000 - -// BASS_GetDeviceInfo flags -#define BASS_DEVICES_AIRPLAY 0x1000000 - -typedef struct { - DWORD flags; // device capabilities (DSCAPS_xxx flags) - DWORD hwsize; // size of total device hardware memory - DWORD hwfree; // size of free device hardware memory - DWORD freesam; // number of free sample slots in the hardware - DWORD free3d; // number of free 3D sample slots in the hardware - DWORD minrate; // min sample rate supported by the hardware - DWORD maxrate; // max sample rate supported by the hardware - BOOL eax; // device supports EAX? (always FALSE if BASS_DEVICE_3D was not used) - DWORD minbuf; // recommended minimum buffer length in ms (requires BASS_DEVICE_LATENCY) - DWORD dsver; // DirectSound version - DWORD latency; // delay (in ms) before start of playback (requires BASS_DEVICE_LATENCY) - DWORD initflags; // BASS_Init "flags" parameter - DWORD speakers; // number of speakers available - DWORD freq; // current output rate -} BASS_INFO; - -// BASS_INFO flags (from DSOUND.H) -#define DSCAPS_CONTINUOUSRATE 0x00000010 // supports all sample rates between min/maxrate -#define DSCAPS_EMULDRIVER 0x00000020 // device does NOT have hardware DirectSound support -#define DSCAPS_CERTIFIED 0x00000040 // device driver has been certified by Microsoft -#define DSCAPS_SECONDARYMONO 0x00000100 // mono -#define DSCAPS_SECONDARYSTEREO 0x00000200 // stereo -#define DSCAPS_SECONDARY8BIT 0x00000400 // 8 bit -#define DSCAPS_SECONDARY16BIT 0x00000800 // 16 bit - -// Recording device info structure -typedef struct { - DWORD flags; // device capabilities (DSCCAPS_xxx flags) - DWORD formats; // supported standard formats (WAVE_FORMAT_xxx flags) - DWORD inputs; // number of inputs - BOOL singlein; // TRUE = only 1 input can be set at a time - DWORD freq; // current input rate -} BASS_RECORDINFO; - -// BASS_RECORDINFO flags (from DSOUND.H) -#define DSCCAPS_EMULDRIVER DSCAPS_EMULDRIVER // device does NOT have hardware DirectSound recording support -#define DSCCAPS_CERTIFIED DSCAPS_CERTIFIED // device driver has been certified by Microsoft - -// defines for formats field of BASS_RECORDINFO (from MMSYSTEM.H) -#ifndef WAVE_FORMAT_1M08 -#define WAVE_FORMAT_1M08 0x00000001 /* 11.025 kHz, Mono, 8-bit */ -#define WAVE_FORMAT_1S08 0x00000002 /* 11.025 kHz, Stereo, 8-bit */ -#define WAVE_FORMAT_1M16 0x00000004 /* 11.025 kHz, Mono, 16-bit */ -#define WAVE_FORMAT_1S16 0x00000008 /* 11.025 kHz, Stereo, 16-bit */ -#define WAVE_FORMAT_2M08 0x00000010 /* 22.05 kHz, Mono, 8-bit */ -#define WAVE_FORMAT_2S08 0x00000020 /* 22.05 kHz, Stereo, 8-bit */ -#define WAVE_FORMAT_2M16 0x00000040 /* 22.05 kHz, Mono, 16-bit */ -#define WAVE_FORMAT_2S16 0x00000080 /* 22.05 kHz, Stereo, 16-bit */ -#define WAVE_FORMAT_4M08 0x00000100 /* 44.1 kHz, Mono, 8-bit */ -#define WAVE_FORMAT_4S08 0x00000200 /* 44.1 kHz, Stereo, 8-bit */ -#define WAVE_FORMAT_4M16 0x00000400 /* 44.1 kHz, Mono, 16-bit */ -#define WAVE_FORMAT_4S16 0x00000800 /* 44.1 kHz, Stereo, 16-bit */ -#endif - -// Sample info structure -typedef struct { - DWORD freq; // default playback rate - float volume; // default volume (0-1) - float pan; // default pan (-1=left, 0=middle, 1=right) - DWORD flags; // BASS_SAMPLE_xxx flags - DWORD length; // length (in bytes) - DWORD max; // maximum simultaneous playbacks - DWORD origres; // original resolution - DWORD chans; // number of channels - DWORD mingap; // minimum gap (ms) between creating channels - DWORD mode3d; // BASS_3DMODE_xxx mode - float mindist; // minimum distance - float maxdist; // maximum distance - DWORD iangle; // angle of inside projection cone - DWORD oangle; // angle of outside projection cone - float outvol; // delta-volume outside the projection cone - DWORD vam; // voice allocation/management flags (BASS_VAM_xxx) - DWORD priority; // priority (0=lowest, 0xffffffff=highest) -} BASS_SAMPLE; - -#define BASS_SAMPLE_8BITS 1 // 8 bit -#define BASS_SAMPLE_FLOAT 256 // 32 bit floating-point -#define BASS_SAMPLE_MONO 2 // mono -#define BASS_SAMPLE_LOOP 4 // looped -#define BASS_SAMPLE_3D 8 // 3D functionality -#define BASS_SAMPLE_SOFTWARE 16 // not using hardware mixing -#define BASS_SAMPLE_MUTEMAX 32 // mute at max distance (3D only) -#define BASS_SAMPLE_VAM 64 // DX7 voice allocation & management -#define BASS_SAMPLE_FX 128 // old implementation of DX8 effects -#define BASS_SAMPLE_OVER_VOL 0x10000 // override lowest volume -#define BASS_SAMPLE_OVER_POS 0x20000 // override longest playing -#define BASS_SAMPLE_OVER_DIST 0x30000 // override furthest from listener (3D only) - -#define BASS_STREAM_PRESCAN 0x20000 // enable pin-point seeking/length (MP3/MP2/MP1) -#define BASS_STREAM_AUTOFREE 0x40000 // automatically free the stream when it stop/ends -#define BASS_STREAM_RESTRATE 0x80000 // restrict the download rate of internet file streams -#define BASS_STREAM_BLOCK 0x100000 // download/play internet file stream in small blocks -#define BASS_STREAM_DECODE 0x200000 // don't play the stream, only decode (BASS_ChannelGetData) -#define BASS_STREAM_STATUS 0x800000 // give server status info (HTTP/ICY tags) in DOWNLOADPROC - -#define BASS_MP3_IGNOREDELAY 0x200 // ignore LAME/Xing/VBRI/iTunes delay & padding info -#define BASS_MP3_SETPOS BASS_STREAM_PRESCAN - -#define BASS_MUSIC_FLOAT BASS_SAMPLE_FLOAT -#define BASS_MUSIC_MONO BASS_SAMPLE_MONO -#define BASS_MUSIC_LOOP BASS_SAMPLE_LOOP -#define BASS_MUSIC_3D BASS_SAMPLE_3D -#define BASS_MUSIC_FX BASS_SAMPLE_FX -#define BASS_MUSIC_AUTOFREE BASS_STREAM_AUTOFREE -#define BASS_MUSIC_DECODE BASS_STREAM_DECODE -#define BASS_MUSIC_PRESCAN BASS_STREAM_PRESCAN // calculate playback length -#define BASS_MUSIC_CALCLEN BASS_MUSIC_PRESCAN -#define BASS_MUSIC_RAMP 0x200 // normal ramping -#define BASS_MUSIC_RAMPS 0x400 // sensitive ramping -#define BASS_MUSIC_SURROUND 0x800 // surround sound -#define BASS_MUSIC_SURROUND2 0x1000 // surround sound (mode 2) -#define BASS_MUSIC_FT2PAN 0x2000 // apply FastTracker 2 panning to XM files -#define BASS_MUSIC_FT2MOD 0x2000 // play .MOD as FastTracker 2 does -#define BASS_MUSIC_PT1MOD 0x4000 // play .MOD as ProTracker 1 does -#define BASS_MUSIC_NONINTER 0x10000 // non-interpolated sample mixing -#define BASS_MUSIC_SINCINTER 0x800000 // sinc interpolated sample mixing -#define BASS_MUSIC_POSRESET 0x8000 // stop all notes when moving position -#define BASS_MUSIC_POSRESETEX 0x400000 // stop all notes and reset bmp/etc when moving position -#define BASS_MUSIC_STOPBACK 0x80000 // stop the music on a backwards jump effect -#define BASS_MUSIC_NOSAMPLE 0x100000 // don't load the samples - -// Speaker assignment flags -#define BASS_SPEAKER_FRONT 0x1000000 // front speakers -#define BASS_SPEAKER_REAR 0x2000000 // rear/side speakers -#define BASS_SPEAKER_CENLFE 0x3000000 // center & LFE speakers (5.1) -#define BASS_SPEAKER_REAR2 0x4000000 // rear center speakers (7.1) -#define BASS_SPEAKER_N(n) ((n)<<24) // n'th pair of speakers (max 15) -#define BASS_SPEAKER_LEFT 0x10000000 // modifier: left -#define BASS_SPEAKER_RIGHT 0x20000000 // modifier: right -#define BASS_SPEAKER_FRONTLEFT BASS_SPEAKER_FRONT|BASS_SPEAKER_LEFT -#define BASS_SPEAKER_FRONTRIGHT BASS_SPEAKER_FRONT|BASS_SPEAKER_RIGHT -#define BASS_SPEAKER_REARLEFT BASS_SPEAKER_REAR|BASS_SPEAKER_LEFT -#define BASS_SPEAKER_REARRIGHT BASS_SPEAKER_REAR|BASS_SPEAKER_RIGHT -#define BASS_SPEAKER_CENTER BASS_SPEAKER_CENLFE|BASS_SPEAKER_LEFT -#define BASS_SPEAKER_LFE BASS_SPEAKER_CENLFE|BASS_SPEAKER_RIGHT -#define BASS_SPEAKER_REAR2LEFT BASS_SPEAKER_REAR2|BASS_SPEAKER_LEFT -#define BASS_SPEAKER_REAR2RIGHT BASS_SPEAKER_REAR2|BASS_SPEAKER_RIGHT - -#define BASS_ASYNCFILE 0x40000000 -#define BASS_UNICODE 0x80000000 - -#define BASS_RECORD_PAUSE 0x8000 // start recording paused -#define BASS_RECORD_ECHOCANCEL 0x2000 -#define BASS_RECORD_AGC 0x4000 - -// DX7 voice allocation & management flags -#define BASS_VAM_HARDWARE 1 -#define BASS_VAM_SOFTWARE 2 -#define BASS_VAM_TERM_TIME 4 -#define BASS_VAM_TERM_DIST 8 -#define BASS_VAM_TERM_PRIO 16 - -// Channel info structure -typedef struct { - DWORD freq; // default playback rate - DWORD chans; // channels - DWORD flags; // BASS_SAMPLE/STREAM/MUSIC/SPEAKER flags - DWORD ctype; // type of channel - DWORD origres; // original resolution - HPLUGIN plugin; // plugin - HSAMPLE sample; // sample - const char *filename; // filename -} BASS_CHANNELINFO; - -#define BASS_ORIGRES_FLOAT 0x10000 - -// BASS_CHANNELINFO types -#define BASS_CTYPE_SAMPLE 1 -#define BASS_CTYPE_RECORD 2 -#define BASS_CTYPE_STREAM 0x10000 -#define BASS_CTYPE_STREAM_VORBIS 0x10002 -#define BASS_CTYPE_STREAM_OGG 0x10002 -#define BASS_CTYPE_STREAM_MP1 0x10003 -#define BASS_CTYPE_STREAM_MP2 0x10004 -#define BASS_CTYPE_STREAM_MP3 0x10005 -#define BASS_CTYPE_STREAM_AIFF 0x10006 -#define BASS_CTYPE_STREAM_CA 0x10007 -#define BASS_CTYPE_STREAM_MF 0x10008 -#define BASS_CTYPE_STREAM_AM 0x10009 -#define BASS_CTYPE_STREAM_DUMMY 0x18000 -#define BASS_CTYPE_STREAM_DEVICE 0x18001 -#define BASS_CTYPE_STREAM_WAV 0x40000 // WAVE flag, LOWORD=codec -#define BASS_CTYPE_STREAM_WAV_PCM 0x50001 -#define BASS_CTYPE_STREAM_WAV_FLOAT 0x50003 -#define BASS_CTYPE_MUSIC_MOD 0x20000 -#define BASS_CTYPE_MUSIC_MTM 0x20001 -#define BASS_CTYPE_MUSIC_S3M 0x20002 -#define BASS_CTYPE_MUSIC_XM 0x20003 -#define BASS_CTYPE_MUSIC_IT 0x20004 -#define BASS_CTYPE_MUSIC_MO3 0x00100 // MO3 flag - -typedef struct { - DWORD ctype; // channel type -#if defined(_WIN32_WCE) || (WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) - const wchar_t *name; // format description - const wchar_t *exts; // file extension filter (*.ext1;*.ext2;etc...) -#else - const char *name; // format description - const char *exts; // file extension filter (*.ext1;*.ext2;etc...) -#endif -} BASS_PLUGINFORM; - -typedef struct { - DWORD version; // version (same form as BASS_GetVersion) - DWORD formatc; // number of formats - const BASS_PLUGINFORM *formats; // the array of formats -} BASS_PLUGININFO; - -// 3D vector (for 3D positions/velocities/orientations) -typedef struct BASS_3DVECTOR { -#ifdef __cplusplus - BASS_3DVECTOR() {}; - BASS_3DVECTOR(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}; -#endif - float x; // +=right, -=left - float y; // +=up, -=down - float z; // +=front, -=behind -} BASS_3DVECTOR; - -// 3D channel modes -#define BASS_3DMODE_NORMAL 0 // normal 3D processing -#define BASS_3DMODE_RELATIVE 1 // position is relative to the listener -#define BASS_3DMODE_OFF 2 // no 3D processing - -// software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM) -#define BASS_3DALG_DEFAULT 0 -#define BASS_3DALG_OFF 1 -#define BASS_3DALG_FULL 2 -#define BASS_3DALG_LIGHT 3 - -// EAX environments, use with BASS_SetEAXParameters -enum -{ - EAX_ENVIRONMENT_GENERIC, - EAX_ENVIRONMENT_PADDEDCELL, - EAX_ENVIRONMENT_ROOM, - EAX_ENVIRONMENT_BATHROOM, - EAX_ENVIRONMENT_LIVINGROOM, - EAX_ENVIRONMENT_STONEROOM, - EAX_ENVIRONMENT_AUDITORIUM, - EAX_ENVIRONMENT_CONCERTHALL, - EAX_ENVIRONMENT_CAVE, - EAX_ENVIRONMENT_ARENA, - EAX_ENVIRONMENT_HANGAR, - EAX_ENVIRONMENT_CARPETEDHALLWAY, - EAX_ENVIRONMENT_HALLWAY, - EAX_ENVIRONMENT_STONECORRIDOR, - EAX_ENVIRONMENT_ALLEY, - EAX_ENVIRONMENT_FOREST, - EAX_ENVIRONMENT_CITY, - EAX_ENVIRONMENT_MOUNTAINS, - EAX_ENVIRONMENT_QUARRY, - EAX_ENVIRONMENT_PLAIN, - EAX_ENVIRONMENT_PARKINGLOT, - EAX_ENVIRONMENT_SEWERPIPE, - EAX_ENVIRONMENT_UNDERWATER, - EAX_ENVIRONMENT_DRUGGED, - EAX_ENVIRONMENT_DIZZY, - EAX_ENVIRONMENT_PSYCHOTIC, - - EAX_ENVIRONMENT_COUNT // total number of environments -}; - -// EAX presets, usage: BASS_SetEAXParameters(EAX_PRESET_xxx) -#define EAX_PRESET_GENERIC EAX_ENVIRONMENT_GENERIC,0.5F,1.493F,0.5F -#define EAX_PRESET_PADDEDCELL EAX_ENVIRONMENT_PADDEDCELL,0.25F,0.1F,0.0F -#define EAX_PRESET_ROOM EAX_ENVIRONMENT_ROOM,0.417F,0.4F,0.666F -#define EAX_PRESET_BATHROOM EAX_ENVIRONMENT_BATHROOM,0.653F,1.499F,0.166F -#define EAX_PRESET_LIVINGROOM EAX_ENVIRONMENT_LIVINGROOM,0.208F,0.478F,0.0F -#define EAX_PRESET_STONEROOM EAX_ENVIRONMENT_STONEROOM,0.5F,2.309F,0.888F -#define EAX_PRESET_AUDITORIUM EAX_ENVIRONMENT_AUDITORIUM,0.403F,4.279F,0.5F -#define EAX_PRESET_CONCERTHALL EAX_ENVIRONMENT_CONCERTHALL,0.5F,3.961F,0.5F -#define EAX_PRESET_CAVE EAX_ENVIRONMENT_CAVE,0.5F,2.886F,1.304F -#define EAX_PRESET_ARENA EAX_ENVIRONMENT_ARENA,0.361F,7.284F,0.332F -#define EAX_PRESET_HANGAR EAX_ENVIRONMENT_HANGAR,0.5F,10.0F,0.3F -#define EAX_PRESET_CARPETEDHALLWAY EAX_ENVIRONMENT_CARPETEDHALLWAY,0.153F,0.259F,2.0F -#define EAX_PRESET_HALLWAY EAX_ENVIRONMENT_HALLWAY,0.361F,1.493F,0.0F -#define EAX_PRESET_STONECORRIDOR EAX_ENVIRONMENT_STONECORRIDOR,0.444F,2.697F,0.638F -#define EAX_PRESET_ALLEY EAX_ENVIRONMENT_ALLEY,0.25F,1.752F,0.776F -#define EAX_PRESET_FOREST EAX_ENVIRONMENT_FOREST,0.111F,3.145F,0.472F -#define EAX_PRESET_CITY EAX_ENVIRONMENT_CITY,0.111F,2.767F,0.224F -#define EAX_PRESET_MOUNTAINS EAX_ENVIRONMENT_MOUNTAINS,0.194F,7.841F,0.472F -#define EAX_PRESET_QUARRY EAX_ENVIRONMENT_QUARRY,1.0F,1.499F,0.5F -#define EAX_PRESET_PLAIN EAX_ENVIRONMENT_PLAIN,0.097F,2.767F,0.224F -#define EAX_PRESET_PARKINGLOT EAX_ENVIRONMENT_PARKINGLOT,0.208F,1.652F,1.5F -#define EAX_PRESET_SEWERPIPE EAX_ENVIRONMENT_SEWERPIPE,0.652F,2.886F,0.25F -#define EAX_PRESET_UNDERWATER EAX_ENVIRONMENT_UNDERWATER,1.0F,1.499F,0.0F -#define EAX_PRESET_DRUGGED EAX_ENVIRONMENT_DRUGGED,0.875F,8.392F,1.388F -#define EAX_PRESET_DIZZY EAX_ENVIRONMENT_DIZZY,0.139F,17.234F,0.666F -#define EAX_PRESET_PSYCHOTIC EAX_ENVIRONMENT_PSYCHOTIC,0.486F,7.563F,0.806F - -typedef DWORD (CALLBACK STREAMPROC)(HSTREAM handle, void *buffer, DWORD length, void *user); -/* User stream callback function. -handle : The stream that needs writing -buffer : Buffer to write the samples in -length : Number of bytes to write -user : The 'user' parameter value given when calling BASS_StreamCreate -RETURN : Number of bytes written. Set the BASS_STREAMPROC_END flag to end the stream. */ - -#define BASS_STREAMPROC_END 0x80000000 // end of user stream flag - -// special STREAMPROCs -#define STREAMPROC_DUMMY (STREAMPROC*)0 // "dummy" stream -#define STREAMPROC_PUSH (STREAMPROC*)-1 // push stream -#define STREAMPROC_DEVICE (STREAMPROC*)-2 // device mix stream -#define STREAMPROC_DEVICE_3D (STREAMPROC*)-3 // device 3D mix stream - -// BASS_StreamCreateFileUser file systems -#define STREAMFILE_NOBUFFER 0 -#define STREAMFILE_BUFFER 1 -#define STREAMFILE_BUFFERPUSH 2 - -// User file stream callback functions -typedef void (CALLBACK FILECLOSEPROC)(void *user); -typedef QWORD (CALLBACK FILELENPROC)(void *user); -typedef DWORD (CALLBACK FILEREADPROC)(void *buffer, DWORD length, void *user); -typedef BOOL (CALLBACK FILESEEKPROC)(QWORD offset, void *user); - -typedef struct { - FILECLOSEPROC *close; - FILELENPROC *length; - FILEREADPROC *read; - FILESEEKPROC *seek; -} BASS_FILEPROCS; - -// BASS_StreamPutFileData options -#define BASS_FILEDATA_END 0 // end & close the file - -// BASS_StreamGetFilePosition modes -#define BASS_FILEPOS_CURRENT 0 -#define BASS_FILEPOS_DECODE BASS_FILEPOS_CURRENT -#define BASS_FILEPOS_DOWNLOAD 1 -#define BASS_FILEPOS_END 2 -#define BASS_FILEPOS_START 3 -#define BASS_FILEPOS_CONNECTED 4 -#define BASS_FILEPOS_BUFFER 5 -#define BASS_FILEPOS_SOCKET 6 -#define BASS_FILEPOS_ASYNCBUF 7 -#define BASS_FILEPOS_SIZE 8 -#define BASS_FILEPOS_BUFFERING 9 - -typedef void (CALLBACK DOWNLOADPROC)(const void *buffer, DWORD length, void *user); -/* Internet stream download callback function. -buffer : Buffer containing the downloaded data... NULL=end of download -length : Number of bytes in the buffer -user : The 'user' parameter value given when calling BASS_StreamCreateURL */ - -// BASS_ChannelSetSync types -#define BASS_SYNC_POS 0 -#define BASS_SYNC_END 2 -#define BASS_SYNC_META 4 -#define BASS_SYNC_SLIDE 5 -#define BASS_SYNC_STALL 6 -#define BASS_SYNC_DOWNLOAD 7 -#define BASS_SYNC_FREE 8 -#define BASS_SYNC_SETPOS 11 -#define BASS_SYNC_MUSICPOS 10 -#define BASS_SYNC_MUSICINST 1 -#define BASS_SYNC_MUSICFX 3 -#define BASS_SYNC_OGG_CHANGE 12 -#define BASS_SYNC_DEV_FAIL 14 -#define BASS_SYNC_DEV_FORMAT 15 -#define BASS_SYNC_THREAD 0x20000000 // flag: call sync in other thread -#define BASS_SYNC_MIXTIME 0x40000000 // flag: sync at mixtime, else at playtime -#define BASS_SYNC_ONETIME 0x80000000 // flag: sync only once, else continuously - -typedef void (CALLBACK SYNCPROC)(HSYNC handle, DWORD channel, DWORD data, void *user); -/* Sync callback function. -handle : The sync that has occured -channel: Channel that the sync occured in -data : Additional data associated with the sync's occurance -user : The 'user' parameter given when calling BASS_ChannelSetSync */ - -typedef void (CALLBACK DSPPROC)(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user); -/* DSP callback function. -handle : The DSP handle -channel: Channel that the DSP is being applied to -buffer : Buffer to apply the DSP to -length : Number of bytes in the buffer -user : The 'user' parameter given when calling BASS_ChannelSetDSP */ - -typedef BOOL (CALLBACK RECORDPROC)(HRECORD handle, const void *buffer, DWORD length, void *user); -/* Recording callback function. -handle : The recording handle -buffer : Buffer containing the recorded sample data -length : Number of bytes -user : The 'user' parameter value given when calling BASS_RecordStart -RETURN : TRUE = continue recording, FALSE = stop */ - -// BASS_ChannelIsActive return values -#define BASS_ACTIVE_STOPPED 0 -#define BASS_ACTIVE_PLAYING 1 -#define BASS_ACTIVE_STALLED 2 -#define BASS_ACTIVE_PAUSED 3 -#define BASS_ACTIVE_PAUSED_DEVICE 4 - -// Channel attributes -#define BASS_ATTRIB_FREQ 1 -#define BASS_ATTRIB_VOL 2 -#define BASS_ATTRIB_PAN 3 -#define BASS_ATTRIB_EAXMIX 4 -#define BASS_ATTRIB_NOBUFFER 5 -#define BASS_ATTRIB_VBR 6 -#define BASS_ATTRIB_CPU 7 -#define BASS_ATTRIB_SRC 8 -#define BASS_ATTRIB_NET_RESUME 9 -#define BASS_ATTRIB_SCANINFO 10 -#define BASS_ATTRIB_NORAMP 11 -#define BASS_ATTRIB_BITRATE 12 -#define BASS_ATTRIB_BUFFER 13 -#define BASS_ATTRIB_GRANULE 14 -#define BASS_ATTRIB_MUSIC_AMPLIFY 0x100 -#define BASS_ATTRIB_MUSIC_PANSEP 0x101 -#define BASS_ATTRIB_MUSIC_PSCALER 0x102 -#define BASS_ATTRIB_MUSIC_BPM 0x103 -#define BASS_ATTRIB_MUSIC_SPEED 0x104 -#define BASS_ATTRIB_MUSIC_VOL_GLOBAL 0x105 -#define BASS_ATTRIB_MUSIC_ACTIVE 0x106 -#define BASS_ATTRIB_MUSIC_VOL_CHAN 0x200 // + channel # -#define BASS_ATTRIB_MUSIC_VOL_INST 0x300 // + instrument # - -// BASS_ChannelSlideAttribute flags -#define BASS_SLIDE_LOG 0x1000000 - -// BASS_ChannelGetData flags -#define BASS_DATA_AVAILABLE 0 // query how much data is buffered -#define BASS_DATA_FIXED 0x20000000 // flag: return 8.24 fixed-point data -#define BASS_DATA_FLOAT 0x40000000 // flag: return floating-point sample data -#define BASS_DATA_FFT256 0x80000000 // 256 sample FFT -#define BASS_DATA_FFT512 0x80000001 // 512 FFT -#define BASS_DATA_FFT1024 0x80000002 // 1024 FFT -#define BASS_DATA_FFT2048 0x80000003 // 2048 FFT -#define BASS_DATA_FFT4096 0x80000004 // 4096 FFT -#define BASS_DATA_FFT8192 0x80000005 // 8192 FFT -#define BASS_DATA_FFT16384 0x80000006 // 16384 FFT -#define BASS_DATA_FFT32768 0x80000007 // 32768 FFT -#define BASS_DATA_FFT_INDIVIDUAL 0x10 // FFT flag: FFT for each channel, else all combined -#define BASS_DATA_FFT_NOWINDOW 0x20 // FFT flag: no Hanning window -#define BASS_DATA_FFT_REMOVEDC 0x40 // FFT flag: pre-remove DC bias -#define BASS_DATA_FFT_COMPLEX 0x80 // FFT flag: return complex data -#define BASS_DATA_FFT_NYQUIST 0x100 // FFT flag: return extra Nyquist value - -// BASS_ChannelGetLevelEx flags -#define BASS_LEVEL_MONO 1 -#define BASS_LEVEL_STEREO 2 -#define BASS_LEVEL_RMS 4 -#define BASS_LEVEL_VOLPAN 8 - -// BASS_ChannelGetTags types : what's returned -#define BASS_TAG_ID3 0 // ID3v1 tags : TAG_ID3 structure -#define BASS_TAG_ID3V2 1 // ID3v2 tags : variable length block -#define BASS_TAG_OGG 2 // OGG comments : series of null-terminated UTF-8 strings -#define BASS_TAG_HTTP 3 // HTTP headers : series of null-terminated ANSI strings -#define BASS_TAG_ICY 4 // ICY headers : series of null-terminated ANSI strings -#define BASS_TAG_META 5 // ICY metadata : ANSI string -#define BASS_TAG_APE 6 // APE tags : series of null-terminated UTF-8 strings -#define BASS_TAG_MP4 7 // MP4/iTunes metadata : series of null-terminated UTF-8 strings -#define BASS_TAG_WMA 8 // WMA tags : series of null-terminated UTF-8 strings -#define BASS_TAG_VENDOR 9 // OGG encoder : UTF-8 string -#define BASS_TAG_LYRICS3 10 // Lyric3v2 tag : ASCII string -#define BASS_TAG_CA_CODEC 11 // CoreAudio codec info : TAG_CA_CODEC structure -#define BASS_TAG_MF 13 // Media Foundation tags : series of null-terminated UTF-8 strings -#define BASS_TAG_WAVEFORMAT 14 // WAVE format : WAVEFORMATEEX structure -#define BASS_TAG_AM_MIME 15 // Android Media MIME type : ASCII string -#define BASS_TAG_AM_NAME 16 // Android Media codec name : ASCII string -#define BASS_TAG_RIFF_INFO 0x100 // RIFF "INFO" tags : series of null-terminated ANSI strings -#define BASS_TAG_RIFF_BEXT 0x101 // RIFF/BWF "bext" tags : TAG_BEXT structure -#define BASS_TAG_RIFF_CART 0x102 // RIFF/BWF "cart" tags : TAG_CART structure -#define BASS_TAG_RIFF_DISP 0x103 // RIFF "DISP" text tag : ANSI string -#define BASS_TAG_RIFF_CUE 0x104 // RIFF "cue " chunk : TAG_CUE structure -#define BASS_TAG_RIFF_SMPL 0x105 // RIFF "smpl" chunk : TAG_SMPL structure -#define BASS_TAG_APE_BINARY 0x1000 // + index #, binary APE tag : TAG_APE_BINARY structure -#define BASS_TAG_MUSIC_NAME 0x10000 // MOD music name : ANSI string -#define BASS_TAG_MUSIC_MESSAGE 0x10001 // MOD message : ANSI string -#define BASS_TAG_MUSIC_ORDERS 0x10002 // MOD order list : BYTE array of pattern numbers -#define BASS_TAG_MUSIC_AUTH 0x10003 // MOD author : UTF-8 string -#define BASS_TAG_MUSIC_INST 0x10100 // + instrument #, MOD instrument name : ANSI string -#define BASS_TAG_MUSIC_SAMPLE 0x10300 // + sample #, MOD sample name : ANSI string - -// ID3v1 tag structure -typedef struct { - char id[3]; - char title[30]; - char artist[30]; - char album[30]; - char year[4]; - char comment[30]; - BYTE genre; -} TAG_ID3; - -// Binary APE tag structure -typedef struct { - const char *key; - const void *data; - DWORD length; -} TAG_APE_BINARY; - -// BWF "bext" tag structure -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4200) -#endif -#pragma pack(push,1) -typedef struct { - char Description[256]; // description - char Originator[32]; // name of the originator - char OriginatorReference[32]; // reference of the originator - char OriginationDate[10]; // date of creation (yyyy-mm-dd) - char OriginationTime[8]; // time of creation (hh-mm-ss) - QWORD TimeReference; // first sample count since midnight (little-endian) - WORD Version; // BWF version (little-endian) - BYTE UMID[64]; // SMPTE UMID - BYTE Reserved[190]; -#if defined(__GNUC__) && __GNUC__<3 - char CodingHistory[0]; // history -#elif 1 // change to 0 if compiler fails the following line - char CodingHistory[]; // history -#else - char CodingHistory[1]; // history -#endif -} TAG_BEXT; -#pragma pack(pop) - -// BWF "cart" tag structures -typedef struct -{ - DWORD dwUsage; // FOURCC timer usage ID - DWORD dwValue; // timer value in samples from head -} TAG_CART_TIMER; - -typedef struct -{ - char Version[4]; // version of the data structure - char Title[64]; // title of cart audio sequence - char Artist[64]; // artist or creator name - char CutID[64]; // cut number identification - char ClientID[64]; // client identification - char Category[64]; // category ID, PSA, NEWS, etc - char Classification[64]; // classification or auxiliary key - char OutCue[64]; // out cue text - char StartDate[10]; // yyyy-mm-dd - char StartTime[8]; // hh:mm:ss - char EndDate[10]; // yyyy-mm-dd - char EndTime[8]; // hh:mm:ss - char ProducerAppID[64]; // name of vendor or application - char ProducerAppVersion[64]; // version of producer application - char UserDef[64]; // user defined text - DWORD dwLevelReference; // sample value for 0 dB reference - TAG_CART_TIMER PostTimer[8]; // 8 time markers after head - char Reserved[276]; - char URL[1024]; // uniform resource locator -#if defined(__GNUC__) && __GNUC__<3 - char TagText[0]; // free form text for scripts or tags -#elif 1 // change to 0 if compiler fails the following line - char TagText[]; // free form text for scripts or tags -#else - char TagText[1]; // free form text for scripts or tags -#endif -} TAG_CART; - -// RIFF "cue " tag structures -typedef struct -{ - DWORD dwName; - DWORD dwPosition; - DWORD fccChunk; - DWORD dwChunkStart; - DWORD dwBlockStart; - DWORD dwSampleOffset; -} TAG_CUE_POINT; - -typedef struct -{ - DWORD dwCuePoints; -#if defined(__GNUC__) && __GNUC__<3 - TAG_CUE_POINT CuePoints[0]; -#elif 1 // change to 0 if compiler fails the following line - TAG_CUE_POINT CuePoints[]; -#else - TAG_CUE_POINT CuePoints[1]; -#endif -} TAG_CUE; - -// RIFF "smpl" tag structures -typedef struct -{ - DWORD dwIdentifier; - DWORD dwType; - DWORD dwStart; - DWORD dwEnd; - DWORD dwFraction; - DWORD dwPlayCount; -} TAG_SMPL_LOOP; - -typedef struct -{ - DWORD dwManufacturer; - DWORD dwProduct; - DWORD dwSamplePeriod; - DWORD dwMIDIUnityNote; - DWORD dwMIDIPitchFraction; - DWORD dwSMPTEFormat; - DWORD dwSMPTEOffset; - DWORD cSampleLoops; - DWORD cbSamplerData; -#if defined(__GNUC__) && __GNUC__<3 - TAG_SMPL_LOOP SampleLoops[0]; -#elif 1 // change to 0 if compiler fails the following line - TAG_SMPL_LOOP SampleLoops[]; -#else - TAG_SMPL_LOOP SampleLoops[1]; -#endif -} TAG_SMPL; -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -// CoreAudio codec info structure -typedef struct { - DWORD ftype; // file format - DWORD atype; // audio format - const char *name; // description -} TAG_CA_CODEC; - -#ifndef _WAVEFORMATEX_ -#define _WAVEFORMATEX_ -#pragma pack(push,1) -typedef struct tWAVEFORMATEX -{ - WORD wFormatTag; - WORD nChannels; - DWORD nSamplesPerSec; - DWORD nAvgBytesPerSec; - WORD nBlockAlign; - WORD wBitsPerSample; - WORD cbSize; -} WAVEFORMATEX, *PWAVEFORMATEX, *LPWAVEFORMATEX; -typedef const WAVEFORMATEX *LPCWAVEFORMATEX; -#pragma pack(pop) -#endif - -// BASS_ChannelGetLength/GetPosition/SetPosition modes -#define BASS_POS_BYTE 0 // byte position -#define BASS_POS_MUSIC_ORDER 1 // order.row position, MAKELONG(order,row) -#define BASS_POS_OGG 3 // OGG bitstream number -#define BASS_POS_RESET 0x2000000 // flag: reset user file buffers -#define BASS_POS_RELATIVE 0x4000000 // flag: seek relative to the current position -#define BASS_POS_INEXACT 0x8000000 // flag: allow seeking to inexact position -#define BASS_POS_DECODE 0x10000000 // flag: get the decoding (not playing) position -#define BASS_POS_DECODETO 0x20000000 // flag: decode to the position instead of seeking -#define BASS_POS_SCAN 0x40000000 // flag: scan to the position - -// BASS_ChannelSetDevice/GetDevice option -#define BASS_NODEVICE 0x20000 - -// BASS_RecordSetInput flags -#define BASS_INPUT_OFF 0x10000 -#define BASS_INPUT_ON 0x20000 - -#define BASS_INPUT_TYPE_MASK 0xff000000 -#define BASS_INPUT_TYPE_UNDEF 0x00000000 -#define BASS_INPUT_TYPE_DIGITAL 0x01000000 -#define BASS_INPUT_TYPE_LINE 0x02000000 -#define BASS_INPUT_TYPE_MIC 0x03000000 -#define BASS_INPUT_TYPE_SYNTH 0x04000000 -#define BASS_INPUT_TYPE_CD 0x05000000 -#define BASS_INPUT_TYPE_PHONE 0x06000000 -#define BASS_INPUT_TYPE_SPEAKER 0x07000000 -#define BASS_INPUT_TYPE_WAVE 0x08000000 -#define BASS_INPUT_TYPE_AUX 0x09000000 -#define BASS_INPUT_TYPE_ANALOG 0x0a000000 - -// BASS_ChannelSetFX effect types -#define BASS_FX_DX8_CHORUS 0 -#define BASS_FX_DX8_COMPRESSOR 1 -#define BASS_FX_DX8_DISTORTION 2 -#define BASS_FX_DX8_ECHO 3 -#define BASS_FX_DX8_FLANGER 4 -#define BASS_FX_DX8_GARGLE 5 -#define BASS_FX_DX8_I3DL2REVERB 6 -#define BASS_FX_DX8_PARAMEQ 7 -#define BASS_FX_DX8_REVERB 8 -#define BASS_FX_VOLUME 9 - -typedef struct { - float fWetDryMix; - float fDepth; - float fFeedback; - float fFrequency; - DWORD lWaveform; // 0=triangle, 1=sine - float fDelay; - DWORD lPhase; // BASS_DX8_PHASE_xxx -} BASS_DX8_CHORUS; - -typedef struct { - float fGain; - float fAttack; - float fRelease; - float fThreshold; - float fRatio; - float fPredelay; -} BASS_DX8_COMPRESSOR; - -typedef struct { - float fGain; - float fEdge; - float fPostEQCenterFrequency; - float fPostEQBandwidth; - float fPreLowpassCutoff; -} BASS_DX8_DISTORTION; - -typedef struct { - float fWetDryMix; - float fFeedback; - float fLeftDelay; - float fRightDelay; - BOOL lPanDelay; -} BASS_DX8_ECHO; - -typedef struct { - float fWetDryMix; - float fDepth; - float fFeedback; - float fFrequency; - DWORD lWaveform; // 0=triangle, 1=sine - float fDelay; - DWORD lPhase; // BASS_DX8_PHASE_xxx -} BASS_DX8_FLANGER; - -typedef struct { - DWORD dwRateHz; // Rate of modulation in hz - DWORD dwWaveShape; // 0=triangle, 1=square -} BASS_DX8_GARGLE; - -typedef struct { - int lRoom; // [-10000, 0] default: -1000 mB - int lRoomHF; // [-10000, 0] default: 0 mB - float flRoomRolloffFactor; // [0.0, 10.0] default: 0.0 - float flDecayTime; // [0.1, 20.0] default: 1.49s - float flDecayHFRatio; // [0.1, 2.0] default: 0.83 - int lReflections; // [-10000, 1000] default: -2602 mB - float flReflectionsDelay; // [0.0, 0.3] default: 0.007 s - int lReverb; // [-10000, 2000] default: 200 mB - float flReverbDelay; // [0.0, 0.1] default: 0.011 s - float flDiffusion; // [0.0, 100.0] default: 100.0 % - float flDensity; // [0.0, 100.0] default: 100.0 % - float flHFReference; // [20.0, 20000.0] default: 5000.0 Hz -} BASS_DX8_I3DL2REVERB; - -typedef struct { - float fCenter; - float fBandwidth; - float fGain; -} BASS_DX8_PARAMEQ; - -typedef struct { - float fInGain; // [-96.0,0.0] default: 0.0 dB - float fReverbMix; // [-96.0,0.0] default: 0.0 db - float fReverbTime; // [0.001,3000.0] default: 1000.0 ms - float fHighFreqRTRatio; // [0.001,0.999] default: 0.001 -} BASS_DX8_REVERB; - -#define BASS_DX8_PHASE_NEG_180 0 -#define BASS_DX8_PHASE_NEG_90 1 -#define BASS_DX8_PHASE_ZERO 2 -#define BASS_DX8_PHASE_90 3 -#define BASS_DX8_PHASE_180 4 - -typedef struct { - float fTarget; - float fCurrent; - float fTime; - DWORD lCurve; -} BASS_FX_VOLUME_PARAM; - -typedef void (CALLBACK IOSNOTIFYPROC)(DWORD status); -/* iOS notification callback function. -status : The notification (BASS_IOSNOTIFY_xxx) */ - -#define BASS_IOSNOTIFY_INTERRUPT 1 // interruption started -#define BASS_IOSNOTIFY_INTERRUPT_END 2 // interruption ended - -BOOL BASSDEF(BASS_SetConfig)(DWORD option, DWORD value); -DWORD BASSDEF(BASS_GetConfig)(DWORD option); -BOOL BASSDEF(BASS_SetConfigPtr)(DWORD option, const void *value); -void *BASSDEF(BASS_GetConfigPtr)(DWORD option); -DWORD BASSDEF(BASS_GetVersion)(); -int BASSDEF(BASS_ErrorGetCode)(); -BOOL BASSDEF(BASS_GetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info); -#if defined(_WIN32) && !defined(_WIN32_WCE) && !(WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) -BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, HWND win, const GUID *dsguid); -#else -BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, void *win, void *dsguid); -#endif -BOOL BASSDEF(BASS_SetDevice)(DWORD device); -DWORD BASSDEF(BASS_GetDevice)(); -BOOL BASSDEF(BASS_Free)(); -#if defined(_WIN32) && !defined(_WIN32_WCE) && !(WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) -void *BASSDEF(BASS_GetDSoundObject)(DWORD object); -#endif -BOOL BASSDEF(BASS_GetInfo)(BASS_INFO *info); -BOOL BASSDEF(BASS_Update)(DWORD length); -float BASSDEF(BASS_GetCPU)(); -BOOL BASSDEF(BASS_Start)(); -BOOL BASSDEF(BASS_Stop)(); -BOOL BASSDEF(BASS_Pause)(); -BOOL BASSDEF(BASS_IsStarted)(); -BOOL BASSDEF(BASS_SetVolume)(float volume); -float BASSDEF(BASS_GetVolume)(); - -HPLUGIN BASSDEF(BASS_PluginLoad)(const char *file, DWORD flags); -BOOL BASSDEF(BASS_PluginFree)(HPLUGIN handle); -const BASS_PLUGININFO *BASSDEF(BASS_PluginGetInfo)(HPLUGIN handle); - -BOOL BASSDEF(BASS_Set3DFactors)(float distf, float rollf, float doppf); -BOOL BASSDEF(BASS_Get3DFactors)(float *distf, float *rollf, float *doppf); -BOOL BASSDEF(BASS_Set3DPosition)(const BASS_3DVECTOR *pos, const BASS_3DVECTOR *vel, const BASS_3DVECTOR *front, const BASS_3DVECTOR *top); -BOOL BASSDEF(BASS_Get3DPosition)(BASS_3DVECTOR *pos, BASS_3DVECTOR *vel, BASS_3DVECTOR *front, BASS_3DVECTOR *top); -void BASSDEF(BASS_Apply3D)(); -#if defined(_WIN32) && !defined(_WIN32_WCE) && !(WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) -BOOL BASSDEF(BASS_SetEAXParameters)(int env, float vol, float decay, float damp); -BOOL BASSDEF(BASS_GetEAXParameters)(DWORD *env, float *vol, float *decay, float *damp); -#endif - -HMUSIC BASSDEF(BASS_MusicLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD flags, DWORD freq); -BOOL BASSDEF(BASS_MusicFree)(HMUSIC handle); - -HSAMPLE BASSDEF(BASS_SampleLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD max, DWORD flags); -HSAMPLE BASSDEF(BASS_SampleCreate)(DWORD length, DWORD freq, DWORD chans, DWORD max, DWORD flags); -BOOL BASSDEF(BASS_SampleFree)(HSAMPLE handle); -BOOL BASSDEF(BASS_SampleSetData)(HSAMPLE handle, const void *buffer); -BOOL BASSDEF(BASS_SampleGetData)(HSAMPLE handle, void *buffer); -BOOL BASSDEF(BASS_SampleGetInfo)(HSAMPLE handle, BASS_SAMPLE *info); -BOOL BASSDEF(BASS_SampleSetInfo)(HSAMPLE handle, const BASS_SAMPLE *info); -HCHANNEL BASSDEF(BASS_SampleGetChannel)(HSAMPLE handle, BOOL onlynew); -DWORD BASSDEF(BASS_SampleGetChannels)(HSAMPLE handle, HCHANNEL *channels); -BOOL BASSDEF(BASS_SampleStop)(HSAMPLE handle); - -HSTREAM BASSDEF(BASS_StreamCreate)(DWORD freq, DWORD chans, DWORD flags, STREAMPROC *proc, void *user); -HSTREAM BASSDEF(BASS_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags); -HSTREAM BASSDEF(BASS_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user); -HSTREAM BASSDEF(BASS_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *proc, void *user); -BOOL BASSDEF(BASS_StreamFree)(HSTREAM handle); -QWORD BASSDEF(BASS_StreamGetFilePosition)(HSTREAM handle, DWORD mode); -DWORD BASSDEF(BASS_StreamPutData)(HSTREAM handle, const void *buffer, DWORD length); -DWORD BASSDEF(BASS_StreamPutFileData)(HSTREAM handle, const void *buffer, DWORD length); - -BOOL BASSDEF(BASS_RecordGetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info); -BOOL BASSDEF(BASS_RecordInit)(int device); -BOOL BASSDEF(BASS_RecordSetDevice)(DWORD device); -DWORD BASSDEF(BASS_RecordGetDevice)(); -BOOL BASSDEF(BASS_RecordFree)(); -BOOL BASSDEF(BASS_RecordGetInfo)(BASS_RECORDINFO *info); -const char *BASSDEF(BASS_RecordGetInputName)(int input); -BOOL BASSDEF(BASS_RecordSetInput)(int input, DWORD flags, float volume); -DWORD BASSDEF(BASS_RecordGetInput)(int input, float *volume); -HRECORD BASSDEF(BASS_RecordStart)(DWORD freq, DWORD chans, DWORD flags, RECORDPROC *proc, void *user); - -double BASSDEF(BASS_ChannelBytes2Seconds)(DWORD handle, QWORD pos); -QWORD BASSDEF(BASS_ChannelSeconds2Bytes)(DWORD handle, double pos); -DWORD BASSDEF(BASS_ChannelGetDevice)(DWORD handle); -BOOL BASSDEF(BASS_ChannelSetDevice)(DWORD handle, DWORD device); -DWORD BASSDEF(BASS_ChannelIsActive)(DWORD handle); -BOOL BASSDEF(BASS_ChannelGetInfo)(DWORD handle, BASS_CHANNELINFO *info); -const char *BASSDEF(BASS_ChannelGetTags)(DWORD handle, DWORD tags); -DWORD BASSDEF(BASS_ChannelFlags)(DWORD handle, DWORD flags, DWORD mask); -BOOL BASSDEF(BASS_ChannelUpdate)(DWORD handle, DWORD length); -BOOL BASSDEF(BASS_ChannelLock)(DWORD handle, BOOL lock); -BOOL BASSDEF(BASS_ChannelPlay)(DWORD handle, BOOL restart); -BOOL BASSDEF(BASS_ChannelStop)(DWORD handle); -BOOL BASSDEF(BASS_ChannelPause)(DWORD handle); -BOOL BASSDEF(BASS_ChannelSetAttribute)(DWORD handle, DWORD attrib, float value); -BOOL BASSDEF(BASS_ChannelGetAttribute)(DWORD handle, DWORD attrib, float *value); -BOOL BASSDEF(BASS_ChannelSlideAttribute)(DWORD handle, DWORD attrib, float value, DWORD time); -BOOL BASSDEF(BASS_ChannelIsSliding)(DWORD handle, DWORD attrib); -BOOL BASSDEF(BASS_ChannelSetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size); -DWORD BASSDEF(BASS_ChannelGetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size); -BOOL BASSDEF(BASS_ChannelSet3DAttributes)(DWORD handle, int mode, float min, float max, int iangle, int oangle, float outvol); -BOOL BASSDEF(BASS_ChannelGet3DAttributes)(DWORD handle, DWORD *mode, float *min, float *max, DWORD *iangle, DWORD *oangle, float *outvol); -BOOL BASSDEF(BASS_ChannelSet3DPosition)(DWORD handle, const BASS_3DVECTOR *pos, const BASS_3DVECTOR *orient, const BASS_3DVECTOR *vel); -BOOL BASSDEF(BASS_ChannelGet3DPosition)(DWORD handle, BASS_3DVECTOR *pos, BASS_3DVECTOR *orient, BASS_3DVECTOR *vel); -QWORD BASSDEF(BASS_ChannelGetLength)(DWORD handle, DWORD mode); -BOOL BASSDEF(BASS_ChannelSetPosition)(DWORD handle, QWORD pos, DWORD mode); -QWORD BASSDEF(BASS_ChannelGetPosition)(DWORD handle, DWORD mode); -DWORD BASSDEF(BASS_ChannelGetLevel)(DWORD handle); -BOOL BASSDEF(BASS_ChannelGetLevelEx)(DWORD handle, float *levels, float length, DWORD flags); -DWORD BASSDEF(BASS_ChannelGetData)(DWORD handle, void *buffer, DWORD length); -HSYNC BASSDEF(BASS_ChannelSetSync)(DWORD handle, DWORD type, QWORD param, SYNCPROC *proc, void *user); -BOOL BASSDEF(BASS_ChannelRemoveSync)(DWORD handle, HSYNC sync); -HDSP BASSDEF(BASS_ChannelSetDSP)(DWORD handle, DSPPROC *proc, void *user, int priority); -BOOL BASSDEF(BASS_ChannelRemoveDSP)(DWORD handle, HDSP dsp); -BOOL BASSDEF(BASS_ChannelSetLink)(DWORD handle, DWORD chan); -BOOL BASSDEF(BASS_ChannelRemoveLink)(DWORD handle, DWORD chan); -HFX BASSDEF(BASS_ChannelSetFX)(DWORD handle, DWORD type, int priority); -BOOL BASSDEF(BASS_ChannelRemoveFX)(DWORD handle, HFX fx); - -BOOL BASSDEF(BASS_FXSetParameters)(HFX handle, const void *params); -BOOL BASSDEF(BASS_FXGetParameters)(HFX handle, void *params); -BOOL BASSDEF(BASS_FXReset)(HFX handle); -BOOL BASSDEF(BASS_FXSetPriority)(HFX handle, int priority); - -#ifdef __cplusplus -} - -#if defined(_WIN32) && !defined(NOBASSOVERLOADS) -static inline HPLUGIN BASS_PluginLoad(const WCHAR *file, DWORD flags) -{ - return BASS_PluginLoad((const char*)file, flags|BASS_UNICODE); -} - -static inline HMUSIC BASS_MusicLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD flags, DWORD freq) -{ - return BASS_MusicLoad(mem, (const void*)file, offset, length, flags|BASS_UNICODE, freq); -} - -static inline HSAMPLE BASS_SampleLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD max, DWORD flags) -{ - return BASS_SampleLoad(mem, (const void*)file, offset, length, max, flags|BASS_UNICODE); -} - -static inline HSTREAM BASS_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags) -{ - return BASS_StreamCreateFile(mem, (const void*)file, offset, length, flags|BASS_UNICODE); -} - -static inline HSTREAM BASS_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user) -{ - return BASS_StreamCreateURL((const char*)url, offset, flags|BASS_UNICODE, proc, user); -} - -static inline BOOL BASS_SetConfigPtr(DWORD option, const WCHAR *value) -{ - return BASS_SetConfigPtr(option|BASS_UNICODE, (const void*)value); -} -#endif -#endif - -#endif diff --git a/modem/constellation.c b/modem/constellation.c deleted file mode 100644 index c59c361..0000000 --- a/modem/constellation.c +++ /dev/null @@ -1,170 +0,0 @@ -/* -* High Speed modem to transfer data in a 2,7kHz SSB channel -* ========================================================= -* Author: DJ0ABR -* -* (c) DJ0ABR -* www.dj0abr.de -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -*/ - -#include "qo100modem.h" - -// functions for non-differential QPSK -// depending on the phase shift rotate a data blocks constellation - -//uint8_t headerbytes[HEADERLEN] = {0x53, 0xe1, 0xa6}; -// corresponds to these QPSK symbols: -// bits: 01010011 11100001 10100110 -// syms: 1 1 0 3 3 2 0 1 2 2 1 2 - -uint8_t rxbytebuf[UDPBLOCKLEN+100]; // +100 ... reserve, just to be sure - -uint8_t *convertQPSKSymToBytes(uint8_t *rxsymbols) -{ - int sidx = 0; - for(int i=0; i> 6) & 3; - syms[symidx++] = (bytes[i] >> 4) & 3; - syms[symidx++] = (bytes[i] >> 2) & 3; - syms[symidx++] = (bytes[i] >> 0) & 3; - } -} - -void rotateQPSKsyms(uint8_t *src, uint8_t *dst, int len) -{ - for(int i=0; i> 5) & 7; - syms[symidx++] = (bytes[0+i] >> 2) & 7; - syms[symidx++] = ((bytes[0+i] & 3) << 1) | ((bytes[1+i] >> 7) & 1); - syms[symidx++] = (bytes[1+i] >> 4) & 7; - syms[symidx++] = (bytes[1+i] >> 1) & 7; - syms[symidx++] = ((bytes[1+i] & 1) << 2) | ((bytes[2+i] >> 6) & 3); - syms[symidx++] = (bytes[2+i] >> 3) & 7; - syms[symidx++] = bytes[2+i] & 7; - } -} - -void rotate8PSKsyms(uint8_t *src, uint8_t *dst, int len) -{ - for(int i=0; i> 1; - rxbytebuf[i+1] = rxsymbols[sidx++] << 7; - rxbytebuf[i+1] |= rxsymbols[sidx++] << 4; - rxbytebuf[i+1] |= rxsymbols[sidx++] << 1; - rxbytebuf[i+1] |= rxsymbols[sidx] >> 2; - rxbytebuf[i+2] = rxsymbols[sidx++] << 6; - rxbytebuf[i+2] |= rxsymbols[sidx++] << 3; - rxbytebuf[i+2] |= rxsymbols[sidx++]; - } - return rxbytebuf; -} - -void shiftleft(uint8_t *data, int shiftnum, int len) -{ - for(int j=0; j=0; i--) - { - b1 = (data[i] & 0x80)>>7; - data[i] <<= 1; - data[i] |= b2; - b2 = b1; - } - } -} diff --git a/modem/crc16.c b/modem/crc16.c deleted file mode 100644 index d182087..0000000 --- a/modem/crc16.c +++ /dev/null @@ -1,83 +0,0 @@ -/* -* High Speed modem to transfer data in a 2,7kHz SSB channel -* ========================================================= -* Author: DJ0ABR -* -* (c) DJ0ABR -* www.dj0abr.de -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -*/ - -#include "qo100modem.h" - -// since we use a static crc register we need TWO separated registers -// for RX and TX to get it thread safe, no.2 is for file ID generation - -uint16_t reg16[3] = {0xffff,0xffff}; // shift register - -uint16_t Crc16_bytecalc(int rxtx, uint8_t byt) -{ - uint16_t polynom = 0x8408; // generator polynom - - for (int i = 0; i < 8; ++i) - { - if ((reg16[rxtx] & 1) != (byt & 1)) - reg16[rxtx] = (uint16_t)((reg16[rxtx] >> 1) ^ polynom); - else - reg16[rxtx] >>= 1; - byt >>= 1; - } - return reg16[rxtx]; -} - -uint16_t Crc16_messagecalc(int rxtx, uint8_t *data,int len) -{ - reg16[rxtx] = 0xffff; - for (int i = 0; i < len; i++) - reg16[rxtx] = Crc16_bytecalc(rxtx,data[i]); - return reg16[rxtx]; -} - -// ================================================================= - -uint32_t reg32[2] = {0xffffffff,0xffffffff}; // Shiftregister - -void crc32_bytecalc(int rxtx, unsigned char byte) -{ -int i; -uint32_t polynom = 0xEDB88320; // Generatorpolynom - - for (i=0; i<8; ++i) - { - if ((reg32[rxtx]&1) != (byte&1)) - reg32[rxtx] = (reg32[rxtx]>>1)^polynom; - else - reg32[rxtx] >>= 1; - byte >>= 1; - } -} - -uint32_t crc32_messagecalc(int rxtx, unsigned char *data, int len) -{ -int i; - - reg32[rxtx] = 0xffffffff; - for(i=0; i -#include -#include - -#include "fec/schifra_galois_field.hpp" -#include "fec/schifra_galois_field_polynomial.hpp" -#include "fec/schifra_sequential_root_generator_polynomial_creator.hpp" -#include "fec/schifra_reed_solomon_encoder.hpp" -#include "fec/schifra_reed_solomon_decoder.hpp" -#include "fec/schifra_reed_solomon_block.hpp" -#include "fec/schifra_error_processes.hpp" - -/* Finite Field Parameters */ -const std::size_t field_descriptor = 8; -const std::size_t generator_polynomial_index = 120; -const std::size_t generator_polynomial_root_count = FECLEN; - -/* Reed Solomon Code Parameters */ -const std::size_t code_length = FECBLOCKLEN; -const std::size_t fec_length = FECLEN; -const std::size_t data_length = code_length - fec_length; - -/* Instantiate Finite Field and Generator Polynomials */ -const schifra::galois::field field(field_descriptor, - schifra::galois::primitive_polynomial_size06, - schifra::galois::primitive_polynomial06); - -schifra::galois::field_polynomial generator_polynomial(field); - -/* Instantiate Encoder and Decoder (Codec) */ -typedef schifra::reed_solomon::encoder encoder_t; -typedef schifra::reed_solomon::decoder decoder_t; - - - - -int cfec_Reconstruct(uint8_t *darr, uint8_t *destination) -{ -schifra::reed_solomon::block rxblock; - - for(std::size_t i=0; i block; - - // fill payload into an FEC-block - for(std::size_t i=0; i - -typedef unsigned char gf; - -typedef struct { - unsigned long magic; - unsigned short k, n; /* parameters of the code */ - gf* enc_matrix; -} fec_t; - -#if defined(_MSC_VER) -// actually, some of the flavors (i.e. Enterprise) do support restrict -//#define restrict __restrict -#define restrict -#endif - -/** - * param k the number of blocks required to reconstruct - * param m the total number of blocks created - */ -fec_t* fec_new(unsigned short k, unsigned short m); -void fec_free(fec_t* p); - -/** - * @param inpkts the "primary blocks" i.e. the chunks of the input data - * @param fecs buffers into which the secondary blocks will be written - * @param block_nums the numbers of the desired check blocks (the id >= k) which fec_encode() will produce and store into the buffers of the fecs parameter - * @param num_block_nums the length of the block_nums array - * @param sz size of a packet in bytes - */ -void fec_encode(const fec_t* code, const gf** src, gf** fecs, size_t sz); - -/** - * @param inpkts an array of packets (size k); If a primary block, i, is present then it must be at index i. Secondary blocks can appear anywhere. - * @param outpkts an array of buffers into which the reconstructed output packets will be written (only packets which are not present in the inpkts input will be reconstructed and written to outpkts) - * @param index an array of the blocknums of the packets in inpkts - * @param sz size of a packet in bytes - */ -void fec_decode(const fec_t* code, const gf** inpkts, gf** outpkts, const unsigned* index, size_t sz); - -#if defined(_MSC_VER) -#define alloca _alloca -#else -#ifdef __GNUC__ -#ifndef alloca -#define alloca(x) __builtin_alloca(x) -#endif -#else -#include -#endif -#endif - -/** - * zfec -- fast forward error correction library with Python interface - * - * Copyright (C) 2007-2008 Allmydata, Inc. - * Author: Zooko Wilcox-O'Hearn - * - * This file is part of zfec. - * - * See README.rst for licensing information. - */ - -/* - * Much of this work is derived from the "fec" software by Luigi Rizzo, et - * al., the copyright notice and licence terms of which are included below - * for reference. - * - * fec.h -- forward error correction based on Vandermonde matrices - * 980614 - * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it) - * - * Portions derived from code by Phil Karn (karn@ka9q.ampr.org), - * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari - * Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995 - * - * Modifications by Dan Rubenstein (see Modifications.txt for - * their description. - * Modifications (C) 1998 Dan Rubenstein (drubenst@cs.umass.edu) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - diff --git a/modem/fec/schifra_crc.hpp b/modem/fec/schifra_crc.hpp deleted file mode 100644 index 62b1073..0000000 --- a/modem/fec/schifra_crc.hpp +++ /dev/null @@ -1,172 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_CRC_HPP -#define INCLUDE_SCHIFRA_CRC_HPP - - -#include -#include - - -namespace schifra -{ - - class crc32 - { - public: - - typedef std::size_t crc32_t; - - crc32(const crc32_t& _key, const crc32_t& _state = 0x00) - : key(_key), - state(_state), - initial_state(_state) - { - initialize_crc32_table(); - } - - void reset() - { - state = initial_state; - } - - void update_1byte(const unsigned char data) - { - state = (state >> 8) ^ table[data]; - } - - void update(const unsigned char data[], const std::size_t& count) - { - for (std::size_t i = 0; i < count; ++i) - { - update_1byte(data[i]); - } - } - - void update(char data[], const std::size_t& count) - { - for (std::size_t i = 0; i < count; ++i) - { - update_1byte(static_cast(data[i])); - } - } - - void update(const std::string& data) - { - for (std::size_t i = 0; i < data.size(); ++i) - { - update_1byte(static_cast(data[i])); - } - } - - void update(const std::size_t& data) - { - update_1byte(static_cast((data ) & 0xFF)); - update_1byte(static_cast((data >> 8) & 0xFF)); - update_1byte(static_cast((data >> 16) & 0xFF)); - update_1byte(static_cast((data >> 24) & 0xFF)); - } - - crc32_t crc() - { - return state; - } - - private: - - crc32& operator=(const crc32&); - - void initialize_crc32_table() - { - for (std::size_t i = 0; i < 0xFF; ++i) - { - crc32_t reg = i; - - for (int j = 0; j < 0x08; ++j) - { - reg = ((reg & 1) ? (reg >> 1) ^ key : reg >> 1); - } - - table[i] = reg; - } - } - - protected: - - crc32_t key; - crc32_t state; - const crc32_t initial_state; - crc32_t table[256]; - }; - - class schifra_crc : public crc32 - { - public: - - schifra_crc(const crc32_t _key) - : crc32(_key,0xAAAAAAAA) - {} - - void update(const unsigned char& data) - { - state = ((state >> 8) ^ table[data]) ^ ((state << 8) ^ table[~data]); - } - - void update(const unsigned char data[], const std::size_t& count) - { - for (std::size_t i = 0; i < count; ++i) - { - update_1byte(data[i]); - } - } - - void update(const char data[], const std::size_t& count) - { - for (std::size_t i = 0; i < count; ++i) - { - update_1byte(static_cast(data[i])); - } - } - - void update(const std::string& data) - { - for (std::size_t i = 0; i < data.size(); ++i) - { - update_1byte(static_cast(data[i])); - } - } - - void update(const std::size_t& data) - { - update_1byte(static_cast((data ) & 0xFF)); - update_1byte(static_cast((data >> 8) & 0xFF)); - update_1byte(static_cast((data >> 16) & 0xFF)); - update_1byte(static_cast((data >> 24) & 0xFF)); - } - - }; - -} // namespace schifra - - -#endif diff --git a/modem/fec/schifra_ecc_traits.hpp b/modem/fec/schifra_ecc_traits.hpp deleted file mode 100644 index 879d056..0000000 --- a/modem/fec/schifra_ecc_traits.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_ECC_TRAITS_HPP -#define INCLUDE_SCHIFRA_ECC_TRAITS_HPP - - -namespace schifra -{ - namespace traits - { - - template struct symbol; - /* bits per symbol */ - template <> struct symbol< 3> { enum {size = 2}; }; - template <> struct symbol< 7> { enum {size = 3}; }; - template <> struct symbol< 15> { enum {size = 4}; }; - template <> struct symbol< 31> { enum {size = 5}; }; - template <> struct symbol< 63> { enum {size = 6}; }; - template <> struct symbol< 127> { enum {size = 7}; }; - template <> struct symbol< 255> { enum {size = 8}; }; - template <> struct symbol< 511> { enum {size = 9}; }; - template <> struct symbol< 1023> { enum {size = 10}; }; - template <> struct symbol< 2047> { enum {size = 11}; }; - template <> struct symbol< 4195> { enum {size = 12}; }; - template <> struct symbol< 8191> { enum {size = 13}; }; - template <> struct symbol<16383> { enum {size = 14}; }; - template <> struct symbol<32768> { enum {size = 15}; }; - template <> struct symbol<65535> { enum {size = 16}; }; - - /* Credits: Modern C++ Design - Andrei Alexandrescu */ - template class __static_assert__ - { - public: - - __static_assert__(...) {} - }; - - template <> class __static_assert__ {}; - template <> class __static_assert__; - - template - struct validate_reed_solomon_code_parameters - { - private: - - __static_assert__<(code_length > 0)> assertion1; - __static_assert__<(code_length > fec_length)> assertion2; - __static_assert__<(code_length > data_length)> assertion3; - __static_assert__<(code_length == fec_length + data_length)> assertion4; - }; - - template - struct validate_reed_solomon_block_parameters - { - private: - - __static_assert__<(code_length > 0)> assertion1; - __static_assert__<(code_length > fec_length)> assertion2; - __static_assert__<(code_length > data_length)> assertion3; - __static_assert__<(code_length == fec_length + data_length)> assertion4; - }; - - template - struct equivalent_encoder_decoder - { - private: - - __static_assert__<(Encoder::trait::code_length == Decoder::trait::code_length)> assertion1; - __static_assert__<(Encoder::trait::fec_length == Decoder::trait::fec_length) > assertion2; - __static_assert__<(Encoder::trait::data_length == Decoder::trait::data_length)> assertion3; - }; - - template - class reed_solomon_triat - { - public: - - typedef validate_reed_solomon_code_parameters vrscp; - - enum { code_length = code_length_ }; - enum { fec_length = fec_length_ }; - enum { data_length = data_length_ }; - }; - - } - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_erasure_channel.hpp b/modem/fec/schifra_erasure_channel.hpp deleted file mode 100644 index 194107a..0000000 --- a/modem/fec/schifra_erasure_channel.hpp +++ /dev/null @@ -1,256 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_ERASURE_CHANNEL_HPP -#define INCLUDE_SCHIFRA_ERASURE_CHANNEL_HPP - - -#include "schifra_reed_solomon_block.hpp" -#include "schifra_reed_solomon_encoder.hpp" -#include "schifra_reed_solomon_decoder.hpp" -#include "schifra_reed_solomon_interleaving.hpp" -#include "schifra_utilities.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template - inline void interleaved_stack_erasure_mapper(const std::vector& missing_row_index, - std::vector& erasure_row_list) - { - erasure_row_list.resize(block_length); - - for (std::size_t i = 0; i < block_length; ++i) - { - erasure_row_list[i].reserve(fec_length); - } - - for (std::size_t i = 0; i < missing_row_index.size(); ++i) - { - for (std::size_t j = 0; j < block_length; ++j) - { - erasure_row_list[j].push_back(missing_row_index[i]); - } - } - } - - template - inline bool erasure_channel_stack_encode(const encoder& encoder, - block (&output)[code_length]) - { - for (std::size_t i = 0; i < code_length; ++i) - { - if (!encoder.encode(output[i])) - { - std::cout << "erasure_channel_stack_encode() - Error: Failed to encode block[" << i <<"]" << std::endl; - - return false; - } - } - - interleave(output); - - return true; - } - - template - class erasure_code_decoder : public decoder - { - public: - - typedef decoder decoder_type; - typedef typename decoder_type::block_type block_type; - typedef std::vector polynomial_list_type; - - erasure_code_decoder(const galois::field& gfield, - const unsigned int& gen_initial_index) - : decoder(gfield, gen_initial_index) - { - for (std::size_t i = 0; i < code_length; ++i) - { - received_.push_back(galois::field_polynomial(decoder_type::field_, code_length - 1)); - syndrome_.push_back(galois::field_polynomial(decoder_type::field_)); - } - }; - - bool decode(block_type rsblock[code_length], const erasure_locations_t& erasure_list) const - { - if ( - (!decoder_type::decoder_valid_) || - (erasure_list.size() != fec_length) - ) - { - return false; - } - - for (std::size_t i = 0; i < code_length; ++i) - { - decoder_type::load_message (received_[i], rsblock [i]); - decoder_type::compute_syndrome(received_[i], syndrome_[i]); - } - - erasure_locations_t erasure_locations; - decoder_type::prepare_erasure_list(erasure_locations,erasure_list); - - galois::field_polynomial gamma(galois::field_element(decoder_type::field_, 1)); - - decoder_type::compute_gamma(gamma,erasure_locations); - - std::vector gamma_roots; - - find_roots_in_data(gamma,gamma_roots); - - polynomial_list_type omega; - - for (std::size_t i = 0; i < code_length; ++i) - { - omega.push_back((gamma * syndrome_[i]) % fec_length); - } - - galois::field_polynomial gamma_derivative = gamma.derivative(); - - for (std::size_t i = 0; i < gamma_roots.size(); ++i) - { - int error_location = static_cast(gamma_roots[i]); - galois::field_symbol alpha_inverse = decoder_type::field_.alpha(error_location); - galois::field_element denominator = gamma_derivative(alpha_inverse); - - if (denominator == 0) - { - return false; - } - - for (std::size_t j = 0; j < code_length; ++j) - { - galois::field_element numerator = (omega[j](alpha_inverse) * decoder_type::root_exponent_table_[error_location]); - /* - A minor optimization can be made in the event the - numerator is equal to zero by not executing the - following line. - */ - rsblock[j][error_location - 1] ^= decoder_type::field_.div(numerator.poly(),denominator.poly()); - } - } - - return true; - } - - private: - - void find_roots_in_data(const galois::field_polynomial& poly, std::vector& root_list) const - { - /* - Chien Search, as described in parent, but only - for locations within the data range of the message. - */ - root_list.reserve(fec_length << 1); - root_list.resize(0); - - std::size_t polynomial_degree = poly.deg(); - std::size_t root_list_size = 0; - - for (int i = 1; i <= static_cast(data_length); ++i) - { - if (0 == poly(decoder_type::field_.alpha(i)).poly()) - { - root_list.push_back(i); - root_list_size++; - - if (root_list_size == polynomial_degree) - { - break; - } - } - } - } - - mutable polynomial_list_type received_; - mutable polynomial_list_type syndrome_; - - }; - - template - inline bool erasure_channel_stack_decode(const decoder& general_decoder, - const erasure_locations_t& missing_row_index, - block (&output)[code_length]) - { - if (missing_row_index.empty()) - { - return true; - } - - interleave(output); - - for (std::size_t i = 0; i < code_length; ++i) - { - if (!general_decoder.decode(output[i],missing_row_index)) - { - std::cout << "[2] erasure_channel_stack_decode() - Error: Failed to decode block[" << i <<"]" << std::endl; - - return false; - } - } - - return true; - } - - template - inline bool erasure_channel_stack_decode(const erasure_code_decoder& erasure_decoder, - const erasure_locations_t& missing_row_index, - block (&output)[code_length]) - { - /* - Note: 1. Missing row indicies must be unique. - 2. Missing row indicies must exist within - the stack's size. - 3. There will be NO errors in the rows (aka output) - 4. The information members of the blocks will - not be utilized. - There are NO exceptions to these rules! - */ - if (missing_row_index.empty()) - { - return true; - } - else if (missing_row_index.size() == fec_length) - { - interleave(output); - - return erasure_decoder.decode(output,missing_row_index); - } - else - return erasure_channel_stack_decode( - static_cast&>(erasure_decoder), - missing_row_index, - output); - } - - } // namespace reed_solomon - -} // namepsace schifra - - -#endif diff --git a/modem/fec/schifra_error_processes.hpp b/modem/fec/schifra_error_processes.hpp deleted file mode 100644 index d2f61fe..0000000 --- a/modem/fec/schifra_error_processes.hpp +++ /dev/null @@ -1,602 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_ERROR_PROCESSES_HPP -#define INCLUDE_SCHIFRA_ERROR_PROCESSES_HPP - - -#include -#include -#include -#include -#include -#include - -#include "schifra_reed_solomon_block.hpp" -#include "schifra_fileio.hpp" - - -namespace schifra -{ - - template - inline void add_erasure_error(const std::size_t& position, reed_solomon::block& block) - { - block[position] = (~block[position]) & 0xFF; // Or one can simply equate to zero - } - - template - inline void add_error(const std::size_t& position, reed_solomon::block& block) - { - block[position] = (~block[position]) & 0xFF; - } - - template - inline void add_error_4bit_symbol(const std::size_t& position, reed_solomon::block& block) - { - block[position] = (~block[position]) & 0x0F; - } - - template - inline void corrupt_message_all_errors00(reed_solomon::block& rsblock, - const std::size_t& start_position, - const std::size_t& scale = 1) - { - for (std::size_t i = 0; i < (fec_length >> 1); ++i) - { - add_error((start_position + scale * i) % code_length,rsblock); - } - } - - template - inline void corrupt_message_all_errors_wth_mask(reed_solomon::block& rsblock, - const std::size_t& start_position, - const int& mask, - const std::size_t& scale = 1) - { - for (std::size_t i = 0; i < (fec_length >> 1); ++i) - { - std::size_t position = (start_position + scale * i) % code_length; - rsblock[position] = (~rsblock[position]) & mask; - - } - } - - template - inline void corrupt_message_all_errors(schifra::reed_solomon::block& rsblock, - const std::size_t error_count, - const std::size_t& start_position, - const std::size_t& scale = 1) - { - for (std::size_t i = 0; i < error_count; ++i) - { - add_error((start_position + scale * i) % code_length,rsblock); - } - } - - template - inline void corrupt_message_all_erasures00(reed_solomon::block& rsblock, - reed_solomon::erasure_locations_t& erasure_list, - const std::size_t& start_position, - const std::size_t& scale = 1) - { - std::size_t erasures[code_length]; - - for (std::size_t i = 0; i < code_length; ++i) erasures[i] = 0; - - for (std::size_t i = 0; i < fec_length; ++i) - { - std::size_t error_position = (start_position + scale * i) % code_length; - add_erasure_error(error_position,rsblock); - erasures[error_position] = 1; - } - - for (std::size_t i = 0; i < code_length; ++i) - { - if (erasures[i] == 1) erasure_list.push_back(i); - } - } - - template - inline void corrupt_message_all_erasures(reed_solomon::block& rsblock, - reed_solomon::erasure_locations_t& erasure_list, - const std::size_t erasure_count, - const std::size_t& start_position, - const std::size_t& scale = 1) - { - std::size_t erasures[code_length]; - - for (std::size_t i = 0; i < code_length; ++i) erasures[i] = 0; - - for (std::size_t i = 0; i < erasure_count; ++i) - { - /* Note: Must make sure duplicate erasures are not added */ - std::size_t error_position = (start_position + scale * i) % code_length; - add_erasure_error(error_position,rsblock); - erasures[error_position] = 1; - } - - for (std::size_t i = 0; i < code_length; ++i) - { - if (erasures[i] == 1) erasure_list.push_back(i); - } - } - - namespace error_mode - { - enum type - { - errors_erasures, // Errors first then erasures - erasures_errors // Erasures first then errors - }; - } - - template - inline void corrupt_message_errors_erasures(reed_solomon::block& rsblock, - const error_mode::type& mode, - const std::size_t& start_position, - const std::size_t& erasure_count, - reed_solomon::erasure_locations_t& erasure_list, - const std::size_t between_space = 0) - { - std::size_t error_count = (fec_length - erasure_count) >> 1; - - if ((2 * error_count) + erasure_count > fec_length) - { - std::cout << "corrupt_message_errors_erasures() - ERROR Too many erasures and errors!" << std::endl; - std::cout << "Error Count: " << error_count << std::endl; - std::cout << "Erasure Count: " << error_count << std::endl; - - return; - } - - std::size_t erasures[code_length]; - - for (std::size_t i = 0; i < code_length; ++i) erasures[i] = 0; - - std::size_t error_position = 0; - - switch (mode) - { - case error_mode::erasures_errors : { - for (std::size_t i = 0; i < erasure_count; ++i) - { - error_position = (start_position + i) % code_length; - add_erasure_error(error_position,rsblock); - erasures[error_position] = 1; - } - - for (std::size_t i = 0; i < error_count; ++i) - { - error_position = (start_position + erasure_count + between_space + i) % code_length; - add_error(error_position,rsblock); - } - } - break; - - case error_mode::errors_erasures : { - for (std::size_t i = 0; i < error_count; ++i) - { - error_position = (start_position + i) % code_length; - add_error(error_position,rsblock); - } - - for (std::size_t i = 0; i < erasure_count; ++i) - { - error_position = (start_position + error_count + between_space + i) % code_length; - add_erasure_error(error_position,rsblock); - erasures[error_position] = 1; - } - } - break; - } - - for (std::size_t i = 0; i < code_length; ++i) - { - if (erasures[i] == 1) erasure_list.push_back(i); - } - - } - - template - inline void corrupt_message_interleaved_errors_erasures(reed_solomon::block& rsblock, - const std::size_t& start_position, - const std::size_t& erasure_count, - reed_solomon::erasure_locations_t& erasure_list) - { - std::size_t error_count = (fec_length - erasure_count) >> 1; - - if ((2 * error_count) + erasure_count > fec_length) - { - std::cout << "corrupt_message_interleaved_errors_erasures() - [1] ERROR Too many erasures and errors!" << std::endl; - std::cout << "Error Count: " << error_count << std::endl; - std::cout << "Erasure Count: " << error_count << std::endl; - - return; - } - - std::size_t erasures[code_length]; - - for (std::size_t i = 0; i < code_length; ++i) erasures[i] = 0; - - std::size_t e = 0; - std::size_t s = 0; - std::size_t i = 0; - - while ((e < error_count) || (s < erasure_count) || (i < (error_count + erasure_count))) - { - std::size_t error_position = (start_position + i) % code_length; - - if (((i & 0x01) == 0) && (s < erasure_count)) - { - add_erasure_error(error_position,rsblock); - erasures[error_position] = 1; - s++; - } - else if (((i & 0x01) == 1) && (e < error_count)) - { - e++; - add_error(error_position,rsblock); - } - ++i; - } - - for (std::size_t j = 0; j < code_length; ++j) - { - if (erasures[j] == 1) erasure_list.push_back(j); - } - - if ((2 * e) + erasure_list.size() > fec_length) - { - std::cout << "corrupt_message_interleaved_errors_erasures() - [2] ERROR Too many erasures and errors!" << std::endl; - std::cout << "Error Count: " << error_count << std::endl; - std::cout << "Erasure Count: " << error_count << std::endl; - - return; - } - } - - namespace details - { - template - struct corrupt_message_all_errors_segmented_impl - { - static void process(reed_solomon::block& rsblock, - const std::size_t& start_position, - const std::size_t& distance_between_blocks = 1) - { - std::size_t block_1_error_count = (fec_length >> 2); - std::size_t block_2_error_count = (fec_length >> 1) - block_1_error_count; - - for (std::size_t i = 0; i < block_1_error_count; ++i) - { - add_error((start_position + i) % code_length,rsblock); - } - - std::size_t new_start_position = (start_position + (block_1_error_count)) + distance_between_blocks; - - for (std::size_t i = 0; i < block_2_error_count; ++i) - { - add_error((new_start_position + i) % code_length,rsblock); - } - } - }; - - template - struct corrupt_message_all_errors_segmented_impl - { - static void process(reed_solomon::block&, - const std::size_t&, const std::size_t&) - {} - }; - } - - template - inline void corrupt_message_all_errors_segmented(reed_solomon::block& rsblock, - const std::size_t& start_position, - const std::size_t& distance_between_blocks = 1) - { - details::corrupt_message_all_errors_segmented_impl 2)>:: - process(rsblock,start_position,distance_between_blocks); - } - - inline bool check_for_duplicate_erasures(const std::vector& erasure_list) - { - for (std::size_t i = 0; i < erasure_list.size(); ++i) - { - for (std::size_t j = i + 1; j < erasure_list.size(); ++j) - { - if (erasure_list[i] == erasure_list[j]) - { - return false; - } - } - } - - return true; - } - - inline void dump_erasure_list(const schifra::reed_solomon::erasure_locations_t& erasure_list) - { - for (std::size_t i = 0; i < erasure_list.size(); ++i) - { - std::cout << "[" << i << "," << erasure_list[i] << "] "; - } - - std::cout << std::endl; - } - - template - inline bool is_block_equivelent(const reed_solomon::block& rsblock, - const std::string& data, - const bool display = false, - const bool all_errors = false) - { - std::string::const_iterator it = data.begin(); - - bool error_found = false; - - for (std::size_t i = 0; i < code_length - fec_length; ++i, ++it) - { - if (static_cast(rsblock.data[i] & 0xFF) != (*it)) - { - error_found = true; - - if (display) - { - printf("is_block_equivelent() - Error at loc : %02d\td1: %02X\td2: %02X\n", - static_cast(i), - rsblock.data[i], - static_cast(*it)); - } - - if (!all_errors) - return false; - } - } - - return !error_found; - } - - template - inline bool are_blocks_equivelent(const reed_solomon::block& block1, - const reed_solomon::block& block2, - const std::size_t span = code_length, - const bool display = false, - const bool all_errors = false) - { - bool error_found = false; - - for (std::size_t i = 0; i < span; ++i) - { - if (block1[i] != block2[i]) - { - error_found = true; - - if (display) - { - printf("are_blocks_equivelent() - Error at loc : %02d\td1: %04X\td2: %04X\n", - static_cast(i), - block1[i], - block2[i]); - } - - if (!all_errors) - return false; - } - } - - return !error_found; - } - - template - inline bool block_stacks_equivelent(const reed_solomon::block block_stack1[stack_size], - const reed_solomon::block block_stack2[stack_size]) - { - for (std::size_t i = 0; i < stack_size; ++i) - { - if (!are_blocks_equivelent(block_stack1[i],block_stack2[i])) - { - return false; - } - } - - return true; - } - - template - inline bool block_stacks_equivelent(const reed_solomon::data_block block_stack1[stack_size], - const reed_solomon::data_block block_stack2[stack_size]) - { - for (std::size_t i = 0; i < stack_size; ++i) - { - for (std::size_t j = 0; j < block_length; ++j) - { - if (block_stack1[i][j] != block_stack2[i][j]) - { - return false; - } - } - } - - return true; - } - - inline void corrupt_file_with_burst_errors(const std::string& file_name, - const long& start_position, - const long& burst_length) - { - if (!schifra::fileio::file_exists(file_name)) - { - std::cout << "corrupt_file() - Error: " << file_name << " does not exist!" << std::endl; - return; - } - - if (static_cast(start_position + burst_length) >= schifra::fileio::file_size(file_name)) - { - std::cout << "corrupt_file() - Error: Burst error out of bounds." << std::endl; - return; - } - - std::vector data(burst_length); - - std::ifstream ifile(file_name.c_str(), std::ios::in | std::ios::binary); - - if (!ifile) - { - return; - } - - ifile.seekg(start_position,std::ios_base::beg); - ifile.read(&data[0],burst_length); - ifile.close(); - - for (long i = 0; i < burst_length; ++i) - { - data[i] = ~data[i]; - } - - std::ofstream ofile(file_name.c_str(), std::ios::in | std::ios::out | std::ios::binary); - - if (!ofile) - { - return; - } - - ofile.seekp(start_position,std::ios_base::beg); - ofile.write(&data[0],burst_length); - ofile.close(); - } - - static const std::size_t global_random_error_index[] = - { - 13, 170, 148, 66, 228, 208, 182, 92, - 4, 137, 97, 99, 237, 151, 15, 0, - 119, 243, 41, 222, 33, 211, 188, 5, - 44, 30, 210, 111, 54, 79, 61, 223, - 239, 149, 73, 115, 201, 234, 194, 62, - 147, 70, 19, 49, 72, 52, 164, 29, - 102, 225, 203, 153, 18, 205, 40, 217, - 165, 177, 166, 134, 236, 68, 231, 154, - 116, 136, 47, 240, 46, 89, 120, 183, - 242, 28, 161, 226, 241, 230, 10, 131, - 207, 132, 83, 171, 202, 195, 227, 206, - 112, 88, 90, 146, 117, 180, 26, 78, - 118, 254, 107, 110, 220, 7, 192, 187, - 31, 175, 127, 209, 32, 12, 84, 128, - 190, 156, 95, 105, 104, 246, 91, 215, - 219, 142, 36, 186, 247, 233, 167, 133, - 160, 16, 140, 169, 23, 96, 155, 235, - 179, 76, 253, 103, 238, 67, 35, 121, - 100, 27, 213, 58, 77, 248, 174, 39, - 214, 56, 42, 200, 106, 21, 129, 114, - 252, 113, 168, 53, 25, 216, 64, 232, - 81, 75, 2, 224, 250, 60, 135, 204, - 48, 196, 94, 63, 244, 191, 93, 126, - 138, 159, 9, 85, 249, 34, 185, 163, - 17, 65, 184, 82, 109, 172, 108, 69, - 150, 3, 20, 221, 162, 212, 152, 59, - 198, 74, 229, 55, 87, 178, 141, 199, - 57, 130, 80, 173, 101, 122, 144, 51, - 139, 11, 8, 125, 158, 124, 123, 37, - 14, 24, 22, 43, 197, 50, 98, 6, - 176, 251, 86, 218, 193, 71, 145, 1, - 45, 38, 189, 143, 245, 157, 181 - }; - - static const std::size_t error_index_size = sizeof(global_random_error_index) / sizeof(std::size_t); - - template - inline void corrupt_message_all_errors_at_index(schifra::reed_solomon::block& rsblock, - const std::size_t error_count, - const std::size_t& error_index_start_position, - const bool display_positions = false) - { - schifra::reed_solomon::block tmp_rsblock = rsblock; - - for (std::size_t i = 0; i < error_count; ++i) - { - std::size_t error_position = (global_random_error_index[(error_index_start_position + i) % error_index_size]) % code_length; - - add_error(error_position,rsblock); - - if (display_positions) - { - std::cout << "Error index: " << error_position << std::endl; - } - } - } - - template - inline void corrupt_message_all_errors_at_index(schifra::reed_solomon::block& rsblock, - const std::size_t error_count, - const std::size_t& error_index_start_position, - const std::vector& random_error_index, - const bool display_positions = false) - { - for (std::size_t i = 0; i < error_count; ++i) - { - std::size_t error_position = (random_error_index[(error_index_start_position + i) % random_error_index.size()]) % code_length; - - add_error(error_position,rsblock); - - if (display_positions) - { - std::cout << "Error index: " << error_position << std::endl; - } - } - } - - inline void generate_error_index(const std::size_t index_size, - std::vector& random_error_index, - std::size_t seed) - { - if (0 == seed) - { - seed = 0xA5A5A5A5; - } - - ::srand(static_cast(seed)); - - std::deque index_list; - - for (std::size_t i = 0; i < index_size; ++i) - { - index_list.push_back(i); - } - - random_error_index.reserve(index_size); - random_error_index.resize(0); - - while (!index_list.empty()) - { - // possibly the worst way of doing this. - std::size_t index = ::rand() % index_list.size(); - - random_error_index.push_back(index_list[index]); - index_list.erase(index_list.begin() + index); - } - } - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_fileio.hpp b/modem/fec/schifra_fileio.hpp deleted file mode 100644 index 00443a1..0000000 --- a/modem/fec/schifra_fileio.hpp +++ /dev/null @@ -1,227 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_FILEIO_HPP -#define INCLUDE_SCHIFRA_FILEIO_HPP - - -#include -#include -#include -#include -#include - -#include "schifra_crc.hpp" - - -namespace schifra -{ - - namespace fileio - { - - inline void read_into_vector(const std::string& file_name, std::vector& buffer) - { - std::ifstream file(file_name.c_str()); - if (!file) return; - std::string line; - while (std::getline(file,line)) - { - buffer.push_back(line); - } - file.close(); - } - - inline void write_from_vector(const std::string& file_name, const std::vector& buffer) - { - std::ofstream file(file_name.c_str()); - if (!file) return; - std::ostream_iterator os(file,"\n"); - std::copy(buffer.begin(),buffer.end(), os); - file.close(); - } - - inline bool file_exists(const std::string& file_name) - { - std::ifstream file(file_name.c_str(), std::ios::binary); - return ((!file) ? false : true); - } - - inline std::size_t file_size(const std::string& file_name) - { - std::ifstream file(file_name.c_str(),std::ios::binary); - if (!file) return 0; - file.seekg (0, std::ios::end); - return static_cast(file.tellg()); - } - - inline void load_file(const std::string& file_name, std::string& buffer) - { - std::ifstream file(file_name.c_str(), std::ios::binary); - if (!file) return; - buffer.assign(std::istreambuf_iterator(file),std::istreambuf_iterator()); - file.close(); - } - - inline void load_file(const std::string& file_name, char** buffer, std::size_t& buffer_size) - { - std::ifstream in_stream(file_name.c_str(),std::ios::binary); - if (!in_stream) return; - buffer_size = file_size(file_name); - *buffer = new char[buffer_size]; - in_stream.read(*buffer,static_cast(buffer_size)); - in_stream.close(); - } - - inline void write_file(const std::string& file_name, const std::string& buffer) - { - std::ofstream file(file_name.c_str(),std::ios::binary); - file << buffer; - file.close(); - } - - inline void write_file(const std::string& file_name, char* buffer, const std::size_t& buffer_size) - { - std::ofstream out_stream(file_name.c_str(),std::ios::binary); - if (!out_stream) return; - out_stream.write(buffer,static_cast(buffer_size)); - out_stream.close(); - } - - inline bool copy_file(const std::string& src_file_name, const std::string& dest_file_name) - { - std::ifstream src_file(src_file_name.c_str(),std::ios::binary); - std::ofstream dest_file(dest_file_name.c_str(),std::ios::binary); - if (!src_file) return false; - if (!dest_file) return false; - - const std::size_t block_size = 1024; - char buffer[block_size]; - - std::size_t remaining_bytes = file_size(src_file_name); - - while (remaining_bytes >= block_size) - { - src_file.read(&buffer[0],static_cast(block_size)); - dest_file.write(&buffer[0],static_cast(block_size)); - remaining_bytes -= block_size; - } - - if (remaining_bytes > 0) - { - src_file.read(&buffer[0],static_cast(remaining_bytes)); - dest_file.write(&buffer[0],static_cast(remaining_bytes)); - remaining_bytes = 0; - } - - src_file.close(); - dest_file.close(); - - return true; - } - - inline bool files_identical(const std::string& file_name1, const std::string& file_name2) - { - std::ifstream file1(file_name1.c_str(),std::ios::binary); - std::ifstream file2(file_name2.c_str(),std::ios::binary); - if (!file1) return false; - if (!file2) return false; - if (file_size(file_name1) != file_size(file_name2)) return false; - - const std::size_t block_size = 1024; - char buffer1[block_size]; - char buffer2[block_size]; - - std::size_t remaining_bytes = file_size(file_name1); - - while (remaining_bytes >= block_size) - { - file1.read(&buffer1[0],static_cast(block_size)); - file2.read(&buffer2[0],static_cast(block_size)); - - for (std::size_t i = 0; i < block_size; ++i) - { - if (buffer1[i] != buffer2[i]) - { - return false; - } - } - - remaining_bytes -= block_size; - } - - if (remaining_bytes > 0) - { - file1.read(&buffer1[0],static_cast(remaining_bytes)); - file2.read(&buffer2[0],static_cast(remaining_bytes)); - - for (std::size_t i = 0; i < remaining_bytes; ++i) - { - if (buffer1[i] != buffer2[i]) - { - return false; - } - } - - remaining_bytes = 0; - } - - file1.close(); - file2.close(); - - return true; - } - - inline std::size_t file_crc(crc32& crc_module, const std::string& file_name) - { - std::ifstream file(file_name.c_str(),std::ios::binary); - if (!file) return 0; - - const std::size_t block_size = 1024; - char buffer[block_size]; - - std::size_t remaining_bytes = file_size(file_name); - - crc_module.reset(); - - while (remaining_bytes >= block_size) - { - file.read(&buffer[0],static_cast(block_size)); - crc_module.update(buffer,block_size); - remaining_bytes -= block_size; - } - - if (remaining_bytes > 0) - { - file.read(&buffer[0],static_cast(remaining_bytes)); - crc_module.update(buffer,remaining_bytes); - remaining_bytes = 0; - } - - return crc_module.crc(); - } - - } // namespace fileio - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_galois_field.hpp b/modem/fec/schifra_galois_field.hpp deleted file mode 100644 index ec7ee3a..0000000 --- a/modem/fec/schifra_galois_field.hpp +++ /dev/null @@ -1,518 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_GALOIS_FIELD_HPP -#define INCLUDE_SCHIFRA_GALOIS_FIELD_HPP - - -#include -#include -#include -#include -#include - - -namespace schifra -{ - - namespace galois - { - - typedef int field_symbol; - const field_symbol GFERROR = -1; - - class field - { - public: - - field(const int pwr, const std::size_t primpoly_deg, const unsigned int* primitive_poly); - ~field(); - - bool operator==(const field& gf) const; - bool operator!=(const field& gf) const; - - inline field_symbol index(const field_symbol value) const - { - return index_of_[value]; - } - - inline field_symbol alpha(const field_symbol value) const - { - return alpha_to_[value]; - } - - inline unsigned int size() const - { - return field_size_; - } - - inline unsigned int pwr() const - { - return power_; - } - - inline unsigned int mask() const - { - return field_size_; - } - - inline field_symbol add(const field_symbol& a, const field_symbol& b) const - { - return (a ^ b); - } - - inline field_symbol sub(const field_symbol& a, const field_symbol& b) const - { - return (a ^ b); - } - - inline field_symbol normalize(field_symbol x) const - { - while (x < 0) - { - x += static_cast(field_size_); - } - - while (x >= static_cast(field_size_)) - { - x -= static_cast(field_size_); - x = (x >> power_) + (x & field_size_); - } - - return x; - } - - inline field_symbol mul(const field_symbol& a, const field_symbol& b) const - { - #if !defined(NO_GFLUT) - return mul_table_[a][b]; - #else - if ((a == 0) || (b == 0)) - return 0; - else - return alpha_to_[normalize(index_of_[a] + index_of_[b])]; - #endif - } - - inline field_symbol div(const field_symbol& a, const field_symbol& b) const - { - #if !defined(NO_GFLUT) - return div_table_[a][b]; - #else - if ((a == 0) || (b == 0)) - return 0; - else - return alpha_to_[normalize(index_of_[a] - index_of_[b] + field_size_)]; - #endif - } - - inline field_symbol exp(const field_symbol& a, int n) const - { - #if !defined(NO_GFLUT) - if (n >= 0) - return exp_table_[a][n & field_size_]; - else - { - while (n < 0) n += field_size_; - - return (n ? exp_table_[a][n] : 1); - } - #else - if (a != 0) - { - if (n < 0) - { - while (n < 0) n += field_size_; - return (n ? alpha_to_[normalize(index_of_[a] * n)] : 1); - } - else if (n) - return alpha_to_[normalize(index_of_[a] * static_cast(n))]; - else - return 1; - } - else - return 0; - #endif - } - - #ifdef LINEAR_EXP_LUT - inline field_symbol* const linear_exp(const field_symbol& a) const - { - #if !defined(NO_GFLUT) - static const field_symbol upper_bound = 2 * field_size_; - if ((a >= 0) && (a <= upper_bound)) - return linear_exp_table_[a]; - else - return reinterpret_cast(0); - #else - return reinterpret_cast(0); - #endif - } - #endif - - inline field_symbol inverse(const field_symbol& val) const - { - #if !defined(NO_GFLUT) - return mul_inverse_[val]; - #else - return alpha_to_[normalize(field_size_ - index_of_[val])]; - #endif - } - - inline unsigned int prim_poly_term(const unsigned int index) const - { - return prim_poly_[index]; - } - - friend std::ostream& operator << (std::ostream& os, const field& gf); - - private: - - field(); - field(const field& gfield); - field& operator=(const field& gfield); - - void generate_field(const unsigned int* prim_poly_); - field_symbol gen_mul (const field_symbol& a, const field_symbol& b) const; - field_symbol gen_div (const field_symbol& a, const field_symbol& b) const; - field_symbol gen_exp (const field_symbol& a, const std::size_t& n) const; - field_symbol gen_inverse (const field_symbol& val) const; - - std::size_t create_array(char buffer_[], - const std::size_t& length, - const std::size_t offset, - field_symbol** array); - - std::size_t create_2d_array(char buffer_[], - std::size_t row_cnt, std::size_t col_cnt, - const std::size_t offset, - field_symbol*** array); - unsigned int power_; - std::size_t prim_poly_deg_; - unsigned int field_size_; - unsigned int prim_poly_hash_; - unsigned int* prim_poly_; - field_symbol* alpha_to_; // aka exponential or anti-log - field_symbol* index_of_; // aka log - field_symbol* mul_inverse_; // multiplicative inverse - field_symbol** mul_table_; - field_symbol** div_table_; - field_symbol** exp_table_; - field_symbol** linear_exp_table_; - char* buffer_; - }; - - inline field::field(const int pwr, const std::size_t primpoly_deg, const unsigned int* primitive_poly) - : power_(pwr), - prim_poly_deg_(primpoly_deg), - field_size_((1 << power_) - 1) - { - alpha_to_ = new field_symbol [field_size_ + 1]; - index_of_ = new field_symbol [field_size_ + 1]; - - #if !defined(NO_GFLUT) - - #ifdef LINEAR_EXP_LUT - static const std::size_t buffer_size = ((6 * (field_size_ + 1) * (field_size_ + 1)) + ((field_size_ + 1) * 2)) * sizeof(field_symbol); - #else - static const std::size_t buffer_size = ((4 * (field_size_ + 1) * (field_size_ + 1)) + ((field_size_ + 1) * 2)) * sizeof(field_symbol); - #endif - - buffer_ = new char[buffer_size]; - std::size_t offset = 0; - offset = create_2d_array(buffer_,(field_size_ + 1),(field_size_ + 1),offset,&mul_table_); - offset = create_2d_array(buffer_,(field_size_ + 1),(field_size_ + 1),offset,&div_table_); - offset = create_2d_array(buffer_,(field_size_ + 1),(field_size_ + 1),offset,&exp_table_); - - #ifdef LINEAR_EXP_LUT - offset = create_2d_array(buffer_,(field_size_ + 1),(field_size_ + 1) * 2,offset,&linear_exp_table_); - #else - linear_exp_table_ = 0; - #endif - - offset = create_array(buffer_,(field_size_ + 1) * 2,offset,&mul_inverse_); - - #else - - buffer_ = 0; - mul_table_ = 0; - div_table_ = 0; - exp_table_ = 0; - mul_inverse_ = 0; - linear_exp_table_ = 0; - - #endif - - prim_poly_ = new unsigned int [prim_poly_deg_ + 1]; - - for (unsigned int i = 0; i < (prim_poly_deg_ + 1); ++i) - { - prim_poly_[i] = primitive_poly[i]; - } - - prim_poly_hash_ = 0xAAAAAAAA; - - for (std::size_t i = 0; i < (prim_poly_deg_ + 1); ++i) - { - prim_poly_hash_ += ((i & 1) == 0) ? ( (prim_poly_hash_ << 7) ^ primitive_poly[i] * (prim_poly_hash_ >> 3)) : - (~((prim_poly_hash_ << 11) + (primitive_poly[i] ^ (prim_poly_hash_ >> 5)))); - } - - generate_field(primitive_poly); - } - - inline field::~field() - { - if (0 != alpha_to_) { delete [] alpha_to_; alpha_to_ = 0; } - if (0 != index_of_) { delete [] index_of_; index_of_ = 0; } - if (0 != prim_poly_) { delete [] prim_poly_; prim_poly_ = 0; } - - #if !defined(NO_GFLUT) - - if (0 != mul_table_) { delete [] mul_table_; mul_table_ = 0; } - if (0 != div_table_) { delete [] div_table_; div_table_ = 0; } - if (0 != exp_table_) { delete [] exp_table_; exp_table_ = 0; } - - #ifdef LINEAR_EXP_LUT - if (0 != linear_exp_table_) { delete [] linear_exp_table_; linear_exp_table_ = 0; } - #endif - - if (0 != buffer_) { delete [] buffer_; buffer_ = 0; } - - #endif - } - - inline bool field::operator==(const field& gf) const - { - return ( - (this->power_ == gf.power_) && - (this->prim_poly_hash_ == gf.prim_poly_hash_) - ); - } - - inline bool field::operator!=(const field& gf) const - { - return !field::operator ==(gf); - } - - inline void field::generate_field(const unsigned int* prim_poly) - { - /* - Note: It is assumed that the degree of the primitive - polynomial will be equivelent to the m value as - in GF(2^m) - */ - - field_symbol mask = 1; - - alpha_to_[power_] = 0; - - for (field_symbol i = 0; i < static_cast(power_); ++i) - { - alpha_to_[i] = mask; - index_of_[alpha_to_[i]] = i; - - if (prim_poly[i] != 0) - { - alpha_to_[power_] ^= mask; - } - - mask <<= 1; - } - - index_of_[alpha_to_[power_]] = power_; - - mask >>= 1; - - for (field_symbol i = power_ + 1; i < static_cast(field_size_); ++i) - { - if (alpha_to_[i - 1] >= mask) - alpha_to_[i] = alpha_to_[power_] ^ ((alpha_to_[i - 1] ^ mask) << 1); - else - alpha_to_[i] = alpha_to_[i - 1] << 1; - - index_of_[alpha_to_[i]] = i; - } - - index_of_[0] = GFERROR; - alpha_to_[field_size_] = 1; - - #if !defined(NO_GFLUT) - - for (field_symbol i = 0; i < static_cast(field_size_ + 1); ++i) - { - for (field_symbol j = 0; j < static_cast(field_size_ + 1); ++j) - { - mul_table_[i][j] = gen_mul(i,j); - div_table_[i][j] = gen_div(i,j); - exp_table_[i][j] = gen_exp(i,j); - } - } - - #ifdef LINEAR_EXP_LUT - for (field_symbol i = 0; i < static_cast(field_size_ + 1); ++i) - { - for (int j = 0; j < static_cast(2 * field_size_); ++j) - { - linear_exp_table_[i][j] = gen_exp(i,j); - } - } - #endif - - for (field_symbol i = 0; i < static_cast(field_size_ + 1); ++i) - { - mul_inverse_[i] = gen_inverse(i); - mul_inverse_[i + (field_size_ + 1)] = mul_inverse_[i]; - } - - #endif - } - - inline field_symbol field::gen_mul(const field_symbol& a, const field_symbol& b) const - { - if ((a == 0) || (b == 0)) - return 0; - else - return alpha_to_[normalize(index_of_[a] + index_of_[b])]; - } - - inline field_symbol field::gen_div(const field_symbol& a, const field_symbol& b) const - { - if ((a == 0) || (b == 0)) - return 0; - else - return alpha_to_[normalize(index_of_[a] - index_of_[b] + field_size_)]; - } - - inline field_symbol field::gen_exp(const field_symbol& a, const std::size_t& n) const - { - if (a != 0) - return ((n == 0) ? 1 : alpha_to_[normalize(index_of_[a] * static_cast(n))]); - else - return 0; - } - - inline field_symbol field::gen_inverse(const field_symbol& val) const - { - return alpha_to_[normalize(field_size_ - index_of_[val])]; - } - - inline std::size_t field::create_array(char buffer[], - const std::size_t& length, - const std::size_t offset, - field_symbol** array) - { - const std::size_t row_size = length * sizeof(field_symbol); - (*array) = new(buffer + offset)field_symbol[length]; - return row_size + offset; - } - - inline std::size_t field::create_2d_array(char buffer[], - std::size_t row_cnt, std::size_t col_cnt, - const std::size_t offset, - field_symbol*** array) - { - const std::size_t row_size = col_cnt * sizeof(field_symbol); - char* buffer__offset = buffer + offset; - (*array) = new field_symbol* [row_cnt]; - for (std::size_t i = 0; i < row_cnt; ++i) - { - (*array)[i] = new(buffer__offset + (i * row_size))field_symbol[col_cnt]; - } - return (row_cnt * row_size) + offset; - } - - inline std::ostream& operator << (std::ostream& os, const field& gf) - { - for (std::size_t i = 0; i < (gf.field_size_ + 1); ++i) - { - os << i << "\t" << gf.alpha_to_[i] << "\t" << gf.index_of_[i] << std::endl; - } - - return os; - } - - /* 1x^0 + 1x^1 + 0x^2 + 1x^3 */ - const unsigned int primitive_polynomial00[] = {1, 1, 0, 1}; - const unsigned int primitive_polynomial_size00 = 4; - - /* 1x^0 + 1x^1 + 0x^2 + 0x^3 + 1x^4*/ - const unsigned int primitive_polynomial01[] = {1, 1, 0, 0, 1}; - const unsigned int primitive_polynomial_size01 = 5; - - /* 1x^0 + 0x^1 + 1x^2 + 0x^3 + 0x^4 + 1x^5 */ - const unsigned int primitive_polynomial02[] = {1, 0, 1, 0, 0, 1}; - const unsigned int primitive_polynomial_size02 = 6; - - /* 1x^0 + 1x^1 + 0x^2 + 0x^3 + 0x^4 + 0x^5 + 1x^6 */ - const unsigned int primitive_polynomial03[] = {1, 1, 0, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size03 = 7; - - /* 1x^0 + 0x^1 + 0x^2 + 1x^3 + 0x^4 + 0x^5 + 0x^6 + 1x^7 */ - const unsigned int primitive_polynomial04[] = {1, 0, 0, 1, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size04 = 8; - - /* 1x^0 + 0x^1 + 1x^2 + 1x^3 + 1x^4 + 0x^5 + 0x^6 + 0x^7 + 1x^8 */ - const unsigned int primitive_polynomial05[] = {1, 0, 1, 1, 1, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size05 = 9; - - /* 1x^0 + 1x^1 + 1x^2 + 0x^3 + 0x^4 + 0x^5 + 0x^6 + 1x^7 + 1x^8 */ - const unsigned int primitive_polynomial06[] = {1, 1, 1, 0, 0, 0, 0, 1, 1}; - const unsigned int primitive_polynomial_size06 = 9; - - /* 1x^0 + 0x^1 + 0x^2 + 0x^3 + 1x^4 + 0x^5 + 0x^6 + 0x^7 + 0x^8 + 1x^9 */ - const unsigned int primitive_polynomial07[] = {1, 0, 0, 0, 1, 0, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size07 = 10; - - /* 1x^0 + 0x^1 + 0x^2 + 1x^3 + 0x^4 + 0x^5 + 0x^6 + 0x^7 + 0x^8 + 0x^9 + 1x^10 */ - const unsigned int primitive_polynomial08[] = {1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size08 = 11; - - /* 1x^0 + 0x^1 + 1x^2 + 0x^3 + 0x^4 + 0x^5 + 0x^6 + 0x^7 + 0x^8 + 0x^9 + 0x^10 + 1x^11 */ - const unsigned int primitive_polynomial09[] = {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size09 = 12; - - /* 1x^0 + 1x^1 + 0x^2 + 0x^3 + 1x^4 + 0x^5 + 1x^6 + 0x^7 + 0x^8 + 0x^9 + 0x^10 + 0x^11 + 1x^12 */ - const unsigned int primitive_polynomial10[] = {1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size10 = 13; - - /* 1x^0 + 1x^1 + 0x^2 + 1x^3 + 1x^4 + 0x^5 + 0x^6 + 0x^7 + 0x^8 + 0x^9 + 0x^10 + 0x^11 + 0x^12 + 1x^13 */ - const unsigned int primitive_polynomial11[] = {1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size11 = 14; - - /* 1x^0 + 1x^1 + 0x^2 + 0x^3 + 0x^4 + 0x^5 + 1x^6 + 0x^7 + 0x^8 + 0x^9 + 1x^10 + 0x^11 + 0x^12 + 0x^13 + 1x^14 */ - const unsigned int primitive_polynomial12[] = {1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size12 = 15; - - /* 1x^0 + 1x^1 + 0x^2 + 0x^3 + 0x^4 + 0x^5 + 0x^6 + 0x^7 + 0x^8 + 0x^9 + 0x^10 + 0x^11 + 0x^12 + 0x^13 + 0x^14 + 1x^15 */ - const unsigned int primitive_polynomial13[] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size13 = 16; - - /* 1x^0 + 1x^1 + 0x^2 + 1x^3 + 0x^4 + 0x^5 + 0x^6 + 0x^7 + 0x^8 + 0x^9 + 0x^10 + 0x^11 + 1x^12 + 0x^13 + 0x^14 + 0x^15 + 1x^16 */ - const unsigned int primitive_polynomial14[] = {1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1}; - const unsigned int primitive_polynomial_size14 = 17; - - } // namespace galois - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_galois_field_element.hpp b/modem/fec/schifra_galois_field_element.hpp deleted file mode 100644 index e6aa89b..0000000 --- a/modem/fec/schifra_galois_field_element.hpp +++ /dev/null @@ -1,277 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_GALOIS_FIELD_ELEMENT_HPP -#define INCLUDE_SCHIFRA_GALOIS_FIELD_ELEMENT_HPP - - -#include -#include - -#include "schifra_galois_field.hpp" - - -namespace schifra -{ - - namespace galois - { - - class field_element - { - public: - - field_element(const field& gfield) - : field_(gfield), - poly_value_(-1) - {} - - field_element(const field& gfield,const field_symbol& v) - : field_(const_cast(gfield)), - poly_value_(v) - {} - - field_element(const field_element& gfe) - : field_(const_cast(gfe.field_)), - poly_value_(gfe.poly_value_) - {} - - ~field_element() - {} - - inline field_element& operator = (const field_element& gfe) - { - if ((this != &gfe) && (&field_ == &gfe.field_)) - { - poly_value_ = gfe.poly_value_; - } - - return *this; - } - - inline field_element& operator = (const field_symbol& v) - { - poly_value_ = v & field_.size(); - return *this; - } - - inline field_element& operator += (const field_element& gfe) - { - poly_value_ ^= gfe.poly_value_; - return *this; - } - - inline field_element& operator += (const field_symbol& v) - { - poly_value_ ^= v; - return *this; - } - - inline field_element& operator -= (const field_element& gfe) - { - *this += gfe; - return *this; - } - - inline field_element& operator -= (const field_symbol& v) - { - *this += v; - return *this; - } - - inline field_element& operator *= (const field_element& gfe) - { - poly_value_ = field_.mul(poly_value_, gfe.poly_value_); - return *this; - } - - inline field_element& operator *= (const field_symbol& v) - { - poly_value_ = field_.mul(poly_value_, v); - return *this; - } - - inline field_element& operator /= (const field_element& gfe) - { - poly_value_ = field_.div(poly_value_, gfe.poly_value_); - return *this; - } - - inline field_element& operator /= (const field_symbol& v) - { - poly_value_ = field_.div(poly_value_, v); - return *this; - } - - inline field_element& operator ^= (const int& n) - { - poly_value_ = field_.exp(poly_value_,n); - return *this; - } - - inline bool operator == (const field_element& gfe) const - { - return ((field_ == gfe.field_) && (poly_value_ == gfe.poly_value_)); - } - - inline bool operator == (const field_symbol& v) const - { - return (poly_value_ == v); - } - - inline bool operator != (const field_element& gfe) const - { - return ((field_ != gfe.field_) || (poly_value_ != gfe.poly_value_)); - } - - inline bool operator != (const field_symbol& v) const - { - return (poly_value_ != v); - } - - inline bool operator < (const field_element& gfe) - { - return (poly_value_ < gfe.poly_value_); - } - - inline bool operator < (const field_symbol& v) - { - return (poly_value_ < v); - } - - inline bool operator > (const field_element& gfe) - { - return (poly_value_ > gfe.poly_value_); - } - - inline bool operator > (const field_symbol& v) - { - return (poly_value_ > v); - } - - inline field_symbol index() const - { - return field_.index(poly_value_); - } - - inline field_symbol poly() const - { - return poly_value_; - } - - inline field_symbol& poly() - { - return poly_value_; - } - - inline const field& galois_field() const - { - return field_; - } - - inline field_symbol inverse() const - { - return field_.inverse(poly_value_); - } - - inline void normalize() - { - poly_value_ &= field_.size(); - } - - friend std::ostream& operator << (std::ostream& os, const field_element& gfe); - - private: - - const field& field_; - field_symbol poly_value_; - - }; - - inline field_element operator + (const field_element& a, const field_element& b); - inline field_element operator - (const field_element& a, const field_element& b); - inline field_element operator * (const field_element& a, const field_element& b); - inline field_element operator * (const field_element& a, const field_symbol& b); - inline field_element operator * (const field_symbol& a, const field_element& b); - inline field_element operator / (const field_element& a, const field_element& b); - inline field_element operator ^ (const field_element& a, const int& b); - - inline std::ostream& operator << (std::ostream& os, const field_element& gfe) - { - os << gfe.poly_value_; - return os; - } - - inline field_element operator + (const field_element& a, const field_element& b) - { - field_element result = a; - result += b; - return result; - } - - inline field_element operator - (const field_element& a, const field_element& b) - { - field_element result = a; - result -= b; - return result; - } - - inline field_element operator * (const field_element& a, const field_element& b) - { - field_element result = a; - result *= b; - return result; - } - - inline field_element operator * (const field_element& a, const field_symbol& b) - { - field_element result = a; - result *= b; - return result; - } - - inline field_element operator * (const field_symbol& a, const field_element& b) - { - field_element result = b; - result *= a; - return result; - } - - inline field_element operator / (const field_element& a, const field_element& b) - { - field_element result = a; - result /= b; - return result; - } - - inline field_element operator ^ (const field_element& a, const int& b) - { - field_element result = a; - result ^= b; - return result; - } - - } // namespace galois - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_galois_field_polynomial.hpp b/modem/fec/schifra_galois_field_polynomial.hpp deleted file mode 100644 index 63ff7d1..0000000 --- a/modem/fec/schifra_galois_field_polynomial.hpp +++ /dev/null @@ -1,839 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_GALOIS_FIELD_POLYNOMIAL_HPP -#define INCLUDE_SCHIFRA_GALOIS_FIELD_POLYNOMIAL_HPP - - -#include -#include -#include - -#include "schifra_galois_field.hpp" -#include "schifra_galois_field_element.hpp" - - -namespace schifra -{ - - namespace galois - { - - class field_polynomial - { - public: - - field_polynomial(const field& gfield); - field_polynomial(const field& gfield, const unsigned int& degree); - field_polynomial(const field& gfield, const unsigned int& degree, const field_element element[]); - field_polynomial(const field_polynomial& polynomial); - field_polynomial(const field_element& gfe); - ~field_polynomial() {} - - bool valid() const; - int deg() const; - const field& galois_field() const; - void set_degree(const unsigned int& x); - void simplify(); - - field_polynomial& operator = (const field_polynomial& polynomial); - field_polynomial& operator = (const field_element& element); - field_polynomial& operator += (const field_polynomial& element); - field_polynomial& operator += (const field_element& element); - field_polynomial& operator -= (const field_polynomial& element); - field_polynomial& operator -= (const field_element& element); - field_polynomial& operator *= (const field_polynomial& polynomial); - field_polynomial& operator *= (const field_element& element); - field_polynomial& operator /= (const field_polynomial& divisor); - field_polynomial& operator /= (const field_element& element); - field_polynomial& operator %= (const field_polynomial& divisor); - field_polynomial& operator %= (const unsigned int& power); - field_polynomial& operator ^= (const unsigned int& n); - field_polynomial& operator <<= (const unsigned int& n); - field_polynomial& operator >>= (const unsigned int& n); - - field_element& operator[] (const std::size_t& term); - field_element operator() (const field_element& value); - field_element operator() (field_symbol value); - - const field_element& operator[](const std::size_t& term) const; - const field_element operator()(const field_element& value) const; - const field_element operator()(field_symbol value) const; - - bool operator==(const field_polynomial& polynomial) const; - bool operator!=(const field_polynomial& polynomial) const; - - bool monic() const; - - field_polynomial derivative() const; - - friend std::ostream& operator << (std::ostream& os, const field_polynomial& polynomial); - - private: - - typedef std::vector::iterator poly_iter; - typedef std::vector::const_iterator const_poly_iter; - - void simplify(field_polynomial& polynomial) const; - - field& field_; - std::vector poly_; - }; - - field_polynomial operator + (const field_polynomial& a, const field_polynomial& b); - field_polynomial operator + (const field_polynomial& a, const field_element& b); - field_polynomial operator + (const field_element& a, const field_polynomial& b); - field_polynomial operator + (const field_polynomial& a, const field_symbol& b); - field_polynomial operator + (const field_symbol& a, const field_polynomial& b); - field_polynomial operator - (const field_polynomial& a, const field_polynomial& b); - field_polynomial operator - (const field_polynomial& a, const field_element& b); - field_polynomial operator - (const field_element& a, const field_polynomial& b); - field_polynomial operator - (const field_polynomial& a, const field_symbol& b); - field_polynomial operator - (const field_symbol& a, const field_polynomial& b); - field_polynomial operator * (const field_polynomial& a, const field_polynomial& b); - field_polynomial operator * (const field_element& a, const field_polynomial& b); - field_polynomial operator * (const field_polynomial& a, const field_element& b); - field_polynomial operator / (const field_polynomial& a, const field_polynomial& b); - field_polynomial operator / (const field_polynomial& a, const field_element& b); - field_polynomial operator % (const field_polynomial& a, const field_polynomial& b); - field_polynomial operator % (const field_polynomial& a, const unsigned int& power); - field_polynomial operator ^ (const field_polynomial& a, const int& n); - field_polynomial operator <<(const field_polynomial& a, const unsigned int& n); - field_polynomial operator >>(const field_polynomial& a, const unsigned int& n); - field_polynomial gcd(const field_polynomial& a, const field_polynomial& b); - - inline field_polynomial::field_polynomial(const field& gfield) - : field_(const_cast(gfield)) - { - poly_.clear(); - poly_.reserve(256); - } - - inline field_polynomial::field_polynomial(const field& gfield, const unsigned int& degree) - : field_(const_cast(gfield)) - { - poly_.reserve(256); - poly_.resize(degree + 1,field_element(field_,0)); - } - - inline field_polynomial::field_polynomial(const field& gfield, const unsigned int& degree, const field_element element[]) - : field_(const_cast(gfield)) - { - poly_.reserve(256); - - if (element != NULL) - { - /* - It is assumed that element is an array of field elements - with size/element count of degree + 1. - */ - for (unsigned int i = 0; i <= degree; ++i) - { - poly_.push_back(element[i]); - } - } - else - poly_.resize(degree + 1, field_element(field_, 0)); - } - - inline field_polynomial::field_polynomial(const field_polynomial& polynomial) - : field_(const_cast(polynomial.field_)), - poly_ (polynomial.poly_) - {} - - inline field_polynomial::field_polynomial(const field_element& element) - : field_(const_cast(element.galois_field())) - { - poly_.resize(1,element); - } - - inline bool field_polynomial::valid() const - { - return (poly_.size() > 0); - } - - inline int field_polynomial::deg() const - { - return static_cast(poly_.size()) - 1; - } - - inline const field& field_polynomial::galois_field() const - { - return field_; - } - - inline void field_polynomial::set_degree(const unsigned int& x) - { - poly_.resize(x - 1,field_element(field_,0)); - } - - inline field_polynomial& field_polynomial::operator = (const field_polynomial& polynomial) - { - if ((this != &polynomial) && (&field_ == &(polynomial.field_))) - { - poly_ = polynomial.poly_; - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator = (const field_element& element) - { - if (&field_ == &(element.galois_field())) - { - poly_.resize(1,element); - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator += (const field_polynomial& polynomial) - { - if (&field_ == &(polynomial.field_)) - { - if (poly_.size() < polynomial.poly_.size()) - { - const_poly_iter it0 = polynomial.poly_.begin(); - - for (poly_iter it1 = poly_.begin(); it1 != poly_.end(); ++it0, ++it1) - { - (*it1) += (*it0); - } - - while (it0 != polynomial.poly_.end()) - { - poly_.push_back(*it0); - ++it0; - } - } - else - { - poly_iter it0 = poly_.begin(); - - for (const_poly_iter it1 = polynomial.poly_.begin(); it1 != polynomial.poly_.end(); ++it0, ++it1) - { - (*it0) += (*it1); - } - } - - simplify(*this); - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator += (const field_element& element) - { - poly_[0] += element; - return *this; - } - - inline field_polynomial& field_polynomial::operator -= (const field_polynomial& element) - { - return (*this += element); - } - - inline field_polynomial& field_polynomial::operator -= (const field_element& element) - { - poly_[0] -= element; - return *this; - } - - inline field_polynomial& field_polynomial::operator *= (const field_polynomial& polynomial) - { - if (&field_ == &(polynomial.field_)) - { - field_polynomial product(field_,deg() + polynomial.deg() + 1); - - poly_iter result_it = product.poly_.begin(); - - for (poly_iter it0 = poly_.begin(); it0 != poly_.end(); ++it0) - { - poly_iter current_result_it = result_it; - - for (const_poly_iter it1 = polynomial.poly_.begin(); it1 != polynomial.poly_.end(); ++it1) - { - (*current_result_it) += (*it0) * (*it1); - ++current_result_it; - } - - ++result_it; - } - - simplify(product); - poly_ = product.poly_; - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator *= (const field_element& element) - { - if (field_ == element.galois_field()) - { - for (poly_iter it = poly_.begin(); it != poly_.end(); ++it) - { - (*it) *= element; - } - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator /= (const field_polynomial& divisor) - { - if ( - (&field_ == &divisor.field_) && - (deg() >= divisor.deg()) && - (divisor.deg() >= 0) - ) - { - field_polynomial quotient (field_, deg() - divisor.deg() + 1); - field_polynomial remainder(field_, divisor.deg() - 1); - - for (int i = static_cast(deg()); i >= 0; i--) - { - if (i <= static_cast(quotient.deg())) - { - quotient[i] = remainder[remainder.deg()] / divisor[divisor.deg()]; - - for (int j = static_cast(remainder.deg()); j > 0; --j) - { - remainder[j] = remainder[j - 1] + (quotient[i] * divisor[j]); - } - - remainder[0] = poly_[i] + (quotient[i] * divisor[0]); - } - else - { - for (int j = static_cast(remainder.deg()); j > 0; --j) - { - remainder[j] = remainder[j - 1]; - } - - remainder[0] = poly_[i]; - } - } - - simplify(quotient); - poly_ = quotient.poly_; - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator /= (const field_element& element) - { - if (field_ == element.galois_field()) - { - for (poly_iter it = poly_.begin(); it != poly_.end(); ++it) - { - (*it) /= element; - } - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator %= (const field_polynomial& divisor) - { - if ( - (field_ == divisor.field_) && - (deg() >= divisor.deg() ) && - (divisor.deg() >= 0 ) - ) - { - field_polynomial quotient (field_, deg() - divisor.deg() + 1); - field_polynomial remainder(field_, divisor.deg() - 1); - - for (int i = static_cast(deg()); i >= 0; i--) - { - if (i <= static_cast(quotient.deg())) - { - quotient[i] = remainder[remainder.deg()] / divisor[divisor.deg()]; - - for (int j = static_cast(remainder.deg()); j > 0; --j) - { - remainder[j] = remainder[j - 1] + (quotient[i] * divisor[j]); - } - - remainder[0] = poly_[i] + (quotient[i] * divisor[0]); - } - else - { - for (int j = static_cast(remainder.deg()); j > 0; --j) - { - remainder[j] = remainder[j - 1]; - } - - remainder[0] = poly_[i]; - } - } - - poly_ = remainder.poly_; - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator %= (const unsigned int& power) - { - if (poly_.size() >= power) - { - poly_.resize(power,field_element(field_,0)); - simplify(*this); - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator ^= (const unsigned int& n) - { - field_polynomial result = *this; - - for (std::size_t i = 0; i < n; ++i) - { - result *= *this; - } - - *this = result; - - return *this; - } - - inline field_polynomial& field_polynomial::operator <<= (const unsigned int& n) - { - if (poly_.size() > 0) - { - size_t initial_size = poly_.size(); - - poly_.resize(poly_.size() + n, field_element(field_,0)); - - for (size_t i = initial_size - 1; static_cast(i) >= 0; --i) - { - poly_[i + n] = poly_[i]; - } - - for (unsigned int i = 0; i < n; ++i) - { - poly_[i] = 0; - } - } - - return *this; - } - - inline field_polynomial& field_polynomial::operator >>= (const unsigned int& n) - { - if (n <= poly_.size()) - { - for (unsigned int i = 0; i <= deg() - n; ++i) - { - poly_[i] = poly_[i + n]; - } - - poly_.resize(poly_.size() - n,field_element(field_,0)); - } - else if (static_cast(n) >= (deg() + 1)) - { - poly_.resize(0,field_element(field_,0)); - } - - return *this; - } - - inline const field_element& field_polynomial::operator [] (const std::size_t& term) const - { - assert(term < poly_.size()); - return poly_[term]; - } - - inline field_element& field_polynomial::operator [] (const std::size_t& term) - { - assert(term < poly_.size()); - return poly_[term]; - } - - inline field_element field_polynomial::operator () (const field_element& value) - { - field_element result(field_,0); - - if (!poly_.empty()) - { - int i = 0; - field_symbol total_sum = 0 ; - field_symbol value_poly_form = value.poly(); - - for (poly_iter it = poly_.begin(); it != poly_.end(); ++it, ++i) - { - total_sum ^= field_.mul(field_.exp(value_poly_form,i), (*it).poly()); - } - - result = total_sum; - } - - return result; - } - - inline const field_element field_polynomial::operator () (const field_element& value) const - { - if (!poly_.empty()) - { - int i = 0; - field_symbol total_sum = 0 ; - field_symbol value_poly_form = value.poly(); - - for (const_poly_iter it = poly_.begin(); it != poly_.end(); ++it, ++i) - { - total_sum ^= field_.mul(field_.exp(value_poly_form,i), (*it).poly()); - } - - return field_element(field_,total_sum); - } - - return field_element(field_,0); - } - - inline field_element field_polynomial::operator () (field_symbol value) - { - if (!poly_.empty()) - { - int i = 0; - field_symbol total_sum = 0 ; - - for (const_poly_iter it = poly_.begin(); it != poly_.end(); ++it, ++i) - { - total_sum ^= field_.mul(field_.exp(value,i), (*it).poly()); - } - - return field_element(field_,total_sum); - } - - return field_element(field_,0); - } - - inline const field_element field_polynomial::operator () (field_symbol value) const - { - if (!poly_.empty()) - { - int i = 0; - field_symbol total_sum = 0 ; - - for (const_poly_iter it = poly_.begin(); it != poly_.end(); ++it, ++i) - { - total_sum ^= field_.mul(field_.exp(value, i), (*it).poly()); - } - - return field_element(field_,total_sum); - } - - return field_element(field_,0); - } - - inline bool field_polynomial::operator == (const field_polynomial& polynomial) const - { - if (field_ == polynomial.field_) - { - if (poly_.size() != polynomial.poly_.size()) - return false; - else - { - const_poly_iter it0 = polynomial.poly_.begin(); - - for (const_poly_iter it1 = poly_.begin(); it1 != poly_.end(); ++it0, ++it1) - { - if ((*it0) != (*it1)) - return false; - } - - return true; - } - } - else - return false; - } - - inline bool field_polynomial::operator != (const field_polynomial& polynomial) const - { - return !(*this == polynomial); - } - - inline field_polynomial field_polynomial::derivative() const - { - if ((*this).poly_.size() > 1) - { - field_polynomial deriv(field_,deg()); - - const std::size_t upper_bound = poly_.size() - 1; - - for (std::size_t i = 0; i < upper_bound; i += 2) - { - deriv.poly_[i] = poly_[i + 1]; - } - - simplify(deriv); - return deriv; - } - - return field_polynomial(field_,0); - } - - inline bool field_polynomial::monic() const - { - return (poly_[poly_.size() - 1] == static_cast(1)); - } - - inline void field_polynomial::simplify() - { - simplify(*this); - } - - inline void field_polynomial::simplify(field_polynomial& polynomial) const - { - std::size_t poly_size = polynomial.poly_.size(); - - if ((poly_size > 0) && (polynomial.poly_.back() == 0)) - { - poly_iter it = polynomial.poly_.end (); - poly_iter begin = polynomial.poly_.begin(); - - std::size_t count = 0; - - while ((begin != it) && (*(--it) == 0)) - { - ++count; - } - - if (0 != count) - { - polynomial.poly_.resize(poly_size - count, field_element(field_,0)); - } - } - } - - inline field_polynomial operator + (const field_polynomial& a, const field_polynomial& b) - { - field_polynomial result = a; - result += b; - return result; - } - - inline field_polynomial operator + (const field_polynomial& a, const field_element& b) - { - field_polynomial result = a; - result += b; - return result; - } - - inline field_polynomial operator + (const field_element& a, const field_polynomial& b) - { - field_polynomial result = b; - result += a; - return result; - } - - inline field_polynomial operator + (const field_polynomial& a, const field_symbol& b) - { - return a + field_element(a.galois_field(),b); - } - - inline field_polynomial operator + (const field_symbol& a, const field_polynomial& b) - { - return b + field_element(b.galois_field(),a); - } - - inline field_polynomial operator - (const field_polynomial& a, const field_polynomial& b) - { - field_polynomial result = a; - result -= b; - return result; - } - - inline field_polynomial operator - (const field_polynomial& a, const field_element& b) - { - field_polynomial result = a; - result -= b; - return result; - } - - inline field_polynomial operator - (const field_element& a, const field_polynomial& b) - { - field_polynomial result = b; - result -= a; - return result; - } - - inline field_polynomial operator - (const field_polynomial& a, const field_symbol& b) - { - return a - field_element(a.galois_field(),b); - } - - inline field_polynomial operator - (const field_symbol& a, const field_polynomial& b) - { - return b - field_element(b.galois_field(),a); - } - - inline field_polynomial operator * (const field_polynomial& a, const field_polynomial& b) - { - field_polynomial result = a; - result *= b; - return result; - } - - inline field_polynomial operator * (const field_element& a, const field_polynomial& b) - { - field_polynomial result = b; - result *= a; - return result; - } - - inline field_polynomial operator * (const field_polynomial& a, const field_element& b) - { - field_polynomial result = a; - result *= b; - return result; - } - - inline field_polynomial operator / (const field_polynomial& a, const field_polynomial& b) - { - field_polynomial result = a; - result /= b; - return result; - } - - inline field_polynomial operator / (const field_polynomial& a, const field_element& b) - { - field_polynomial result = a; - result /= b; - return result; - } - - inline field_polynomial operator % (const field_polynomial& a, const field_polynomial& b) - { - field_polynomial result = a; - result %= b; - return result; - } - - inline field_polynomial operator % (const field_polynomial& a, const unsigned int& n) - { - field_polynomial result = a; - result %= n; - return result; - } - - inline field_polynomial operator ^ (const field_polynomial& a, const int& n) - { - field_polynomial result = a; - result ^= n; - return result; - } - - inline field_polynomial operator << (const field_polynomial& a, const unsigned int& n) - { - field_polynomial result = a; - result <<= n; - return result; - } - - inline field_polynomial operator >> (const field_polynomial& a, const unsigned int& n) - { - field_polynomial result = a; - result >>= n; - return result; - } - - inline field_polynomial gcd(const field_polynomial& a, const field_polynomial& b) - { - if (&a.galois_field() == &b.galois_field()) - { - if ((!a.valid()) && (!b.valid())) - { - field_polynomial error_polynomial(a.galois_field()); - return error_polynomial; - } - - if (!a.valid()) return b; - if (!b.valid()) return a; - - field_polynomial x = a % b; - field_polynomial y = b; - field_polynomial z = x; - - while ((z = (y % x)).valid()) - { - y = x; - x = z; - } - return x; - } - else - { - field_polynomial error_polynomial(a.galois_field()); - return error_polynomial; - } - } - - inline field_polynomial generate_X(const field& gfield) - { - const field_element xgfe[2] = { - galois::field_element(gfield, 0), - galois::field_element(gfield, 1) - }; - - field_polynomial X_(gfield,1,xgfe); - - return X_; - } - - inline std::ostream& operator << (std::ostream& os, const field_polynomial& polynomial) - { - if (polynomial.deg() >= 0) - { - /* - for (unsigned int i = 0; i < polynomial.poly_.size(); ++i) - { - os << polynomial.poly[i].index() - << ((i != (polynomial.deg())) ? " " : ""); - } - - std::cout << " poly form: "; - */ - - for (unsigned int i = 0; i < polynomial.poly_.size(); ++i) - { - os << polynomial.poly_[i].poly() - << " " - << "x^" - << i - << ((static_cast(i) != (polynomial.deg())) ? " + " : ""); - } - } - - return os; - } - - } // namespace galois - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_galois_utilities.hpp b/modem/fec/schifra_galois_utilities.hpp deleted file mode 100644 index e3c9f3e..0000000 --- a/modem/fec/schifra_galois_utilities.hpp +++ /dev/null @@ -1,115 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_GALOIS_UTILITIES_HPP -#define INCLUDE_SCHIFRA_GALOIS_UTILITIES_HPP - - -#include -#include -#include -#include -#include -#include -#include - -#include "schifra_galois_field.hpp" -#include "schifra_galois_field_polynomial.hpp" - - -namespace schifra -{ - - namespace galois - { - - inline std::string convert_to_string(const unsigned int& value, const unsigned int& width) - { - std::stringstream stream; - stream << std::setw(width) << std::setfill('0') << value; - return stream.str(); - } - - inline std::string convert_to_string(const int& value, const unsigned int& width) - { - std::stringstream stream; - stream << std::setw(width) << std::setfill('0') << value; - return stream.str(); - } - - inline std::string convert_to_bin(const unsigned int& value, const unsigned int& field_descriptor) - { - std::string output = std::string(field_descriptor, ' '); - - for (unsigned int i = 0; i < field_descriptor; ++i) - { - output[i] = ((((value >> (field_descriptor - 1 - i)) & 1) == 1) ? '1' : '0'); - } - - return output; - } - - inline void alpha_table(std::ostream& os, const field& gf) - { - std::vector str_list; - - for (unsigned int i = 0; i < gf.size() + 1; ++i) - { - str_list.push_back("alpha^" + convert_to_string(gf.index(i),2) + "\t" + - convert_to_bin (i,gf.pwr()) + "\t" + - convert_to_string(gf.alpha(i),2)); - } - - std::sort(str_list.begin(),str_list.end()); - std::copy(str_list.begin(),str_list.end(),std::ostream_iterator(os,"\n")); - } - - inline void polynomial_alpha_form(std::ostream& os, const field_polynomial& polynomial) - { - for (int i = 0; i < (polynomial.deg() + 1); ++i) - { - field_symbol alpha_power = polynomial.galois_field().index(polynomial[i].poly()); - - if (alpha_power != 0) - os << static_cast(224) << "^" << convert_to_string(alpha_power,2); - else - os << 1; - - os << " * " - << "x^" - << i - << ((i != (polynomial.deg())) ? " + " : ""); - } - } - - inline void polynomial_alpha_form(std::ostream& os, const std::string& prepend, const field_polynomial& polynomial) - { - os << prepend; - polynomial_alpha_form(os,polynomial); - os << std::endl; - } - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_bitio.hpp b/modem/fec/schifra_reed_solomon_bitio.hpp deleted file mode 100644 index 6130d47..0000000 --- a/modem/fec/schifra_reed_solomon_bitio.hpp +++ /dev/null @@ -1,201 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_BITIO_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_BITIO_HPP - - -#include - - -namespace schifra -{ - - namespace reed_solomon - { - - namespace bitio - { - - template class convert_data_to_symbol; - - template <> - class convert_data_to_symbol<2> - { - public: - - template - convert_data_to_symbol(const BitBlock data[], const std::size_t data_length, int symbol[]) - { - const BitBlock* d_it = & data[0]; - int* s_it = &symbol[0]; - - for (std::size_t i = 0; i < data_length; ++i, ++d_it, s_it+=4) - { - (* s_it ) = (*d_it) & 0x03; - (*(s_it + 1)) = ((*d_it) >> 2) & 0x03; - (*(s_it + 2)) = ((*d_it) >> 4) & 0x03; - (*(s_it + 3)) = ((*d_it) >> 6) & 0x03; - } - } - }; - - template <> - class convert_data_to_symbol<4> - { - public: - - template - convert_data_to_symbol(const BitBlock data[], const std::size_t data_length, int symbol[]) - { - const BitBlock* d_it = & data[0]; - int* s_it = &symbol[0]; - - for (std::size_t i = 0; i < data_length; ++i, ++d_it, s_it+=2) - { - (* s_it ) = (*d_it) & 0x0F; - (*(s_it + 1)) = ((*d_it) >> 4) & 0x0F; - } - } - }; - - template <> - class convert_data_to_symbol<8> - { - public: - - template - convert_data_to_symbol(const BitBlock data[], const std::size_t data_length, int symbol[]) - { - const BitBlock* d_it = & data[0]; - int* s_it = &symbol[0]; - - for (std::size_t i = 0; i < data_length; ++i, ++d_it, ++s_it) - { - (*s_it) = (*d_it) & 0xFF; - } - } - }; - - template <> - class convert_data_to_symbol<16> - { - public: - - template - convert_data_to_symbol(const BitBlock data[], const std::size_t data_length, int symbol[]) - { - const BitBlock* d_it = & data[0]; - int* s_it = &symbol[0]; - - for (std::size_t i = 0; i < data_length; i+=2, d_it+=2, ++s_it) - { - (*s_it) = (*d_it) & 0x000000FF; - (*s_it) |= (static_cast((*(d_it + 1))) << 8) & 0x0000FF00; - } - } - }; - - template <> - class convert_data_to_symbol<24> - { - public: - - template - convert_data_to_symbol(const BitBlock data[], const std::size_t data_length, int symbol[]) - { - BitBlock* d_it = & data[0]; - int* s_it = &symbol[0]; - - for (std::size_t i = 0; i < data_length; i+=3, d_it+=3, ++s_it) - { - (*s_it) |= (*d_it) & 0x000000FF; - (*s_it) |= (static_cast((*(d_it + 1))) << 8) & 0x0000FF00; - (*s_it) |= (static_cast((*(d_it + 2))) << 16) & 0x00FF0000; - } - } - }; - - template class convert_symbol_to_data; - - template <> - class convert_symbol_to_data<4> - { - public: - - template - convert_symbol_to_data(const int symbol[], BitBlock data[], const std::size_t data_length) - { - BitBlock* d_it = & data[0]; - const int* s_it = &symbol[0]; - - for (std::size_t i = 0; i < data_length; ++i, ++d_it, ++s_it) - { - (*d_it) = (*s_it) & 0x0000000F; - (*d_it) |= ((*(s_it + 1)) & 0x0000000F) << 4; - } - } - }; - - template <> - class convert_symbol_to_data<8> - { - public: - template - convert_symbol_to_data(const int symbol[], BitBlock data[], const std::size_t data_length) - { - BitBlock* d_it = & data[0]; - const int* s_it = &symbol[0]; - - for (std::size_t i = 0; i < data_length; ++i, ++d_it, ++s_it) - { - (*d_it) = static_cast((*s_it) & 0xFF); - } - } - }; - - template <> - class convert_symbol_to_data<16> - { - public: - - template - convert_symbol_to_data(const int symbol[], BitBlock data[], const std::size_t data_length) - { - BitBlock* d_it = & data[0]; - const int* s_it = &symbol[0]; - - for (std::size_t i = 0; i < data_length; ++i, ++d_it, ++s_it) - { - (*d_it) = (*s_it) & 0xFFFF; - } - } - }; - - } // namespace bitio - - } // namespace reed_solomon - -} // namespace schifra - - -#endif diff --git a/modem/fec/schifra_reed_solomon_block.hpp b/modem/fec/schifra_reed_solomon_block.hpp deleted file mode 100644 index ec1852c..0000000 --- a/modem/fec/schifra_reed_solomon_block.hpp +++ /dev/null @@ -1,382 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_BLOCK_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_BLOCK_HPP - - -#include -#include - -#include "schifra_galois_field.hpp" -#include "schifra_ecc_traits.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template - struct block - { - public: - - typedef galois::field_symbol symbol_type; - typedef traits::reed_solomon_triat trait; - typedef traits::symbol symbol; - typedef block block_t; - - enum error_t - { - e_no_error = 0, - e_encoder_error0 = 1, - e_encoder_error1 = 2, - e_decoder_error0 = 3, - e_decoder_error1 = 4, - e_decoder_error2 = 5, - e_decoder_error3 = 6, - e_decoder_error4 = 7 - }; - - block() - : errors_detected (0), - errors_corrected(0), - zero_numerators (0), - unrecoverable(false), - error(e_no_error) - { - traits::validate_reed_solomon_block_parameters(); - } - - block(const std::string& _data, const std::string& _fec) - : errors_detected (0), - errors_corrected(0), - zero_numerators (0), - unrecoverable(false), - error(e_no_error) - { - traits::validate_reed_solomon_block_parameters(); - - for (std::size_t i = 0; i < data_length; ++i) - { - data[i] = static_cast(_data[i]); - } - - for (std::size_t i = 0; i < fec_length; ++i) - { - data[i + data_length] = static_cast(_fec[i]); - } - } - - galois::field_symbol& operator[](const std::size_t& index) - { - return data[index]; - } - - const galois::field_symbol& operator[](const std::size_t& index) const - { - return data[index]; - } - - galois::field_symbol& operator()(const std::size_t& index) - { - return operator[](index); - } - - galois::field_symbol& fec(const std::size_t& index) - { - return data[data_length + index]; - } - - bool data_to_string(std::string& data_str) const - { - if (data_str.length() != data_length) - { - return false; - } - - for (std::size_t i = 0; i < data_length; ++i) - { - data_str[i] = static_cast(data[i]); - } - - return true; - } - - bool fec_to_string(std::string& fec_str) const - { - if (fec_str.length() != fec_length) - { - return false; - } - - for (std::size_t i = 0; i < fec_length; ++i) - { - fec_str[i] = static_cast(data[data_length + i]); - } - - return true; - } - - std::string fec_to_string() const - { - std::string fec_str(fec_length,0x00); - fec_to_string(fec_str); - return fec_str; - } - - void clear(galois::field_symbol value = 0) - { - for (std::size_t i = 0; i < code_length; ++i) - { - data[i] = value; - } - } - - void clear_data(galois::field_symbol value = 0) - { - for (std::size_t i = 0; i < data_length; ++i) - { - data[i] = value; - } - } - - void clear_fec(galois::field_symbol value = 0) - { - for (std::size_t i = 0; i < fec_length; ++i) - { - data[data_length + i] = value; - } - } - - void reset(galois::field_symbol value = 0) - { - clear(value); - errors_detected = 0; - errors_corrected = 0; - zero_numerators = 0; - unrecoverable = false; - error = e_no_error; - } - - template - void copy_state(const BlockType& b) - { - errors_detected = b.errors_detected; - errors_corrected = b.errors_corrected; - zero_numerators = b.zero_numerators; - unrecoverable = b.unrecoverable; - error = static_cast(b.error); - } - - inline std::string error_as_string() const - { - switch (error) - { - case e_no_error : return "No Error"; - case e_encoder_error0 : return "Invalid Encoder"; - case e_encoder_error1 : return "Incompatible Generator Polynomial"; - case e_decoder_error0 : return "Invalid Decoder"; - case e_decoder_error1 : return "Decoder Failure - Non-zero Syndrome"; - case e_decoder_error2 : return "Decoder Failure - Too Many Errors/Erasures"; - case e_decoder_error3 : return "Decoder Failure - Invalid Symbol Correction"; - case e_decoder_error4 : return "Decoder Failure - Invalid Codeword Correction"; - default : return "Invalid Error Code"; - } - } - - std::size_t errors_detected; - std::size_t errors_corrected; - std::size_t zero_numerators; - bool unrecoverable; - error_t error; - galois::field_symbol data[code_length]; - }; - - template - inline void copy(const block& src_block, block& dest_block) - { - for (std::size_t index = 0; index < code_length; ++index) - { - dest_block.data[index] = src_block.data[index]; - } - } - - template - inline void copy(const T src_data[], block& dest_block) - { - for (std::size_t index = 0; index < (code_length - fec_length); ++index, ++src_data) - { - dest_block.data[index] = static_cast::symbol_type>(*src_data); - } - } - - template - inline void copy(const T src_data[], - const std::size_t& src_length, - block& dest_block) - { - for (std::size_t index = 0; index < src_length; ++index, ++src_data) - { - dest_block.data[index] = static_cast::symbol_type>(*src_data); - } - } - - template - inline void copy(const block src_block_stack[stack_size], - block dest_block_stack[stack_size]) - { - for (std::size_t row = 0; row < stack_size; ++row) - { - copy(src_block_stack[row], dest_block_stack[row]); - } - } - - template - inline bool copy(const T src_data[], - const std::size_t src_length, - block dest_block_stack[stack_size]) - { - const std::size_t data_length = code_length - fec_length; - - if (src_length > (stack_size * data_length)) - { - return false; - } - - const std::size_t row_count = src_length / data_length; - - for (std::size_t row = 0; row < row_count; ++row, src_data += data_length) - { - copy(src_data, dest_block_stack[row]); - } - - if ((src_length % data_length) != 0) - { - copy(src_data, src_length % data_length, dest_block_stack[row_count]); - } - - return true; - } - - template - inline void full_copy(const block& src_block, - T dest_data[]) - { - for (std::size_t i = 0; i < code_length; ++i, ++dest_data) - { - (*dest_data) = static_cast(src_block[i]); - } - } - - template - inline void copy(const block src_block_stack[stack_size], - T dest_data[]) - { - const std::size_t data_length = code_length - fec_length; - - for (std::size_t i = 0; i < stack_size; ++i) - { - for (std::size_t j = 0; j < data_length; ++j, ++dest_data) - { - (*dest_data) = static_cast(src_block_stack[i][j]); - } - } - } - - template - inline std::ostream& operator<<(std::ostream& os, const block& rs_block) - { - for (std::size_t i = 0; i < code_length; ++i) - { - os << static_cast(rs_block[i]); - } - - return os; - } - - template - struct data_block - { - public: - - typedef T value_type; - - T& operator[](const std::size_t index) { return data[index]; } - const T& operator[](const std::size_t index) const { return data[index]; } - - T* begin() { return data; } - const T* begin() const { return data; } - - T* end() { return data + block_length; } - const T* end() const { return data + block_length; } - - void clear(T value = 0) - { - for (std::size_t i = 0; i < block_length; ++i) - { - data[i] = value; - } - } - - private: - - T data[block_length]; - }; - - template - inline void copy(const data_block& src_block, data_block& dest_block) - { - for (std::size_t index = 0; index < block_length; ++index) - { - dest_block[index] = src_block[index]; - } - } - - template - inline void copy(const data_block src_block_stack[stack_size], - data_block dest_block_stack[stack_size]) - { - for (std::size_t row = 0; row < stack_size; ++row) - { - copy(src_block_stack[row], dest_block_stack[row]); - } - } - - template - inline void full_copy(const data_block& src_block, T dest_data[]) - { - for (std::size_t i = 0; i < block_length; ++i, ++dest_data) - { - (*dest_data) = static_cast(src_block[i]); - } - } - - typedef std::vector erasure_locations_t; - - } // namespace reed_solomon - -} // namepsace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_codec_validator.hpp b/modem/fec/schifra_reed_solomon_codec_validator.hpp deleted file mode 100644 index 3057c39..0000000 --- a/modem/fec/schifra_reed_solomon_codec_validator.hpp +++ /dev/null @@ -1,998 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_CODEC_VALIDATOR_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_CODEC_VALIDATOR_HPP - - -#include -#include -#include - -#include "schifra_galois_field.hpp" -#include "schifra_galois_field_polynomial.hpp" -#include "schifra_sequential_root_generator_polynomial_creator.hpp" -#include "schifra_reed_solomon_block.hpp" -#include "schifra_reed_solomon_encoder.hpp" -#include "schifra_reed_solomon_decoder.hpp" -#include "schifra_ecc_traits.hpp" -#include "schifra_error_processes.hpp" -#include "schifra_utilities.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template , - typename decoder_type = decoder, - std::size_t data_length = code_length - fec_length> - class codec_validator - { - public: - - typedef block block_type; - - codec_validator(const galois::field& gf, - const unsigned int gpii, - const std::string& msg) - : field_(gf), - generator_polynomial_(galois::field_polynomial(field_)), - rs_encoder_(reinterpret_cast(0)), - rs_decoder_(reinterpret_cast(0)), - message(msg), - genpoly_initial_index_(gpii), - blocks_processed_(0), - block_failures_(0) - { - traits::equivalent_encoder_decoder(); - - if ( - !make_sequential_root_generator_polynomial(field_, - genpoly_initial_index_, - fec_length, - generator_polynomial_) - ) - { - return; - } - - rs_encoder_ = new encoder_type(field_,generator_polynomial_); - rs_decoder_ = new decoder_type(field_,genpoly_initial_index_); - - if (!rs_encoder_->encode(message,rs_block_original)) - { - std::cout << "codec_validator() - ERROR: Encoding process failed!" << std::endl; - return; - } - } - - bool execute() - { - schifra::utils::timer timer; - timer.start(); - - bool result = stage1() && - stage2() && - stage3() && - stage4() && - stage5() && - stage6() && - stage7() && - stage8() && - stage9() && - stage10() && - stage11() && - stage12() ; - - timer.stop(); - - double time = timer.time(); - - print_codec_properties(); - std::cout << "Blocks decoded: " << blocks_processed_ << - "\tDecoding Failures: " << block_failures_ << - "\tRate: " << ((blocks_processed_ * data_length) * 8.0) / (1048576.0 * time) << "Mbps" << std::endl; - /* - Note: The throughput rate is not only the throughput of reed solomon - encoding and decoding, but also that of the steps needed to add - simulated transmission errors to the reed solomon block such as - the calculation of the positions and additions of errors and - erasures to the reed solomon block, which normally in a true - data transmission medium would not be taken into consideration. - */ - return result; - } - - ~codec_validator() - { - delete rs_encoder_; - delete rs_decoder_; - } - - void print_codec_properties() - { - std::cout << "Codec: RS(" << code_length << "," << data_length << "," << fec_length <<") "; - } - - private: - - bool stage1() - { - /* Burst Error Only Combinations */ - - const std::size_t initial_failure_count = block_failures_; - - for (std::size_t error_count = 1; error_count <= (fec_length >> 1); ++error_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - block_type rs_block = rs_block_original; - - corrupt_message_all_errors - ( - rs_block, - error_count, - start_position, - 1 - ); - - if (!rs_decoder_->decode(rs_block)) - { - print_codec_properties(); - std::cout << "stage1() - Decoding Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage1() - Error Correcting Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage1() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != error_count) - { - print_codec_properties(); - std::cout << "stage1() - Error In The Number Of Detected Errors! Errors Detected: " << rs_block.errors_detected << std::endl; - ++block_failures_; - } - else if (rs_block.errors_corrected != error_count) - { - print_codec_properties(); - std::cout << "stage1() - Error In The Number Of Corrected Errors! Errors Corrected: " << rs_block.errors_corrected << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage2() - { - /* Burst Erasure Only Combinations */ - - const std::size_t initial_failure_count = block_failures_; - - erasure_locations_t erasure_list; - - for (std::size_t erasure_count = 1; erasure_count <= fec_length; ++erasure_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - block_type rs_block = rs_block_original; - - corrupt_message_all_erasures - ( - rs_block, - erasure_list, - erasure_count, - start_position, - 1 - ); - - if (!rs_decoder_->decode(rs_block,erasure_list)) - { - print_codec_properties(); - std::cout << "stage2() - Decoding Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - std::cout << "stage2() - Error Correcting Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage2() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != erasure_count) - { - print_codec_properties(); - std::cout << "stage2() - Error In The Number Of Detected Errors! Errors Detected: " << rs_block.errors_detected << std::endl; - ++block_failures_; - } - else if (rs_block.errors_corrected != erasure_count) - { - print_codec_properties(); - std::cout << "stage2() - Error In The Number Of Corrected Errors! Errors Corrected: " << rs_block.errors_corrected << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - erasure_list.clear(); - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage3() - { - /* Consecutive Burst Erasure and Error Combinations */ - - const std::size_t initial_failure_count = block_failures_; - - erasure_locations_t erasure_list; - - for (std::size_t erasure_count = 1; erasure_count <= fec_length; ++erasure_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - block_type rs_block = rs_block_original; - - corrupt_message_errors_erasures - ( - rs_block, - error_mode::erasures_errors, - start_position,erasure_count, - erasure_list - ); - - if (!rs_decoder_->decode(rs_block,erasure_list)) - { - print_codec_properties(); - std::cout << "stage3() - Decoding Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage3() - Error Correcting Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage3() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - erasure_list.clear(); - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage4() - { - /* Consecutive Burst Error and Erasure Combinations */ - - const std::size_t initial_failure_count = block_failures_; - - erasure_locations_t erasure_list; - - for (std::size_t erasure_count = 1; erasure_count <= fec_length; ++erasure_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - block_type rs_block = rs_block_original; - - corrupt_message_errors_erasures - ( - rs_block, - error_mode::errors_erasures, - start_position, - erasure_count, - erasure_list - ); - - if (!rs_decoder_->decode(rs_block,erasure_list)) - { - print_codec_properties(); - std::cout << "stage4() - Decoding Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage4() - Error Correcting Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage4() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - erasure_list.clear(); - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage5() - { - /* Distanced Burst Erasure and Error Combinations */ - - const std::size_t initial_failure_count = block_failures_; - - erasure_locations_t erasure_list; - - for (std::size_t between_distance = 1; between_distance <= 10; ++between_distance) - { - for (std::size_t erasure_count = 1; erasure_count <= fec_length; ++erasure_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - block_type rs_block = rs_block_original; - - corrupt_message_errors_erasures - ( - rs_block, - error_mode::erasures_errors, - start_position, - erasure_count, - erasure_list, - between_distance - ); - - if (!rs_decoder_->decode(rs_block,erasure_list)) - { - print_codec_properties(); - std::cout << "stage5() - Decoding Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage5() - Error Correcting Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage5() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - erasure_list.clear(); - } - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage6() - { - /* Distanced Burst Error and Erasure Combinations */ - - const std::size_t initial_failure_count = block_failures_; - - erasure_locations_t erasure_list; - - for (std::size_t between_distance = 1; between_distance <= 10; ++between_distance) - { - for (std::size_t erasure_count = 1; erasure_count <= fec_length; ++erasure_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - block_type rs_block = rs_block_original; - - corrupt_message_errors_erasures - ( - rs_block, - error_mode::errors_erasures, - start_position, - erasure_count, - erasure_list,between_distance - ); - - if (!rs_decoder_->decode(rs_block,erasure_list)) - { - print_codec_properties(); - std::cout << "stage6() - Decoding Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage6() - Error Correcting Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage6() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - erasure_list.clear(); - } - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage7() - { - /* Intermittent Error Combinations */ - - const std::size_t initial_failure_count = block_failures_; - - for (std::size_t error_count = 1; error_count < (fec_length >> 1); ++error_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - for (std::size_t scale = 1; scale < 5; ++scale) - { - block_type rs_block = rs_block_original; - - corrupt_message_all_errors - ( - rs_block, - error_count, - start_position, - scale - ); - - if (!rs_decoder_->decode(rs_block)) - { - print_codec_properties(); - std::cout << "stage7() - Decoding Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage7() - Error Correcting Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage7() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != error_count) - { - print_codec_properties(); - std::cout << "stage7() - Error In The Number Of Detected Errors! Errors Detected: " << rs_block.errors_detected << std::endl; - ++block_failures_; - } - else if (rs_block.errors_corrected != error_count) - { - print_codec_properties(); - std::cout << "stage7() - Error In The Number Of Corrected Errors! Errors Corrected: " << rs_block.errors_corrected << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - } - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage8() - { - /* Intermittent Erasure Combinations */ - - const std::size_t initial_failure_count = block_failures_; - - erasure_locations_t erasure_list; - - for (std::size_t erasure_count = 1; erasure_count <= fec_length; ++erasure_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - for (std::size_t scale = 4; scale < 5; ++scale) - { - block_type rs_block = rs_block_original; - - corrupt_message_all_erasures - ( - rs_block, - erasure_list, - erasure_count, - start_position, - scale - ); - - if (!rs_decoder_->decode(rs_block,erasure_list)) - { - print_codec_properties(); - std::cout << "stage8() - Decoding Failure! start position: " << start_position << "\t scale: " << scale << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage8() - Error Correcting Failure! start position: " << start_position << "\t scale: " << scale < erasure_count) - { - print_codec_properties(); - std::cout << "stage8() - Error In The Number Of Detected Errors! Errors Detected: " << rs_block.errors_detected << std::endl; - ++block_failures_; - } - else if (rs_block.errors_corrected > erasure_count) - { - print_codec_properties(); - std::cout << "stage8() - Error In The Number Of Corrected Errors! Errors Corrected: " << rs_block.errors_corrected << std::endl; - ++block_failures_; - } - ++blocks_processed_; - erasure_list.clear(); - } - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage9() - { - /* Burst Interleaved Error and Erasure Combinations */ - - const std::size_t initial_failure_count = block_failures_; - - erasure_locations_t erasure_list; - - for (std::size_t erasure_count = 1; erasure_count <= fec_length; ++erasure_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - block_type rs_block = rs_block_original; - - corrupt_message_interleaved_errors_erasures - ( - rs_block, - start_position, - erasure_count, - erasure_list - ); - - if (!rs_decoder_->decode(rs_block,erasure_list)) - { - print_codec_properties(); - std::cout << "stage9() - Decoding Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage9() - Error Correcting Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage9() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - ++blocks_processed_; - erasure_list.clear(); - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage10() - { - /* Segmented Burst Errors */ - - const std::size_t initial_failure_count = block_failures_; - - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - for (std::size_t distance_between_blocks = 0; distance_between_blocks < 5; ++distance_between_blocks) - { - block_type rs_block = rs_block_original; - - corrupt_message_all_errors_segmented - ( - rs_block, - start_position, - distance_between_blocks - ); - - if (!rs_decoder_->decode(rs_block)) - { - print_codec_properties(); - std::cout << "stage10() - Decoding Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage10() - Error Correcting Failure! start position: " << start_position << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage10() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - } - } - - return (block_failures_ == initial_failure_count); - } - - bool stage11() - { - /* No Errors */ - - const std::size_t initial_failure_count = block_failures_; - - block_type rs_block = rs_block_original; - - if (!rs_decoder_->decode(rs_block)) - { - print_codec_properties(); - std::cout << "stage11() - Decoding Failure!" << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage11() - Error Correcting Failure!" << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != 0) - { - print_codec_properties(); - std::cout << "stage11() - Error Correcting Failure!" << std::endl; - ++block_failures_; - } - else if (rs_block.errors_corrected != 0) - { - print_codec_properties(); - std::cout << "stage11() - Error Correcting Failure!" << std::endl; - ++block_failures_; - } - else if (rs_block.unrecoverable) - { - print_codec_properties(); - std::cout << "stage11() - Error Correcting Failure!" << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - - return (block_failures_ == initial_failure_count); - } - - bool stage12() - { - /* Random Errors Only */ - - const std::size_t initial_failure_count = block_failures_; - - std::vector random_error_index; - generate_error_index((fec_length >> 1),random_error_index,0xA5A5A5A5); - - for (std::size_t error_count = 1; error_count <= (fec_length >> 1); ++error_count) - { - for (std::size_t error_index = 0; error_index < error_index_size; ++error_index) - { - block_type rs_block = rs_block_original; - - corrupt_message_all_errors_at_index - ( - rs_block, - error_count, - error_index, - random_error_index - ); - - if (!rs_decoder_->decode(rs_block)) - { - print_codec_properties(); - std::cout << "stage12() - Decoding Failure! error index: " << error_index << std::endl; - ++block_failures_; - } - else if (!is_block_equivelent(rs_block,message)) - { - print_codec_properties(); - std::cout << "stage12() - Error Correcting Failure! error index: " << error_index << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != rs_block.errors_corrected) - { - print_codec_properties(); - std::cout << "stage12() - Discrepancy between the number of errors detected and corrected. [" << rs_block.errors_detected << "," << rs_block.errors_corrected << "]" << std::endl; - ++block_failures_; - } - else if (rs_block.errors_detected != error_count) - { - print_codec_properties(); - std::cout << "stage12() - Error In The Number Of Detected Errors! Errors Detected: " << rs_block.errors_detected << std::endl; - ++block_failures_; - } - else if (rs_block.errors_corrected != error_count) - { - print_codec_properties(); - std::cout << "stage12() - Error In The Number Of Corrected Errors! Errors Corrected: " << rs_block.errors_corrected << std::endl; - ++block_failures_; - } - - ++blocks_processed_; - } - } - - return (block_failures_ == initial_failure_count); - } - - protected: - - codec_validator() {} - - private: - - codec_validator(const codec_validator&); - const codec_validator& operator=(const codec_validator&); - - const galois::field& field_; - galois::field_polynomial generator_polynomial_; - encoder_type* rs_encoder_; - decoder_type* rs_decoder_; - block_type rs_block_original; - const std::string& message; - const unsigned int genpoly_initial_index_; - unsigned int blocks_processed_; - unsigned int block_failures_; - }; - - template - void create_messages(std::vector& message_list, const bool full_test_set = false) - { - /* Various message bit patterns */ - - message_list.clear(); - - if (full_test_set) - { - for (std::size_t i = 0; i < 256; ++i) - { - message_list.push_back(std::string(data_length, static_cast(i))); - } - } - else - { - message_list.push_back(std::string(data_length,static_cast(0x00))); - message_list.push_back(std::string(data_length,static_cast(0xAA))); - message_list.push_back(std::string(data_length,static_cast(0xA5))); - message_list.push_back(std::string(data_length,static_cast(0xAC))); - message_list.push_back(std::string(data_length,static_cast(0xCA))); - message_list.push_back(std::string(data_length,static_cast(0x5A))); - message_list.push_back(std::string(data_length,static_cast(0xCC))); - message_list.push_back(std::string(data_length,static_cast(0xF0))); - message_list.push_back(std::string(data_length,static_cast(0x0F))); - message_list.push_back(std::string(data_length,static_cast(0xFF))); - message_list.push_back(std::string(data_length,static_cast(0x92))); - message_list.push_back(std::string(data_length,static_cast(0x6D))); - message_list.push_back(std::string(data_length,static_cast(0x77))); - message_list.push_back(std::string(data_length,static_cast(0x7A))); - message_list.push_back(std::string(data_length,static_cast(0xA7))); - message_list.push_back(std::string(data_length,static_cast(0xE5))); - message_list.push_back(std::string(data_length,static_cast(0xEB))); - } - - std::string tmp_str = std::string(data_length,static_cast(0x00)); - - for (std::size_t i = 0; i < data_length; ++i) - { - tmp_str[i] = static_cast(i); - } - - message_list.push_back(tmp_str); - - for (int i = data_length - 1; i >= 0; --i) - { - tmp_str[i] = static_cast(i); - } - - message_list.push_back(tmp_str); - - for (std::size_t i = 0; i < data_length; ++i) - { - tmp_str[i] = (((i & 0x01) == 1) ? static_cast(i) : 0x00); - } - - message_list.push_back(tmp_str); - - for (std::size_t i = 0; i < data_length; ++i) - { - tmp_str[i] = (((i & 0x01) == 0) ? static_cast(i) : 0x00); - } - - message_list.push_back(tmp_str); - - for (int i = data_length - 1; i >= 0; --i) - { - tmp_str[i] = (((i & 0x01) == 1) ? static_cast(i) : 0x00); - } - - message_list.push_back(tmp_str); - - for (int i = data_length - 1; i >= 0; --i) - { - tmp_str[i] = (((i & 0x01) == 0) ? static_cast(i) : 0x00); - } - - message_list.push_back(tmp_str); - - tmp_str = std::string(data_length,static_cast(0x00)); - - for (std::size_t i = 0; i < (data_length >> 1); ++i) - { - tmp_str[i] = static_cast(0xFF); - } - - message_list.push_back(tmp_str); - - tmp_str = std::string(data_length,static_cast(0xFF)); - - for (std::size_t i = 0; i < (data_length >> 1); ++i) - { - tmp_str[i] = static_cast(0x00); - } - - message_list.push_back(tmp_str); - } - - template - inline bool codec_validation_test(const std::size_t prim_poly_size,const unsigned int prim_poly[]) - { - const unsigned int data_length = code_length - fec_length; - - galois::field field(field_descriptor,prim_poly_size,prim_poly); - std::vector message_list; - create_messages(message_list); - - for (std::size_t i = 0; i < message_list.size(); ++i) - { - codec_validator - validator(field, gen_poly_index, message_list[i]); - - if (!validator.execute()) - { - return false; - } - } - - return true; - } - - template - inline bool shortened_codec_validation_test(const std::size_t prim_poly_size,const unsigned int prim_poly[]) - { - typedef shortened_encoder encoder_type; - typedef shortened_decoder decoder_type; - - const unsigned int data_length = code_length - fec_length; - - galois::field field(field_descriptor,prim_poly_size,prim_poly); - std::vector message_list; - create_messages(message_list); - - for (std::size_t i = 0; i < message_list.size(); ++i) - { - codec_validator - validator(field,gen_poly_index,message_list[i]); - - if (!validator.execute()) - { - return false; - } - - } - - return true; - } - - inline bool codec_validation_test00() - { - return codec_validation_test<8,120,255, 2>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 4>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 6>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 10>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 12>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 14>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 16>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 18>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 20>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 22>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 24>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 32>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 64>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 80>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255, 96>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && - codec_validation_test<8,120,255,128>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) ; - } - - inline bool codec_validation_test01() - { - return shortened_codec_validation_test<8,120,126,14>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && /* Intelsat 1 RS Code */ - shortened_codec_validation_test<8,120,194,16>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && /* Intelsat 2 RS Code */ - shortened_codec_validation_test<8,120,219,18>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && /* Intelsat 3 RS Code */ - shortened_codec_validation_test<8,120,225,20>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) && /* Intelsat 4 RS Code */ - shortened_codec_validation_test<8, 1,204,16>(galois::primitive_polynomial_size05,galois::primitive_polynomial05) && /* DBV/MPEG-2 TSP RS Code */ - shortened_codec_validation_test<8, 1,104,27>(galois::primitive_polynomial_size05,galois::primitive_polynomial05) && /* Magnetic Storage Outer RS Code */ - shortened_codec_validation_test<8, 1,204,12>(galois::primitive_polynomial_size05,galois::primitive_polynomial05) && /* Magnetic Storage Inner RS Code */ - shortened_codec_validation_test<8,120, 72,10>(galois::primitive_polynomial_size06,galois::primitive_polynomial06) ; /* VDL Mode 3 RS Code */ - } - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_decoder.hpp b/modem/fec/schifra_reed_solomon_decoder.hpp deleted file mode 100644 index 498e133..0000000 --- a/modem/fec/schifra_reed_solomon_decoder.hpp +++ /dev/null @@ -1,485 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_DECODER_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_DECODER_HPP - - -#include "schifra_galois_field.hpp" -#include "schifra_galois_field_element.hpp" -#include "schifra_galois_field_polynomial.hpp" -#include "schifra_reed_solomon_block.hpp" -#include "schifra_ecc_traits.hpp" - - -namespace schifra -{ - namespace reed_solomon - { - - template - class decoder - { - public: - - typedef traits::reed_solomon_triat trait; - typedef block block_type; - - decoder(const galois::field& field, const unsigned int& gen_initial_index = 0) - : decoder_valid_(field.size() == code_length), - field_(field), - X_(galois::generate_X(field_)), - gen_initial_index_(gen_initial_index) - { - if (decoder_valid_) - { - //Note: code_length and field size can be used interchangeably - create_lookup_tables(); - } - }; - - const galois::field& field() const - { - return field_; - } - - bool decode(block_type& rsblock) const - { - std::vector erasure_list; - return decode(rsblock,erasure_list); - } - - bool decode(block_type& rsblock, const erasure_locations_t& erasure_list) const - { - if ((!decoder_valid_) || (erasure_list.size() > fec_length)) - { - rsblock.errors_detected = 0; - rsblock.errors_corrected = 0; - rsblock.zero_numerators = 0; - rsblock.unrecoverable = true; - rsblock.error = block_type::e_decoder_error0; - - return false; - } - - galois::field_polynomial received(field_,code_length - 1); - load_message(received,rsblock); - - galois::field_polynomial syndrome(field_); - - if (compute_syndrome(received,syndrome) == 0) - { - rsblock.errors_detected = 0; - rsblock.errors_corrected = 0; - rsblock.zero_numerators = 0; - rsblock.unrecoverable = false; - - return true; - } - - galois::field_polynomial lambda(galois::field_element(field_,1)); - - erasure_locations_t erasure_locations; - - if (!erasure_list.empty()) - { - prepare_erasure_list(erasure_locations, erasure_list); - - compute_gamma(lambda, erasure_locations); - } - - if (erasure_list.size() < fec_length) - { - modified_berlekamp_massey_algorithm(lambda, syndrome, erasure_list.size()); - } - - std::vector error_locations; - - find_roots(lambda, error_locations); - - if (0 == error_locations.size()) - { - /* - Syndrome is non-zero yet no error locations have - been obtained, conclusion: - It is possible that there are MORE errrors in the - message than can be detected and corrected for this - particular code. - */ - - rsblock.errors_detected = 0; - rsblock.errors_corrected = 0; - rsblock.zero_numerators = 0; - rsblock.unrecoverable = true; - rsblock.error = block_type::e_decoder_error1; - - return false; - } - else if (((2 * error_locations.size()) - erasure_list.size()) > fec_length) - { - /* - Too many errors\erasures! 2E + S <= fec_length - L = E + S - E = L - S - 2E = 2L - 2S - 2E + S = 2L - 2S + S - = 2L - S - Where: - L : Error Locations - E : Errors - S : Erasures - - */ - - rsblock.errors_detected = error_locations.size(); - rsblock.errors_corrected = 0; - rsblock.zero_numerators = 0; - rsblock.unrecoverable = true; - rsblock.error = block_type::e_decoder_error2; - - return false; - } - else - rsblock.errors_detected = error_locations.size(); - - return forney_algorithm(error_locations, lambda, syndrome, rsblock); - } - - private: - - decoder(); - decoder(const decoder& dec); - decoder& operator=(const decoder& dec); - - protected: - - void load_message(galois::field_polynomial& received, const block_type& rsblock) const - { - /* - Load message data into received polynomial in reverse order. - */ - - for (std::size_t i = 0; i < code_length; ++i) - { - received[code_length - 1 - i] = rsblock[i]; - } - } - - void create_lookup_tables() - { - root_exponent_table_.reserve(field_.size() + 1); - - for (int i = 0; i < static_cast(field_.size() + 1); ++i) - { - root_exponent_table_.push_back(field_.exp(field_.alpha(code_length - i),(1 - gen_initial_index_))); - } - - syndrome_exponent_table_.reserve(fec_length); - - for (int i = 0; i < static_cast(fec_length); ++i) - { - syndrome_exponent_table_.push_back(field_.alpha(gen_initial_index_ + i)); - } - - gamma_table_.reserve(field_.size() + 1); - - for (int i = 0; i < static_cast(field_.size() + 1); ++i) - { - gamma_table_.push_back((1 + (X_ * galois::field_element(field_,field_.alpha(i))))); - } - } - - void prepare_erasure_list(erasure_locations_t& erasure_locations, const erasure_locations_t& erasure_list) const - { - /* - Note: 1. Erasure positions must be unique. - 2. Erasure positions must exist within the code block. - There are NO exceptions to these rules! - */ - - erasure_locations.resize(erasure_list.size()); - - for (std::size_t i = 0; i < erasure_list.size(); ++i) - { - erasure_locations[i] = (code_length - 1 - erasure_list[i]); - } - } - - int compute_syndrome(const galois::field_polynomial& received, - galois::field_polynomial& syndrome) const - { - int error_flag = 0; - syndrome = galois::field_polynomial(field_,fec_length - 1); - - for (std::size_t i = 0; i < fec_length; ++i) - { - syndrome[i] = received(syndrome_exponent_table_[i]); - error_flag |= syndrome[i].poly(); - } - - return error_flag; - } - - void compute_gamma(galois::field_polynomial& gamma, const erasure_locations_t& erasure_locations) const - { - for (std::size_t i = 0; i < erasure_locations.size(); ++i) - { - gamma *= gamma_table_[erasure_locations[i]]; - } - } - - void find_roots(const galois::field_polynomial& poly, std::vector& root_list) const - { - /* - Chien Search: Find the roots of the error locator polynomial - via an exhaustive search over all non-zero elements in the - given finite field. - */ - - root_list.reserve(fec_length << 1); - root_list.resize(0); - - const std::size_t polynomial_degree = poly.deg(); - - for (int i = 1; i <= static_cast(code_length); ++i) - { - if (0 == poly(field_.alpha(i)).poly()) - { - root_list.push_back(i); - - if (polynomial_degree == root_list.size()) - { - break; - } - } - } - } - - void compute_discrepancy(galois::field_element& discrepancy, - const galois::field_polynomial& lambda, - const galois::field_polynomial& syndrome, - const std::size_t& l, - const std::size_t& round) const - { - /* - Compute the lambda discrepancy at the current round of BMA - */ - - const std::size_t upper_bound = std::min(static_cast(l), lambda.deg()); - - discrepancy = 0; - - for (std::size_t i = 0; i <= upper_bound; ++i) - { - discrepancy += lambda[i] * syndrome[round - i]; - } - } - - void modified_berlekamp_massey_algorithm(galois::field_polynomial& lambda, - const galois::field_polynomial& syndrome, - const std::size_t erasure_count) const - { - /* - Modified Berlekamp-Massey Algorithm - Identify the shortest length linear feed-back shift register (LFSR) - that will generate the sequence equivalent to the syndrome. - */ - - int i = -1; - std::size_t l = erasure_count; - - galois::field_element discrepancy(field_,0); - galois::field_polynomial previous_lambda = lambda << 1; - - for (std::size_t round = erasure_count; round < fec_length; ++round) - { - compute_discrepancy(discrepancy, lambda, syndrome, l, round); - - if (discrepancy != 0) - { - galois::field_polynomial tau = lambda - (discrepancy * previous_lambda); - - if (static_cast(l) < (static_cast(round) - i)) - { - const std::size_t tmp = round - i; - i = static_cast(round - l); - l = tmp; - previous_lambda = lambda / discrepancy; - } - - lambda = tau; - } - - previous_lambda <<= 1; - } - } - - bool forney_algorithm(const std::vector& error_locations, - const galois::field_polynomial& lambda, - const galois::field_polynomial& syndrome, - block_type& rsblock) const - { - /* - The Forney algorithm for computing the error magnitudes - */ - const galois::field_polynomial omega = (lambda * syndrome) % fec_length; - const galois::field_polynomial lambda_derivative = lambda.derivative(); - - rsblock.errors_corrected = 0; - rsblock.zero_numerators = 0; - - for (std::size_t i = 0; i < error_locations.size(); ++i) - { - const unsigned int error_location = error_locations[i]; - const galois::field_symbol alpha_inverse = field_.alpha(error_location); - const galois::field_symbol numerator = (omega(alpha_inverse) * root_exponent_table_[error_location]).poly(); - const galois::field_symbol denominator = lambda_derivative(alpha_inverse).poly(); - - if (0 != numerator) - { - if (0 != denominator) - { - rsblock[error_location - 1] ^= field_.div(numerator, denominator); - rsblock.errors_corrected++; - } - else - { - rsblock.unrecoverable = true; - rsblock.error = block_type::e_decoder_error3; - return false; - } - } - else - ++rsblock.zero_numerators; - } - - if (lambda.deg() == static_cast(rsblock.errors_detected)) - return true; - else - { - rsblock.unrecoverable = true; - rsblock.error = block_type::e_decoder_error4; - return false; - } - } - - protected: - - bool decoder_valid_; - const galois::field& field_; - std::vector root_exponent_table_; - std::vector syndrome_exponent_table_; - std::vector gamma_table_; - const galois::field_polynomial X_; - const unsigned int gen_initial_index_; - }; - - template - class shortened_decoder - { - public: - - typedef traits::reed_solomon_triat trait; - typedef block block_type; - - shortened_decoder(const galois::field& field, const unsigned int gen_initial_index = 0) - : decoder_(field, gen_initial_index) - {} - - inline bool decode(block_type& rsblock, const erasure_locations_t& erasure_list) const - { - typename natural_decoder_type::block_type block; - - std::fill_n(&block[0], padding_length, typename block_type::symbol_type(0)); - - for (std::size_t i = 0; i < code_length; ++i) - { - block.data[padding_length + i] = rsblock.data[i]; - } - - erasure_locations_t shifted_position_erasure_list(erasure_list.size(),0); - - for (std::size_t i = 0; i < erasure_list.size(); ++i) - { - shifted_position_erasure_list[i] = erasure_list[i] + padding_length; - } - - if (decoder_.decode(block, shifted_position_erasure_list)) - { - for (std::size_t i = 0; i < code_length; ++i) - { - rsblock.data[i] = block.data[padding_length + i]; - } - - rsblock.copy_state(block); - return true; - } - else - { - rsblock.copy_state(block); - return false; - } - } - - inline bool decode(block_type& rsblock) const - { - typename natural_decoder_type::block_type block; - - std::fill_n(&block[0], padding_length, typename block_type::symbol_type(0)); - - for (std::size_t i = 0; i < code_length; ++i) - { - block.data[padding_length + i] = rsblock.data[i]; - } - - if (decoder_.decode(block)) - { - for (std::size_t i = 0; i < code_length; ++i) - { - rsblock.data[i] = block.data[padding_length + i]; - } - - rsblock.copy_state(block); - return true; - } - else - { - rsblock.copy_state(block); - return false; - } - } - - private: - - typedef decoder natural_decoder_type; - const natural_decoder_type decoder_; - }; - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_encoder.hpp b/modem/fec/schifra_reed_solomon_encoder.hpp deleted file mode 100644 index 87641b8..0000000 --- a/modem/fec/schifra_reed_solomon_encoder.hpp +++ /dev/null @@ -1,204 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_ENCODER_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_ENCODER_HPP - - -#include - -#include "schifra_galois_field.hpp" -#include "schifra_galois_field_element.hpp" -#include "schifra_galois_field_polynomial.hpp" -#include "schifra_reed_solomon_block.hpp" -#include "schifra_ecc_traits.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template - class encoder - { - public: - - typedef traits::reed_solomon_triat trait; - typedef block block_type; - - encoder(const galois::field& gfield, const galois::field_polynomial& generator) - : encoder_valid_(code_length == gfield.size()), - field_(gfield), - generator_(generator) - {} - - ~encoder() - {} - - inline bool encode(block_type& rsblock) const - { - if (!encoder_valid_) - { - rsblock.error = block_type::e_encoder_error0; - return false; - } - - const galois::field_polynomial parities = msg_poly(rsblock) % generator_; - const galois::field_symbol mask = field_.mask(); - - if (parities.deg() == (fec_length - 1)) - { - for (std::size_t i = 0; i < fec_length; ++i) - { - rsblock.fec(i) = parities[fec_length - 1 - i].poly() & mask; - } - } - else - { - /* - Note: Encoder should never branch here. - Possible issues to look for: - 1. Generator polynomial degree is not equivelent to fec length - 2. Field and code length are not consistent. - - */ - rsblock.error = block_type::e_encoder_error1; - return false; - } - - return true; - } - - inline bool encode(const std::string& data, block_type& rsblock) const - { - std::string::const_iterator itr = data.begin(); - const galois::field_symbol mask = field_.mask(); - - for (std::size_t i = 0; i < data_length; ++i, ++itr) - { - rsblock.data[i] = static_cast(*itr) & mask; - } - - return encode(rsblock); - } - - private: - - encoder(); - encoder(const encoder& enc); - encoder& operator=(const encoder& enc); - - inline galois::field_polynomial msg_poly(const block_type& rsblock) const - { - galois::field_polynomial message(field_, code_length); - - for (std::size_t i = fec_length; i < code_length; ++i) - { - message[i] = rsblock.data[code_length - 1 - i]; - } - - return message; - } - - const bool encoder_valid_; - const galois::field& field_; - const galois::field_polynomial generator_; - }; - - template - class shortened_encoder - { - public: - - typedef traits::reed_solomon_triat trait; - typedef block block_type; - typedef block short_block_t; - - shortened_encoder(const galois::field& gfield, - const galois::field_polynomial& generator) - : encoder_(gfield, generator) - {} - - inline bool encode(block_type& rsblock) const - { - short_block_t block; - - std::fill_n(&block[0], padding_length, typename block_type::symbol_type(0)); - - for (std::size_t i = 0; i < data_length; ++i) - { - block.data[padding_length + i] = rsblock.data[i]; - } - - if (encoder_.encode(block)) - { - for (std::size_t i = 0; i < fec_length; ++i) - { - rsblock.fec(i) = block.fec(i); - } - - return true; - } - else - return false; - } - - inline bool encode(const std::string& data, block_type& rsblock) const - { - short_block_t block; - - std::fill_n(&block[0], padding_length, typename block_type::symbol_type(0)); - - for (std::size_t i = 0; i < data_length; ++i) - { - block.data[padding_length + i] = data[i]; - } - - if (encoder_.encode(block)) - { - for (std::size_t i = 0; i < code_length; ++i) - { - rsblock.data[i] = block.data[padding_length + i]; - } - - return true; - } - else - return false; - } - - private: - - const encoder encoder_; - }; - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_file_decoder.hpp b/modem/fec/schifra_reed_solomon_file_decoder.hpp deleted file mode 100644 index f189868..0000000 --- a/modem/fec/schifra_reed_solomon_file_decoder.hpp +++ /dev/null @@ -1,171 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_FILE_DECODER_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_FILE_DECODER_HPP - - -#include -#include - -#include "schifra_reed_solomon_block.hpp" -#include "schifra_reed_solomon_decoder.hpp" -#include "schifra_fileio.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template - class file_decoder - { - public: - - typedef decoder decoder_type; - typedef typename decoder_type::block_type block_type; - - file_decoder(const decoder_type& decoder, - const std::string& input_file_name, - const std::string& output_file_name) - : current_block_index_(0) - { - std::size_t remaining_bytes = schifra::fileio::file_size(input_file_name); - - if (remaining_bytes == 0) - { - std::cout << "reed_solomon::file_decoder() - Error: input file has ZERO size." << std::endl; - return; - } - - std::ifstream in_stream(input_file_name.c_str(),std::ios::binary); - if (!in_stream) - { - std::cout << "reed_solomon::file_decoder() - Error: input file could not be opened." << std::endl; - return; - } - - std::ofstream out_stream(output_file_name.c_str(),std::ios::binary); - if (!out_stream) - { - std::cout << "reed_solomon::file_decoder() - Error: output file could not be created." << std::endl; - return; - } - - current_block_index_ = 0; - - while (remaining_bytes >= code_length) - { - process_complete_block(decoder,in_stream,out_stream); - remaining_bytes -= code_length; - current_block_index_++; - } - - if (remaining_bytes > 0) - { - process_partial_block(decoder,in_stream,out_stream,remaining_bytes); - } - - in_stream.close(); - out_stream.close(); - } - - private: - - inline void process_complete_block(const decoder_type& decoder, - std::ifstream& in_stream, - std::ofstream& out_stream) - { - in_stream.read(&buffer_[0],static_cast(code_length)); - copy(buffer_,code_length,block_); - - if (!decoder.decode(block_)) - { - std::cout << "reed_solomon::file_decoder.process_complete_block() - Error during decoding of block " << current_block_index_ << "!" << std::endl; - return; - } - - for (std::size_t i = 0; i < data_length; ++i) - { - buffer_[i] = static_cast(block_[i]); - } - - out_stream.write(&buffer_[0],static_cast(data_length)); - } - - inline void process_partial_block(const decoder_type& decoder, - std::ifstream& in_stream, - std::ofstream& out_stream, - const std::size_t& read_amount) - { - if (read_amount <= fec_length) - { - std::cout << "reed_solomon::file_decoder.process_partial_block() - Error during decoding of block " << current_block_index_ << "!" << std::endl; - return; - } - - in_stream.read(&buffer_[0],static_cast(read_amount)); - - for (std::size_t i = 0; i < (read_amount - fec_length); ++i) - { - block_.data[i] = static_cast(buffer_[i]); - } - - if ((read_amount - fec_length) < data_length) - { - for (std::size_t i = (read_amount - fec_length); i < data_length; ++i) - { - block_.data[i] = 0; - } - } - - for (std::size_t i = 0; i < fec_length; ++i) - { - block_.fec(i) = static_cast(buffer_[(read_amount - fec_length) + i]); - } - - if (!decoder.decode(block_)) - { - std::cout << "reed_solomon::file_decoder.process_partial_block() - Error during decoding of block " << current_block_index_ << "!" << std::endl; - return; - } - - for (std::size_t i = 0; i < (read_amount - fec_length); ++i) - { - buffer_[i] = static_cast(block_.data[i]); - } - - out_stream.write(&buffer_[0],static_cast(read_amount - fec_length)); - } - - block_type block_; - std::size_t current_block_index_; - char buffer_[code_length]; - }; - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_file_encoder.hpp b/modem/fec/schifra_reed_solomon_file_encoder.hpp deleted file mode 100644 index 98649ab..0000000 --- a/modem/fec/schifra_reed_solomon_file_encoder.hpp +++ /dev/null @@ -1,138 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_FILE_ENCODER_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_FILE_ENCODER_HPP - - -#include -#include -#include - -#include "schifra_reed_solomon_block.hpp" -#include "schifra_reed_solomon_encoder.hpp" -#include "schifra_fileio.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template - class file_encoder - { - public: - - typedef encoder encoder_type; - typedef typename encoder_type::block_type block_type; - - file_encoder(const encoder_type& encoder, - const std::string& input_file_name, - const std::string& output_file_name) - { - std::size_t remaining_bytes = schifra::fileio::file_size(input_file_name); - if (remaining_bytes == 0) - { - std::cout << "reed_solomon::file_encoder() - Error: input file has ZERO size." << std::endl; - return; - } - - std::ifstream in_stream(input_file_name.c_str(),std::ios::binary); - if (!in_stream) - { - std::cout << "reed_solomon::file_encoder() - Error: input file could not be opened." << std::endl; - return; - } - - std::ofstream out_stream(output_file_name.c_str(),std::ios::binary); - if (!out_stream) - { - std::cout << "reed_solomon::file_encoder() - Error: output file could not be created." << std::endl; - return; - } - - std::memset(data_buffer_,0,sizeof(data_buffer_)); - std::memset(fec_buffer_ ,0,sizeof(fec_buffer_ )); - - while (remaining_bytes >= data_length) - { - process_block(encoder,in_stream,out_stream,data_length); - remaining_bytes -= data_length; - } - - if (remaining_bytes > 0) - { - process_block(encoder,in_stream,out_stream,remaining_bytes); - } - - in_stream.close(); - out_stream.close(); - } - - private: - - inline void process_block(const encoder_type& encoder, - std::ifstream& in_stream, - std::ofstream& out_stream, - const std::size_t& read_amount) - { - in_stream.read(&data_buffer_[0],static_cast(read_amount)); - for (std::size_t i = 0; i < read_amount; ++i) - { - block_.data[i] = (data_buffer_[i] & 0xFF); - } - - if (read_amount < data_length) - { - for (std::size_t i = read_amount; i < data_length; ++i) - { - block_.data[i] = 0x00; - } - } - - if (!encoder.encode(block_)) - { - std::cout << "reed_solomon::file_encoder.process_block() - Error during encoding of block!" << std::endl; - return; - } - - for (std::size_t i = 0; i < fec_length; ++i) - { - fec_buffer_[i] = static_cast(block_.fec(i) & 0xFF); - } - - out_stream.write(&data_buffer_[0],static_cast(read_amount)); - out_stream.write(&fec_buffer_[0],fec_length); - } - - block_type block_; - char data_buffer_[data_length]; - char fec_buffer_[fec_length]; - }; - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_file_interleaver.hpp b/modem/fec/schifra_reed_solomon_file_interleaver.hpp deleted file mode 100644 index 54cd7b4..0000000 --- a/modem/fec/schifra_reed_solomon_file_interleaver.hpp +++ /dev/null @@ -1,247 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_FILE_INTERLEAVER_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_FILE_INTERLEAVER_HPP - - -#include -#include - -#include "schifra_reed_solomon_interleaving.hpp" -#include "schifra_fileio.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template - class file_interleaver - { - public: - - file_interleaver(const std::string& input_file_name, - const std::string& output_file_name) - { - std::size_t remaining_bytes = schifra::fileio::file_size(input_file_name); - - if (0 == remaining_bytes) - { - std::cout << "reed_solomon::file_interleaver() - Error: input file has ZERO size." << std::endl; - return; - } - - std::ifstream in_stream(input_file_name.c_str(),std::ios::binary); - - if (!in_stream) - { - std::cout << "reed_solomon::file_interleaver() - Error: input file could not be opened." << std::endl; - return; - } - - std::ofstream out_stream(output_file_name.c_str(),std::ios::binary); - - if (!out_stream) - { - std::cout << "reed_solomon::file_interleaver() - Error: output file could not be created." << std::endl; - return; - } - - while (remaining_bytes >= (block_length * stack_size)) - { - process_block(in_stream,out_stream); - remaining_bytes -= (block_length * stack_size); - } - - if (remaining_bytes > 0) - { - process_incomplete_block(in_stream,out_stream,remaining_bytes); - } - - in_stream.close(); - out_stream.close(); - } - - private: - - inline void process_block(std::ifstream& in_stream, - std::ofstream& out_stream) - { - for (std::size_t i = 0; i < stack_size; ++i) - { - in_stream.read(&block_stack_[i][0],static_cast(block_length)); - } - - interleave(block_stack_); - - for (std::size_t i = 0; i < stack_size; ++i) - { - out_stream.write(&block_stack_[i][0],static_cast(block_length)); - } - } - - inline void process_incomplete_block(std::ifstream& in_stream, - std::ofstream& out_stream, - const std::size_t amount) - { - std::size_t complete_row_count = amount / block_length; - std::size_t remainder = amount % block_length; - - for (std::size_t i = 0; i < complete_row_count; ++i) - { - in_stream.read(&block_stack_[i][0],static_cast(block_length)); - } - - if (remainder != 0) - { - in_stream.read(&block_stack_[complete_row_count][0],static_cast(remainder)); - } - - if (remainder == 0) - interleave(block_stack_,complete_row_count); - else - interleave(block_stack_,complete_row_count + 1,remainder); - - for (std::size_t i = 0; i < complete_row_count; ++i) - { - out_stream.write(&block_stack_[i][0],static_cast(block_length)); - } - - if (remainder != 0) - { - out_stream.write(&block_stack_[complete_row_count][0],static_cast(remainder)); - } - } - - data_block block_stack_[stack_size]; - - }; - - template - class file_deinterleaver - { - public: - - file_deinterleaver(const std::string& input_file_name, - const std::string& output_file_name) - { - std::size_t input_file_size = schifra::fileio::file_size(input_file_name); - - if (input_file_size == 0) - { - std::cout << "reed_solomon::file_deinterleaver() - Error: input file has ZERO size." << std::endl; - return; - } - - std::ifstream in_stream(input_file_name.c_str(),std::ios::binary); - - if (!in_stream) - { - std::cout << "reed_solomon::file_deinterleaver() - Error: input file could not be opened." << std::endl; - return; - } - - std::ofstream out_stream(output_file_name.c_str(),std::ios::binary); - - if (!out_stream) - { - std::cout << "reed_solomon::file_deinterleaver() - Error: output file could not be created." << std::endl; - return; - } - - for (std::size_t i = 0; i < (input_file_size / (block_length * stack_size)); ++i) - { - process_block(in_stream,out_stream); - } - - if ((input_file_size % (block_length * stack_size)) != 0) - { - process_incomplete_block(in_stream,out_stream,(input_file_size % (block_length * stack_size))); - } - - in_stream.close(); - out_stream.close(); - } - - private: - - inline void process_block(std::ifstream& in_stream, - std::ofstream& out_stream) - { - for (std::size_t i = 0; i < stack_size; ++i) - { - in_stream.read(&block_stack_[i][0],static_cast(block_length)); - } - - deinterleave(block_stack_); - - for (std::size_t i = 0; i < stack_size; ++i) - { - out_stream.write(&block_stack_[i][0],static_cast(block_length)); - } - } - - inline void process_incomplete_block(std::ifstream& in_stream, - std::ofstream& out_stream, - const std::size_t amount) - { - std::size_t complete_row_count = amount / block_length; - std::size_t remainder = amount % block_length; - - for (std::size_t i = 0; i < complete_row_count; ++i) - { - in_stream.read(&block_stack_[i][0],static_cast(block_length)); - } - - if (remainder != 0) - { - in_stream.read(&block_stack_[complete_row_count][0],static_cast(remainder)); - } - - if (remainder == 0) - deinterleave(block_stack_,complete_row_count); - else - deinterleave(block_stack_,complete_row_count + 1,remainder); - - for (std::size_t i = 0; i < complete_row_count; ++i) - { - out_stream.write(&block_stack_[i][0],static_cast(block_length)); - } - - if (remainder != 0) - { - out_stream.write(&block_stack_[complete_row_count][0],static_cast(remainder)); - } - } - - data_block block_stack_[stack_size]; - - }; - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_general_codec.hpp b/modem/fec/schifra_reed_solomon_general_codec.hpp deleted file mode 100644 index a73ee30..0000000 --- a/modem/fec/schifra_reed_solomon_general_codec.hpp +++ /dev/null @@ -1,210 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_GENERAL_CODEC_HPP -#define INCLUDE_SCHIFRA_REED_GENERAL_CODEC_HPP - - -#include "schifra_galois_field.hpp" -#include "schifra_galois_field_polynomial.hpp" -#include "schifra_sequential_root_generator_polynomial_creator.hpp" -#include "schifra_reed_solomon_block.hpp" -#include "schifra_reed_solomon_encoder.hpp" -#include "schifra_reed_solomon_decoder.hpp" -#include "schifra_ecc_traits.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template - void* create_encoder(const galois::field& field, - const std::size_t& gen_poly_index) - { - const std::size_t data_length = code_length - fec_length; - traits::validate_reed_solomon_code_parameters(); - galois::field_polynomial gen_polynomial(field); - - if ( - !make_sequential_root_generator_polynomial(field, - gen_poly_index, - fec_length, - gen_polynomial) - ) - { - return reinterpret_cast(0); - } - - return new encoder(field,gen_polynomial); - } - - template - void* create_decoder(const galois::field& field, - const std::size_t& gen_poly_index) - { - const std::size_t data_length = code_length - fec_length; - traits::validate_reed_solomon_code_parameters(); - return new decoder(field,static_cast(gen_poly_index)); - } - - template - class general_codec - { - public: - - general_codec(const galois::field& field, - const std::size_t& gen_poly_index) - { - for (std::size_t i = 0; i < max_fec_length; ++i) - { - encoder_[i] = 0; - decoder_[i] = 0; - } - - encoder_[ 2] = create_encoder(field, gen_poly_index); - encoder_[ 4] = create_encoder(field, gen_poly_index); - encoder_[ 6] = create_encoder(field, gen_poly_index); - encoder_[ 8] = create_encoder(field, gen_poly_index); - encoder_[ 10] = create_encoder(field, gen_poly_index); - encoder_[ 12] = create_encoder(field, gen_poly_index); - encoder_[ 14] = create_encoder(field, gen_poly_index); - encoder_[ 16] = create_encoder(field, gen_poly_index); - encoder_[ 18] = create_encoder(field, gen_poly_index); - encoder_[ 20] = create_encoder(field, gen_poly_index); - encoder_[ 22] = create_encoder(field, gen_poly_index); - encoder_[ 24] = create_encoder(field, gen_poly_index); - encoder_[ 26] = create_encoder(field, gen_poly_index); - encoder_[ 28] = create_encoder(field, gen_poly_index); - encoder_[ 30] = create_encoder(field, gen_poly_index); - encoder_[ 32] = create_encoder(field, gen_poly_index); - encoder_[ 64] = create_encoder(field, gen_poly_index); - encoder_[ 80] = create_encoder(field, gen_poly_index); - encoder_[ 96] = create_encoder(field, gen_poly_index); - encoder_[128] = create_encoder(field, gen_poly_index); - - decoder_[ 2] = create_decoder(field, gen_poly_index); - decoder_[ 4] = create_decoder(field, gen_poly_index); - decoder_[ 6] = create_decoder(field, gen_poly_index); - decoder_[ 8] = create_decoder(field, gen_poly_index); - decoder_[ 10] = create_decoder(field, gen_poly_index); - decoder_[ 12] = create_decoder(field, gen_poly_index); - decoder_[ 14] = create_decoder(field, gen_poly_index); - decoder_[ 16] = create_decoder(field, gen_poly_index); - decoder_[ 18] = create_decoder(field, gen_poly_index); - decoder_[ 20] = create_decoder(field, gen_poly_index); - decoder_[ 22] = create_decoder(field, gen_poly_index); - decoder_[ 24] = create_decoder(field, gen_poly_index); - decoder_[ 26] = create_decoder(field, gen_poly_index); - decoder_[ 28] = create_decoder(field, gen_poly_index); - decoder_[ 30] = create_decoder(field, gen_poly_index); - decoder_[ 32] = create_decoder(field, gen_poly_index); - decoder_[ 64] = create_decoder(field, gen_poly_index); - decoder_[ 80] = create_decoder(field, gen_poly_index); - decoder_[ 96] = create_decoder(field, gen_poly_index); - decoder_[128] = create_decoder(field, gen_poly_index); - } - - ~general_codec() - { - delete static_cast*>(encoder_[ 2]); - delete static_cast*>(encoder_[ 4]); - delete static_cast*>(encoder_[ 6]); - delete static_cast*>(encoder_[ 8]); - delete static_cast*>(encoder_[ 10]); - delete static_cast*>(encoder_[ 12]); - delete static_cast*>(encoder_[ 14]); - delete static_cast*>(encoder_[ 16]); - delete static_cast*>(encoder_[ 18]); - delete static_cast*>(encoder_[ 20]); - delete static_cast*>(encoder_[ 22]); - delete static_cast*>(encoder_[ 24]); - delete static_cast*>(encoder_[ 26]); - delete static_cast*>(encoder_[ 28]); - delete static_cast*>(encoder_[ 30]); - delete static_cast*>(encoder_[ 32]); - delete static_cast*>(encoder_[ 64]); - delete static_cast*>(encoder_[ 80]); - delete static_cast*>(encoder_[ 96]); - delete static_cast*>(encoder_[128]); - - delete static_cast*>(decoder_[ 2]); - delete static_cast*>(decoder_[ 4]); - delete static_cast*>(decoder_[ 6]); - delete static_cast*>(decoder_[ 8]); - delete static_cast*>(decoder_[ 10]); - delete static_cast*>(decoder_[ 12]); - delete static_cast*>(decoder_[ 14]); - delete static_cast*>(decoder_[ 16]); - delete static_cast*>(decoder_[ 18]); - delete static_cast*>(decoder_[ 20]); - delete static_cast*>(decoder_[ 22]); - delete static_cast*>(decoder_[ 24]); - delete static_cast*>(decoder_[ 26]); - delete static_cast*>(decoder_[ 28]); - delete static_cast*>(decoder_[ 30]); - delete static_cast*>(decoder_[ 32]); - delete static_cast*>(decoder_[ 64]); - delete static_cast*>(decoder_[ 80]); - delete static_cast*>(decoder_[ 96]); - delete static_cast*>(decoder_[128]); - } - - template - bool encode(Block& block) const - { - /* - cl : code length - fl : fec length - */ - typedef reed_solomon::encoder encoder_type; - traits::__static_assert__<(Block::trait::fec_length <= max_fec_length)>(); - if (encoder_[Block::trait::fec_length] == 0) - return false; - else - return static_cast(encoder_[Block::trait::fec_length])->encode(block); - } - - template - bool decode(Block& block) const - { - typedef reed_solomon::decoder decoder_type; - traits::__static_assert__<(Block::trait::fec_length <= max_fec_length)>(); - if (decoder_[Block::trait::fec_length] == 0) - return false; - else - return static_cast(decoder_[Block::trait::fec_length])->decode(block); - } - - private: - - void* encoder_[max_fec_length + 1]; - void* decoder_[max_fec_length + 1]; - }; - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_interleaving.hpp b/modem/fec/schifra_reed_solomon_interleaving.hpp deleted file mode 100644 index 0f62290..0000000 --- a/modem/fec/schifra_reed_solomon_interleaving.hpp +++ /dev/null @@ -1,639 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_INTERLEAVING_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_INTERLEAVING_HPP - - -#include -#include -#include - -#include "schifra_reed_solomon_block.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template - inline void interleave(block (&block_stack)[code_length]) - { - for (std::size_t i = 0; i < code_length; ++i) - { - for (std::size_t j = i + 1; j < code_length; ++j) - { - typename block::symbol_type tmp = block_stack[i][j]; - block_stack[i][j] = block_stack[j][i]; - block_stack[j][i] = tmp; - } - } - } - - template - inline void interleave(block (&block_stack)[row_count]) - { - block auxiliary_stack[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = 0; - - for (std::size_t index = 0; index < code_length; ++index) - { - for (std::size_t row = 0; row < row_count; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_index == code_length) - { - aux_index = 0; - aux_row++; - } - } - } - - copy(auxiliary_stack,block_stack); - } - - template - inline void interleave(block (&block_stack)[row_count], - const std::size_t partial_code_length) - { - if (partial_code_length == code_length) - { - interleave(block_stack); - } - else - { - block auxiliary_stack[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = 0; - - for (std::size_t index = 0; index < partial_code_length; ++index) - { - for (std::size_t row = 0; row < row_count; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_index == code_length) - { - aux_index = 0; - aux_row++; - } - } - } - - for (std::size_t index = partial_code_length; index < code_length; ++index) - { - for (std::size_t row = 0; row < row_count - 1; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_index == code_length) - { - aux_index = 0; - aux_row++; - } - } - } - - for (std::size_t row = 0; row < row_count - 1; ++row) - { - for (std::size_t index = 0; index < code_length - fec_length; ++index) - { - block_stack[row].data[index] = auxiliary_stack[row].data[index]; - } - for (std::size_t index = 0; index < fec_length; ++index) - { - block_stack[row].fec[index] = auxiliary_stack[row].fec[index]; - } - } - - for (std::size_t index = 0; index < partial_code_length; ++index) - { - block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; - } - } - } - - template - inline void interleave(data_block (&block_stack)[block_length]) - { - for (std::size_t i = 0; i < block_length; ++i) - { - for (std::size_t j = i + 1; j < block_length; ++j) - { - T tmp = block_stack[i][j]; - block_stack[i][j] = block_stack[j][i]; - block_stack[j][i] = tmp; - } - } - } - - template - inline void interleave(data_block (&block_stack)[row_count]) - { - data_block auxiliary_stack[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = 0; - - for (std::size_t index = 0; index < block_length; ++index) - { - for (std::size_t row = 0; row < row_count; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_index == block_length) - { - aux_index = 0; - aux_row++; - } - } - } - - copy(auxiliary_stack,block_stack); - } - - template - inline void interleave(data_block (&block_stack)[row_count], - const std::size_t partial_block_length) - { - if (partial_block_length == block_length) - { - interleave(block_stack); - } - else - { - data_block auxiliary_stack[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = 0; - - for (std::size_t index = 0; index < partial_block_length; ++index) - { - for (std::size_t row = 0; row < row_count; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_index == block_length) - { - aux_index = 0; - aux_row++; - } - } - } - - for (std::size_t index = partial_block_length; index < block_length; ++index) - { - for (std::size_t row = 0; row < row_count - 1; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - if (++aux_index == block_length) - { - aux_index = 0; - aux_row++; - } - } - } - - for (std::size_t row = 0; row < row_count - 1; ++row) - { - for (std::size_t index = 0; index < block_length; ++index) - { - block_stack[row][index] = auxiliary_stack[row][index]; - } - } - - for (std::size_t index = 0; index < partial_block_length; ++index) - { - block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; - } - } - } - - template - inline void interleave(data_block block_stack[], - const std::size_t row_count) - { - data_block* auxiliary_stack = new data_block[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = 0; - - for (std::size_t index = 0; index < block_length; ++index) - { - for (std::size_t row = 0; row < row_count; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_index == block_length) - { - aux_index = 0; - aux_row++; - } - } - } - - for (std::size_t row = 0; row < row_count; ++row) - { - for (std::size_t index = 0; index < block_length; ++index) - { - block_stack[row][index] = auxiliary_stack[row][index]; - } - } - - delete[] auxiliary_stack; - } - - template - inline void interleave(data_block block_stack[], - const std::size_t row_count, - const std::size_t partial_block_length) - { - data_block* auxiliary_stack = new data_block[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = 0; - - for (std::size_t index = 0; index < partial_block_length; ++index) - { - for (std::size_t row = 0; row < row_count; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_index == block_length) - { - aux_index = 0; - aux_row++; - } - } - } - - for (std::size_t index = partial_block_length; index < block_length; ++index) - { - for (std::size_t row = 0; row < row_count - 1; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_index == block_length) - { - aux_index = 0; - aux_row++; - } - } - } - - for (std::size_t row = 0; row < row_count - 1; ++row) - { - for (std::size_t index = 0; index < block_length; ++index) - { - block_stack[row][index] = auxiliary_stack[row][index]; - } - } - - for (std::size_t index = 0; index < partial_block_length; ++index) - { - block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; - } - - delete[] auxiliary_stack; - } - - template - inline void deinterleave(block (&block_stack)[row_count]) - { - block auxiliary_stack[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = 0; - - for (std::size_t row = 0; row < row_count; ++row) - { - for (std::size_t index = 0; index < code_length; ++index) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_row == row_count) - { - aux_row = 0; - aux_index++; - } - } - } - - copy(auxiliary_stack,block_stack); - } - - template - inline void deinterleave(block (&block_stack)[row_count], - const std::size_t partial_code_length) - { - if (partial_code_length == code_length) - { - deinterleave(block_stack); - } - else - { - block auxiliary_stack[row_count]; - - std::size_t aux_row1 = 0; - std::size_t aux_index1 = 0; - - std::size_t aux_row2 = 0; - std::size_t aux_index2 = 0; - - for (std::size_t i = 0; i < partial_code_length * row_count; ++i) - { - auxiliary_stack[aux_row1][aux_index1] = block_stack[aux_row2][aux_index2]; - - if (++aux_row1 == row_count) - { - aux_row1 = 0; - aux_index1++; - } - - if (++aux_index2 == code_length) - { - aux_index2 = 0; - aux_row2++; - } - } - - for (std::size_t i = 0; aux_index1 < code_length; ++i) - { - auxiliary_stack[aux_row1][aux_index1] = block_stack[aux_row2][aux_index2]; - - if (++aux_row1 == (row_count - 1)) - { - aux_row1 = 0; - aux_index1++; - } - - if (++aux_index2 == code_length) - { - aux_index2 = 0; - aux_row2++; - } - } - - for (std::size_t row = 0; row < row_count - 1; ++row) - { - for (std::size_t index = 0; index < code_length; ++index) - { - block_stack[row][index] = auxiliary_stack[row][index]; - } - } - - for (std::size_t index = 0; index < partial_code_length; ++index) - { - block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; - } - } - } - - template - inline void deinterleave(data_block (&block_stack)[block_length]) - { - data_block auxiliary_stack[block_length]; - - for (std::size_t row = 0; row < block_length; ++row) - { - for (std::size_t index = 0; index < block_length; ++index) - { - auxiliary_stack[index][row] = block_stack[row][index]; - } - } - - copy(auxiliary_stack,block_stack); - } - - template - inline void deinterleave(data_block (&block_stack)[row_count]) - { - data_block auxiliary_stack[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = 0; - - for (std::size_t row = 0; row < row_count; ++row) - { - for (std::size_t index = 0; index < block_length; ++index) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_row == row_count) - { - aux_row = 0; - aux_index++; - } - } - } - - copy(auxiliary_stack,block_stack); - } - - template - inline void deinterleave(data_block block_stack[], - const std::size_t row_count) - { - data_block* auxiliary_stack = new data_block[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = 0; - - for (std::size_t row = 0; row < row_count; ++row) - { - for (std::size_t index = 0; index < block_length; ++index) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_row == row_count) - { - aux_row = 0; - aux_index++; - } - } - } - - for (std::size_t row = 0; row < row_count; ++row) - { - for (std::size_t index = 0; index < block_length; ++index) - { - block_stack[row][index] = auxiliary_stack[row][index]; - } - } - - delete[] auxiliary_stack; - } - - template - inline void deinterleave(data_block block_stack[], - const std::size_t row_count, - const std::size_t partial_block_length) - { - if (row_count == 1) return; - - data_block* auxiliary_stack = new data_block[row_count]; - - std::size_t aux_row1 = 0; - std::size_t aux_index1 = 0; - - std::size_t aux_row2 = 0; - std::size_t aux_index2 = 0; - - for (std::size_t i = 0; i < partial_block_length * row_count; ++i) - { - auxiliary_stack[aux_row1][aux_index1] = block_stack[aux_row2][aux_index2]; - - if (++aux_row1 == row_count) - { - aux_row1 = 0; - aux_index1++; - } - - if (++aux_index2 == block_length) - { - aux_index2 = 0; - aux_row2++; - } - } - - for (std::size_t i = 0; aux_index1 < block_length; ++i) - { - auxiliary_stack[aux_row1][aux_index1] = block_stack[aux_row2][aux_index2]; - - if (++aux_row1 == (row_count - 1)) - { - aux_row1 = 0; - aux_index1++; - } - - if (++aux_index2 == block_length) - { - aux_index2 = 0; - aux_row2++; - } - } - - for (std::size_t row = 0; row < row_count - 1; ++row) - { - for (std::size_t index = 0; index < block_length; ++index) - { - block_stack[row][index] = auxiliary_stack[row][index]; - } - } - - for (std::size_t index = 0; index < partial_block_length; ++index) - { - block_stack[row_count - 1][index] = auxiliary_stack[row_count - 1][index]; - } - - delete[] auxiliary_stack; - } - - template - inline void interleave_columnskip(data_block* block_stack) - { - for (std::size_t i = 0; i < block_length; ++i) - { - for (std::size_t j = i + 1; j < block_length; ++j) - { - std::size_t x1 = i + skip_columns; - std::size_t x2 = j + skip_columns; - - T tmp = block_stack[i][x2]; - block_stack[i][x2] = block_stack[j][x1]; - block_stack[j][x1] = tmp; - } - } - } - - template - inline void interleave_columnskip(data_block* block_stack, const std::size_t& row_count) - { - data_block* auxiliary_stack = new data_block[row_count]; - - std::size_t aux_row = 0; - std::size_t aux_index = skip_columns; - - for (std::size_t index = skip_columns; index < block_length; ++index) - { - for (std::size_t row = 0; row < row_count; ++row) - { - auxiliary_stack[aux_row][aux_index] = block_stack[row][index]; - - if (++aux_index == block_length) - { - aux_index = skip_columns; - aux_row++; - } - } - } - - for (std::size_t row = 0; row < row_count; ++row) - { - for (std::size_t index = skip_columns; index < block_length; ++index) - { - block_stack[row][index] = auxiliary_stack[row][index]; - } - } - - delete[] auxiliary_stack; - } - - template - inline void interleave(T* block_stack[data_length]) - { - for (std::size_t i = 0; i < data_length; ++i) - { - for (std::size_t j = i + 1; j < data_length; ++j) - { - T tmp = block_stack[i][j]; - block_stack[i][j] = block_stack[j][i]; - block_stack[j][i] = tmp; - } - } - } - - template - inline void interleave_columnskip(T* block_stack[data_length]) - { - for (std::size_t i = skip_columns; i < data_length; ++i) - { - for (std::size_t j = i + 1; j < data_length; ++j) - { - T tmp = block_stack[i][j]; - block_stack[i][j] = block_stack[j][i]; - block_stack[j][i] = tmp; - } - } - } - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_product_code.hpp b/modem/fec/schifra_reed_solomon_product_code.hpp deleted file mode 100644 index 15f00c4..0000000 --- a/modem/fec/schifra_reed_solomon_product_code.hpp +++ /dev/null @@ -1,238 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_PRODUCT_CODE_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_PRODUCT_CODE_HPP - - -#include -#include -#include - -#include "schifra_reed_solomon_block.hpp" -#include "schifra_reed_solomon_encoder.hpp" -#include "schifra_reed_solomon_decoder.hpp" -#include "schifra_reed_solomon_interleaving.hpp" -#include "schifra_reed_solomon_bitio.hpp" -#include "schifra_ecc_traits.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - template - class square_product_code_encoder - { - public: - - typedef encoder encoder_type; - typedef block block_type; - typedef traits::reed_solomon_triat trait; - typedef unsigned char data_type; - typedef data_type* data_ptr_type; - - enum { data_size = data_length * data_length }; - enum { total_size = code_length * code_length }; - - square_product_code_encoder(const encoder_type& enc) - : encoder_(enc) - {} - - bool encode(data_ptr_type data) - { - data_ptr_type curr_data_ptr = data; - - for (std::size_t row = 0; row < data_length; ++row, curr_data_ptr += data_length) - { - copy(curr_data_ptr, data_length, block_stack_[row]); - - if (!encoder_.encode(block_stack_[row])) - { - return false; - } - } - - block_type vertical_block; - - for (std::size_t col = 0; col < code_length; ++col) - { - for (std::size_t row = 0; row < data_length; ++row) - { - vertical_block[row] = block_stack_[row][col]; - } - - if (!encoder_.encode(vertical_block)) - { - return false; - } - - for (std::size_t fec_index = 0; fec_index < fec_length; ++fec_index) - { - block_stack_[data_length + fec_index].fec(fec_index) = vertical_block.fec(fec_index); - } - } - - return true; - } - - bool encode_and_interleave(data_ptr_type data) - { - if (!encode(data)) - { - return false; - } - - interleave(block_stack_); - - return true; - } - - void output(data_ptr_type output_data) - { - for (std::size_t row = 0; row < code_length; ++row, output_data += code_length) - { - bitio::convert_symbol_to_data::size>(block_stack_[row].data,output_data,code_length); - } - } - - void clear() - { - for (std::size_t i = 0; i < code_length; ++i) - { - block_stack_[i].clear(); - } - } - - private: - - square_product_code_encoder(const square_product_code_encoder& spce); - square_product_code_encoder& operator=(const square_product_code_encoder& spce); - - block_type block_stack_[code_length]; - const encoder_type& encoder_; - }; - - template - class square_product_code_decoder - { - public: - - typedef decoder decoder_type; - typedef block block_type; - typedef traits::reed_solomon_triat trait; - typedef unsigned char data_type; - typedef data_type* data_ptr_type; - - enum { data_size = data_length * data_length }; - enum { total_size = code_length * code_length }; - - square_product_code_decoder(const decoder_type& decoder) - : decoder_(decoder) - {} - - void decode(data_ptr_type data) - { - copy_proxy(data); - decode_proxy(); - } - - void deinterleave_and_decode(data_ptr_type data) - { - copy_proxy(data); - interleave(block_stack_); - decode_proxy(); - } - - void output(data_ptr_type output_data) - { - for (std::size_t row = 0; row < data_length; ++row, output_data += data_length) - { - bitio::convert_symbol_to_data::size>(block_stack_[row].data,output_data,data_length); - } - } - - void clear() - { - for (std::size_t i = 0; i < code_length; ++i) - { - block_stack_[i].clear(); - } - } - - private: - - square_product_code_decoder(const square_product_code_decoder& spcd); - square_product_code_decoder& operator=(const square_product_code_decoder& spcd); - - void copy_proxy(data_ptr_type data) - { - for (std::size_t row = 0; row < code_length; ++row, data += code_length) - { - bitio::convert_data_to_symbol::size>(data,code_length,block_stack_[row].data); - } - } - - void decode_proxy() - { - bool first_iteration_failure = false; - - for (std::size_t row = 0; row < data_length; ++row) - { - if (!decoder_.decode(block_stack_[row])) - { - first_iteration_failure = true; - } - } - - if (!first_iteration_failure) - { - /* - Either no errors detected or all errors have - been detected and corrected. - */ - return; - } - - block_type vertical_block; - - for (std::size_t col = 0; col < code_length; ++col) - { - for (std::size_t row = 0; row < data_length; ++row) - { - vertical_block[row] = block_stack_[row][col]; - } - - decoder_.decode(vertical_block); - } - } - - block_type block_stack_[code_length]; - const decoder_type& decoder_; - }; - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_reed_solomon_speed_evaluator.hpp b/modem/fec/schifra_reed_solomon_speed_evaluator.hpp deleted file mode 100644 index 16ac54c..0000000 --- a/modem/fec/schifra_reed_solomon_speed_evaluator.hpp +++ /dev/null @@ -1,411 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_REED_SOLOMON_SPPED_EVALUATOR_HPP -#define INCLUDE_SCHIFRA_REED_SOLOMON_SPPED_EVALUATOR_HPP - - -#include -#include -#include -#include - -#include "schifra_galois_field.hpp" -#include "schifra_sequential_root_generator_polynomial_creator.hpp" -#include "schifra_reed_solomon_block.hpp" -#include "schifra_reed_solomon_encoder.hpp" -#include "schifra_reed_solomon_decoder.hpp" -#include "schifra_reed_solomon_file_encoder.hpp" -#include "schifra_reed_solomon_file_decoder.hpp" -#include "schifra_error_processes.hpp" -#include "schifra_utilities.hpp" - - -namespace schifra -{ - - namespace reed_solomon - { - - template - void create_messages(const encoder& rs_encoder, - std::vector< block >& original_block_list, - const bool full_test_set = false) - { - const std::size_t data_length = code_length - fec_length; - std::vector message_list; - if (full_test_set) - { - for (unsigned int i = 0; i < 256; ++i) - { - message_list.push_back(std::string(data_length,static_cast(i))); - } - } - else - { - message_list.push_back(std::string(data_length,static_cast(0x00))); - message_list.push_back(std::string(data_length,static_cast(0xAA))); - message_list.push_back(std::string(data_length,static_cast(0xA5))); - message_list.push_back(std::string(data_length,static_cast(0xAC))); - message_list.push_back(std::string(data_length,static_cast(0xCA))); - message_list.push_back(std::string(data_length,static_cast(0x5A))); - message_list.push_back(std::string(data_length,static_cast(0xCC))); - message_list.push_back(std::string(data_length,static_cast(0xF0))); - message_list.push_back(std::string(data_length,static_cast(0x0F))); - message_list.push_back(std::string(data_length,static_cast(0xFF))); - message_list.push_back(std::string(data_length,static_cast(0x92))); - message_list.push_back(std::string(data_length,static_cast(0x6D))); - message_list.push_back(std::string(data_length,static_cast(0x77))); - message_list.push_back(std::string(data_length,static_cast(0x7A))); - message_list.push_back(std::string(data_length,static_cast(0xA7))); - message_list.push_back(std::string(data_length,static_cast(0xE5))); - message_list.push_back(std::string(data_length,static_cast(0xEB))); - } - - std::string tmp_str = std::string(data_length,static_cast(0x00)); - - for (std::size_t i = 0; i < data_length; ++i) - { - tmp_str[i] = static_cast(i); - } - - message_list.push_back(tmp_str); - - for (int i = data_length - 1; i >= 0; --i) - { - tmp_str[i] = static_cast(i); - } - - message_list.push_back(tmp_str); - - for (std::size_t i = 0; i < data_length; ++i) - { - tmp_str[i] = (((i & 0x01) == 1) ? static_cast(i) : 0x00); - } - - message_list.push_back(tmp_str); - - for (std::size_t i = 0; i < data_length; ++i) - { - tmp_str[i] = (((i & 0x01) == 0) ? static_cast(i) : 0x00); - } - - message_list.push_back(tmp_str); - - for (int i = data_length - 1; i >= 0; --i) - { - tmp_str[i] = (((i & 0x01) == 1) ? static_cast(i) : 0x00); - } - - message_list.push_back(tmp_str); - - for (int i = data_length - 1; i >= 0; --i) - { - tmp_str[i] = (((i & 0x01) == 0) ? static_cast(i) : 0x00); - } - - message_list.push_back(tmp_str); - - tmp_str = std::string(data_length,static_cast(0x00)); - - for (std::size_t i = 0; i < (data_length >> 1); ++i) - { - tmp_str[i] = static_cast(0xFF); - } - - message_list.push_back(tmp_str); - - tmp_str = std::string(data_length,static_cast(0xFF)) ; - - for (std::size_t i = 0; i < (data_length >> 1); ++i) - { - tmp_str[i] = static_cast(0x00); - } - - message_list.push_back(tmp_str); - - for (std::size_t i = 0; i < message_list.size(); ++i) - { - block current_block; - rs_encoder.encode(message_list[i],current_block); - original_block_list.push_back(current_block); - } - } - - template , - typename RSDecoder = decoder, - std::size_t data_length = code_length - fec_length> - struct all_errors_decoder_speed_test - { - public: - - all_errors_decoder_speed_test(const std::size_t prim_poly_size, const unsigned int prim_poly[]) - { - galois::field field(field_descriptor,prim_poly_size,prim_poly); - galois::field_polynomial generator_polynomial(field); - - if ( - !make_sequential_root_generator_polynomial(field, - gen_poly_index, - fec_length, - generator_polynomial) - ) - { - return; - } - - RSEncoder rs_encoder(field,generator_polynomial); - RSDecoder rs_decoder(field,gen_poly_index); - - std::vector< block > original_block; - - create_messages(rs_encoder,original_block); - - std::vector > rs_block; - std::vector block_index_list; - - for (std::size_t block_index = 0; block_index < original_block.size(); ++block_index) - { - for (std::size_t error_count = 1; error_count <= (fec_length >> 1); ++error_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - block block = original_block[block_index]; - corrupt_message_all_errors(block,error_count,start_position,1); - rs_block.push_back(block); - block_index_list.push_back(block_index); - } - } - } - - const std::size_t max_iterations = 100; - std::size_t blocks_decoded = 0; - std::size_t block_failures = 0; - - schifra::utils::timer timer; - timer.start(); - - for (std::size_t j = 0; j < max_iterations; ++j) - { - for (std::size_t i = 0; i < rs_block.size(); ++i) - { - if (!rs_decoder.decode(rs_block[i])) - { - std::cout << "Decoding Failure!" << std::endl; - block_failures++; - } - else if (!are_blocks_equivelent(rs_block[i],original_block[block_index_list[i]])) - { - std::cout << "Error Correcting Failure!" << std::endl; - block_failures++; - } - else - blocks_decoded++; - } - } - - timer.stop(); - - double time = timer.time(); - double mbps = ((max_iterations * rs_block.size() * data_length) * 8.0) / (1048576.0 * time); - - print_codec_properties(); - - if (block_failures == 0) - printf("Blocks decoded: %8d Time:%8.3fsec Rate:%8.3fMbps\n", - static_cast(blocks_decoded), - time, - mbps); - else - std::cout << "Blocks decoded: " << blocks_decoded << "\tDecode Failures: " << block_failures <<"\tTime: " << time <<"sec\tRate: " << mbps << "Mbps" << std::endl; - } - - void print_codec_properties() - { - printf("[All Errors Test] Codec: RS(%03d,%03d,%03d) ", - static_cast(code_length), - static_cast(data_length), - static_cast(fec_length)); - } - }; - - template , - typename RSDecoder = decoder, - std::size_t data_length = code_length - fec_length> - struct all_erasures_decoder_speed_test - { - public: - - all_erasures_decoder_speed_test(const std::size_t prim_poly_size, const unsigned int prim_poly[]) - { - galois::field field(field_descriptor,prim_poly_size,prim_poly); - galois::field_polynomial generator_polynomial(field); - - if ( - !make_sequential_root_generator_polynomial(field, - gen_poly_index, - fec_length, - generator_polynomial) - ) - { - return; - } - - RSEncoder rs_encoder(field,generator_polynomial); - RSDecoder rs_decoder(field,gen_poly_index); - - std::vector< block > original_block; - - create_messages(rs_encoder,original_block); - - std::vector > rs_block; - std::vector erasure_list; - std::vector block_index_list; - - for (std::size_t block_index = 0; block_index < original_block.size(); ++block_index) - { - for (std::size_t erasure_count = 1; erasure_count <= fec_length; ++erasure_count) - { - for (std::size_t start_position = 0; start_position < code_length; ++start_position) - { - block block = original_block[block_index]; - erasure_locations_t erasures; - corrupt_message_all_erasures(block,erasures,erasure_count,start_position,1); - - if (erasure_count != erasures.size()) - { - std::cout << "all_erasures_decoder_speed_test() - Failed to properly generate erasures list. Details:"; - std::cout << "(" << block_index << "," << erasure_count << "," << start_position << ")" << std::endl; - } - - rs_block.push_back(block); - erasure_list.push_back(erasures); - block_index_list.push_back(block_index); - } - } - } - - const std::size_t max_iterations = 100; - std::size_t blocks_decoded = 0; - std::size_t block_failures = 0; - - schifra::utils::timer timer; - timer.start(); - - for (std::size_t j = 0; j < max_iterations; ++j) - { - for (std::size_t i = 0; i < rs_block.size(); ++i) - { - if (!rs_decoder.decode(rs_block[i],erasure_list[i])) - { - std::cout << "Decoding Failure!" << std::endl; - block_failures++; - } - else if (!are_blocks_equivelent(rs_block[i],original_block[block_index_list[i]])) - { - std::cout << "Error Correcting Failure!" << std::endl; - block_failures++; - } - else - blocks_decoded++; - } - } - - timer.stop(); - - double time = timer.time(); - double mbps = ((max_iterations * rs_block.size() * data_length) * 8.0) / (1048576.0 * time); - - print_codec_properties(); - - if (block_failures == 0) - printf("Blocks decoded: %8d Time:%8.3fsec Rate:%8.3fMbps\n", - static_cast(blocks_decoded), - time, - mbps); - else - std::cout << "Blocks decoded: " << blocks_decoded << "\tDecode Failures: " << block_failures <<"\tTime: " << time <<"sec\tRate: " << mbps << "Mbps" << std::endl; - } - - void print_codec_properties() - { - printf("[All Erasures Test] Codec: RS(%03d,%03d,%03d) ", - static_cast(code_length), - static_cast(data_length), - static_cast(fec_length)); - } - - }; - - void speed_test_00() - { - all_errors_decoder_speed_test<8,120,255, 2>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 4>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 6>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 8>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 10>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 12>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 14>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 16>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 18>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 20>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 32>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 48>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 64>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 80>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255, 96>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_errors_decoder_speed_test<8,120,255,128>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - } - - void speed_test_01() - { - all_erasures_decoder_speed_test<8,120,255, 2>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 4>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 6>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 8>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 10>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 12>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 14>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 16>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 18>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 20>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 32>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 48>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 64>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 80>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255, 96>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - all_erasures_decoder_speed_test<8,120,255,128>(galois::primitive_polynomial_size06,galois::primitive_polynomial06); - } - - } // namespace reed_solomon - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_sequential_root_generator_polynomial_creator.hpp b/modem/fec/schifra_sequential_root_generator_polynomial_creator.hpp deleted file mode 100644 index 02c9682..0000000 --- a/modem/fec/schifra_sequential_root_generator_polynomial_creator.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_SEQUENTIAL_ROOT_GENERATOR_POLYNOMIAL_CREATOR_HPP -#define INCLUDE_SCHIFRA_SEQUENTIAL_ROOT_GENERATOR_POLYNOMIAL_CREATOR_HPP - - -#include - -#include "schifra_galois_field.hpp" -#include "schifra_galois_field_element.hpp" -#include "schifra_galois_field_polynomial.hpp" - - -namespace schifra -{ - - inline bool make_sequential_root_generator_polynomial(const galois::field& field, - const std::size_t initial_index, - const std::size_t num_elements, - galois::field_polynomial& generator_polynomial) - { - if ( - (initial_index >= field.size()) || - ((initial_index + num_elements) > field.size()) - ) - { - return false; - } - - galois::field_element alpha(field, 2); - galois::field_polynomial X = galois::generate_X(field); - generator_polynomial = galois::field_element(field, 1); - - for (std::size_t i = initial_index; i < (initial_index + num_elements); ++i) - { - generator_polynomial *= (X + (alpha ^ static_cast(i))); - } - - return true; - } - -} // namespace schifra - -#endif diff --git a/modem/fec/schifra_utilities.hpp b/modem/fec/schifra_utilities.hpp deleted file mode 100644 index d52844d..0000000 --- a/modem/fec/schifra_utilities.hpp +++ /dev/null @@ -1,198 +0,0 @@ -/* -(**************************************************************************) -(* *) -(* Schifra *) -(* Reed-Solomon Error Correcting Code Library *) -(* *) -(* Release Version 0.0.1 *) -(* http://www.schifra.com *) -(* Copyright (c) 2000-2020 Arash Partow, All Rights Reserved. *) -(* *) -(* The Schifra Reed-Solomon error correcting code library and all its *) -(* components are supplied under the terms of the General Schifra License *) -(* agreement. The contents of the Schifra Reed-Solomon error correcting *) -(* code library and all its components may not be copied or disclosed *) -(* except in accordance with the terms of that agreement. *) -(* *) -(* URL: http://www.schifra.com/license.html *) -(* *) -(**************************************************************************) -*/ - - -#ifndef INCLUDE_SCHIFRA_UTILITES_HPP -#define INCLUDE_SCHIFRA_UTILITES_HPP - - -#include - -#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) - #include -#else - #include - #include -#endif - - -namespace schifra -{ - - namespace utils - { - - const std::size_t high_bits_in_char[256] = { - 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 - }; - - template - inline std::size_t hamming_distance_element(const T v1, const T v2) - { - std::size_t distance = 0; - const unsigned char* it1 = reinterpret_cast(&v1); - const unsigned char* it2 = reinterpret_cast(&v2); - for (std::size_t i = 0; i < sizeof(T); ++i, ++it1, ++it2) - { - distance += high_bits_in_char[((*it1) ^ (*it2)) & 0xFF]; - } - return distance; - } - - inline std::size_t hamming_distance(const unsigned char data1[], const unsigned char data2[], const std::size_t length) - { - std::size_t distance = 0; - const unsigned char* it1 = data1; - const unsigned char* it2 = data2; - for (std::size_t i = 0; i < length; ++i, ++it1, ++it2) - { - distance += high_bits_in_char[((*it1) ^ (*it2)) & 0xFF]; - } - return distance; - } - - template - inline std::size_t hamming_distance(ForwardIterator it1_begin, ForwardIterator it2_begin, ForwardIterator it1_end) - { - std::size_t distance = 0; - ForwardIterator it1 = it1_begin; - ForwardIterator it2 = it2_begin; - for (; it1 != it1_end; ++it1, ++it2) - { - distance += hamming_distance_element(*it1,*it2); - } - return distance; - } - - class timer - { - public: - - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) - timer() - : in_use_(false) - { - QueryPerformanceFrequency(&clock_frequency_); - } - - inline void start() - { - in_use_ = true; - QueryPerformanceCounter(&start_time_); - } - - inline void stop() - { - QueryPerformanceCounter(&stop_time_); - in_use_ = false; - } - - inline double time() const - { - return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart); - } - - #else - - timer() - : in_use_(false) - { - start_time_.tv_sec = 0; - start_time_.tv_usec = 0; - stop_time_.tv_sec = 0; - stop_time_.tv_usec = 0; - } - - inline void start() - { - in_use_ = true; - gettimeofday(&start_time_,0); - } - - inline void stop() - { - gettimeofday(&stop_time_, 0); - in_use_ = false; - } - - inline unsigned long long int usec_time() const - { - if (!in_use_) - { - if (stop_time_.tv_sec >= start_time_.tv_sec) - { - return 1000000 * (stop_time_.tv_sec - start_time_.tv_sec ) + - (stop_time_.tv_usec - start_time_.tv_usec); - } - else - return std::numeric_limits::max(); - } - else - return std::numeric_limits::max(); - } - - inline double time() const - { - return usec_time() * 0.000001; - } - - #endif - - inline bool in_use() const - { - return in_use_; - } - - private: - - bool in_use_; - - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) - LARGE_INTEGER start_time_; - LARGE_INTEGER stop_time_; - LARGE_INTEGER clock_frequency_; - #else - struct timeval start_time_; - struct timeval stop_time_; - #endif - }; - - } // namespace utils - -} // namespace schifra - - -#endif diff --git a/modem/fft.c b/modem/fft.c deleted file mode 100644 index 8bc4f24..0000000 --- a/modem/fft.c +++ /dev/null @@ -1,140 +0,0 @@ -/* -* High Speed modem to transfer data in a 2,7kHz SSB channel -* ========================================================= -* Author: DJ0ABR -* -* (c) DJ0ABR -* www.dj0abr.de -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -*/ - -#include "qo100modem.h" -#include -#include - -#define AUDIOSAMPLERATE 8000 - -double *din = NULL; // input data for fft -fftw_complex *cpout = NULL; // ouput data from fft -fftw_plan plan = NULL; -#define fft_rate (AUDIOSAMPLERATE / 10) // resolution: 10 Hz -int fftidx = 0; -int fftcnt = fft_rate/2+1; // number of output values -uint16_t fftout[AUDIOSAMPLERATE / 10/2+1]; - -uint16_t *make_waterfall(uint8_t *pdata, int len, int *retlen) -{ - int fftrdy = 0; - // get the real sample in float (imag is not required for the FFT) - int re=0; - - // GR sends 8 Bytes containing 4x 0x000003e8 (marker) and 4x input-samples (real integer) - #define dlen 8 - static uint8_t rbuf[dlen]; - - for(int i=0; i 0; sh--) - rbuf[sh] = rbuf[sh - 1]; - rbuf[0] = pdata[i]; - - // check for BIG/LITTLE endian - if(rbuf[0] == 0 && rbuf[1] == 0 && rbuf[2] == 3 && rbuf[3] == 0xe8) - { - re = rbuf[4]; - re <<= 24; - re += rbuf[5]; - re <<= 16; - re += rbuf[6]; - re <<= 8; - re += rbuf[7]; - } - else if(rbuf[0] == 0xe8 && rbuf[1] == 3 && rbuf[2] == 0 && rbuf[3] == 0) - { - re = rbuf[7]; - re <<= 24; - re += rbuf[6]; - re <<= 16; - re += rbuf[5]; - re <<= 8; - re += rbuf[4]; - } - else - continue; - - // the value was scaled in GR by 2^24 = 16777216 - // in order to send it in an INT - // undo this scaling - float fre = (float)re / 16777216; - - // fre are the float samples - // fill into the fft input buffer - din[fftidx++] = fre; - - if(fftidx == fft_rate) - { - fftidx = 0; - - // the fft buffer is full, execute the FFT - fftw_execute(plan); - - for (int j = 0; j < fftcnt; j++) - { - // calculate absolute value (magnitute without phase) - float fre = cpout[j][0]; - float fim = cpout[j][1]; - float mag = sqrt((fre * fre) + (fim * fim)); - - fftout[j] = (uint16_t)mag; - - fftrdy = 1; - } - } - } - - if(fftrdy == 1) - { - *retlen = fftcnt; - return fftout; - } - - return NULL; -} - -void init_fft() -{ -char fn[300]; - - sprintf(fn, "capture_fft_%d", fft_rate); // wisdom file for each capture rate - - fftw_import_wisdom_from_filename(fn); - - din = (double *)fftw_malloc(sizeof(double) * fft_rate); - cpout = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * fft_rate); - - plan = fftw_plan_dft_r2c_1d(fft_rate, din, cpout, FFTW_MEASURE); - - fftw_export_wisdom_to_filename(fn); -} - -void exit_fft() -{ - if(plan) fftw_destroy_plan(plan); - if(din) fftw_free(din); - if(cpout) fftw_free(cpout); -} diff --git a/modem/frame_packer.c b/modem/frame_packer.c deleted file mode 100644 index 3562c13..0000000 --- a/modem/frame_packer.c +++ /dev/null @@ -1,325 +0,0 @@ -/* -* High Speed modem to transfer data in a 2,7kHz SSB channel -* ========================================================= -* Author: DJ0ABR -* -* (c) DJ0ABR -* www.dj0abr.de -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -*/ - -#include "qo100modem.h" - -void Insert(uint8_t bit); -uint8_t *FindDatablock(); - -uint8_t rxbuffer[UDPBLOCKLEN*8/2+100]; // 3...bits per symbol QPSK, enough space also for QPSK and 8PSK, +100 ... reserve, just to be sure -uint8_t rx_status = 0; - -int framecounter = 0; -int lastframenum = 0; - -// header for TX, -uint8_t TXheaderbytes[HEADERLEN] = {0x53, 0xe1, 0xa6}; -// corresponds to these QPSK symbols: -// bits: 01010011 11100001 10100110 -// QPSK: -// syms: 1 1 0 3 3 2 0 1 2 2 1 2 -// 8PSK: -// syms: 2 4 7 6 0 6 4 6 - -// QPSK -// each header has 12 symbols -// we have 4 constellations -uint8_t QPSK_headertab[4][HEADERLEN*8/2]; - -// 8PSK -// each header has 12 symbols -// we have 8 constellations -uint8_t _8PSK_headertab[8][HEADERLEN*8/3]; - -// init header tables -void init_packer() -{ - // create the QPSK symbol table for the HEADER - // in all possible rotations - convertBytesToSyms_QPSK(TXheaderbytes, QPSK_headertab[0], 3); - for(int i=1; i<4; i++) - rotateQPSKsyms(QPSK_headertab[i-1], QPSK_headertab[i], 12); - - // create the 8PSK symbol table for the HEADER - // in all possible rotations - convertBytesToSyms_8PSK(TXheaderbytes, _8PSK_headertab[0], 3); - for(int i=1; i<8; i++) - rotate8PSKsyms(_8PSK_headertab[i-1], _8PSK_headertab[i], 8); -} - -// packs a payload into an udp data block -// the payload has a size of PAYLOADLEN -// type ... inserted in the "frame type information" field -// status ... specifies first/last frame of a data stream -uint8_t *Pack(uint8_t *payload, int type, int status, int *plen) -{ - FRAME frame; // raw frame without fec - - // polulate the raw frame - - // make the frame counter - if(status & (1<<4)) - framecounter = 0; // first block of a stream - else - framecounter++; - - // insert frame counter and status bits - frame.counter_LSB = framecounter & 0xff; - int framecnt_MSB = (framecounter >> 8) & 0x03; // Bit 8+9 of framecounter - frame.status = framecnt_MSB << 6; - frame.status += ((status & 0x03)<<4); - frame.status += (type & 0x0f); - - // insert the payload - memcpy(frame.payload, payload, PAYLOADLEN); - - // calculate and insert the CRC16 - uint16_t crc16 = Crc16_messagecalc(CRC16TX,(uint8_t *)(&frame), CRCSECUREDLEN); - frame.crc16_MSB = (uint8_t)(crc16 >> 8); - frame.crc16_LSB = (uint8_t)(crc16 & 0xff); - - // make the final arry for transmission - static uint8_t txblock[UDPBLOCKLEN]; - - // calculate the fec and insert into txblock (leave space for the header) - GetFEC((uint8_t *)(&frame), DATABLOCKLEN, txblock+HEADERLEN); - - // scramble - TX_Scramble(txblock+HEADERLEN, FECBLOCKLEN); // scramble all data - - // insert the header - memcpy(txblock,TXheaderbytes,HEADERLEN); - - /* test pattern - * for(int i=0; i>6; // frame counter MSB - framenumrx <<= 8; - framenumrx += frame.counter_LSB; // frame counter LSB - - if (lastframenum != framenumrx) rx_status |= 4; - lastframenum = framenumrx; - if (++lastframenum >= 1024) lastframenum = 0; // 1024 = 2^10 (10 bit frame number) - - // extract information and build the string for the application - // we have 10 Management Byte then the payload follows - static uint8_t payload[PAYLOADLEN+10]; - payload[0] = frame.status & 0x0f; // frame type - payload[1] = (frame.status & 0xc0)>>6; // frame counter MSB - payload[2] = frame.counter_LSB; // frame counter LSB - payload[3] = (frame.status & 0x30)>>4; // first/last frame marker - payload[4] = rx_status; // frame lost information - payload[5] = speed >> 8; // measured line speed - payload[6] = speed; - payload[7] = 0; // free for later use - payload[8] = 0; - payload[9] = 0; - - //printf("Frame no.: %d, type:%d, minfo:%d\n",framenumrx,payload[0],payload[3]); - - memcpy(payload+10,frame.payload,PAYLOADLEN); - - return payload; -} diff --git a/modem/frameformat.h b/modem/frameformat.h deleted file mode 100644 index 83bf06c..0000000 --- a/modem/frameformat.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -* High Speed modem to transfer data in a 2,7kHz SSB channel -* ========================================================= -* Author: DJ0ABR -* -* (c) DJ0ABR -* www.dj0abr.de -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -*/ - -/* - * The total length of the FEC-secured part is 255, - * this is a requirement of the Shifra FEC routine, which - * is the best FEC that I have seen so far, highly recommended -*/ - -// total "on the air" frame size -// the total length must be a multiple of 2 and 3, so QPSK and 8PSK symbols fit into full bytes -// this is the case with a total length of 258 -#define HEADERLEN 3 -#define FECBLOCKLEN 255 -#define UDPBLOCKLEN (HEADERLEN + FECBLOCKLEN) - -/* !!! IMPORTANT for GNU RADIO !!! - * the UDP payload size for TX MUST be exactly UDPBLOCKLEN (258 in this case) or - * the transmitter will not align bits to symbols correctly ! - * - * RX payload size is not that important. But the currect size for - * QPSK is UDPBLOCKLEN*8/2 = 1032 and for 8PSK UDPBLOCKLEN*8/3 = 688 - * so we can use 344 which are 2 blocks for 8PSK and 3 blocks for QPSK - * */ - -// size of the elements inside an FECblock -// sum must be 255 -#define FECLEN 32 // supported: 16,32,64,128 -#define STATUSLEN 2 -#define CRCLEN 2 -#define PAYLOADLEN (FECBLOCKLEN - FECLEN - CRCLEN - STATUSLEN) -#define CRCSECUREDLEN (PAYLOADLEN + STATUSLEN) -#define DATABLOCKLEN (PAYLOADLEN + CRCLEN + STATUSLEN) - - -// the header is not FEC secured therefore we give some room for bit -// errors. Only 24 out of the 32 bits must be correct for -// a valid frame detection -extern uint8_t header[HEADERLEN]; - -typedef struct { - // the total size of the following data must be 255 - 32 = 223 bytes - // the FEC is calculated on FRAME with a length of 223 and returns - // a data block with length 255. - - // we use a 10 bits frame counter -> 1024 values - // so we can transmit a data block with a maximum - // size of 255 * 1024 = 261kByte. With the maximum modem speed - // this would be a transmission time of 5,8 minutes which - // is more then enough for a single data block - uint8_t counter_LSB; // lower 8 bits of the frame counter - - // the status byte contains these information: - // bit 0..3 : 4 bit (16 values) frame type information - // bit 4 : first frame of a block if "1" - // bit 5 : last frame of a block if "1" - // bit 6..7 : MSB of the frame counter - uint8_t status; - - // payload - uint8_t payload[PAYLOADLEN]; - - // CRC16 - uint8_t crc16_MSB; - uint8_t crc16_LSB; -} FRAME; diff --git a/modem/install_gnuradio_ubuntu b/modem/install_gnuradio_ubuntu deleted file mode 100755 index f8f7001..0000000 --- a/modem/install_gnuradio_ubuntu +++ /dev/null @@ -1,6 +0,0 @@ -sudo apt-get update -sudo apt-get install software-properties-common -sudo add-apt-repository ppa:gnuradio/gnuradio-releases -sudo apt-get update -sudo apt-get install gnuradio -sudo ldconfig diff --git a/modem/liquid-dsp-install b/modem/liquid-dsp-install deleted file mode 100755 index 765daa1..0000000 --- a/modem/liquid-dsp-install +++ /dev/null @@ -1,9 +0,0 @@ -sudo apt install git autoconf libsndfile-dev libasound-dev -git clone git://github.com/jgaeddert/liquid-dsp.git -cd liquid-dsp -./bootstrap.sh -./configure -make -j 8 -sudo make install -sudo ldconfig - diff --git a/modem/liquid_if.c b/modem/liquid_if.c deleted file mode 100644 index 82571be..0000000 --- a/modem/liquid_if.c +++ /dev/null @@ -1,171 +0,0 @@ -/* -* High Speed modem to transfer data in a 2,7kHz SSB channel -* ========================================================= -* Author: DJ0ABR -* -* (c) DJ0ABR -* www.dj0abr.de -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -* liquid_dsp_interface.c ... functions using liquid-dsp -* -* liquid-dsp must be previously installed by running ./liquid-dsp-install (under linux) -* -*/ - -#include "qo100modem.h" - -void modulator(uint8_t sym_in); -void close_dsp(); - -// modem objects -modulation_scheme ms = LIQUID_MODEM_QPSK; -modem mod = NULL; - -// NCOs for mixing baseband <-> 1500 Hz -#define FREQUENCY 1500 -int type = LIQUID_NCO; // nco type -nco_crcf upnco = NULL; - -// TX-Interpolator Filter Parameters -// 44100 input rate for 2205 Sym/s = 20 -// change for other rates -firinterp_crcf TX_interpolator = NULL; -unsigned int k_SampPerSymb = 20; // 44100 / (4410/2) -unsigned int m_filterDelay_Symbols = 15; // not too short for good filter -float beta_excessBW = 0.3f; // filter excess bandwidth factor -float tau_FracSymbOffset = -0.2f; // fractional symbol offset - -int init_dsp() -{ - close_dsp(); - printf("create DSP\n"); - - k_SampPerSymb = txinterpolfactor; - if(bitsPerSymbol == 2) - ms = LIQUID_MODEM_QPSK; - else - ms = LIQUID_MODEM_DPSK8; - - // create modulator - mod = modem_create(ms); - - // create NCO for upmixing to 1500 Hz - double RADIANS_PER_SAMPLE = ((2.0*M_PI*(double)FREQUENCY)/(float)caprate); - - upnco = nco_crcf_create(LIQUID_NCO); - nco_crcf_set_phase(upnco, 0.0f); - nco_crcf_set_frequency(upnco, RADIANS_PER_SAMPLE); - - // TX: Interpolator Filter - // compute delay - while (tau_FracSymbOffset < 0) tau_FracSymbOffset += 1.0f; // ensure positive tau - float g = k_SampPerSymb*tau_FracSymbOffset; // number of samples offset - int ds=floorf(g); // additional symbol delay - float dt = (g - (float)ds); // fractional sample offset - // force dt to be in [0.5,0.5] - if (dt > 0.5f) - { - dt -= 1.0f; - ds++; - } - - // calculate filter coeffs - unsigned int h_len_NumFilterCoeefs = 2 * k_SampPerSymb * m_filterDelay_Symbols + 1; - float h[h_len_NumFilterCoeefs]; - liquid_firdes_prototype( LIQUID_FIRFILT_RRC, - k_SampPerSymb, - m_filterDelay_Symbols, - beta_excessBW, - dt, - h); - // create the filter - TX_interpolator = firinterp_crcf_create(k_SampPerSymb,h,h_len_NumFilterCoeefs); - - printf("DSP created\n"); - return 1; -} - -void close_dsp() -{ - if(mod != NULL) modem_destroy(mod); - if(upnco != NULL) nco_crcf_destroy(upnco); - if(TX_interpolator != NULL) firinterp_crcf_destroy(TX_interpolator); - mod = NULL; - upnco = NULL; - TX_interpolator = NULL; -} - -// d ... symbols to send -// len ... number of symbols in d -void sendToModulator(uint8_t *d, int len) -{ - - //printf("sendToModulator %d bytes\n",len); - - int symanz = len * 8 / bitsPerSymbol; - uint8_t syms[symanz]; - if(bitsPerSymbol == 2) - convertBytesToSyms_QPSK(d, syms, len); - else - convertBytesToSyms_8PSK(d, syms, len); - - for(int i=0; i>1); - - modulator(syms[i]); - } -} - -// call for every symbol -// modulates, filters and upmixes symbols and send it to soundcard -void modulator(uint8_t sym_in) -{ - liquid_float_complex sample; - modem_modulate(mod, sym_in, &sample); - - //printf("TX ================= sample: %f + i%f\n", sample.real, sample.imag); - - // interpolate by k_SampPerSymb - liquid_float_complex y[k_SampPerSymb]; - firinterp_crcf_execute(TX_interpolator, sample, y); - - for(unsigned int i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int isRunning(char *prgname); -void install_signal_handler(); -void sighandler(int signum); -int run_console_program(char *cmd); diff --git a/modem/qo100modem.c b/modem/qo100modem.c deleted file mode 100644 index 017f475..0000000 --- a/modem/qo100modem.c +++ /dev/null @@ -1,575 +0,0 @@ -/* -* High Speed modem to transfer data in a 2,7kHz SSB channel -* ========================================================= -* Author: DJ0ABR -* -* (c) DJ0ABR -* www.dj0abr.de -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -*/ - -#include "qo100modem.h" - -int Open_BC_Socket(); -void startModem(); -void stopModem(); -void getMyIP(); -void bc_rxdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock); -void appdata_rxdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock); -void GRdata_rxdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock); -void GRdata_FFTdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock); -void GRdata_I_Qdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock); - -// threads will exit if set to 0 -int keeprunning = 1; - -// UDP I/O -int BC_sock_AppToModem = -1; -int DATA_sock_AppToModem = -1; -int DATA_sock_from_GR = -1; -int DATA_sock_FFT_from_GR = -1; -int DATA_sock_I_Q_from_GR = -1; - -int UdpBCport_AppToModem = 40131; -int UdpDataPort_AppToModem = 40132; -int UdpDataPort_ModemToApp = 40133; - -int UdpDataPort_toGR = 40134; -int UdpDataPort_fromGR = 40135; -int UdpDataPort_fromGR_FFT = 40136; -int UdpDataPort_fromGR_I_Q = 40137; - -// op mode depending values -// default mode if not set by the app -int speedmode = 4; -int bitsPerSymbol = 2; // QPSK=2, 8PSK=3 -int constellationSize = 4; // QPSK=4, 8PSK=8 - -char localIP[]={"127.0.0.1"}; -char ownfilename[]={"qo100modem"}; -char myIP[20]; -char appIP[20] = {0}; -int fixappIP = 0; -int restart_modems = 0; -int doNotLoadModems = 0; - -int caprate = 44100; -int txinterpolfactor = 20; - -int main(int argc, char *argv[]) -{ -int opt = 0; -char *modemip = NULL; - - while ((opt = getopt(argc, argv, "m:e:")) != -1) - { - switch(opt) - { - case 'e': - doNotLoadModems = 1; - break; - case 'm': - modemip = optarg; - memset(appIP,0,20); - int len = strlen(modemip); - if(len < 16) - { - memcpy(appIP,modemip,len); - fixappIP = 1; - printf("Application IP set to: %s\n",modemip); - } - else - { - printf("invalid Application IP: %s\n",modemip); - exit(0); - } - break; - } - } - - if(doNotLoadModems == 0 && isRunning(ownfilename) == 1) - exit(0); - - install_signal_handler(); - - init_packer(); - initFEC(); - init_fft(); - init_audio(); - - // start udp RX to listen for broadcast search message from Application - UdpRxInit(&BC_sock_AppToModem, UdpBCport_AppToModem, &bc_rxdata, &keeprunning); - - // start udp RX for data from application - UdpRxInit(&DATA_sock_AppToModem, UdpDataPort_AppToModem, &appdata_rxdata, &keeprunning); - - // start udp RX to listen for data from GR Receiver - UdpRxInit(&DATA_sock_from_GR, UdpDataPort_fromGR, &GRdata_rxdata, &keeprunning); - - // start udp RX to listen for Audio-Samples (FFT) data from GR Receiver - UdpRxInit(&DATA_sock_FFT_from_GR, UdpDataPort_fromGR_FFT, &GRdata_FFTdata, &keeprunning); - - // start udp RX to listen for IQ data from GR Receiver - UdpRxInit(&DATA_sock_I_Q_from_GR, UdpDataPort_fromGR_I_Q, &GRdata_I_Qdata, &keeprunning); - - getMyIP(); - - printf("QO100modem initialised and running\n"); - - while (keeprunning) - { - if(restart_modems == 1) - { - stopModem(); - startModem(); - restart_modems = 0; - } - - doArraySend(); - - usleep(100); - } - printf("stopped: %d\n",keeprunning); - - close(BC_sock_AppToModem); - - return 0; -} - -typedef struct { - int audio; - int tx; - int rx; -} SPEEDRATE; - -SPEEDRATE sr[9] = { - // QPSK modes - {48000, 32, 8}, // AudioRate, TX-Resampler, RX-Resampler/4 - {44100, 28, 7}, // see samprate.ods - {44100, 24, 6}, - {48000, 24, 6}, - {44100, 20, 5}, - {48000, 20, 5}, - - // 8PSK modes - {44100, 24, 6}, - {48000, 24, 6} -}; - -void startModem() -{ -char srx[512]; - - if(speedmode >= 0 && speedmode <=5) - { - bitsPerSymbol = 2; // QPSK=2, 8PSK=3 - constellationSize = (1<= 6 && speedmode <=7) - { - bitsPerSymbol = 3; // QPSK=2, 8PSK=3 - constellationSize = (1<= 0 && speedmode <=5) - sprintf(srx,"python3 qpsk_rx.py -r %d -s %d &",sr[speedmode].rx,sr[speedmode].audio); - else if(speedmode >= 6 && speedmode <=7) - sprintf(srx,"python3 rx_8psk.py -r %d -s %d &",sr[speedmode].rx,sr[speedmode].audio); - else - { - printf("wrong modem number\n"); - exit(0); - } - - // int TX audio and modulator - init_dsp(); - init_audio(); - - // the RX modem needs the app's IP address as a parameter -i ip - if(run_console_program(srx) == -1) - { - printf("cannot start RX modem\n"); - exit(0); - } -} - -void stopModem() -{ - if(doNotLoadModems == 1) return; - printf("stop modem\n"); - int ret = system("killall python3"); - if(ret){} - // wait until stop job is done - sleep(1); -} - -void getMyIP() -{ - struct ifaddrs *ifaddr, *ifa; - int s; - char host[NI_MAXHOST]; - - if (getifaddrs(&ifaddr) == -1) - { - printf("getifaddrs error\n"); - exit(0); - } - - - ifa = ifaddr; - while(ifa) - { - s=getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in),host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); - - if(ifa->ifa_addr->sa_family==AF_INET) - { - if (s != 0) - { - printf("getnameinfo() failed: %s\n", gai_strerror(s)); - exit(0); - } - strcpy(myIP, host); - if(strncmp(host,"127",3) != 0) - break; - } - - ifa = ifa->ifa_next; - } - - freeifaddrs(ifaddr); - - return; -} - -// called from UDP RX thread for Broadcast-search from App -void bc_rxdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock) -{ - if (len > 0 && pdata[0] == 0x3c) - { - char rxip[20]; - strcpy(rxip,inet_ntoa(rxsock->sin_addr)); - - if(fixappIP == 0) - { - if(strcmp(appIP,rxip)) - { - printf("new app IP: %s, restarting modems\n",rxip); - restart_modems = 1; - } - strcpy(appIP,rxip); - //printf("app (%s) is searching modem. Sending modem IP to the app\n",appIP); - // App searches for the modem IP, mirror the received messages - // so the app gets an UDP message with this local IP - pdata[0] = 3; - sendUDP(appIP,UdpDataPort_ModemToApp,pdata,1); - } - else - { - // appIP is fixed, answer only to this IP - if(!strcmp(appIP,rxip)) - { - //printf("app (%s) is searching modem. Sending modem IP to the app\n",appIP); - restart_modems = 1; - // App searches for the modem IP, mirror the received messages - // so the app gets an UDP message with this local IP - pdata[0] = 3; - sendUDP(appIP,UdpDataPort_ModemToApp,pdata,1); - } - } - } -} - -// called by UDP RX thread for data from App -void appdata_rxdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock) -{ - uint8_t type = pdata[0]; - uint8_t minfo = pdata[1]; - - if(len != (PAYLOADLEN+2)) - { - printf("data from app: wrong length:%d (should be %d)\n",len-2,PAYLOADLEN); - return; - } - - // type values: see oscardata config.cs: frame types - if(type == 16) - { - // Byte 1 contains the resampler ratio for TX and RX modem - speedmode = pdata[1]; - printf("set speedmode to %d\n",speedmode); - restart_modems = 1; - return; - } - - if(type == 17) - { - // auto send file - // TODO - - // for testing only: - // simulate sending a text file with 1kB length - int testlen = 100000; - uint8_t arr[testlen]; - char c = 'A'; - for(int i=0; i'Z') c='A'; - } - arraySend(arr, testlen, 3, (char *)"testfile.txt"); - return; - } - if(type == 18) - { - // auto send folder - // TODO - } - - if(type == 19) - { - // shut down this modem PC - int r = system("sudo shutdown now"); - exit(r); - } - - if(getSending() == 1) return; // already sending (Array sending) - - if(minfo == 0) - { - // this is the first frame of a larger file - // send it multiple times, like a preamble, to give the - // receiver some time for synchronisation - // duration: 3 seconds - // caprate: samples/s. This are symbols: caprate/txinterpolfactor - // and bits: symbols * bitsPerSymbol - // and bytes/second: bits/8 = (caprate/txinterpolfactor) * bitsPerSymbol / 8 - // one frame has 258 bytes, so we need for 5s: 5* ((caprate/txinterpolfactor) * bitsPerSymbol / 8) /258 + 1 frames - int numframespreamble = 3* ((caprate/txinterpolfactor) * bitsPerSymbol / 8) /258 + 1; - for(int i=0; i= 1s - meansumbytes += len; - if(ts < 5000000) - { - // do not measure - return; - } - - // ts ... time in us since last measurement - // divide by the number of bits - ts /= (meansumbytes*8); // time for one bit - int tbit = (int)ts; - int sp1 = 1000000/tbit; - // convert speed of symbols to speed of bits - speed = sp1 * bitsPerSymbol / 8; - - int mean = 0; - if(sparr[0] == -1) - { - for(int i=0; i0; i--) - sparr[i] = sparr[i-1]; - sparr[0] = speed; - } - - for(int i=0; i (10000*2+1)) - { - printf("txpl too small !!!\n"); - return; - } - - int bidx = 0; - txpl[bidx++] = 4; // type 4: FFT data follows - - for(int i=0; i> 8; - txpl[bidx++] = fft[i]; - } - sendUDP(appIP,UdpDataPort_ModemToApp,txpl,bidx); - } -} - -uint8_t lastb[12]; - -void display_IQ(uint8_t *pdata, int len) -{ - for (int i = 0; i < len; i++) - { - // insert new byte in lastb - for (int sh = 12 - 1; sh > 0; sh--) - lastb[sh] = lastb[sh - 1]; - lastb[0] = pdata[i]; - - // test if aligned - // for PC - if (lastb[0] == 0 && lastb[1] == 0 && lastb[2] == 3 && lastb[3] == 0xe8) - { - // we are aligned to a re value - int re = lastb[4]; - re <<= 8; - re += lastb[5]; - re <<= 8; - re += lastb[6]; - re <<= 8; - re += lastb[7]; - - int im = lastb[8]; - im <<= 8; - im += lastb[9]; - im <<= 8; - im += lastb[10]; - im <<= 8; - im += lastb[11]; - - double fre = (double)re / 16777216; - double fim = (double)im / 16777216; - printf("re: %f im: %f\n",fre,fim); - - } - // and for ARM - else if (lastb[0] == 0xe8 && lastb[1] == 3 && lastb[2] == 0 && lastb[3] == 0) - { - // we are aligned to a re value - int re = lastb[7]; - re <<= 8; - re += lastb[6]; - re <<= 8; - re += lastb[5]; - re <<= 8; - re += lastb[4]; - - int im = lastb[11]; - im <<= 8; - im += lastb[10]; - im <<= 8; - im += lastb[9]; - im <<= 8; - im += lastb[8]; - - double fre = (double)re / 16777216; - double fim = (double)im / 16777216; - printf("ARM re: %f im: %f\n",fre,fim); - } - } -} - -// called by UDP RX thread for IQ data from GR -void GRdata_I_Qdata(uint8_t *pdata, int len, struct sockaddr_in* rxsock) -{ - // these data are floats multiplied by 2^24 and then converted to int - // for testing convert it back and display it - //display_IQ(pdata,len); - - // send the data "as is" to app - uint8_t txpl[len+1]; - memcpy(txpl+1,pdata,len); - txpl[0] = 5; // type 5: IQ data follows - sendUDP(appIP,UdpDataPort_ModemToApp,txpl,len+1); -} diff --git a/modem/qo100modem.h b/modem/qo100modem.h deleted file mode 100644 index 388938b..0000000 --- a/modem/qo100modem.h +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "frameformat.h" -#include "main_helper.h" -#include "udp.h" -#include "bass.h" -#include - -#define jpg_tempfilename "rxdata.jpg" - -#define CRC16TX 0 -#define CRC16RX 1 -#define CRC16FILE 2 - -void stopModem(); -uint8_t *unpack_data(uint8_t *rxd, int len); -void TX_Scramble(uint8_t *data, int len); -uint8_t *RX_Scramble(uint8_t *data, int len); -uint16_t Crc16_messagecalc(int rxtx, uint8_t *data,int len); -uint32_t crc32_messagecalc(int txrx, unsigned char *data, int len); -int cfec_Reconstruct(uint8_t *darr, uint8_t *destination); -uint8_t *Pack(uint8_t *payload, int type, int status, int *plen); -void GetFEC(uint8_t *txblock, int len, uint8_t *destArray); -void initFEC(); -void toGR_sendData(uint8_t *data, int type, int status); -uint16_t *make_waterfall(uint8_t *pdata, int len, int *retlen); -void init_fft(); -void exit_fft(); -uint8_t *convertQPSKSymToBytes(uint8_t *rxsymbols); -uint8_t *convert8PSKSymToBytes(uint8_t *rxsymbols, int len); -uint8_t *getPayload(uint8_t *rxb); -void showbytestring(char *title, uint8_t *data, int anz); -void init_packer(); -void convertBytesToSyms_QPSK(uint8_t *bytes, uint8_t *syms, int bytenum); -void rotateQPSKsyms(uint8_t *src, uint8_t *dst, int len); -uint8_t * rotateBackQPSK(uint8_t *buf, int len, int rotations); -void convertBytesToSyms_8PSK(uint8_t *bytes, uint8_t *syms, int bytenum); -void rotate8PSKsyms(uint8_t *src, uint8_t *dst, int len); -uint8_t * rotateBack8PSK(uint8_t *buf, int len, int rotations); -void setSending(uint8_t onoff); -int getSending(); -void doArraySend(); -int arraySend(uint8_t *data, int length, uint8_t type, char *filename); -void shiftleft(uint8_t *data, int shiftnum, int len); -void showbytestring16(char *title, uint16_t *data, int anz); -int isTXRunning(char *prgname); -int pb_fifo_freespace(int nolock); -int init_audio(); -void sendToModulator(uint8_t *d, int len); -void pb_write_fifo(float sample); -int init_dsp(); - - -extern int keeprunning; -extern int BC_sock_AppToModem; -extern int speed; -extern int speedmode; -extern int bitsPerSymbol; -extern int constellationSize; -extern int caprate; -extern int txinterpolfactor; - -/* - * Constellation as produced by the GR Constellation Decoder: - * - * 0 ... +1+1j - * 1 ... -1+1j - * 2 ... -1-1j - * 3 ... +1-1j - * - * - * */ diff --git a/modem/qpsk_rx.py b/modem/qpsk_rx.py deleted file mode 100755 index d53783e..0000000 --- a/modem/qpsk_rx.py +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# -# SPDX-License-Identifier: GPL-3.0 -# -# GNU Radio Python Flow Graph -# Title: QPSK RX-Modem -# Author: DJ0ABR -# Description: works with Gnu Radio 3.8.xxx -# GNU Radio version: 3.8.2.0 - -from gnuradio import analog -from gnuradio import audio -from gnuradio import blocks -from gnuradio import digital -from gnuradio import filter -from gnuradio.filter import firdes -from gnuradio import gr -import sys -import signal -from argparse import ArgumentParser -from gnuradio.eng_arg import eng_float, intx -from gnuradio import eng_notation - - -class qpsk_rx(gr.top_block): - - def __init__(self, resamp=5, samp_rate=44100): - gr.top_block.__init__(self, "QPSK RX-Modem") - - ################################################## - # Parameters - ################################################## - self.resamp = resamp - self.samp_rate = samp_rate - - ################################################## - # Variables - ################################################## - self.sps = sps = 4 - self.qpsk__constellation = qpsk__constellation = digital.constellation_rect([0.707+0.707j, -0.707+0.707j, -0.707-0.707j, 0.707-0.707j], [0, 1, 2, 3], - 4, 2, 2, 1, 1).base() - self.qpsk__constellation.gen_soft_dec_lut(8) - self.outputsps = outputsps = 8 - self.nfilts = nfilts = 15 - self.mixf = mixf = 1500 - - ################################################## - # Blocks - ################################################## - self.mmse_resampler_xx_1 = filter.mmse_resampler_cc(0, resamp) - self.mmse_resampler_xx_0 = filter.mmse_resampler_ff(0, samp_rate / 8000) - self.low_pass_filter_0 = filter.fir_filter_fff( - 1, - firdes.low_pass( - 8, - samp_rate, - 3500, - 3100, - firdes.WIN_HAMMING, - 6.76)) - self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf(sps, 0.1, firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), 0.35, 11*sps*nfilts), nfilts, nfilts/2, 1.5, outputsps) - self.digital_lms_dd_equalizer_cc_0 = digital.lms_dd_equalizer_cc(15, 0.01, outputsps, qpsk__constellation) - self.digital_costas_loop_cc_0 = digital.costas_loop_cc(0.06, 4, False) - self.digital_constellation_decoder_cb_0 = digital.constellation_decoder_cb(qpsk__constellation) - self.blocks_udp_sink_0_0_0 = blocks.udp_sink(gr.sizeof_int*1, '127.0.0.1', 40137, 120, False) - self.blocks_udp_sink_0_0 = blocks.udp_sink(gr.sizeof_int*1, '127.0.0.1', 40136, 120, False) - self.blocks_udp_sink_0 = blocks.udp_sink(gr.sizeof_char*1, '127.0.0.1', 40135, 344, False) - self.blocks_multiply_xx_0_1_0 = blocks.multiply_vff(1) - self.blocks_multiply_xx_0_1 = blocks.multiply_vff(1) - self.blocks_multiply_xx_0_0_0 = blocks.multiply_vff(1) - self.blocks_interleave_0_0 = blocks.interleave(gr.sizeof_int*1, 1) - self.blocks_interleave_0 = blocks.interleave(gr.sizeof_int*1, 1) - self.blocks_float_to_int_0_1 = blocks.float_to_int(1, 1) - self.blocks_float_to_int_0_0 = blocks.float_to_int(1, 16777216) - self.blocks_float_to_int_0 = blocks.float_to_int(1, 16777216) - self.blocks_float_to_complex_0 = blocks.float_to_complex(1) - self.blocks_complex_to_float_1 = blocks.complex_to_float(1) - self.blocks_complex_to_float_0 = blocks.complex_to_float(1) - self.audio_source_0 = audio.source(samp_rate, '', True) - self.analog_sig_source_x_0_0_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, mixf, 1, 0, 0) - self.analog_const_source_x_0_1 = analog.sig_source_f(0, analog.GR_CONST_WAVE, 0, 0, 16777216) - self.analog_const_source_x_0_0 = analog.sig_source_i(0, analog.GR_CONST_WAVE, 0, 0, 1000) - self.analog_const_source_x_0 = analog.sig_source_i(0, analog.GR_CONST_WAVE, 0, 0, 1000) - self.analog_agc2_xx_0_0 = analog.agc2_cc(0.01, 0.2, 1, 1) - self.analog_agc2_xx_0_0.set_max_gain(3) - - - - ################################################## - # Connections - ################################################## - self.connect((self.analog_agc2_xx_0_0, 0), (self.digital_costas_loop_cc_0, 0)) - self.connect((self.analog_const_source_x_0, 0), (self.blocks_interleave_0, 0)) - self.connect((self.analog_const_source_x_0_0, 0), (self.blocks_interleave_0_0, 0)) - self.connect((self.analog_const_source_x_0_1, 0), (self.blocks_multiply_xx_0_1_0, 1)) - self.connect((self.analog_sig_source_x_0_0_0, 0), (self.blocks_complex_to_float_1, 0)) - self.connect((self.audio_source_0, 0), (self.low_pass_filter_0, 0)) - self.connect((self.audio_source_0, 0), (self.mmse_resampler_xx_0, 0)) - self.connect((self.blocks_complex_to_float_0, 0), (self.blocks_float_to_int_0, 0)) - self.connect((self.blocks_complex_to_float_0, 1), (self.blocks_float_to_int_0_0, 0)) - self.connect((self.blocks_complex_to_float_1, 1), (self.blocks_multiply_xx_0_0_0, 1)) - self.connect((self.blocks_complex_to_float_1, 0), (self.blocks_multiply_xx_0_1, 1)) - self.connect((self.blocks_float_to_complex_0, 0), (self.mmse_resampler_xx_1, 0)) - self.connect((self.blocks_float_to_int_0, 0), (self.blocks_interleave_0_0, 1)) - self.connect((self.blocks_float_to_int_0_0, 0), (self.blocks_interleave_0_0, 2)) - self.connect((self.blocks_float_to_int_0_1, 0), (self.blocks_interleave_0, 1)) - self.connect((self.blocks_interleave_0, 0), (self.blocks_udp_sink_0_0, 0)) - self.connect((self.blocks_interleave_0_0, 0), (self.blocks_udp_sink_0_0_0, 0)) - self.connect((self.blocks_multiply_xx_0_0_0, 0), (self.blocks_float_to_complex_0, 0)) - self.connect((self.blocks_multiply_xx_0_1, 0), (self.blocks_float_to_complex_0, 1)) - self.connect((self.blocks_multiply_xx_0_1_0, 0), (self.blocks_float_to_int_0_1, 0)) - self.connect((self.digital_constellation_decoder_cb_0, 0), (self.blocks_udp_sink_0, 0)) - self.connect((self.digital_costas_loop_cc_0, 0), (self.blocks_complex_to_float_0, 0)) - self.connect((self.digital_costas_loop_cc_0, 0), (self.digital_constellation_decoder_cb_0, 0)) - self.connect((self.digital_lms_dd_equalizer_cc_0, 0), (self.analog_agc2_xx_0_0, 0)) - self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.digital_lms_dd_equalizer_cc_0, 0)) - self.connect((self.low_pass_filter_0, 0), (self.blocks_multiply_xx_0_0_0, 0)) - self.connect((self.low_pass_filter_0, 0), (self.blocks_multiply_xx_0_1, 0)) - self.connect((self.mmse_resampler_xx_0, 0), (self.blocks_multiply_xx_0_1_0, 0)) - self.connect((self.mmse_resampler_xx_1, 0), (self.digital_pfb_clock_sync_xxx_0, 0)) - - - def get_resamp(self): - return self.resamp - - def set_resamp(self, resamp): - self.resamp = resamp - self.mmse_resampler_xx_1.set_resamp_ratio(self.resamp) - - def get_samp_rate(self): - return self.samp_rate - - def set_samp_rate(self, samp_rate): - self.samp_rate = samp_rate - self.analog_sig_source_x_0_0_0.set_sampling_freq(self.samp_rate) - self.low_pass_filter_0.set_taps(firdes.low_pass(8, self.samp_rate, 3500, 3100, firdes.WIN_HAMMING, 6.76)) - self.mmse_resampler_xx_0.set_resamp_ratio(self.samp_rate / 8000) - - def get_sps(self): - return self.sps - - def set_sps(self, sps): - self.sps = sps - self.digital_pfb_clock_sync_xxx_0.update_taps(firdes.root_raised_cosine(self.nfilts, self.nfilts, 1.0/float(self.sps), 0.35, 11*self.sps*self.nfilts)) - - def get_qpsk__constellation(self): - return self.qpsk__constellation - - def set_qpsk__constellation(self, qpsk__constellation): - self.qpsk__constellation = qpsk__constellation - - def get_outputsps(self): - return self.outputsps - - def set_outputsps(self, outputsps): - self.outputsps = outputsps - - def get_nfilts(self): - return self.nfilts - - def set_nfilts(self, nfilts): - self.nfilts = nfilts - self.digital_pfb_clock_sync_xxx_0.update_taps(firdes.root_raised_cosine(self.nfilts, self.nfilts, 1.0/float(self.sps), 0.35, 11*self.sps*self.nfilts)) - - def get_mixf(self): - return self.mixf - - def set_mixf(self, mixf): - self.mixf = mixf - self.analog_sig_source_x_0_0_0.set_frequency(self.mixf) - - - - -def argument_parser(): - description = 'works with Gnu Radio 3.8.xxx' - parser = ArgumentParser(description=description) - parser.add_argument( - "-r", "--resamp", dest="resamp", type=intx, default=5, - help="Set resamp [default=%(default)r]") - parser.add_argument( - "-s", "--samp-rate", dest="samp_rate", type=intx, default=44100, - help="Set samp_rate [default=%(default)r]") - return parser - - -def main(top_block_cls=qpsk_rx, options=None): - if options is None: - options = argument_parser().parse_args() - tb = top_block_cls(resamp=options.resamp, samp_rate=options.samp_rate) - - def sig_handler(sig=None, frame=None): - tb.stop() - tb.wait() - - sys.exit(0) - - signal.signal(signal.SIGINT, sig_handler) - signal.signal(signal.SIGTERM, sig_handler) - - tb.start() - - tb.wait() - - -if __name__ == '__main__': - main() diff --git a/modem/rx_8psk.py b/modem/rx_8psk.py deleted file mode 100755 index 9547706..0000000 --- a/modem/rx_8psk.py +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# -# SPDX-License-Identifier: GPL-3.0 -# -# GNU Radio Python Flow Graph -# Title: 8PSK Modem DJ0ABR -# Author: kurt -# Description: requires GNU Radio 3.8xxx -# GNU Radio version: 3.8.2.0 - -from gnuradio import analog -from gnuradio import audio -from gnuradio import blocks -from gnuradio import digital -from gnuradio import filter -from gnuradio.filter import firdes -from gnuradio import gr -import sys -import signal -from argparse import ArgumentParser -from gnuradio.eng_arg import eng_float, intx -from gnuradio import eng_notation - - -class rx_8psk(gr.top_block): - - def __init__(self, resamp=6, samp_rate=48000): - gr.top_block.__init__(self, "8PSK Modem DJ0ABR") - - ################################################## - # Parameters - ################################################## - self.resamp = resamp - self.samp_rate = samp_rate - - ################################################## - # Variables - ################################################## - self.sps = sps = 4 - self.nfilts = nfilts = 32 - self.rrc_taps = rrc_taps = firdes.root_raised_cosine(nfilts, nfilts, 1.1/float(sps), 0.2, 11*sps*nfilts) - self.outputsps = outputsps = 7 - self.mixf = mixf = 1500 - - ################################################## - # Blocks - ################################################## - self.mmse_resampler_xx_0_0 = filter.mmse_resampler_ff(0, samp_rate / 8000) - self.mmse_resampler_xx_0 = filter.mmse_resampler_cc(0, resamp) - self.low_pass_filter_0 = filter.fir_filter_fff( - 1, - firdes.low_pass( - 12, - samp_rate, - 3900, - 3300, - firdes.WIN_HAMMING, - 6.76)) - self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf(sps, 0.06, rrc_taps, nfilts, nfilts/16, 2, outputsps) - self.digital_lms_dd_equalizer_cc_0 = digital.lms_dd_equalizer_cc(15, 0.01, outputsps, digital.constellation_8psk_natural().base()) - self.digital_diff_decoder_bb_0 = digital.diff_decoder_bb(8) - self.digital_costas_loop_cc_0 = digital.costas_loop_cc(0.15, 8, False) - self.digital_constellation_decoder_cb_0 = digital.constellation_decoder_cb(digital.constellation_8psk_natural().base()) - self.blocks_udp_sink_0_0_0 = blocks.udp_sink(gr.sizeof_int*1, '127.0.0.1', 40137, 120, False) - self.blocks_udp_sink_0_0 = blocks.udp_sink(gr.sizeof_int*1, '127.0.0.1', 40136, 120, False) - self.blocks_udp_sink_0 = blocks.udp_sink(gr.sizeof_char*1, '127.0.0.1', 40135, 344, False) - self.blocks_multiply_xx_0_1_0 = blocks.multiply_vff(1) - self.blocks_multiply_xx_0_1 = blocks.multiply_vff(1) - self.blocks_multiply_xx_0_0_0 = blocks.multiply_vff(1) - self.blocks_interleave_0_0 = blocks.interleave(gr.sizeof_int*1, 1) - self.blocks_interleave_0 = blocks.interleave(gr.sizeof_int*1, 1) - self.blocks_float_to_int_0_1 = blocks.float_to_int(1, 1) - self.blocks_float_to_int_0_0 = blocks.float_to_int(1, 16777216) - self.blocks_float_to_int_0 = blocks.float_to_int(1, 16777216) - self.blocks_float_to_complex_0 = blocks.float_to_complex(1) - self.blocks_complex_to_float_1 = blocks.complex_to_float(1) - self.blocks_complex_to_float_0 = blocks.complex_to_float(1) - self.audio_source_0 = audio.source(samp_rate, '', True) - self.analog_sig_source_x_0_0_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, mixf, 1, 0, 0) - self.analog_const_source_x_0_1 = analog.sig_source_f(0, analog.GR_CONST_WAVE, 0, 0, 16777216) - self.analog_const_source_x_0_0 = analog.sig_source_i(0, analog.GR_CONST_WAVE, 0, 0, 1000) - self.analog_const_source_x_0 = analog.sig_source_i(0, analog.GR_CONST_WAVE, 0, 0, 1000) - self.analog_agc2_xx_0_0 = analog.agc2_cc(1e-2, 0.2, 1, 2) - self.analog_agc2_xx_0_0.set_max_gain(3) - - - - ################################################## - # Connections - ################################################## - self.connect((self.analog_agc2_xx_0_0, 0), (self.digital_costas_loop_cc_0, 0)) - self.connect((self.analog_const_source_x_0, 0), (self.blocks_interleave_0, 0)) - self.connect((self.analog_const_source_x_0_0, 0), (self.blocks_interleave_0_0, 0)) - self.connect((self.analog_const_source_x_0_1, 0), (self.blocks_multiply_xx_0_1_0, 1)) - self.connect((self.analog_sig_source_x_0_0_0, 0), (self.blocks_complex_to_float_1, 0)) - self.connect((self.audio_source_0, 0), (self.low_pass_filter_0, 0)) - self.connect((self.audio_source_0, 0), (self.mmse_resampler_xx_0_0, 0)) - self.connect((self.blocks_complex_to_float_0, 0), (self.blocks_float_to_int_0, 0)) - self.connect((self.blocks_complex_to_float_0, 1), (self.blocks_float_to_int_0_0, 0)) - self.connect((self.blocks_complex_to_float_1, 1), (self.blocks_multiply_xx_0_0_0, 1)) - self.connect((self.blocks_complex_to_float_1, 0), (self.blocks_multiply_xx_0_1, 1)) - self.connect((self.blocks_float_to_complex_0, 0), (self.mmse_resampler_xx_0, 0)) - self.connect((self.blocks_float_to_int_0, 0), (self.blocks_interleave_0_0, 1)) - self.connect((self.blocks_float_to_int_0_0, 0), (self.blocks_interleave_0_0, 2)) - self.connect((self.blocks_float_to_int_0_1, 0), (self.blocks_interleave_0, 1)) - self.connect((self.blocks_interleave_0, 0), (self.blocks_udp_sink_0_0, 0)) - self.connect((self.blocks_interleave_0_0, 0), (self.blocks_udp_sink_0_0_0, 0)) - self.connect((self.blocks_multiply_xx_0_0_0, 0), (self.blocks_float_to_complex_0, 0)) - self.connect((self.blocks_multiply_xx_0_1, 0), (self.blocks_float_to_complex_0, 1)) - self.connect((self.blocks_multiply_xx_0_1_0, 0), (self.blocks_float_to_int_0_1, 0)) - self.connect((self.digital_constellation_decoder_cb_0, 0), (self.digital_diff_decoder_bb_0, 0)) - self.connect((self.digital_costas_loop_cc_0, 0), (self.blocks_complex_to_float_0, 0)) - self.connect((self.digital_costas_loop_cc_0, 0), (self.digital_constellation_decoder_cb_0, 0)) - self.connect((self.digital_diff_decoder_bb_0, 0), (self.blocks_udp_sink_0, 0)) - self.connect((self.digital_lms_dd_equalizer_cc_0, 0), (self.analog_agc2_xx_0_0, 0)) - self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.digital_lms_dd_equalizer_cc_0, 0)) - self.connect((self.low_pass_filter_0, 0), (self.blocks_multiply_xx_0_0_0, 0)) - self.connect((self.low_pass_filter_0, 0), (self.blocks_multiply_xx_0_1, 0)) - self.connect((self.mmse_resampler_xx_0, 0), (self.digital_pfb_clock_sync_xxx_0, 0)) - self.connect((self.mmse_resampler_xx_0_0, 0), (self.blocks_multiply_xx_0_1_0, 0)) - - - def get_resamp(self): - return self.resamp - - def set_resamp(self, resamp): - self.resamp = resamp - self.mmse_resampler_xx_0.set_resamp_ratio(self.resamp) - - def get_samp_rate(self): - return self.samp_rate - - def set_samp_rate(self, samp_rate): - self.samp_rate = samp_rate - self.analog_sig_source_x_0_0_0.set_sampling_freq(self.samp_rate) - self.low_pass_filter_0.set_taps(firdes.low_pass(12, self.samp_rate, 3900, 3300, firdes.WIN_HAMMING, 6.76)) - self.mmse_resampler_xx_0_0.set_resamp_ratio(self.samp_rate / 8000) - - def get_sps(self): - return self.sps - - def set_sps(self, sps): - self.sps = sps - self.set_rrc_taps(firdes.root_raised_cosine(self.nfilts, self.nfilts, 1.1/float(self.sps), 0.2, 11*self.sps*self.nfilts)) - - def get_nfilts(self): - return self.nfilts - - def set_nfilts(self, nfilts): - self.nfilts = nfilts - self.set_rrc_taps(firdes.root_raised_cosine(self.nfilts, self.nfilts, 1.1/float(self.sps), 0.2, 11*self.sps*self.nfilts)) - - def get_rrc_taps(self): - return self.rrc_taps - - def set_rrc_taps(self, rrc_taps): - self.rrc_taps = rrc_taps - self.digital_pfb_clock_sync_xxx_0.update_taps(self.rrc_taps) - - def get_outputsps(self): - return self.outputsps - - def set_outputsps(self, outputsps): - self.outputsps = outputsps - - def get_mixf(self): - return self.mixf - - def set_mixf(self, mixf): - self.mixf = mixf - self.analog_sig_source_x_0_0_0.set_frequency(self.mixf) - - - - -def argument_parser(): - description = 'requires GNU Radio 3.8xxx' - parser = ArgumentParser(description=description) - parser.add_argument( - "-r", "--resamp", dest="resamp", type=intx, default=6, - help="Set resamp [default=%(default)r]") - parser.add_argument( - "-s", "--samp-rate", dest="samp_rate", type=intx, default=48000, - help="Set samp_rate [default=%(default)r]") - return parser - - -def main(top_block_cls=rx_8psk, options=None): - if options is None: - options = argument_parser().parse_args() - tb = top_block_cls(resamp=options.resamp, samp_rate=options.samp_rate) - - def sig_handler(sig=None, frame=None): - tb.stop() - tb.wait() - - sys.exit(0) - - signal.signal(signal.SIGINT, sig_handler) - signal.signal(signal.SIGTERM, sig_handler) - - tb.start() - - tb.wait() - - -if __name__ == '__main__': - main() diff --git a/modem/scrambler.c b/modem/scrambler.c deleted file mode 100644 index 8fd1e33..0000000 --- a/modem/scrambler.c +++ /dev/null @@ -1,91 +0,0 @@ -/* -* High Speed modem to transfer data in a 2,7kHz SSB channel -* ========================================================= -* Author: DJ0ABR -* -* (c) DJ0ABR -* www.dj0abr.de -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -*/ - -#include "qo100modem.h" - -uint8_t scr[400] = { -130 , 239 , 223 , 19 , 146 , 254 , 12 , 86 , 106 , 68 , -77 , 213 , 243 , 216 , 102 , 227 , 108 , 113 , 229 , 89 , -26 , 64 , 138 , 216 , 225 , 121 , 194 , 137 , 152 , 64 , -51 , 175 , 68 , 200 , 37 , 104 , 247 , 68 , 193 , 50 , -19 , 14 , 196 , 81 , 4 , 236 , 191 , 249 , 83 , 25 , -161 , 171 , 167 , 29 , 33 , 139 , 7 , 152 , 230 , 144 , -125 , 206 , 34 , 236 , 112 , 78 , 219 , 34 , 181 , 161 , -7 , 45 , 198 , 235 , 62 , 115 , 194 , 100 , 209 , 95 , -186 , 161 , 53 , 10 , 110 , 246 , 122 , 246 , 207 , 194 , -178 , 63 , 232 , 93 , 158 , 234 , 231 , 73 , 214 , 64, -130 , 239 , 223 , 19 , 146 , 254 , 12 , 86 , 106 , 68 , -77 , 213 , 243 , 216 , 102 , 227 , 108 , 113 , 229 , 89 , -26 , 64 , 138 , 216 , 225 , 121 , 194 , 137 , 152 , 64 , -51 , 175 , 68 , 200 , 37 , 104 , 247 , 68 , 193 , 50 , -19 , 14 , 196 , 81 , 4 , 236 , 191 , 249 , 83 , 25 , -161 , 171 , 167 , 29 , 33 , 139 , 7 , 152 , 230 , 144 , -125 , 206 , 34 , 236 , 112 , 78 , 219 , 34 , 181 , 161 , -7 , 45 , 198 , 235 , 62 , 115 , 194 , 100 , 209 , 95 , -186 , 161 , 53 , 10 , 110 , 246 , 122 , 246 , 207 , 194 , -178 , 63 , 232 , 93 , 158 , 234 , 231 , 73 , 214 , 64, -130 , 239 , 223 , 19 , 146 , 254 , 12 , 86 , 106 , 68 , -77 , 213 , 243 , 216 , 102 , 227 , 108 , 113 , 229 , 89 , -26 , 64 , 138 , 216 , 225 , 121 , 194 , 137 , 152 , 64 , -51 , 175 , 68 , 200 , 37 , 104 , 247 , 68 , 193 , 50 , -19 , 14 , 196 , 81 , 4 , 236 , 191 , 249 , 83 , 25 , -161 , 171 , 167 , 29 , 33 , 139 , 7 , 152 , 230 , 144 , -125 , 206 , 34 , 236 , 112 , 78 , 219 , 34 , 181 , 161 , -7 , 45 , 198 , 235 , 62 , 115 , 194 , 100 , 209 , 95 , -186 , 161 , 53 , 10 , 110 , 246 , 122 , 246 , 207 , 194 , -178 , 63 , 232 , 93 , 158 , 234 , 231 , 73 , 214 , 64, -130 , 239 , 223 , 19 , 146 , 254 , 12 , 86 , 106 , 68 , -77 , 213 , 243 , 216 , 102 , 227 , 108 , 113 , 229 , 89 , -26 , 64 , 138 , 216 , 225 , 121 , 194 , 137 , 152 , 64 , -51 , 175 , 68 , 200 , 37 , 104 , 247 , 68 , 193 , 50 , -19 , 14 , 196 , 81 , 4 , 236 , 191 , 249 , 83 , 25 , -161 , 171 , 167 , 29 , 33 , 139 , 7 , 152 , 230 , 144 , -125 , 206 , 34 , 236 , 112 , 78 , 219 , 34 , 181 , 161 , -7 , 45 , 198 , 235 , 62 , 115 , 194 , 100 , 209 , 95 , -186 , 161 , 53 , 10 , 110 , 246 , 122 , 246 , 207 , 194 , -178 , 63 , 232 , 93 , 158 , 234 , 231 , 73 , 214 , 64 -}; - -uint8_t rx_scrbuf[400]; - -void TX_Scramble(uint8_t *data, int len) -{ - if (len > 400) return; - - for(int i=0; i 400) return data; - - memcpy(rx_scrbuf,data,len); - - for(int i=0; i= MAXUDPTHREADS) - { - printf("max number of UDP threads\n"); - exit(0); - } - - rxcfg[rxcfg_idx].sock = sock; - rxcfg[rxcfg_idx].port = port; - rxcfg[rxcfg_idx].rxfunc = rxfunc; - rxcfg[rxcfg_idx].keeprunning = keeprunning; - - // bind port - struct sockaddr_in sin; - - *sock = socket(PF_INET, SOCK_DGRAM, 0); - if (*sock == -1){ - printf("Failed to create Socket\n"); - exit(0); - } - - int enable = 1; - setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)); - - memset(&sin, 0, sizeof(struct sockaddr_in)); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - sin.sin_addr.s_addr = INADDR_ANY; - - if (bind(*sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) != 0) - { - printf("Failed to bind socket, port:%d\n",port); - close(*sock); - exit(0); - } - - // port sucessfully bound - // create the receive thread - pthread_t rxthread; - pthread_create(&rxthread, NULL, threadfunction, &(rxcfg[rxcfg_idx])); - - rxcfg_idx++; -} - -void *threadfunction(void *param) -{ - RXCFG rxcfg; - memcpy((uint8_t *)(&rxcfg), (uint8_t *)param, sizeof(RXCFG)); - - socklen_t fromlen; - int recvlen; - char rxbuf[256]; - struct sockaddr_in fromSock; - - fromlen = sizeof(struct sockaddr_in); - while(*rxcfg.keeprunning) - { - recvlen = recvfrom(*rxcfg.sock, rxbuf, 256, 0, (struct sockaddr *)&fromSock, &fromlen); - if (recvlen > 0) - { - // data received, send it to callback function - (*rxcfg.rxfunc)((uint8_t *)rxbuf,recvlen, &fromSock); - } - } - - return NULL; -} - -// send UDP message -void sendUDP(char *destIP, int destPort, uint8_t *pdata, int len) -{ - int sockfd; - struct sockaddr_in servaddr; - - // Creating socket file descriptor - if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { - printf("sendUDP: socket creation failed\n"); - exit(0); - } - - memset(&servaddr, 0, sizeof(servaddr)); - - // Filling server information - servaddr.sin_family = AF_INET; - servaddr.sin_port = htons(destPort); - //printf("Send to <%s><%d> Len:%d\n",destIP,destPort,len); - servaddr.sin_addr.s_addr=inet_addr(destIP); - - sendto(sockfd, (char *)pdata, len, 0, (const struct sockaddr *) &servaddr, sizeof(servaddr)); - close(sockfd); -} - diff --git a/modem/udp.h b/modem/udp.h deleted file mode 100644 index 33163fe..0000000 --- a/modem/udp.h +++ /dev/null @@ -1,9 +0,0 @@ -void UdpRxInit(int *sock, int port, void (*rxfunc)(uint8_t *, int, struct sockaddr_in*), int *keeprunning); -void sendUDP(char *destIP, int destPort, uint8_t *pdata, int len); - -typedef struct { - int *sock; - int port; - void (*rxfunc)(uint8_t *, int, struct sockaddr_in*); - int *keeprunning; -} RXCFG;