Esempio n. 1
0
int main(void) {
    struct freedv *f;
    short  buf[FREEDV_NSAMPLES];
    int    nin, nout;

    /* init all the drivers for various peripherals */

    sm1000_leds_switches_init();
    dac_open(4*DAC_BUF_SZ);
    adc_open();
    f = freedv_open(FREEDV_MODE_1600);

    /* LEDs into a known state */

    led_pwr(1); led_ptt(0); led_rt(0); led_err(0);

    /* 
       TODO:
       [ ] UT analog interfaces from file IO
       [ ] UTs for simultaneous tx & rx on analog interfaces
       [ ] measure CPU load of various parts with a blinky
       [ ] detect program assert type errors with a blinky
       [ ] timer tick function to measure 10ms-ish type times
       [ ] switch debouncing?
       [ ] light led with bit errors
    */

    while(1) {

        if(switch_ptt()) {

            /* Transmit -------------------------------------------------------------------------*/

            /* ADC2 is the SM1000 microphone, DAC1 is the modulator signal we send to radio tx */

            if (adc2_read(buf, FREEDV_NSAMPLES) == FREEDV_NSAMPLES) {
                freedv_tx(f, buf, buf);
                dac1_write(buf, FREEDV_NSAMPLES);
                led_ptt(1); led_rt(0); led_err(0);
            }
        }
        else {
            
            /* Receive --------------------------------------------------------------------------*/

            /* ADC1 is the demod in signal from the radio rx, DAC2 is the SM1000 speaker */

            nin = freedv_nin(f);
            f->total_bit_errors = 0;
            
            if (adc1_read(buf, nin) == nin) {
                nout = freedv_rx(f, buf, buf);
                dac2_write(buf, nout);
                led_ptt(0); led_rt(f->fdmdv_stats.sync); led_err(f->total_bit_errors);
            }

        }
        
    } /* while(1) ... */
}
Esempio n. 2
0
int main(void) {
    struct freedv *f;
    short          adc16k[FDMDV_OS_TAPS_16K+FREEDV_NSAMPLES_16K];
    short          dac16k[FREEDV_NSAMPLES_16K];
    short          adc8k[FREEDV_NSAMPLES];
    short          dac8k[FDMDV_OS_TAPS_8K+FREEDV_NSAMPLES];
    SWITCH_STATE   ss;
    int            nin, nout, i;

    /* init all the drivers for various peripherals */

    SysTick_Config(SystemCoreClock/168000); /* 1 kHz SysTick */
    sm1000_leds_switches_init();
    dac_open(4*DAC_BUF_SZ);
    adc_open(4*ADC_BUF_SZ);
    f = freedv_open(FREEDV_MODE_1600);

    /* put outputs into a known state */

    led_pwr(1); led_ptt(0); led_rt(0); led_err(0); not_cptt(1);

    /* clear filter memories */

    for(i=0; i<FDMDV_OS_TAPS_16K; i++)
	adc16k[i] = 0.0;
    for(i=0; i<FDMDV_OS_TAPS_8K; i++)
	dac8k[i] = 0.0;

    ss.state = SS_IDLE;
    ss.mode  = ANALOG;

    while(1) {
        
        iterate_select_state_machine(&ss);

        if (switch_ptt()) {

            /* Transmit -------------------------------------------------------------------------*/

            /* ADC2 is the SM1000 microphone, DAC1 is the modulator signal we send to radio tx */

            if (adc2_read(&adc16k[FDMDV_OS_TAPS_16K], FREEDV_NSAMPLES_16K) == 0) {
                GPIOE->ODR = (1 << 3);

                fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], FREEDV_NSAMPLES);

                if (ss.mode == ANALOG) {
                    for(i=0; i<FREEDV_NSAMPLES; i++)
                        dac8k[FDMDV_OS_TAPS_8K+i] = adc8k[i];
                    fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], FREEDV_NSAMPLES);              
                    dac1_write(dac16k, FREEDV_NSAMPLES_16K);
                }
                if (ss.mode == DV) {
                    freedv_tx(f, &dac8k[FDMDV_OS_TAPS_8K], adc8k);
                    fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], FREEDV_NSAMPLES);              
                    dac1_write(dac16k, FREEDV_NSAMPLES_16K);
                }

                if (ss.mode == TONE) {
                    while(dac1_write((short*)aSine, SINE_SAMPLES) == 0);
                }

                led_ptt(1); led_rt(0); led_err(0); not_cptt(0);
                GPIOE->ODR &= ~(1 << 3);
            }

        }
        else {
            
            /* Receive --------------------------------------------------------------------------*/

            not_cptt(1); led_ptt(0); 

            /* ADC1 is the demod in signal from the radio rx, DAC2 is the SM1000 speaker */

            if (ss.mode == ANALOG) {

                /* force analog bypass when select down */

                if (adc1_read(&adc16k[FDMDV_OS_TAPS_16K], FREEDV_NSAMPLES_16K) == 0) {
                    fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], FREEDV_NSAMPLES);
                    for(i=0; i<FREEDV_NSAMPLES; i++)
                        dac8k[FDMDV_OS_TAPS_8K+i] = adc8k[i];
                    fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], FREEDV_NSAMPLES);              
                    dac2_write(dac16k, FREEDV_NSAMPLES_16K);
                    led_rt(0); led_err(0);
               }
            }
            else {

                /* regular DV mode */

                nin = freedv_nin(f);   
                nout = nin;
                f->total_bit_errors = 0;

                if (adc1_read(&adc16k[FDMDV_OS_TAPS_16K], 2*nin) == 0) {
                    GPIOE->ODR = (1 << 3);
                    fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], nin);
                    nout = freedv_rx(f, &dac8k[FDMDV_OS_TAPS_8K], adc8k);
                    fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], nout);              
                    dac2_write(dac16k, 2*nout);
                    led_rt(f->fdmdv_stats.sync); led_err(f->total_bit_errors);
                    GPIOE->ODR &= ~(1 << 3);
                }
            }

        }
    } /* while(1) ... */
}
Esempio n. 3
0
int main(int argc, char *argv[]) {
    FILE                      *fin, *fout, *ftxt;
    short                     *speech_out;
    short                     *demod_in;
    struct freedv             *freedv;
    int                        nin, nout, frame = 0;
    struct my_callback_state   my_cb_state;
    struct MODEM_STATS         stats;
    int                        mode;
    int                        sync;
    int                        total_bits;
    int                        total_bit_errors;
    float                      snr_est;
    int                        n_speech_samples;
    int                        n_max_modem_samples;
    float                      clock_offset;
    int                        use_codecrx;
    struct CODEC2             *c2 = NULL;
    int                        i;


    if (argc < 4) {
	printf("usage: %s 1600|700|700B|2400A|2400B|800XA InputModemSpeechFile OutputSpeechRawFile [--test_frames] [--codecrx]\n", argv[0]);
	printf("e.g    %s 1600 hts1a_fdmdv.raw hts1a_out.raw txtLogFile\n", argv[0]);
	exit(1);
    }

    mode = -1;
    if (!strcmp(argv[1],"1600"))
        mode = FREEDV_MODE_1600;
    if (!strcmp(argv[1],"700"))
        mode = FREEDV_MODE_700;
    if (!strcmp(argv[1],"700B"))
        mode = FREEDV_MODE_700B;
    if (!strcmp(argv[1],"2400A"))
        mode = FREEDV_MODE_2400A;
    if (!strcmp(argv[1],"2400B"))
        mode = FREEDV_MODE_2400B;
    if (!strcmp(argv[1],"800XA"))
        mode = FREEDV_MODE_800XA;
    assert(mode != -1);

    if (strcmp(argv[2], "-")  == 0) fin = stdin;
    else if ( (fin = fopen(argv[2],"rb")) == NULL ) {
	fprintf(stderr, "Error opening input raw modem sample file: %s: %s.\n",
         argv[2], strerror(errno));
	exit(1);
    }

    if (strcmp(argv[3], "-") == 0) fout = stdout;
    else if ( (fout = fopen(argv[3],"wb")) == NULL ) {
	fprintf(stderr, "Error opening output speech sample file: %s: %s.\n",
         argv[3], strerror(errno));
	exit(1);
    }

    freedv = freedv_open(mode);
    assert(freedv != NULL);

    use_codecrx = 0;

    if (argc > 4) {
        for (i = 4; i < argc; i++) {
            if (strcmp(argv[i], "--testframes") == 0) {
                freedv_set_test_frames(freedv, 1);
            }
            if (strcmp(argv[i], "--codecrx") == 0) {
                int c2_mode;

                if (mode == FREEDV_MODE_700)  {
		    c2_mode = CODEC2_MODE_700;
		} else if ((mode == FREEDV_MODE_700B)|| (mode == FREEDV_MODE_800XA)) {
                    c2_mode = CODEC2_MODE_700B;
                } else {
                    c2_mode = CODEC2_MODE_1300;
                }
                use_codecrx = 1;

                c2 = codec2_create(c2_mode);
                assert(c2 != NULL);
            }
        }
    }
    freedv_set_snr_squelch_thresh(freedv, -100.0);
    freedv_set_squelch_en(freedv, 1);

    n_speech_samples = freedv_get_n_speech_samples(freedv);
    n_max_modem_samples = freedv_get_n_max_modem_samples(freedv);
    speech_out = (short*)malloc(sizeof(short)*n_speech_samples);
    assert(speech_out != NULL);
    demod_in = (short*)malloc(sizeof(short)*n_max_modem_samples);
    assert(demod_in != NULL);

    ftxt = fopen("freedv_rx_log.txt","wt");
    assert(ftxt != NULL);
    my_cb_state.ftxt = ftxt;
    freedv_set_callback_txt(freedv, &my_put_next_rx_char, NULL, &my_cb_state);
    freedv_set_callback_protocol(freedv, &my_put_next_rx_proto, NULL, &my_cb_state);
    freedv_set_callback_data(freedv, my_datarx, my_datatx, &my_cb_state);

    /* Note we need to work out how many samples demod needs on each
       call (nin).  This is used to adjust for differences in the tx and rx
       sample clock frequencies.  Note also the number of output
       speech samples is time varying (nout). */

    nin = freedv_nin(freedv);
    while(fread(demod_in, sizeof(short), nin, fin) == nin) {
        frame++;

        if (use_codecrx == 0) {
            /* Use the freedv_api to do everything: speech decoding, demodulating */
            nout = freedv_rx(freedv, speech_out, demod_in);
        } else {
            int bits_per_codec_frame = codec2_bits_per_frame(c2);
            int bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
            int codec_frames = freedv_get_n_codec_bits(freedv) / bits_per_codec_frame;
            int samples_per_frame = codec2_samples_per_frame(c2);
            unsigned char encoded[bytes_per_codec_frame * codec_frames];

            /* Use the freedv_api to demodulate only */
            nout = freedv_codecrx(freedv, encoded, demod_in);

            /* deccode the speech ourself (or send it to elsewhere, e.g. network) */
            if (nout) {
                unsigned char *enc_frame = encoded;
		short *speech_frame = speech_out;
		
		nout = 0;
	        for (i = 0; i < codec_frames; i++) {
		    codec2_decode(c2, speech_frame, enc_frame);
		    enc_frame += bytes_per_codec_frame;
		    speech_frame += samples_per_frame;
		    nout += samples_per_frame;
		}
	    }
        }

        nin = freedv_nin(freedv);

        fwrite(speech_out, sizeof(short), nout, fout);
        freedv_get_modem_stats(freedv, &sync, &snr_est);
        freedv_get_modem_extended_stats(freedv,&stats);
        total_bit_errors = freedv_get_total_bit_errors(freedv);
        clock_offset = stats.clock_offset;

        /* log some side info to the txt file */

        if (ftxt != NULL) {
            fprintf(ftxt, "frame: %d  demod sync: %d  nin:%d demod snr: %3.2f dB  bit errors: %d clock_offset: %f\n",
                    frame, sync, nin, snr_est, total_bit_errors, clock_offset);
        }

	/* 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);
    }

    if (freedv_get_test_frames(freedv)) {
        total_bits = freedv_get_total_bits(freedv);
        total_bit_errors = freedv_get_total_bit_errors(freedv);
        fprintf(stderr, "bits: %d errors: %d BER: %3.2f\n", total_bits, total_bit_errors, (float)total_bit_errors/total_bits);
    }

    free(speech_out);
    free(demod_in);
    freedv_close(freedv);
    fclose(fin);
    fclose(fout);

    return 0;
}
int main(int argc, char *argv[]) {
    struct freedv *f;
    short          adc16k[FDMDV_OS_TAPS_16K+FREEDV_NSAMPLES_16K];
    short          dac16k[FREEDV_NSAMPLES_16K];
    short          adc8k[FREEDV_NSAMPLES];
    short          dac8k[FDMDV_OS_TAPS_8K+FREEDV_NSAMPLES];
    FILE          *fin, *fout, *ftotal;
    int            frame, nin_16k, nin, i, nout = 0;
    struct FDMDV_STATS  stats;
    PROFILE_VAR(fdmdv_16_to_8_start, freedv_rx_start, fdmdv_8_to_16_start);

    machdep_profile_init();

    f = freedv_open(FREEDV_MODE_1600);

    // Receive ---------------------------------------------------------------------

    frame = 0;

    fin = fopen("mod_16k.raw", "rb");
    if (fin == NULL) {
        printf("Error opening input file\n");
        exit(1);
    }

    fout = fopen("speechout_16k.raw", "wb");
    if (fout == NULL) {
        printf("Error opening output file\n");
        exit(1);
    }

    ftotal = fopen("total.txt", "wt");
    assert(ftotal != NULL);

    /* clear filter memories */

    for(i=0; i<FDMDV_OS_TAPS_16K; i++)
	adc16k[i] = 0.0;
    for(i=0; i<FDMDV_OS_TAPS_8K; i++)
	dac8k[i] = 0.0;
    
    nin = freedv_nin(f);
    nin_16k = 2*nin;
    nout = nin;
    while (fread(&adc16k[FDMDV_OS_TAPS_16K], sizeof(short), nin_16k, fin) == nin_16k) {

        PROFILE_SAMPLE(fdmdv_16_to_8_start);

        fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], nin);

        PROFILE_SAMPLE_AND_LOG(freedv_rx_start, fdmdv_16_to_8_start, "  fdmdv_16_to_8");

        nout = freedv_rx(f, &dac8k[FDMDV_OS_TAPS_8K], adc8k);
        nin = freedv_nin(f); nin_16k = 2*nin;
        fdmdv_get_demod_stats(f->fdmdv, &stats);

        PROFILE_SAMPLE_AND_LOG(fdmdv_8_to_16_start, freedv_rx_start, "  freedv_rx");     

        fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], nout);              

        PROFILE_SAMPLE_AND_LOG2(fdmdv_8_to_16_start, "  fdmdv_8_to_16");

        fprintf(ftotal, "%d\n", machdep_profile_sample() - fdmdv_16_to_8_start);
        machdep_profile_print_logged_samples();

        fwrite(dac16k, sizeof(short), 2*nout, fout);
        fdmdv_get_demod_stats(f->fdmdv, &stats);
        printf("frame: %d nin_16k: %d sync: %d SNR: %3.2f \n", 
               ++frame, nin_16k, stats.sync, (double)stats.snr_est);
    }

    fclose(fin);
    fclose(fout);
    fclose(ftotal);

    return 0;
}