aboutsummaryrefslogtreecommitdiff
path: root/src/freedv_data_raw_tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/freedv_data_raw_tx.c')
-rw-r--r--src/freedv_data_raw_tx.c836
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);
+ }
}
-