void cohpsk_set_verbose(struct COHPSK *coh, int verbose);
void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[]);
void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[],
- int *bit_errors, float rx_bits_sd[]);
+ int *bit_errors, char rx_bits_sd[]);
int cohpsk_error_pattern_size(void);
void cohpsk_set_frame(struct COHPSK *coh, int frame);
void fdmdv_freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs,
struct freedv_vhf_deframer * deframer;
uint8_t *bits,*invbits;
int frame_size;
+ int uw_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){
frame_size = 96;
+ uw_size = 16;
}else if(frame_type == FREEDV_HF_FRAME_B){
frame_size = 64;
+ uw_size = 8;
}else{
return NULL;
}
deframer->last_uw = 0;
deframer->miss_cnt = 0;
deframer->frame_size = frame_size;
+ deframer->uw_size = uw_size;
deframer->on_inv_bits = 0;
-
+ deframer->ber_est = 0;
deframer->fdc = NULL;
return deframer;
}
/* See if the UW is where it should be, to within a tolerance, in a bit buffer */
-static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int tol, enum frame_payload_type *pt){
+static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int tol,int *rdiff, enum frame_payload_type *pt){
int frame_type = def->ftype;
int bitptr = def->bitptr;
int frame_size = def->frame_size;
+ int uw_len = def->uw_size;
int iuw,ibit;
const uint8_t * uw[2];
- int uw_len;
int can_be_data;
int uw_offset;
int diff[2] = { 0, 0 };
/* Pick the best matching UW */
if (diff[0] < diff[1] || !can_be_data) {
r = match[0];
+ *rdiff = diff[0];
*pt = FRAME_PAYLOAD_TYPE_VOICE;
} else {
r = match[1];
+ *rdiff = diff[1];
*pt = FRAME_PAYLOAD_TYPE_DATA;
}
int last_uw = def->last_uw;
int miss_cnt = def->miss_cnt;
int frame_size = def->frame_size;
+ int uw_size = def->uw_size;
+ int uw_diff;
int i;
int uw_first_tol;
int uw_sync_tol;
if(frame_type == FREEDV_VHF_FRAME_A){
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 */
+ miss_tol = 4; /* 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 */
+ uw_first_tol = 0; /* The UW bit-error tolerance for the first frame */
+ uw_sync_tol = 1; /* The UW bit error tolerance for frames after sync */
+ miss_tol = 3; /* How many UWs may be missed before going into the de-synced state */
}else{
return 0;
}
if(last_uw == frame_size){
last_uw = 0;
- if(!fvhff_match_uw(def,bits,uw_sync_tol, &pt))
+ if(!fvhff_match_uw(def,bits,uw_sync_tol,&uw_diff, &pt))
miss_cnt++;
else
miss_cnt=0;
/* Extract the bits */
extracted_frame = 1;
fvhff_extract_frame(def,bits,codec2_out,proto_out,vc_out,pt);
+
+ /* Update BER estimate */
+ def->ber_est = (.99*def->ber_est) + (.01*((float)uw_diff)/((float)uw_size));
}
/* Not yet sunk */
}else{
/* It's a sync!*/
if(invbits!=NULL){
- if(fvhff_match_uw(def,invbits,uw_first_tol, &pt)){
+ if(fvhff_match_uw(def,invbits,uw_first_tol, &uw_diff, &pt)){
state = ST_SYNC;
last_uw = 0;
miss_cnt = 0;
extracted_frame = 1;
on_inv_bits = 1;
fvhff_extract_frame(def,invbits,codec2_out,proto_out,vc_out,pt);
+ /* Update BER estimate */
+ def->ber_est = (.99*def->ber_est) + (.01*((float)uw_diff)/((float)uw_size));
}
}
- if(fvhff_match_uw(def,strbits,uw_first_tol, &pt)){
+ if(fvhff_match_uw(def,strbits,uw_first_tol, &uw_diff, &pt)){
state = ST_SYNC;
last_uw = 0;
miss_cnt = 0;
extracted_frame = 1;
on_inv_bits = 0;
fvhff_extract_frame(def,strbits,codec2_out,proto_out,vc_out,pt);
+ /* Update BER estimate */
+ def->ber_est = (.98*def->ber_est) + (.02*((float)uw_diff)/((float)uw_size));
}
}
}
int bitptr; /* Pointer into circular bit buffer */
int miss_cnt; /* How many UWs have been missed */
int last_uw; /* How many bits since the last UW? */\r
- int frame_size; /* How big is a frame? */\r
+ int frame_size; /* How big is a frame? */
+ int uw_size; /* How big is the UW */\r
int on_inv_bits; /* Are we using the inverted bits? */\r
+
+ float ber_est; /* Bit error rate estimate */
\r
struct freedv_data_channel *fdc;\r
};\r
#define TESTBER 0.01
/* Frame count */
-#define FRCNT 1500
+#define FRCNT 15000
/* Random bits leading frame */
-#define LRCNT 142
+#define LRCNT 55
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#include <freedv_vhf_framing.h>
#include <golay23.h>
+#include <string.h>
/* The main loop of the test driver */
int main(int argc,char *argv[]){
uint8_t * bit_buffer;
- uint8_t c2_buffer[7] = {0,0,0,0,0,0,0};
+ uint8_t c2_buffer[10];
struct freedv_vhf_deframer * fvd;
int i,p,k;
- int bitbufferlen = (LRCNT+96*FRCNT);
+ int bitbufferlen;
+ int fsize;
+ int ftype;
+ int first_tol;
+
+ if(argc<2){
+ fprintf(stderr,"Usage: %s [A|B]\n",argv[0]);
+ exit(1);
+ }
+
+ if(strcmp(argv[1],"A")==0){
+ ftype = FREEDV_VHF_FRAME_A;
+ first_tol = 2;
+ }else if(strcmp(argv[1],"B")==0){
+ ftype = FREEDV_HF_FRAME_B;
+ first_tol = 5;
+ }else{
+ fprintf(stderr,"Usage: %s [A|B]\n",argv[0]);
+ exit(1);
+ }
srand(1);
golay23_init();
/* Set up the deframer */
- fvd = fvhff_create_deframer(FREEDV_VHF_FRAME_A,1);
+ fvd = fvhff_create_deframer(ftype,1);
+ fsize = fvhff_get_frame_size(fvd);
+ bitbufferlen = (LRCNT+fsize*FRCNT);
+
/* Allocate bit buffer */
bit_buffer = (uint8_t *) malloc(sizeof(uint8_t)*bitbufferlen);
p = 0;
for(i=0; i<FRCNT; i++){
/* Encode frame index into golay codeword to protect from test BER*/
k = golay23_encode((i+1)&0x0FFF);
- c2_buffer[0] = (k )&0xFF;
+ c2_buffer[5] = (k )&0xFF;
c2_buffer[1] = (k>>8 )&0xFF;
- c2_buffer[2] = (k>>16)&0x7F;
+ c2_buffer[0] = (k>>16)&0x7F;
/* Frame the bits */
- fvhff_frame_bits(FREEDV_VHF_FRAME_A, &bit_buffer[p+(i*96)], c2_buffer,NULL,NULL);
+ fvhff_frame_bits(ftype, &bit_buffer[p+(i*fsize)], c2_buffer,NULL,NULL);
}
/* Flip bits */
int first_extract = 0;
int total_extract = 0;
int err_count = 0;
+ printf("\n");
/* Deframe some bits */
- for(i=0; i<bitbufferlen; i+=96){
+ for(i=0; i<bitbufferlen; i+=fsize){
if( fvhff_deframe_bits(fvd, c2_buffer, NULL, NULL, &bit_buffer[i])){
/* Extract golay23 codeword */
- k = ((int)c2_buffer[0]) ;
+ k = ((int)c2_buffer[5]) ;
k |= ((int)c2_buffer[1])<<8 ;
- k |= ((int)c2_buffer[2])<<16;
+ k |= ((int)c2_buffer[0])<<16;
k = k & 0x7FFFFF;
/* Decode frame index */
p = golay23_decode(k);
err_count += golay23_count_errors(k,p);
p = p>>11;
- printf("Got frame %d\n",p);
+
+ printf("%d,\t",p);
total_extract++;
if(first_extract==0)
first_extract=p;
}
}
-
+ printf("\n");
float measured_ber = (float)err_count/(float)(23*total_extract);
printf("First extracted frame %d\n",first_extract);
printf("Extracted %d frames of %d, %f hit rate\n",total_extract,FRCNT,((float)total_extract/(float)FRCNT));
- printf("Bit error rate %f measured\n",measured_ber);
+ printf("Bit error rate %f measured from golay code\n",measured_ber);
+ printf("Bit error rate %f measured by deframer\n",fvd->ber_est);
/* Check test condition */
- if(first_extract<2){
+ if(first_extract<first_tol){
printf("Test passed at test BER of %f!\n",TESTBER);
exit(0);
}else{