diff --git a/examples/Example_Usage.md b/examples/Example_Usage.md index 6d61826..11cb434 100644 --- a/examples/Example_Usage.md +++ b/examples/Example_Usage.md @@ -296,7 +296,7 @@ You can use the experimental M17 Voice Stream and Packet encoder with the follow Encode/Decode Local Feedback Voice Stream (Single Session): -`dsd-fme -fZ -i pulse -o pulse -M M17:3:SP5WWP:BROADCAST` +`dsd-fme -fZ -i pulse -o pulse -M M17:3:SP5WWP:BROADCAST:48000` Using the `-8` option (raw audio monitor) will instead send encoded raw audio to output instead of decoded audio. For example, @@ -304,7 +304,7 @@ To send a voice stream out of stdout into SOCAT TCP to a second/remote DSD-FME s Encode: -`dsd-fme -fZ -8 -i pulse -M M17:9:LWVMOBILE:DSD-FME -o - | socat stdio tcp-listen:7355,forever,reuseaddr` +`dsd-fme -fZ -8 -i pulse -M M17:9:LWVMOBILE:DSD-FME:48000 -o - | socat stdio tcp-listen:7355,forever,reuseaddr` Decode: @@ -323,4 +323,10 @@ SMS Packet Encoder (over SOCAT TCP): Many combinations of input and output can be used as well, and using features like raw audio saving with `-6 m17str.wav` will save a wav file of your encoded audio to be replayed later with `-i m17str.wav` Also note, features function similarly, like -Z for payload, and input options include pulse, oss, stdin, rtl, tcp, etc, using those as the mic in for voice encoding. With the right setup of input/output/input using SOCAT TCP pipes, it is conceivable to use DSD-FME to convert analog audio from NFM into M17 audio, or even change another digital format supported by DSD-FME into M17 audio, if desired (purely for research and fun purposes). Ncurses terminal will function with internal encoder/decoder and wav file creation, with toggle encode/tx with `\` key, but will not function with stdout properly. +The `-M` switch is used to specify user M17 variables, the string is in the format of M17:CAN:SRC:DST:INPUT_RATE. +CAN 1-15; SRC and DST have to be no more than 9 UPPER base40 characters. +BASE40: ' ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/.' +Input Rate Default is 48000; Use Multiples of 8000 up to 48000. +Values not entered into the M17: string are set to default values. M17:7:DSD-FME:DSD-FME:48000 + Information on this section will be updated as features are added or modified, etc. If you need help with a particular function and can't find a suitable answer, always open a new issue here, or make contact on the radio reference forum for additional examples, guidance, ideas, help, etc. \ No newline at end of file diff --git a/include/dsd.h b/include/dsd.h index 58d271e..8eb78d3 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -786,6 +786,7 @@ typedef struct unsigned long long int m17_src; uint8_t m17_can; //can value that was decoded from signal int m17_can_en; //can value supplied to the encoding side + int m17_rate; //sampling rate for audio input char m17_dst_csd[20]; char m17_src_csd[20]; diff --git a/src/dsd_main.c b/src/dsd_main.c index 2c86af7..ca4eb12 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -1190,6 +1190,7 @@ initState (dsd_state * state) state->m17_src = 0; state->m17_can = 0; //can value that was decoded from signal state->m17_can_en = -1; //can value supplied to the encoding side + state->m17_rate = 48000; //sampling rate for audio input memset(state->m17_dst_csd, 0, sizeof(state->m17_dst_csd)); memset(state->m17_src_csd, 0, sizeof(state->m17_src_csd)); sprintf (state->m17_dst_str, "%s", ""); @@ -1312,9 +1313,11 @@ usage () printf (" -fB M17 BERT Encoder\n"); printf (" Example: dsd-fme -fB -M M17:9:DSD-FME:LWVMOBILE -6 m17bert.wav\n"); printf ("\n"); - printf (" -M M17 Encoding User Configuration String: M17:CAN:SRC:DST (see examples above).\n"); - printf (" CAN 1-15; SRC and DST have to be no more than 9 UPPER base40 characters\n"); + printf (" -M M17 Encoding User Configuration String: M17:CAN:SRC:DST:INPUT_RATE (see examples above).\n"); + printf (" CAN 1-15; SRC and DST have to be no more than 9 UPPER base40 characters.\n"); printf (" BASE40: ' ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/.'\n"); + printf (" Input Rate Default is 48000; Use Multiples of 8000 up to 48000.\n"); + printf (" Values not entered into the M17: string are set to default values.\n"); printf (" -S M17 Encoding Packet SMS String: No more than 772 chars, use single quotations (see example above).\n"); printf ("Decoder options:\n"); printf (" -fa Auto Detection\n"); @@ -2998,7 +3001,7 @@ main (int argc, char **argv) if((strncmp(state.m17dat, "M17", 3) == 0)) { //read in values - //string in format of M17:can:src_csd:dst_csd + //string in format of M17:can:src_csd:dst_csd:input_rate //check and capatalize any letters in the CSD for (int i = 0; state.m17dat[i]!='\0'; i++) @@ -3035,6 +3038,10 @@ main (int argc, char **argv) state.str50b[9] = '\0'; } + curr = strtok(NULL, ":"); //m17 input audio rate + if (curr != NULL) + state.m17_rate = atoi(curr); + M17END: ; //do nothing //check to make sure can value is no greater than 15 (4 bit value) @@ -3045,7 +3052,7 @@ main (int argc, char **argv) // fprintf (stderr, " %s;", state.m17dat); //debug print - fprintf (stderr, " M17:%d:%s:%s; \n ", state.m17_can_en, state.str50c, state.str50b); + fprintf (stderr, " M17:%d:%s:%s:%d; \n ", state.m17_can_en, state.str50c, state.str50b, state.m17_rate); } if (opts.playfiles == 1) diff --git a/src/m17.c b/src/m17.c index 9d48f6a..20ffbe1 100644 --- a/src/m17.c +++ b/src/m17.c @@ -1410,6 +1410,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) int i, j, k, x; //basic utility counters short sample = 0; //individual audio sample from source size_t nsam = 160; //number of samples to be read in (default is for codec2 3200 bps) + int dec = state->m17_rate / 8000; //number of samples to run before selecting a sample from source input //send dead air with type 99 for (i = 0; i < 25; i++) @@ -1660,14 +1661,14 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) { for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) pa_simple_read(opts->pulse_digi_dev_in, &sample, 2, NULL ); voice1[i] = sample; //only store the 6th sample } for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) pa_simple_read(opts->pulse_digi_dev_in, &sample, 2, NULL ); voice2[i] = sample; //only store the 6th sample } @@ -1678,7 +1679,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) int result = 0; for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) result = sf_read_short(opts->audio_in_file, &sample, 1); voice1[i] = sample; if (result == 0) @@ -1693,7 +1694,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) result = sf_read_short(opts->audio_in_file, &sample, 1); voice2[i] = sample; if (result == 0) @@ -1711,14 +1712,14 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) { for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) read (opts->audio_in_fd, &sample, 2); voice1[i] = sample; } for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) read (opts->audio_in_fd, &sample, 2); voice2[i] = sample; } @@ -1729,7 +1730,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) int result = 0; for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) result = sf_read_short(opts->tcp_file_in, &sample, 1); voice1[i] = sample; if (result == 0) @@ -1744,7 +1745,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) result = sf_read_short(opts->tcp_file_in, &sample, 1); voice2[i] = sample; if (result == 0) @@ -1763,7 +1764,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) #ifdef USE_RTLSDR for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) if (get_rtlsdr_sample(&sample, opts, state) < 0) cleanupAndExit(opts, state); voice1[i] = sample; @@ -1771,7 +1772,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) for (i = 0; i < nsam; i++) { - for (j = 0; j < 6; j++) + for (j = 0; j < dec; j++) if (get_rtlsdr_sample(&sample, opts, state) < 0) cleanupAndExit(opts, state); voice2[i] = sample;