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;
}
Example #2
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;
}
Example #3
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;
}