From 7f998ccb7847fc9d27b3987b2526bbef8e43c501 Mon Sep 17 00:00:00 2001 From: baobrien Date: Mon, 11 Apr 2016 00:19:30 +0000 Subject: [PATCH] Added new frame format. Extended vhf_deframe_c2 to support new format. Added vhf_frame_c2 to support framing of both formats. git-svn-id: https://svn.code.sf.net/p/freetel/code@2782 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/src/CMakeLists.txt | 3 + codec2-dev/src/freedv_vhf_framing.c | 189 ++++++++++++++++++++++------ codec2-dev/src/freedv_vhf_framing.h | 15 ++- codec2-dev/src/fsk_mod.c | 4 +- codec2-dev/src/vhf_deframe_c2.c | 38 ++++-- 5 files changed, 199 insertions(+), 50 deletions(-) diff --git a/codec2-dev/src/CMakeLists.txt b/codec2-dev/src/CMakeLists.txt index acac63a8..df845fed 100644 --- a/codec2-dev/src/CMakeLists.txt +++ b/codec2-dev/src/CMakeLists.txt @@ -265,6 +265,9 @@ target_link_libraries(fmfsk_demod ${CMAKE_REQUIRED_LIBRARIES} codec2) add_executable(vhf_deframe_c2 vhf_deframe_c2.c) target_link_libraries(vhf_deframe_c2 ${CMAKE_REQUIRED_LIBRARIES} codec2) +add_executable(vhf_frame_c2 vhf_frame_c2.c) +target_link_libraries(vhf_frame_c2 ${CMAKE_REQUIRED_LIBRARIES} codec2) + add_executable(cohpsk_demod cohpsk_demod.c octave.c) target_link_libraries(cohpsk_demod ${CMAKE_REQUIRED_LIBRARIES} codec2) diff --git a/codec2-dev/src/freedv_vhf_framing.c b/codec2-dev/src/freedv_vhf_framing.c index 19905bf6..6b6161f5 100644 --- a/codec2-dev/src/freedv_vhf_framing.c +++ b/codec2-dev/src/freedv_vhf_framing.c @@ -39,7 +39,7 @@ #include #include #include - +#include #include "freedv_vhf_framing.h" /* The voice UW of the VHF type A frame */ @@ -64,6 +64,19 @@ static const uint8_t A_blank[] = {1,0,1,0,0,1,1,1, /* Padding[0:3] Proto[0:3] 0,0,0,0,0,0,1,0, /* Voice[48:51] Proto[12:15] */ 0,1,1,1,0,0,1,0};/* Proto[16:19] Padding[4:7] */ +/* HF Type B UW */ +static const uint8_t B_uw_v[] = {0,1,1,0,0,1,1,1}; + +/* Blank HF type B frame */ +static const uint8_t B_blank[] = {0,1,1,0,0,1,1,1, /* UW[0:7] */ + 0,0,0,0,0,0,0,0, /* Voice1[0:7] */ + 0,0,0,0,0,0,0,0, /* Voice1[8:15] */ + 0,0,0,0,0,0,0,0, /* Voice1[16:23] */ + 0,0,0,0,0,0,0,0, /* Voice1[24:28] Voice2[0:3] */ + 0,0,0,0,0,0,0,0, /* Voice2[4:11] */ + 0,0,0,0,0,0,0,0, /* Voice2[12:19] */ + 0,0,0,0,0,0,0,0};/* Voice2[20:28] */ + /* States */ #define ST_NOSYNC 0 /* Not synchronized */ #define ST_SYNC 1 /* Synchronized */ @@ -120,6 +133,26 @@ void fvhff_frame_bits( int frame_type, bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit); ibit++; } + }else if(frame_type == FREEDV_HF_FRAME_B){ + /* Pointers to both c2 frames so the bit unpack macro works */ + uint8_t * codec2_in1 = &codec2_in[0]; + uint8_t * codec2_in2 = &codec2_in[4]; + /* Fill out frame with blank prototype */ + for(i=0; i<64; i++) + bits_out[i] = B_blank[i]; + + /* Fill out first codec2 block */ + ibit=0; + for(i=8; i<36; i++){ + bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in1,ibit); + ibit++; + } + /* Fill out second codec2 block */ + ibit=0; + for(i=36; i<64; i++){ + bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in2,ibit); + ibit++; + } } } @@ -159,7 +192,7 @@ void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type, bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit); ibit++; } - for(i=56; i<88; i++){ /* Second half */ + for(i=56; i<88; i++){ /* Second half */ bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit); ibit++; } @@ -173,42 +206,89 @@ void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type, struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type, int enable_bit_flip){ struct freedv_vhf_deframer * deframer; uint8_t *bits,*invbits; + int frame_size; + + assert( (frame_type == FREEDV_VHF_FRAME_A) || (frame_type == FREEDV_HF_FRAME_B) ); + /* It's a Type A frame */ if(frame_type == FREEDV_VHF_FRAME_A){ - /* Allocate memory for the thing */ - deframer = malloc(sizeof(struct freedv_vhf_deframer)); - if(deframer == NULL) - return NULL; - - /* Allocate the not-bit buffer */ - if(enable_bit_flip){ - invbits = malloc(sizeof(uint8_t)*96); - if(invbits == NULL) - return NULL; - }else{ - invbits = NULL; - } + frame_size = 96; + }else if(frame_type == FREEDV_HF_FRAME_B){ + frame_size = 64; + }else{ + return NULL; + } + + /* Allocate memory for the thing */ + deframer = malloc(sizeof(struct freedv_vhf_deframer)); + if(deframer == NULL) + return NULL; - /* Allocate the bit buffer */ - bits = malloc(sizeof(uint8_t)*96); - if(bits == NULL) + /* Allocate the not-bit buffer */ + if(enable_bit_flip){ + invbits = malloc(sizeof(uint8_t)*frame_size); + if(invbits == NULL) return NULL; - - deframer->bits = bits; - deframer->invbits = invbits; - deframer->ftype = frame_type; - deframer->state = ST_NOSYNC; - deframer->bitptr = 0; - deframer->last_uw = 0; - deframer->miss_cnt = 0; - deframer->frame_size = 96; - deframer->on_inv_bits = 0; - - deframer->fdc = NULL; - - return deframer; + }else{ + invbits = NULL; + } + + /* Allocate the bit buffer */ + bits = malloc(sizeof(uint8_t)*frame_size); + if(bits == NULL) + return NULL; + + deframer->bits = bits; + deframer->invbits = invbits; + deframer->ftype = frame_type; + deframer->state = ST_NOSYNC; + deframer->bitptr = 0; + deframer->last_uw = 0; + deframer->miss_cnt = 0; + deframer->frame_size = frame_size; + deframer->on_inv_bits = 0; + + deframer->fdc = NULL; + + return deframer; +} + +/* Get size of frame in bits */ +int fvhff_get_frame_size(struct freedv_vhf_deframer * def){ + return def->frame_size; +} + +/* Codec2 size in bytes */ +int fvhff_get_codec2_size(struct freedv_vhf_deframer * def){ + if(def->ftype == FREEDV_VHF_FRAME_A){ + return 7; + } else if(def->ftype == FREEDV_HF_FRAME_B){ + return 8; + } else{ + return 0; + } +} + +/* Protocol bits in bits */ +int fvhff_get_proto_size(struct freedv_vhf_deframer * def){ + if(def->ftype == FREEDV_VHF_FRAME_A){ + return 20; + } else if(def->ftype == FREEDV_HF_FRAME_B){ + return 0; + } else{ + return 0; + } +} + +/* Varicode bits in bits */ +int fvhff_get_varicode_size(struct freedv_vhf_deframer * def){ + if(def->ftype == FREEDV_VHF_FRAME_A){ + return 2; + } else if(def->ftype == FREEDV_HF_FRAME_B){ + return 0; + } else{ + return 0; } - return NULL; } void fvhff_destroy_deframer(struct freedv_vhf_deframer * def){ @@ -229,6 +309,7 @@ static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int to int iuw,ibit; const uint8_t * uw[2]; int uw_len; + int can_be_data; int uw_offset; int diff[2] = { 0, 0 }; int i; @@ -238,9 +319,16 @@ static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int to /* Set up parameters for the standard type of frame */ if(frame_type == FREEDV_VHF_FRAME_A){ uw[0] = A_uw_v; - uw[1] = A_uw_d; + uw[1] = A_uw_d; uw_len = 16; uw_offset = 40; + can_be_data = 1; + } else if(frame_type == FREEDV_HF_FRAME_B){ + uw[0] = B_uw_v; + uw[1] = B_uw_v; + uw_len = 8; + uw_offset = 0; + can_be_data = 0; } else { return 0; } @@ -259,7 +347,7 @@ static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int to match[i] = diff[i] <= tol; } /* Pick the best matching UW */ - if (diff[0] < diff[1]) { + if (diff[0] < diff[1] || !can_be_data) { r = match[0]; *pt = FRAME_PAYLOAD_TYPE_VOICE; } else { @@ -329,6 +417,33 @@ static void fvhff_extract_frame_voice(struct freedv_vhf_deframer * def,uint8_t b } } + }else if(frame_type == FREEDV_HF_FRAME_B){ + /* Pointers to both c2 frames */ + uint8_t * codec2_out1 = &codec2_out[0]; + uint8_t * codec2_out2 = &codec2_out[4]; + + /* Extract codec2 bits */ + memset(codec2_out,0,8); + ibit = 0; + + /* Extract and pack first c2 frame, MSB first */ + iframe = bitptr+8; + if(iframe >= frame_size) iframe-=frame_size; + for(;ibit<28;ibit++){ + codec2_out1[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7)); + iframe++; + if(iframe >= frame_size) iframe=0; + } + + /* Extract and pack second c2 frame, MSB first */ + iframe = bitptr+36; + ibit = 0; + if(iframe >= frame_size) iframe-=frame_size; + for(;ibit<28;ibit++){ + codec2_out2[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7)); + iframe++; + if(iframe >= frame_size) iframe=0; + } } } @@ -425,6 +540,10 @@ int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uin uw_first_tol = 1; /* The UW bit-error tolerance for the first frame */ uw_sync_tol = 3; /* The UW bit error tolerance for frames after sync */ miss_tol = 5; /* How many UWs may be missed before going into the de-synced state */ + }else if(frame_type == FREEDV_HF_FRAME_B){ + uw_first_tol = 1; /* The UW bit-error tolerance for the first frame */ + uw_sync_tol = 3; /* The UW bit error tolerance for frames after sync */ + miss_tol = 5; /* How many UWs may be missed before going into the de-synced state */ }else{ return 0; } diff --git a/codec2-dev/src/freedv_vhf_framing.h b/codec2-dev/src/freedv_vhf_framing.h index a3843ef3..66f0e8e5 100644 --- a/codec2-dev/src/freedv_vhf_framing.h +++ b/codec2-dev/src/freedv_vhf_framing.h @@ -39,7 +39,8 @@ #include "freedv_data_channel.h" /* Standard frame type */ -#define FREEDV_VHF_FRAME_A 1 +#define FREEDV_VHF_FRAME_A 1 +#define FREEDV_HF_FRAME_B 2 struct freedv_vhf_deframer { int ftype; /* Type of frame to be looking for */ @@ -59,12 +60,22 @@ struct freedv_vhf_deframer { /* Init and allocate memory for a freedv-vhf framer/deframer */ struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type,int enable_bit_flip); +/* Get size of various frame parameters */ +/* Frame size in bits */ +int fvhff_get_frame_size(struct freedv_vhf_deframer * def); +/* Codec2 size in bytes */ +int fvhff_get_codec2_size(struct freedv_vhf_deframer * def); +/* Protocol bits in bits */ +int fvhff_get_proto_size(struct freedv_vhf_deframer * def); +/* Varicode bits in bits */ +int fvhff_get_varicode_size(struct freedv_vhf_deframer * def); + /* Free the memory used by a freedv-vhf framer/deframer */ void fvhff_destroy_deframer(struct freedv_vhf_deframer * def); /* Place codec and other bits into a frame */ void fvhff_frame_bits(int frame_type,uint8_t bits_out[],uint8_t codec2_in[],uint8_t proto_in[],uint8_t vc_in[]); -void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,uint8_t bits_out[]); +void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,uint8_t bits_out[]); /* Find and extract frames from a stream of bits */ int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uint8_t proto_out[],uint8_t vc_out[],uint8_t bits_in[]); diff --git a/codec2-dev/src/fsk_mod.c b/codec2-dev/src/fsk_mod.c index cb890c4c..349380a0 100644 --- a/codec2-dev/src/fsk_mod.c +++ b/codec2-dev/src/fsk_mod.c @@ -37,6 +37,7 @@ int main(int argc,char *argv[]){ struct FSK *fsk; int Fs,Rs,f1,fs,M; int i; + int p; FILE *fin,*fout; uint8_t *bitbuf; int16_t *rawbuf; @@ -66,9 +67,10 @@ int main(int argc,char *argv[]){ fout = fopen(argv[7],"w"); } + p = Fs/Rs; /* set up FSK */ - fsk = fsk_create(Fs,Rs,M,f1,fs); + fsk = fsk_create_hbr(Fs,Rs,p,M,f1,fs); if(fin==NULL || fout==NULL || fsk==NULL){ fprintf(stderr,"Couldn't open test vector files\n"); diff --git a/codec2-dev/src/vhf_deframe_c2.c b/codec2-dev/src/vhf_deframe_c2.c index 1477bfbc..207e819a 100644 --- a/codec2-dev/src/vhf_deframe_c2.c +++ b/codec2-dev/src/vhf_deframe_c2.c @@ -38,44 +38,58 @@ int main(int argc,char *argv[]){ FILE *fin,*fout; uint8_t *bitbuf; uint8_t *c2buf; - uint8_t zbuf[] = {0,0,0,0,0,0,0}; + uint8_t zbuf[] = {0,0,0,0,0,0,0,0}; + int frame_fmt = 0; + int fsize,c2size; if(argc<3){ - fprintf(stderr,"usage: %s InputOneBitPerCharFile OutputC2File\n",argv[0]); + fprintf(stderr,"usage: %s (A|B) InputOneBitPerCharFile OutputC2File\n",argv[0]); + exit(1); + } + + if(strcmp(argv[1],"A")==0){ + frame_fmt = FREEDV_VHF_FRAME_A; + } else if (strcmp(argv[1],"B")==0) { + frame_fmt = FREEDV_HF_FRAME_B; + } else { + fprintf(stderr,"usage: %s (A|B) InputOneBitPerCharFile OutputC2File\n",argv[0]); exit(1); } /* Open files */ - if(strcmp(argv[1],"-")==0){ + if(strcmp(argv[2],"-")==0){ fin = stdin; }else{ - fin = fopen(argv[1],"r"); + fin = fopen(argv[2],"r"); } - if(strcmp(argv[2],"-")==0){ + if(strcmp(argv[3],"-")==0){ fout = stdout; }else{ - fout = fopen(argv[2],"w"); + fout = fopen(argv[3],"w"); } /* Set up deframer */ - deframer = fvhff_create_deframer(FREEDV_VHF_FRAME_A,0); + deframer = fvhff_create_deframer(frame_fmt,0); if(fin==NULL || fout==NULL || deframer==NULL){ fprintf(stderr,"Couldn't open test vector files\n"); goto cleanup; } + c2size = fvhff_get_codec2_size(deframer); + fsize = fvhff_get_frame_size(deframer); + /* allocate buffers for processing */ - bitbuf = (uint8_t*)malloc(sizeof(uint8_t)*96); - c2buf = (uint8_t*)malloc(sizeof(uint8_t)*7); + bitbuf = (uint8_t*)malloc(sizeof(uint8_t)*fsize); + c2buf = (uint8_t*)malloc(sizeof(uint8_t)*c2size); /* Deframe! */ - while( fread(bitbuf,sizeof(uint8_t),96,fin) == 96 ){ + while( fread(bitbuf,sizeof(uint8_t),fsize,fin) == fsize ){ if(fvhff_deframe_bits(deframer,c2buf,NULL,NULL,bitbuf)) - fwrite(c2buf,sizeof(uint8_t),7,fout); + fwrite(c2buf,sizeof(uint8_t),c2size,fout); else - fwrite(zbuf,sizeof(uint8_t),7,fout); + fwrite(zbuf,sizeof(uint8_t),c2size,fout); if(fin == stdin || fout == stdin){ fflush(fin); -- 2.25.1