From 50f43273066965aaf99928bf290974c64762389a Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Thu, 18 Apr 2024 11:15:42 -0400 Subject: [PATCH] PA: Adjust Input Fragsize / Latency; M17: Misc Notes About UDP Audio; --- src/dsd_audio.c | 32 +++++++++++++++++++++++++++++++- src/dsd_rigctl.c | 15 ++++++--------- src/m17.c | 10 ++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/dsd_audio.c b/src/dsd_audio.c index 963cc92..0ab5878 100644 --- a/src/dsd_audio.c +++ b/src/dsd_audio.c @@ -23,6 +23,9 @@ pa_sample_spec zz; pa_sample_spec cc; pa_sample_spec ff; //float +//pulse audio buffer attributes (input latency) +pa_buffer_attr lt; + void closePulseOutput (dsd_opts * opts) { pa_simple_free (opts->pulse_digi_dev_out); @@ -72,7 +75,34 @@ void openPulseInput(dsd_opts * opts) cc.channels = opts->pulse_digi_in_channels; cc.rate = opts->pulse_digi_rate_in; //48000 - opts->pulse_digi_dev_in = pa_simple_new(NULL, "DSD-FME", PA_STREAM_RECORD, NULL, opts->output_name, &cc, NULL, NULL, NULL); + //adjust input latency settings (defaults are all -1 to let server set these automatically, but without pavucontrol open, this is approx 2s) + //setting fragsize to 960 for 48000 input seems to do the trick to allow a much faster latency without underrun, may need adjusting if + //modifying the input rate (will only apply IF using pulse audio input, and not any other input method) + + //TODO: set fragsize vs expected input rate if required in the future + //NOTE: If users report any underrun conditions, then either change 960 back to -1, or pass NULL instead of < + + //https://freedesktop.org/software/pulseaudio/doxygen/structpa__buffer__attr.html + + //for now, only going to modify the fragsize if using the encoder, else, let the pa server set it automatically + // if (opts->m17encoder == 1) + // lt.fragsize = 960*5; + // else lt.fragsize = -1; + + //test doing it universally, fall back to above if needed + lt.fragsize = 960*5; + lt.maxlength = -1; + lt.prebuf = -1; + lt.tlength = -1; + + opts->pulse_digi_dev_in = pa_simple_new(NULL, "DSD-FME", PA_STREAM_RECORD, NULL, opts->output_name, &cc, NULL, <, NULL); + + //debug + // if (opts->m17encoder == 1) + // { + // unsigned long long int latency = pa_simple_get_latency (opts->pulse_digi_dev_in, NULL); + // fprintf (stderr, "Pulse Audio Input Latency: %05lld;", latency); + // } } diff --git a/src/dsd_rigctl.c b/src/dsd_rigctl.c index 820ac7e..581981e 100644 --- a/src/dsd_rigctl.c +++ b/src/dsd_rigctl.c @@ -307,16 +307,16 @@ int udp_socket_blaster(dsd_opts * opts, dsd_state * state, size_t nsam, void * d //listen with: //short 8k/2 - //socat stdio udp-listen:23456 | play --buffer 320*2 -q -b 16 -r 8000 -c2 -t s16 - + //socat stdio udp-listen:23456 | play --buffer 640 -q -b 16 -r 8000 -c2 -t s16 - //short 8k/1 - //socat stdio udp-listen:23456 | play --buffer 160*2 -q -b 16 -r 48000 -c2 -t s16 - + //socat stdio udp-listen:23456 | play --buffer 320 -q -b 16 -r 8000 -c1 -t s16 - //float 8k/2 - //socat stdio udp-listen:23456 | play --buffer 320*4 -q -e float -b 32 -r 8000 -c2 -t f32 - + //socat stdio udp-listen:23456 | play --buffer 1280 -q -e float -b 32 -r 8000 -c2 -t f32 - //float 8k/1 - //socat stdio udp-listen:23456 | play --buffer 160*4 -q -e float -b 32 -r 8000 -c1 -t f32 - + //socat stdio udp-listen:23456 | play --buffer 640 -q -e float -b 32 -r 8000 -c1 -t f32 - //send audio or data to socket err = sendto(opts->udp_sockfd, data, nsam, 0, (const struct sockaddr * ) & address, sizeof(struct sockaddr_in)); @@ -345,7 +345,7 @@ int udp_socket_blasterA(dsd_opts * opts, dsd_state * state, size_t nsam, void * //listen with: //short 48k/1 - //socat stdio udp-listen:23456 | play --buffer 960*2 -q -b 16 -r 48000 -c1 -t s16 - + //socat stdio udp-listen:23456 | play --buffer 1920 -q -b 16 -r 48000 -c1 -t s16 - //send audio or data to socket err = sendto(opts->udp_sockfdA, data, nsam, 0, (const struct sockaddr * ) & addressA, sizeof(struct sockaddr_in)); @@ -358,10 +358,7 @@ int m17_socket_blaster(dsd_opts * opts, dsd_state * state, size_t nsam, void * d UNUSED(state); unsigned long long int err = 0; - //listen with: - - //XX packed bytes - //socat stdio udp-listen:17000 | (decoder) + //See notes in m17.c on line ~3395 regarding usage //send audio or data to socket err = sendto(opts->m17_udp_sock, data, nsam, 0, (const struct sockaddr * ) & addressM17, sizeof(struct sockaddr_in)); diff --git a/src/m17.c b/src/m17.c index b081967..392adee 100644 --- a/src/m17.c +++ b/src/m17.c @@ -2156,6 +2156,13 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state) fprintf (stderr, " SQL HIT: %d;", sql_hit); } + //debug show pulse input latency + // if (opts->audio_in_type == 0) + // { + // unsigned long long int latency = pa_simple_get_latency (opts->pulse_digi_dev_in, NULL); + // fprintf (stderr, " Latency: %05lld;", latency); + // } + //convert bit array into symbols and RF/Audio encodeM17RF (opts, state, m17_t4s, 2); @@ -3398,6 +3405,9 @@ void processM17IPF(dsd_opts * opts, dsd_state * state) //encode with: dsd-fme -fZ -M M17:1:N0CALL:ALL:48000:1 -o m17:127.0.0.1:17000 -N 2> m17out.ans //decode with: dsd-fme -fU -i m17:127.0.0.1:17000 -N 2> m17ip.ans + //NOTE: Currently, IP Frame decoding cannot be used with -o udp audio output + //its a rare use case, but should be noted, I think udpbind does something to block that functionality + //Bind UDP Socket int err = 1; //NOTE: err will tell us how many bytes were received, if successful opts->udp_sockfd = UDPBind(opts->m17_hostname, opts->m17_portno);