int main(int argc, char *argv[]) { FILE *fin, *fout; struct FDMDV *fdmdv; char *packed_bits; int *rx_bits; int *codec_bits; COMP rx_fdm[FDMDV_MAX_SAMPLES_PER_FRAME]; short rx_fdm_scaled[FDMDV_MAX_SAMPLES_PER_FRAME]; int i, bit, byte, c; int nin, nin_prev; int sync_bit = 0, reliable_sync_bit; int sync = 0; int f; FILE *foct = NULL; struct FDMDV_STATS stats; COMP *rx_fdm_log; int rx_fdm_log_col_index; COMP *rx_symbols_log; int sync_log[MAX_FRAMES]; float rx_timing_log[MAX_FRAMES]; float foff_log[MAX_FRAMES]; int sync_bit_log[MAX_FRAMES]; int rx_bits_log[FDMDV_BITS_PER_FRAME*MAX_FRAMES]; float snr_est_log[MAX_FRAMES]; float *rx_spec_log; int max_frames_reached; int bits_per_fdmdv_frame; int bits_per_codec_frame; int bytes_per_codec_frame; int Nc; if (argc < 2) { printf("usage: %s InputModemRawFile OutputBitFile [Nc [OctaveDumpFile]]\n", argv[0]); printf("e.g %s hts1a_fdmdv.raw hts1a.c2\n", argv[0]); exit(1); } if (strcmp(argv[1], "-") == 0) fin = stdin; else if ( (fin = fopen(argv[1],"rb")) == NULL ) { fprintf(stderr, "Error opening input modem sample file: %s: %s.\n", argv[1], strerror(errno)); exit(1); } if (strcmp(argv[2], "-") == 0) fout = stdout; else if ( (fout = fopen(argv[2],"wb")) == NULL ) { fprintf(stderr, "Error opening output bit file: %s: %s.\n", argv[2], strerror(errno)); exit(1); } if (argc >= 4) { Nc = atoi(argv[3]); if ((Nc % 2) != 0) { fprintf(stderr, "Error number of carriers must be a multiple of 2\n"); exit(1); } if ((Nc < 2) || (Nc > FDMDV_NC_MAX) ) { fprintf(stderr, "Error number of carriers must be between 2 and %d\n", FDMDV_NC_MAX); exit(1); } } else Nc = FDMDV_NC; fdmdv = fdmdv_create(Nc); bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv); bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv); assert((bits_per_codec_frame % 8) == 0); /* make sure integer number of bytes per frame */ bytes_per_codec_frame = bits_per_codec_frame/8; /* malloc some buffers that are dependant on Nc */ packed_bits = (char*)malloc(bytes_per_codec_frame); assert(packed_bits != NULL); rx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame); assert(rx_bits != NULL); codec_bits = (int*)malloc(2*sizeof(int)*bits_per_fdmdv_frame); assert(codec_bits != NULL); /* malloc some of the larger variables to prevent out of stack problems */ rx_fdm_log = (COMP*)malloc(sizeof(COMP)*FDMDV_MAX_SAMPLES_PER_FRAME*MAX_FRAMES); assert(rx_fdm_log != NULL); rx_spec_log = (float*)malloc(sizeof(float)*FDMDV_NSPEC*MAX_FRAMES); assert(rx_spec_log != NULL); rx_symbols_log = (COMP*)malloc(sizeof(COMP)*(Nc+1)*MAX_FRAMES); assert(rx_fdm_log != NULL); f = 0; nin = FDMDV_NOM_SAMPLES_PER_FRAME; rx_fdm_log_col_index = 0; max_frames_reached = 0; while(fread(rx_fdm_scaled, sizeof(short), nin, fin) == nin) { for(i=0; i<nin; i++) { rx_fdm[i].real = (float)rx_fdm_scaled[i]/FDMDV_SCALE; rx_fdm[i].imag = 0; } nin_prev = nin; fdmdv_demod(fdmdv, rx_bits, &reliable_sync_bit, rx_fdm, &nin); /* log data for optional Octave dump */ if (f < MAX_FRAMES) { fdmdv_get_demod_stats(fdmdv, &stats); /* log modem states for later dumping to Octave log file */ memcpy(&rx_fdm_log[rx_fdm_log_col_index], rx_fdm, sizeof(COMP)*nin_prev); rx_fdm_log_col_index += nin_prev; for(c=0; c<Nc+1; c++) rx_symbols_log[f*(Nc+1)+c] = stats.rx_symbols[c]; foff_log[f] = stats.foff; rx_timing_log[f] = stats.rx_timing; sync_log[f] = stats.sync; sync_bit_log[f] = sync_bit; memcpy(&rx_bits_log[bits_per_fdmdv_frame*f], rx_bits, sizeof(int)*bits_per_fdmdv_frame); snr_est_log[f] = stats.snr_est; fdmdv_get_rx_spectrum(fdmdv, &rx_spec_log[f*FDMDV_NSPEC], rx_fdm, nin_prev); f++; } if ((f == MAX_FRAMES) && !max_frames_reached) { fprintf(stderr,"MAX_FRAMES exceed in Octave log, log truncated\n"); max_frames_reached = 1; } if (reliable_sync_bit) sync = 1; //printf("sync_bit: %d reliable_sync_bit: %d sync: %d\n", sync_bit, reliable_sync_bit, sync); if (sync == 0) { memcpy(codec_bits, rx_bits, bits_per_fdmdv_frame*sizeof(int)); sync = 1; } else { memcpy(&codec_bits[bits_per_fdmdv_frame], rx_bits, bits_per_fdmdv_frame*sizeof(int)); /* pack bits, MSB received first */ bit = 7; byte = 0; memset(packed_bits, 0, bytes_per_codec_frame); for(i=0; i<bits_per_codec_frame; i++) { packed_bits[byte] |= (codec_bits[i] << bit); bit--; if (bit < 0) { bit = 7; byte++; } } assert(byte == bytes_per_codec_frame); fwrite(packed_bits, sizeof(char), bytes_per_codec_frame, fout); sync = 0; } /* if this is in a pipeline, we probably don't want the usual buffering to occur */ if (fout == stdout) fflush(stdout); if (fin == stdin) fflush(stdin); } /* Optional dump to Octave log file */ if (argc == 5) { if ((foct = fopen(argv[4],"wt")) == NULL ) { fprintf(stderr, "Error opening Octave dump file: %s: %s.\n", argv[4], strerror(errno)); exit(1); } octave_save_complex(foct, "rx_fdm_log_c", rx_fdm_log, 1, rx_fdm_log_col_index, FDMDV_MAX_SAMPLES_PER_FRAME); octave_save_complex(foct, "rx_symbols_log_c", (COMP*)rx_symbols_log, Nc+1, f, MAX_FRAMES); octave_save_float(foct, "foff_log_c", foff_log, 1, f, MAX_FRAMES); octave_save_float(foct, "rx_timing_log_c", rx_timing_log, 1, f, MAX_FRAMES); octave_save_int(foct, "sync_log_c", sync_log, 1, f); octave_save_int(foct, "rx_bits_log_c", rx_bits_log, 1, bits_per_fdmdv_frame*f); octave_save_int(foct, "sync_bit_log_c", sync_bit_log, 1, f); octave_save_float(foct, "snr_est_log_c", snr_est_log, 1, f, MAX_FRAMES); octave_save_float(foct, "rx_spec_log_c", rx_spec_log, f, FDMDV_NSPEC, FDMDV_NSPEC); fclose(foct); } //fdmdv_dump_osc_mags(fdmdv); fclose(fin); fclose(fout); free(rx_fdm_log); free(rx_spec_log); fdmdv_destroy(fdmdv); return 0; }
int main(int argc, char *argv[]) { FILE *fin, *fout, *foct; struct COHPSK *cohpsk; float rx_bits[COHPSK_BITS_PER_FRAME]; COMP rx_fdm[COHPSK_MAX_SAMPLES_PER_FRAME]; short rx_fdm_scaled[COHPSK_MAX_SAMPLES_PER_FRAME]; int frames, sync, nin_frame; float *rx_amp_log; float *rx_phi_log; COMP *rx_symb_log; float f_est_log[LOG_FRAMES], ratio_log[LOG_FRAMES]; int i, r, c, log_data_r, oct, logframes; if (argc < 3) { printf("usage: %s InputModemRawFile OutputOneBitPerIntFile [OctaveLogFile]\n", argv[0]); exit(1); } if (strcmp(argv[1], "-") == 0) fin = stdin; else if ( (fin = fopen(argv[1],"rb")) == NULL ) { fprintf(stderr, "Error opening input modem sample file: %s: %s.\n", argv[1], strerror(errno)); exit(1); } if (strcmp(argv[2], "-") == 0) fout = stdout; else if ( (fout = fopen(argv[2],"wb")) == NULL ) { fprintf(stderr, "Error opening output file: %s: %s.\n", argv[2], strerror(errno)); exit(1); } foct = NULL; oct = 0; if (argc == 4) { if ( (foct = fopen(argv[3],"wt")) == NULL ) { fprintf(stderr, "Error opening output Octave file: %s: %s.\n", argv[3], strerror(errno)); exit(1); } oct = 1; } cohpsk = cohpsk_create(); cohpsk_set_verbose(cohpsk, 1); if (oct) { logframes = LOG_FRAMES; rx_amp_log = (float *)malloc(sizeof(float)*logframes*NSYMROW*COHPSK_NC*ND); assert(rx_amp_log != NULL); rx_phi_log = (float *)malloc(sizeof(float)*logframes*NSYMROW*COHPSK_NC*ND); assert(rx_phi_log != NULL); rx_symb_log = (COMP *)malloc(sizeof(COMP)*logframes*NSYMROW*COHPSK_NC*ND); assert(rx_symb_log != NULL); cohpsk->rx_timing_log = (float*)malloc(sizeof(float)*SYNC_FRAMES*logframes*NSYMROWPILOT); assert(cohpsk->rx_timing_log != NULL); } log_data_r = 0; frames = 0; nin_frame = COHPSK_NOM_SAMPLES_PER_FRAME; while(fread(rx_fdm_scaled, sizeof(short), nin_frame, fin) == nin_frame) { frames++; cohpsk_set_frame(cohpsk, frames); /* scale and demod */ for(i=0; i<nin_frame; i++) { rx_fdm[i].real = rx_fdm_scaled[i]/FDMDV_SCALE; rx_fdm[i].imag = 0.0; } cohpsk_demod(cohpsk, rx_bits, &sync, rx_fdm, &nin_frame); if (sync) { fwrite(rx_bits, sizeof(float), COHPSK_BITS_PER_FRAME, fout); if (oct) { for(r=0; r<NSYMROW; r++, log_data_r++) { for(c=0; c<COHPSK_NC*ND; c++) { rx_amp_log[log_data_r*COHPSK_NC*ND+c] = cohpsk->amp_[r][c]; rx_phi_log[log_data_r*COHPSK_NC*ND+c] = cohpsk->phi_[r][c]; rx_symb_log[log_data_r*COHPSK_NC*ND+c] = cohpsk->rx_symb[r][c]; } } f_est_log[frames-1] = cohpsk->f_est; ratio_log[frames-1] = cohpsk->ratio; //fprintf(stderr,"ratio: %f\n", cohpsk->ratio); //printf("frames: %d log_data_r: %d\n", frames, log_data_r); if (frames == logframes) oct = 0; } } /* if this is in a pipeline, we probably don't want the usual buffering to occur */ if (fout == stdout) fflush(stdout); if (fin == stdin) fflush(stdin); } fclose(fin); fclose(fout); /* optionally dump Octave files */ if (foct != NULL) { octave_save_float(foct, "rx_amp_log_c", (float*)rx_amp_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND); octave_save_float(foct, "rx_phi_log_c", (float*)rx_phi_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND); octave_save_complex(foct, "rx_symb_log_c", (COMP*)rx_symb_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND); octave_save_float(foct, "rx_timing_log_c", (float*)cohpsk->rx_timing_log, 1, cohpsk->rx_timing_log_index, cohpsk->rx_timing_log_index); octave_save_float(foct, "f_est_log_c", f_est_log, 1, logframes, logframes); octave_save_float(foct, "ratio_log_c", ratio_log, 1, logframes, logframes); fclose(foct); } cohpsk_destroy(cohpsk); return 0; }
int main(int argc, char *argv[]) { FILE *fin, *fout; struct FDMDV *fdmdv; char packed_bits[BYTES_PER_CODEC_FRAME]; int rx_bits[FDMDV_BITS_PER_FRAME]; int codec_bits[2*FDMDV_BITS_PER_FRAME]; COMP rx_fdm[FDMDV_MAX_SAMPLES_PER_FRAME]; short rx_fdm_scaled[FDMDV_MAX_SAMPLES_PER_FRAME]; int i, bit, byte, c; int nin, nin_prev; int sync_bit; int state, next_state; int f; FILE *foct = NULL; struct FDMDV_STATS stats; float *rx_fdm_log; int rx_fdm_log_col_index; COMP rx_symbols_log[FDMDV_NSYM][MAX_FRAMES]; int coarse_fine_log[MAX_FRAMES]; float rx_timing_log[MAX_FRAMES]; float foff_log[MAX_FRAMES]; int sync_bit_log[MAX_FRAMES]; int rx_bits_log[FDMDV_BITS_PER_FRAME*MAX_FRAMES]; float snr_est_log[MAX_FRAMES]; float *rx_spec_log; int max_frames_reached; if (argc < 3) { printf("usage: %s InputModemRawFile OutputBitFile [OctaveDumpFile]\n", argv[0]); printf("e.g %s hts1a_fdmdv.raw hts1a.c2\n", argv[0]); exit(1); } if (strcmp(argv[1], "-") == 0) fin = stdin; else if ( (fin = fopen(argv[1],"rb")) == NULL ) { fprintf(stderr, "Error opening input modem sample file: %s: %s.\n", argv[1], strerror(errno)); exit(1); } if (strcmp(argv[2], "-") == 0) fout = stdout; else if ( (fout = fopen(argv[2],"wb")) == NULL ) { fprintf(stderr, "Error opening output bit file: %s: %s.\n", argv[2], strerror(errno)); exit(1); } /* malloc some of the bigger variables to prevent out of stack problems */ rx_fdm_log = (float*)malloc(sizeof(float)*FDMDV_MAX_SAMPLES_PER_FRAME*MAX_FRAMES); assert(rx_fdm_log != NULL); rx_spec_log = (float*)malloc(sizeof(float)*FDMDV_NSPEC*MAX_FRAMES); assert(rx_spec_log != NULL); fdmdv = fdmdv_create(); f = 0; state = 0; nin = FDMDV_NOM_SAMPLES_PER_FRAME; rx_fdm_log_col_index = 0; max_frames_reached = 0; while(fread(rx_fdm_scaled, sizeof(short), nin, fin) == nin) { for(i=0; i<nin; i++) { rx_fdm[i].real = (float)rx_fdm_scaled[i]/FDMDV_SCALE; rx_fdm[i].imag = 0; } nin_prev = nin; fdmdv_demod(fdmdv, rx_bits, &sync_bit, rx_fdm, &nin); /* log data for optional Octave dump */ if (f < MAX_FRAMES) { fdmdv_get_demod_stats(fdmdv, &stats); /* log modem states for later dumping to Octave log file */ memcpy(&rx_fdm_log[rx_fdm_log_col_index], rx_fdm, sizeof(float)*nin_prev); rx_fdm_log_col_index += nin_prev; for(c=0; c<FDMDV_NSYM; c++) rx_symbols_log[c][f] = stats.rx_symbols[c]; foff_log[f] = stats.foff; rx_timing_log[f] = stats.rx_timing; coarse_fine_log[f] = stats.fest_coarse_fine; sync_bit_log[f] = sync_bit; memcpy(&rx_bits_log[FDMDV_BITS_PER_FRAME*f], rx_bits, sizeof(int)*FDMDV_BITS_PER_FRAME); snr_est_log[f] = stats.snr_est; fdmdv_get_rx_spectrum(fdmdv, &rx_spec_log[f*FDMDV_NSPEC], rx_fdm, nin_prev); f++; } if ((f == MAX_FRAMES) && !max_frames_reached) { fprintf(stderr,"MAX_FRAMES exceed in Octave log, log truncated\n"); max_frames_reached = 1; } /* state machine to output codec bits only if we have a 0,1 sync bit sequence */ next_state = state; switch (state) { case 0: if (sync_bit == 0) { next_state = 1; memcpy(codec_bits, rx_bits, FDMDV_BITS_PER_FRAME*sizeof(int)); } else next_state = 0; break; case 1: if (sync_bit == 1) { memcpy(&codec_bits[FDMDV_BITS_PER_FRAME], rx_bits, FDMDV_BITS_PER_FRAME*sizeof(int)); /* pack bits, MSB received first */ bit = 7; byte = 0; memset(packed_bits, 0, BYTES_PER_CODEC_FRAME); for(i=0; i<BITS_PER_CODEC_FRAME; i++) { packed_bits[byte] |= (codec_bits[i] << bit); bit--; if (bit < 0) { bit = 7; byte++; } } assert(byte == BYTES_PER_CODEC_FRAME); fwrite(packed_bits, sizeof(char), BYTES_PER_CODEC_FRAME, fout); } next_state = 0; break; } state = next_state; /* if this is in a pipeline, we probably don't want the usual buffering to occur */ if (fout == stdout) fflush(stdout); if (fin == stdin) fflush(stdin); } /* Optional dump to Octave log file */ if (argc == 4) { /* make sure 3rd arg is not just the pipe command */ if (strcmp(argv[3],"|")) { if ((foct = fopen(argv[3],"wt")) == NULL ) { fprintf(stderr, "Error opening Octave dump file: %s: %s.\n", argv[3], strerror(errno)); exit(1); } octave_save_float(foct, "rx_fdm_log_c", rx_fdm_log, 1, rx_fdm_log_col_index, FDMDV_MAX_SAMPLES_PER_FRAME); octave_save_complex(foct, "rx_symbols_log_c", (COMP*)rx_symbols_log, FDMDV_NSYM, f, MAX_FRAMES); octave_save_float(foct, "foff_log_c", foff_log, 1, f, MAX_FRAMES); octave_save_float(foct, "rx_timing_log_c", rx_timing_log, 1, f, MAX_FRAMES); octave_save_int(foct, "coarse_fine_log_c", coarse_fine_log, 1, f); octave_save_int(foct, "rx_bits_log_c", rx_bits_log, 1, FDMDV_BITS_PER_FRAME*f); octave_save_int(foct, "sync_bit_log_c", sync_bit_log, 1, f); octave_save_float(foct, "snr_est_log_c", snr_est_log, 1, f, MAX_FRAMES); octave_save_float(foct, "rx_spec_log_c", rx_spec_log, f, FDMDV_NSPEC, FDMDV_NSPEC); fclose(foct); } } //fdmdv_dump_osc_mags(fdmdv); fclose(fin); fclose(fout); free(rx_fdm_log); free(rx_spec_log); fdmdv_destroy(fdmdv); return 0; }