diff options
| author | drowe67 <[email protected]> | 2023-07-20 08:59:48 +0930 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-07-20 08:59:48 +0930 |
| commit | 06d4c11e699b0351765f10398abb4f663a984f36 (patch) | |
| tree | 33e22af0814c5b6c3d676f096ae8c2ac8a3ed9f0 /src/freedv_data_raw_tx.c | |
| parent | 6588e77f38bdebd7adffe091b22e7760d95d0ccb (diff) | |
| parent | 4d6c143c0abec15e1d6ed1fd95d36f80e6cb7df8 (diff) | |
Merge pull request #3 from drowe67/dr-cleanup21.2.0
Cleanup Part 2
Diffstat (limited to 'src/freedv_data_raw_tx.c')
| -rw-r--r-- | src/freedv_data_raw_tx.c | 836 |
1 files changed, 441 insertions, 395 deletions
diff --git a/src/freedv_data_raw_tx.c b/src/freedv_data_raw_tx.c index b2e47f8..44d53e9 100644 --- a/src/freedv_data_raw_tx.c +++ b/src/freedv_data_raw_tx.c @@ -27,441 +27,487 @@ */ #include <assert.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> #include <errno.h> -#include <stdint.h> #include <getopt.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include "freedv_api.h" #include "fsk.h" -#include "ofdm_internal.h" #include "ldpc_codes.h" +#include "ofdm_internal.h" -size_t send_preamble(struct freedv *freedv, FILE *fout, int use_complex, size_t n_mod_out); -size_t send_modulated_data(struct freedv *freedv, FILE *fout, int use_complex, size_t n_mod_out, uint8_t bytes_in[]); -size_t send_postamble(struct freedv *freedv, FILE *fout, int use_complex, size_t n_mod_out); +size_t send_preamble(struct freedv *freedv, FILE *fout, int use_complex, + size_t n_mod_out); +size_t send_modulated_data(struct freedv *freedv, FILE *fout, int use_complex, + size_t n_mod_out, uint8_t bytes_in[]); +size_t send_postamble(struct freedv *freedv, FILE *fout, int use_complex, + size_t n_mod_out); size_t send_silence(FILE *fout, size_t shorts_per_sample, size_t samples_delay); void comp_to_short(short mod_out_short[], COMP mod_out_comp[], int n_mod_out); int main(int argc, char *argv[]) { - FILE *fin, *fout; - char codename[80] = "H_256_512_4"; - struct freedv_advanced adv = {0,2,100,8000,1000,200, codename}; - struct freedv *freedv; - int mode; - int use_clip, use_txbpf, testframes, Ntestframes = 0; - int use_complex = 0; - float amp = FSK_SCALE; - size_t shorts_per_sample = 1; - int Nbursts = 1, sequence_numbers = 0; - int inter_burst_delay_ms = 0; - int postdelay_ms = 0; - uint8_t source_byte = 0; - - use_clip = -1; use_txbpf = -1; testframes = 0; - int framesperburst = 1; - int quiet = 0; - - int o = 0; - int opt_idx = 0; - while( o != -1 ){ - static struct option long_opts[] = { - {"testframes", required_argument, 0, 't'}, - {"help", no_argument, 0, 'h'}, - {"txbpf", required_argument, 0, 'b'}, - {"clip", required_argument, 0, 'l'}, - {"Fs", required_argument, 0, 'f'}, - {"Rs", required_argument, 0, 'r'}, - {"tone1", required_argument, 0, '1'}, - {"shift", required_argument, 0, 's'}, - {"bursts", required_argument, 0, 'e'}, - {"framesperburst", required_argument, 0, 'g'}, - {"delay", required_argument, 0, 'j'}, - {"postdelay", required_argument, 0, 'k'}, - {"seq", no_argument, 0, 'd'}, - {"source", required_argument, 0, 'i'}, - {"amp", required_argument, 0, 'a'}, - {"quiet", no_argument, 0, 'q'}, - {"complexout", no_argument, 0, 'c'}, - {"code", required_argument, 0, 'o'}, - {"listcodes", no_argument, 0, 'x'}, - {0, 0, 0, 0} - }; - - o = getopt_long(argc,argv,"a:cdt:hb:l:e:f:g:r:1:s:m:qi:o:x",long_opts,&opt_idx); - - switch(o) { - case 'a': - amp = atof(optarg)/2.0; - break; - case 'b': - use_txbpf = atoi(optarg); - break; - case 'c': - use_complex = 1; - shorts_per_sample = 2; - break; - case 'd': - sequence_numbers = 1; - break; - case 'i': - source_byte = strtol(optarg, NULL, 0); - fprintf(stderr,"source byte: 0x%02x\n", source_byte); - break; - case 'e': - Nbursts = atoi(optarg); - break; - case 'g': - framesperburst = atoi(optarg); - break; - case 'j': - inter_burst_delay_ms = atoi(optarg); - break; - case 'k': - postdelay_ms = atoi(optarg); - break; - case 't': - testframes = 1; - Ntestframes = atoi(optarg); - break; - case 'l': - use_clip = atoi(optarg); - break; - case 'm': - adv.M = atoi(optarg); - break; - case 'q': - quiet = 1; - break; - case 'f': - adv.Fs = atoi(optarg); - break; - case 'r': - adv.Rs = atoi(optarg); - break; - case '1': - adv.first_tone = atoi(optarg); - break; - case 's': - adv.tone_spacing = atoi(optarg); - break; - case 'o': - if (ldpc_codes_find(optarg) == -1) { - fprintf(stderr, "%s not found, try --listcodes\n", optarg); - exit(1); - } - strcpy(codename, optarg); - break; - case 'x': - ldpc_codes_list(); - exit(0); - break; - case 'h': - case '?': - goto helpmsg; - break; + FILE *fin, *fout; + char codename[80] = "H_256_512_4"; + struct freedv_advanced adv = {0, 2, 100, 8000, 1000, 200, codename}; + struct freedv *freedv; + int mode; + int use_clip, use_txbpf, testframes, Ntestframes = 0; + int use_complex = 0; + float amp = FSK_SCALE; + size_t shorts_per_sample = 1; + int Nbursts = 1, sequence_numbers = 0; + int inter_burst_delay_ms = 0; + int postdelay_ms = 0; + uint8_t source_byte = 0; + + use_clip = -1; + use_txbpf = -1; + testframes = 0; + int framesperburst = 1; + int quiet = 0; + + int o = 0; + int opt_idx = 0; + while (o != -1) { + static struct option long_opts[] = { + {"testframes", required_argument, 0, 't'}, + {"help", no_argument, 0, 'h'}, + {"txbpf", required_argument, 0, 'b'}, + {"clip", required_argument, 0, 'l'}, + {"Fs", required_argument, 0, 'f'}, + {"Rs", required_argument, 0, 'r'}, + {"tone1", required_argument, 0, '1'}, + {"shift", required_argument, 0, 's'}, + {"bursts", required_argument, 0, 'e'}, + {"framesperburst", required_argument, 0, 'g'}, + {"delay", required_argument, 0, 'j'}, + {"postdelay", required_argument, 0, 'k'}, + {"seq", no_argument, 0, 'd'}, + {"source", required_argument, 0, 'i'}, + {"amp", required_argument, 0, 'a'}, + {"quiet", no_argument, 0, 'q'}, + {"complexout", no_argument, 0, 'c'}, + {"code", required_argument, 0, 'o'}, + {"listcodes", no_argument, 0, 'x'}, + {0, 0, 0, 0}}; + + o = getopt_long(argc, argv, "a:cdt:hb:l:e:f:g:r:1:s:m:qi:o:x", long_opts, + &opt_idx); + + switch (o) { + case 'a': + amp = atof(optarg) / 2.0; + break; + case 'b': + use_txbpf = atoi(optarg); + break; + case 'c': + use_complex = 1; + shorts_per_sample = 2; + break; + case 'd': + sequence_numbers = 1; + break; + case 'i': + source_byte = strtol(optarg, NULL, 0); + fprintf(stderr, "source byte: 0x%02x\n", source_byte); + break; + case 'e': + Nbursts = atoi(optarg); + break; + case 'g': + framesperburst = atoi(optarg); + break; + case 'j': + inter_burst_delay_ms = atoi(optarg); + break; + case 'k': + postdelay_ms = atoi(optarg); + break; + case 't': + testframes = 1; + Ntestframes = atoi(optarg); + break; + case 'l': + use_clip = atoi(optarg); + break; + case 'm': + adv.M = atoi(optarg); + break; + case 'q': + quiet = 1; + break; + case 'f': + adv.Fs = atoi(optarg); + break; + case 'r': + adv.Rs = atoi(optarg); + break; + case '1': + adv.first_tone = atoi(optarg); + break; + case 's': + adv.tone_spacing = atoi(optarg); + break; + case 'o': + if (ldpc_codes_find(optarg) == -1) { + fprintf(stderr, "%s not found, try --listcodes\n", optarg); + exit(1); } - } - int dx = optind; - - if (argc < 4) { - helpmsg: - fprintf(stderr, "\nusage: %s [options] FSK_LDPC|DATAC0|... InputBinaryDataFile OutputModemRawFile\n" - "\n" - " --testframes T send a total of T test frames (T should equal B*N)\n" - " --bursts B send B bursts of N testframes (default 1)\n" - " --framesperburst N burst mode, N frames per burst (default 1)\n" - " --delay ms testframe inter-burst delay in ms\n" - " --postdelay ms additional delay at end of run in ms\n" - " -c complex signed 16 bit output format (default real)\n" - " --clip 0|1 clipping for reduced PAPR\n" - " --txbpf 0|1 bandpass filter\n" - " --seq send packet sequence numbers (breaks testframe BER counting)\n" - " --source Byte insert a (non-zero) source address att byte[0]\n" - " --complexout complex sample output (default real)\n" - " --quiet\n" - "\n" - "For FSK_LDPC only:\n\n" - " -a amp maximum amplitude of FSK signal\n" - " -m 2|4 number of FSK tones\n" - " --Fs FreqHz sample rate (default 8000)\n" - " --Rs FreqHz symbol rate (default 100)\n" - " --tone1 FreqHz freq of first tone (default 1000)\n" - " --shift FreqHz shift between tones (default 200)\n\n" - " --code CodeName LDPC code (defaults (512,256)\n" - " --listcodes list available LDPC codes\n\n" - , argv[0]); - fprintf(stderr, "example: $ %s --testframes 6 --bursts 3 --framesperburst 2 datac0 /dev/zero samples.s16\n", argv[0]); - fprintf(stderr, "example: $ %s -c --testframes 10 FSK_LDPC /dev/zero samples.iq16\n\n", argv[0]); - exit(1); - } - - if( (argc - dx) < 3) { - fprintf(stderr, "too few arguments.\n"); + strcpy(codename, optarg); + break; + case 'x': + ldpc_codes_list(); + exit(0); + break; + case 'h': + case '?': goto helpmsg; + break; } - - mode = -1; - if (!strcmp(argv[dx],"FSK_LDPC") || !strcmp(argv[dx],"fsk_ldpc")) mode = FREEDV_MODE_FSK_LDPC; - if (!strcmp(argv[dx],"DATAC0") || !strcmp(argv[dx],"datac0")) mode = FREEDV_MODE_DATAC0; - if (!strcmp(argv[dx],"DATAC1") || !strcmp(argv[dx],"datac1")) mode = FREEDV_MODE_DATAC1; - if (!strcmp(argv[dx],"DATAC3") || !strcmp(argv[dx],"datac3")) mode = FREEDV_MODE_DATAC3; - if (!strcmp(argv[dx],"DATAC4") || !strcmp(argv[dx],"datac4")) mode = FREEDV_MODE_DATAC4; - if (!strcmp(argv[dx],"DATAC13") || !strcmp(argv[dx],"datac13")) mode = FREEDV_MODE_DATAC13; - if (mode == -1) { - fprintf(stderr, "Error: in mode: %s", argv[dx]); + } + int dx = optind; + + if (argc < 4) { + helpmsg: + fprintf( + stderr, + "\nusage: %s [options] FSK_LDPC|DATAC0|... InputBinaryDataFile " + "OutputModemRawFile\n" + "\n" + " --testframes T send a total of T test frames (T should " + "equal B*N)\n" + " --bursts B send B bursts of N testframes (default " + "1)\n" + " --framesperburst N burst mode, N frames per burst (default " + "1)\n" + " --delay ms testframe inter-burst delay in ms\n" + " --postdelay ms additional delay at end of run in ms\n" + " -c complex signed 16 bit output format " + "(default real)\n" + " --clip 0|1 clipping for reduced PAPR\n" + " --txbpf 0|1 bandpass filter\n" + " --seq send packet sequence numbers (breaks " + "testframe BER counting)\n" + " --source Byte insert a (non-zero) source address att " + "byte[0]\n" + " --complexout complex sample output (default real)\n" + " --quiet\n" + "\n" + "For FSK_LDPC only:\n\n" + " -a amp maximum amplitude of FSK signal\n" + " -m 2|4 number of FSK tones\n" + " --Fs FreqHz sample rate (default 8000)\n" + " --Rs FreqHz symbol rate (default 100)\n" + " --tone1 FreqHz freq of first tone (default 1000)\n" + " --shift FreqHz shift between tones (default 200)\n\n" + " --code CodeName LDPC code (defaults (512,256)\n" + " --listcodes list available LDPC codes\n\n", + argv[0]); + fprintf(stderr, + "example: $ %s --testframes 6 --bursts 3 --framesperburst 2 datac0 " + "/dev/zero samples.s16\n", + argv[0]); + fprintf( + stderr, + "example: $ %s -c --testframes 10 FSK_LDPC /dev/zero samples.iq16\n\n", + argv[0]); + exit(1); + } + + if ((argc - dx) < 3) { + fprintf(stderr, "too few arguments.\n"); + goto helpmsg; + } + + mode = -1; + if (!strcmp(argv[dx], "FSK_LDPC") || !strcmp(argv[dx], "fsk_ldpc")) + mode = FREEDV_MODE_FSK_LDPC; + if (!strcmp(argv[dx], "DATAC0") || !strcmp(argv[dx], "datac0")) + mode = FREEDV_MODE_DATAC0; + if (!strcmp(argv[dx], "DATAC1") || !strcmp(argv[dx], "datac1")) + mode = FREEDV_MODE_DATAC1; + if (!strcmp(argv[dx], "DATAC3") || !strcmp(argv[dx], "datac3")) + mode = FREEDV_MODE_DATAC3; + if (!strcmp(argv[dx], "DATAC4") || !strcmp(argv[dx], "datac4")) + mode = FREEDV_MODE_DATAC4; + if (!strcmp(argv[dx], "DATAC13") || !strcmp(argv[dx], "datac13")) + mode = FREEDV_MODE_DATAC13; + if (mode == -1) { + fprintf(stderr, "Error: in mode: %s", argv[dx]); + exit(1); + } + + if (strcmp(argv[dx + 1], "-") == 0) + fin = stdin; + else if ((fin = fopen(argv[dx + 1], "rb")) == NULL) { + fprintf(stderr, "Error opening input file of bytes: %s: %s.\n", + argv[dx + 1], strerror(errno)); + exit(1); + } + + if (strcmp(argv[dx + 2], "-") == 0) + fout = stdout; + else if ((fout = fopen(argv[dx + 2], "wb")) == NULL) { + fprintf(stderr, "Error opening output modem sample file: %s: %s.\n", + argv[dx + 2], strerror(errno)); + exit(1); + } + + if (mode != FREEDV_MODE_FSK_LDPC) + freedv = freedv_open(mode); + else + freedv = freedv_open_advanced(mode, &adv); + + assert(freedv != NULL); + + /* these are optional ------------------ */ + if (use_clip != -1) freedv_set_clip(freedv, use_clip); + if (use_txbpf != -1) freedv_set_tx_bpf(freedv, use_txbpf); + freedv_set_tx_amp(freedv, amp); + + /* Data modes have a multiple of 8 payload bits/frame */ + int bytes_per_modem_frame = freedv_get_bits_per_modem_frame(freedv) / 8; + int payload_bytes_per_modem_frame = bytes_per_modem_frame; + payload_bytes_per_modem_frame -= 2; /* 16 bits used for the CRC */ + if (!quiet) + fprintf(stderr, "payload bytes_per_modem_frame: %d ", + payload_bytes_per_modem_frame); + assert((freedv_get_bits_per_modem_frame(freedv) % 8) == 0); + int n_mod_out = freedv_get_n_tx_modem_samples(freedv); + uint8_t bytes_in[bytes_per_modem_frame]; + + if (mode == FREEDV_MODE_FSK_LDPC) { + if (!quiet) + fprintf(stderr, + "Frequency: Fs: %4.1f Hz Rs: %5.0f Hz Tone1: %5.0f Hz Shift: " + "%5.0f Hz M: %d \n", + (float)adv.Fs, (float)adv.Rs, (float)adv.first_tone, + (float)adv.tone_spacing, adv.M); + + if (adv.tone_spacing < adv.Rs) { + fprintf(stderr, "Need shift: %d > Rs: %d\n", adv.tone_spacing, adv.Rs); exit(1); } - - if (strcmp(argv[dx+1], "-") == 0) fin = stdin; - else if ( (fin = fopen(argv[dx+1],"rb")) == NULL ) { - fprintf(stderr, "Error opening input file of bytes: %s: %s.\n", argv[dx+1], strerror(errno)); - exit(1); - } - - if (strcmp(argv[dx+2], "-") == 0) fout = stdout; - else if ( (fout = fopen(argv[dx+2],"wb")) == NULL ) { - fprintf(stderr, "Error opening output modem sample file: %s: %s.\n", argv[dx+2], strerror(errno)); - exit(1); - } - - if (mode != FREEDV_MODE_FSK_LDPC) - freedv = freedv_open(mode); - else - freedv = freedv_open_advanced(mode, &adv); - - assert(freedv != NULL); - - /* these are optional ------------------ */ - if (use_clip != -1) freedv_set_clip(freedv, use_clip); - if (use_txbpf != -1) freedv_set_tx_bpf(freedv, use_txbpf); - freedv_set_tx_amp(freedv, amp); - - /* Data modes have a multiple of 8 payload bits/frame */ - int bytes_per_modem_frame = freedv_get_bits_per_modem_frame(freedv)/8; - int payload_bytes_per_modem_frame = bytes_per_modem_frame; - payload_bytes_per_modem_frame -= 2; /* 16 bits used for the CRC */ - if (!quiet) fprintf(stderr, "payload bytes_per_modem_frame: %d ", payload_bytes_per_modem_frame); - assert((freedv_get_bits_per_modem_frame(freedv) % 8) == 0); - int n_mod_out = freedv_get_n_tx_modem_samples(freedv); - uint8_t bytes_in[bytes_per_modem_frame]; - - if (mode == FREEDV_MODE_FSK_LDPC) { - if (!quiet) fprintf(stderr, "Frequency: Fs: %4.1f Hz Rs: %5.0f Hz Tone1: %5.0f Hz Shift: %5.0f Hz M: %d \n", - (float)adv.Fs, (float)adv.Rs, (float)adv.first_tone, (float)adv.tone_spacing, adv.M); - - if (adv.tone_spacing < adv.Rs) { - fprintf(stderr, "Need shift: %d > Rs: %d\n", adv.tone_spacing, adv.Rs); - exit(1); - } + } + + /* a few sanity checks */ + if (testframes) { + if (Ntestframes != framesperburst * Nbursts) { + if (!quiet) + fprintf(stderr, + "Adjusting testframes to equal framesperburst*bursts\n"); + Ntestframes = framesperburst * Nbursts; } - - /* a few sanity checks */ - if (testframes) { - if (Ntestframes != framesperburst*Nbursts) { - if (!quiet) fprintf(stderr, "Adjusting testframes to equal framesperburst*bursts\n"); - Ntestframes = framesperburst*Nbursts; - } - } else { - if (framesperburst != 1) { - fprintf(stderr, "Only one frame per burst currently supported in stdin mode\n"); - exit(1); - } + } else { + if (framesperburst != 1) { + fprintf(stderr, + "Only one frame per burst currently supported in stdin mode\n"); + exit(1); } - - int frames = 0; - size_t on_samples = 0; - size_t off_samples = 0; - - /* initial silence */ - - int samples_delay = 0; - if (inter_burst_delay_ms) { + } + + int frames = 0; + size_t on_samples = 0; + size_t off_samples = 0; + + /* initial silence */ + + int samples_delay = 0; + if (inter_burst_delay_ms) { + /* user defined inter-burst delay */ + samples_delay = FREEDV_FS_8000 * inter_burst_delay_ms / 1000; + } else { + /* just enough silence at the end of burst to allow demod to complete + * processing */ + samples_delay = 2 * freedv_get_n_nom_modem_samples(freedv); + } + off_samples += send_silence(fout, shorts_per_sample, samples_delay); + + /* --------- Test Frame Mode + * --------------------------------------------------*/ + + if (testframes) { + /* generate a fixed test frame */ + uint8_t testframe_bytes[bytes_per_modem_frame]; + memset(testframe_bytes, 0, bytes_per_modem_frame); + int bits_per_frame = freedv_get_bits_per_modem_frame(freedv); + uint8_t testframe_bits[bits_per_frame]; + ofdm_generate_payload_data_bits(testframe_bits, bits_per_frame); + freedv_pack(testframe_bytes, testframe_bits, bits_per_frame); + if (!quiet) fprintf(stderr, "\n"); + + for (int b = 0; b < Nbursts; b++) { + on_samples += send_preamble(freedv, fout, use_complex, n_mod_out); + + for (int fpb = 0; fpb < framesperburst; fpb++) { + memcpy(bytes_in, testframe_bytes, bytes_per_modem_frame); + if (source_byte) bytes_in[0] = source_byte; + if (sequence_numbers) bytes_in[1] = (frames + 1) & 0xff; + + /* The raw data modes requires a CRC in the last two bytes */ + uint16_t crc16 = + freedv_gen_crc16(bytes_in, payload_bytes_per_modem_frame); + bytes_in[bytes_per_modem_frame - 2] = crc16 >> 8; + bytes_in[bytes_per_modem_frame - 1] = crc16 & 0xff; + + on_samples += + send_modulated_data(freedv, fout, use_complex, n_mod_out, bytes_in); + + /* if using pipes we don't want the usual buffering to occur */ + if (fout == stdout) fflush(stdout); + + frames++; + } + + on_samples += send_postamble(freedv, fout, use_complex, n_mod_out); + + int samples_delay = 0; + if (inter_burst_delay_ms) { /* user defined inter-burst delay */ - samples_delay = FREEDV_FS_8000*inter_burst_delay_ms/1000; + samples_delay = FREEDV_FS_8000 * inter_burst_delay_ms / 1000; + } else { + /* just enough silence at the end of burst to allow demod to complete + * processing */ + samples_delay = 2 * freedv_get_n_nom_modem_samples(freedv); + } + off_samples += send_silence(fout, shorts_per_sample, samples_delay); } - else { - /* just enough silence at the end of burst to allow demod to complete processing */ - samples_delay = 2*freedv_get_n_nom_modem_samples(freedv); - } - off_samples += send_silence(fout, shorts_per_sample, samples_delay); - - /* --------- Test Frame Mode --------------------------------------------------*/ - - if (testframes) { - - /* generate a fixed test frame */ - uint8_t testframe_bytes[bytes_per_modem_frame]; - memset(testframe_bytes, 0, bytes_per_modem_frame); - int bits_per_frame = freedv_get_bits_per_modem_frame(freedv); - uint8_t testframe_bits[bits_per_frame]; - ofdm_generate_payload_data_bits(testframe_bits, bits_per_frame); - freedv_pack(testframe_bytes, testframe_bits, bits_per_frame); - if (!quiet) fprintf(stderr, "\n"); - - for(int b=0; b<Nbursts; b++) { - on_samples += send_preamble(freedv, fout, use_complex, n_mod_out); - - for(int fpb=0; fpb<framesperburst; fpb++) { - memcpy(bytes_in, testframe_bytes, bytes_per_modem_frame); - if (source_byte) bytes_in[0] = source_byte; - if (sequence_numbers) bytes_in[1] = (frames+1) & 0xff; - - /* The raw data modes requires a CRC in the last two bytes */ - uint16_t crc16 = freedv_gen_crc16(bytes_in, payload_bytes_per_modem_frame); - bytes_in[bytes_per_modem_frame-2] = crc16 >> 8; - bytes_in[bytes_per_modem_frame-1] = crc16 & 0xff; - - on_samples += send_modulated_data(freedv, fout, use_complex, n_mod_out, bytes_in); - - /* if using pipes we don't want the usual buffering to occur */ - if (fout == stdout) fflush(stdout); - - frames++; - } - - on_samples += send_postamble(freedv, fout, use_complex, n_mod_out); - - int samples_delay = 0; - if (inter_burst_delay_ms) { - /* user defined inter-burst delay */ - samples_delay = FREEDV_FS_8000*inter_burst_delay_ms/1000; - } - else { - /* just enough silence at the end of burst to allow demod to complete processing */ - samples_delay = 2*freedv_get_n_nom_modem_samples(freedv); - } - off_samples += send_silence(fout, shorts_per_sample, samples_delay); - } - } else { + } else { + /* --------- modulate data from stdin mode + * --------------------------------------------------*/ - /* --------- modulate data from stdin mode --------------------------------------------------*/ + while (fread(bytes_in, sizeof(uint8_t), payload_bytes_per_modem_frame, + fin) == payload_bytes_per_modem_frame) { + on_samples += send_preamble(freedv, fout, use_complex, n_mod_out); - while (fread(bytes_in, sizeof(uint8_t), payload_bytes_per_modem_frame, fin) == payload_bytes_per_modem_frame) { - on_samples += send_preamble(freedv, fout, use_complex, n_mod_out); + if (source_byte) bytes_in[0] = source_byte; + if (sequence_numbers) bytes_in[1] = (frames + 1) & 0xff; - if (source_byte) bytes_in[0] = source_byte; - if (sequence_numbers) bytes_in[1] = (frames+1) & 0xff; + /* The raw data modes requires a CRC in the last two bytes */ + uint16_t crc16 = + freedv_gen_crc16(bytes_in, payload_bytes_per_modem_frame); + bytes_in[bytes_per_modem_frame - 2] = crc16 >> 8; + bytes_in[bytes_per_modem_frame - 1] = crc16 & 0xff; - /* The raw data modes requires a CRC in the last two bytes */ - uint16_t crc16 = freedv_gen_crc16(bytes_in, payload_bytes_per_modem_frame); - bytes_in[bytes_per_modem_frame-2] = crc16 >> 8; - bytes_in[bytes_per_modem_frame-1] = crc16 & 0xff; + on_samples += + send_modulated_data(freedv, fout, use_complex, n_mod_out, bytes_in); - on_samples += send_modulated_data(freedv, fout, use_complex, n_mod_out, bytes_in); - - /* if using pipes we don't want the usual buffering to occur */ - if (fout == stdout) fflush(stdout); + /* if using pipes we don't want the usual buffering to occur */ + if (fout == stdout) fflush(stdout); - on_samples += send_postamble(freedv, fout, use_complex, n_mod_out); + on_samples += send_postamble(freedv, fout, use_complex, n_mod_out); - int samples_delay = 0; - if (inter_burst_delay_ms) { - /* user defined inter-burst delay */ - samples_delay = FREEDV_FS_8000*inter_burst_delay_ms/1000; - } - else { - /* just enough silence at the end of burst to allow demod to complete processing */ - samples_delay = 2*freedv_get_n_nom_modem_samples(freedv); - } - off_samples += send_silence(fout, shorts_per_sample, samples_delay); - frames++; - } - } - - /* optional silence at the end of run */ - if (postdelay_ms) { - int samples_delay = FREEDV_FS_8000*postdelay_ms/1000; - if (!quiet) fprintf(stderr, "postdelay: %d %d\n", postdelay_ms, samples_delay); - off_samples += send_silence(fout, shorts_per_sample, samples_delay); + int samples_delay = 0; + if (inter_burst_delay_ms) { + /* user defined inter-burst delay */ + samples_delay = FREEDV_FS_8000 * inter_burst_delay_ms / 1000; + } else { + /* just enough silence at the end of burst to allow demod to complete + * processing */ + samples_delay = 2 * freedv_get_n_nom_modem_samples(freedv); + } + off_samples += send_silence(fout, shorts_per_sample, samples_delay); + frames++; } - - /* SNR offset to use in channel simulator to account for on/off time of burst signal */ - float mark_space_ratio = (float)on_samples/(on_samples+off_samples); - float mark_space_SNR_offset = 10*log10(mark_space_ratio); - if (!quiet) fprintf(stderr, "mark:space: %3.2f SNR offset: %5.2f\n", mark_space_ratio, mark_space_SNR_offset); - - freedv_close(freedv); - fclose(fin); - fclose(fout); - - return 0; -} + } + /* optional silence at the end of run */ + if (postdelay_ms) { + int samples_delay = FREEDV_FS_8000 * postdelay_ms / 1000; + if (!quiet) + fprintf(stderr, "postdelay: %d %d\n", postdelay_ms, samples_delay); + off_samples += send_silence(fout, shorts_per_sample, samples_delay); + } -size_t send_preamble(struct freedv *freedv, FILE *fout, int use_complex, size_t n_mod_out) { - short mod_out_short[2*n_mod_out]; - int shorts_per_sample = 1; - int n_preamble = 0; - - if (use_complex == 0) { - n_preamble = freedv_rawdatapreambletx(freedv, mod_out_short); - } else { - COMP mod_out_comp[n_mod_out]; - n_preamble = freedv_rawdatapreamblecomptx(freedv, mod_out_comp); - comp_to_short(mod_out_short, mod_out_comp, n_preamble); - shorts_per_sample = 2; - } - assert(n_preamble == freedv_get_n_tx_preamble_modem_samples(freedv)); - assert(n_preamble <= n_mod_out); - fwrite(mod_out_short, sizeof(short), shorts_per_sample*n_preamble, fout); - return n_preamble; -} + /* SNR offset to use in channel simulator to account for on/off time of burst + * signal */ + float mark_space_ratio = (float)on_samples / (on_samples + off_samples); + float mark_space_SNR_offset = 10 * log10(mark_space_ratio); + if (!quiet) + fprintf(stderr, "mark:space: %3.2f SNR offset: %5.2f\n", mark_space_ratio, + mark_space_SNR_offset); + freedv_close(freedv); + fclose(fin); + fclose(fout); -size_t send_modulated_data(struct freedv *freedv, FILE *fout, int use_complex, size_t n_mod_out, uint8_t bytes_in[]) { - short mod_out_short[2*n_mod_out]; - int shorts_per_sample = 1; - - if (use_complex == 0) { - freedv_rawdatatx(freedv, mod_out_short, bytes_in); - } else { - COMP mod_out_comp[n_mod_out]; - freedv_rawdatacomptx(freedv, mod_out_comp, bytes_in); - comp_to_short(mod_out_short, mod_out_comp, n_mod_out); - shorts_per_sample = 2; - } - fwrite(mod_out_short, sizeof(short), shorts_per_sample*n_mod_out, fout); - return n_mod_out; + return 0; } - -size_t send_postamble(struct freedv *freedv, FILE *fout, int use_complex, size_t n_mod_out) { - short mod_out_short[2*n_mod_out]; - int shorts_per_sample = 1; - int n_postamble = 0; - - if (use_complex == 0) { - n_postamble = freedv_rawdatapostambletx(freedv, mod_out_short); - } else { - COMP mod_out_comp[n_mod_out]; - n_postamble = freedv_rawdatapostamblecomptx(freedv, mod_out_comp); - comp_to_short(mod_out_short, mod_out_comp, n_postamble); - shorts_per_sample = 2; - } - assert(n_postamble == freedv_get_n_tx_postamble_modem_samples(freedv)); - assert(n_postamble <= n_mod_out); - fwrite(mod_out_short, sizeof(short), shorts_per_sample*n_postamble, fout); - return n_postamble; +size_t send_preamble(struct freedv *freedv, FILE *fout, int use_complex, + size_t n_mod_out) { + short mod_out_short[2 * n_mod_out]; + int shorts_per_sample = 1; + int n_preamble = 0; + + if (use_complex == 0) { + n_preamble = freedv_rawdatapreambletx(freedv, mod_out_short); + } else { + COMP mod_out_comp[n_mod_out]; + n_preamble = freedv_rawdatapreamblecomptx(freedv, mod_out_comp); + comp_to_short(mod_out_short, mod_out_comp, n_preamble); + shorts_per_sample = 2; + } + assert(n_preamble == freedv_get_n_tx_preamble_modem_samples(freedv)); + assert(n_preamble <= n_mod_out); + fwrite(mod_out_short, sizeof(short), shorts_per_sample * n_preamble, fout); + return n_preamble; } +size_t send_modulated_data(struct freedv *freedv, FILE *fout, int use_complex, + size_t n_mod_out, uint8_t bytes_in[]) { + short mod_out_short[2 * n_mod_out]; + int shorts_per_sample = 1; + + if (use_complex == 0) { + freedv_rawdatatx(freedv, mod_out_short, bytes_in); + } else { + COMP mod_out_comp[n_mod_out]; + freedv_rawdatacomptx(freedv, mod_out_comp, bytes_in); + comp_to_short(mod_out_short, mod_out_comp, n_mod_out); + shorts_per_sample = 2; + } + fwrite(mod_out_short, sizeof(short), shorts_per_sample * n_mod_out, fout); + return n_mod_out; +} -size_t send_silence(FILE *fout, size_t shorts_per_sample, size_t samples_delay) { - size_t n = shorts_per_sample*samples_delay; - short sil_short[n]; - for(int i=0; i<n; i++) sil_short[i] = 0; - fwrite(sil_short, sizeof(short), n, fout); - return samples_delay; +size_t send_postamble(struct freedv *freedv, FILE *fout, int use_complex, + size_t n_mod_out) { + short mod_out_short[2 * n_mod_out]; + int shorts_per_sample = 1; + int n_postamble = 0; + + if (use_complex == 0) { + n_postamble = freedv_rawdatapostambletx(freedv, mod_out_short); + } else { + COMP mod_out_comp[n_mod_out]; + n_postamble = freedv_rawdatapostamblecomptx(freedv, mod_out_comp); + comp_to_short(mod_out_short, mod_out_comp, n_postamble); + shorts_per_sample = 2; + } + assert(n_postamble == freedv_get_n_tx_postamble_modem_samples(freedv)); + assert(n_postamble <= n_mod_out); + fwrite(mod_out_short, sizeof(short), shorts_per_sample * n_postamble, fout); + return n_postamble; } +size_t send_silence(FILE *fout, size_t shorts_per_sample, + size_t samples_delay) { + size_t n = shorts_per_sample * samples_delay; + short sil_short[n]; + for (int i = 0; i < n; i++) sil_short[i] = 0; + fwrite(sil_short, sizeof(short), n, fout); + return samples_delay; +} void comp_to_short(short mod_out_short[], COMP mod_out_comp[], int n_mod_out) { - for(int i=0; i<n_mod_out; i++) { - mod_out_short[2*i] = (short)(mod_out_comp[i].real); - mod_out_short[2*i+1] = (short)(mod_out_comp[i].imag); - } + for (int i = 0; i < n_mod_out; i++) { + mod_out_short[2 * i] = (short)(mod_out_comp[i].real); + mod_out_short[2 * i + 1] = (short)(mod_out_comp[i].imag); + } } - |
