UDP Analog Audio Output;

This commit is contained in:
lwvmobile 2024-02-21 10:29:06 -05:00
parent 42fee3bd3e
commit 65fdd7c5b4
6 changed files with 96 additions and 12 deletions

View File

@ -332,7 +332,8 @@ typedef struct
char rigctlhostname[1024];
//UDP Socket Blaster Audio
int udp_sockfd;
int udp_sockfd; //digital
int udp_sockfdA; //analog 48k1
int udp_portno;
char udp_hostname[1024];
@ -1265,7 +1266,9 @@ int csvKeyImportHex(dsd_opts * opts, dsd_state * state);
//UDP Socket Connect and UDP Socket Blaster (audio output)
int udp_socket_connect(dsd_opts * opts, dsd_state * state);
int udp_socket_connectA(dsd_opts * opts, dsd_state * state);
int udp_socket_blaster(dsd_opts * opts, dsd_state * state, size_t nsam, void * data);
int udp_socket_blasterA(dsd_opts * opts, dsd_state * state, size_t nsam, void * data);
#ifdef __cplusplus
extern "C" {

View File

@ -696,7 +696,8 @@ initOpts (dsd_opts * opts)
sprintf (opts->rigctlhostname, "%s", "localhost");
//UDP Socket Blaster Audio
opts->udp_sockfd = 0;
opts->udp_sockfd = 0;
opts->udp_sockfdA = 0;
opts->udp_portno = 23456; //default port, same os OP25's sockaudio.py
sprintf (opts->udp_hostname, "%s", "127.0.0.1");
@ -1510,6 +1511,9 @@ cleanupAndExit (dsd_opts * opts, dsd_state * state)
if (opts->udp_sockfd)
close (opts->udp_sockfd);
if (opts->udp_sockfdA)
close (opts->udp_sockfdA);
//close MBE out files
if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state);
if (opts->mbe_out_fR != NULL) closeMbeOutFileR (opts, state);
@ -2743,8 +2747,23 @@ main (int argc, char **argv)
if (opts.monitor_input_audio == 1 || opts.frame_provoice == 1)
{
fprintf (stderr, "NOTICE: Raw Audio Monitoring and Analog Calls Unavailable over UDP Audio Output\n");
opts.monitor_input_audio = 0;
err = udp_socket_connectA(&opts, &state);
if (err < 0)
{
fprintf (stderr, "Error Configuring UDP Socket for UDP Blaster Audio Analog :( \n");
opts.udp_sockfdA = 0;
opts.monitor_input_audio = 0;
}
else
{
fprintf (stderr, "UDP Blaster Output (Analog): ");
fprintf (stderr, "%s:", opts.udp_hostname);
fprintf (stderr, "%d \n", opts.udp_portno+2);
}
//this functionality is disabled when trunking EDACS, but we still use the behavior for analog channel monitoring
if (opts.frame_provoice == 1 && opts.p25_trunk == 1)
opts.monitor_input_audio = 0;
}
}

View File

@ -2429,6 +2429,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if ( (opts->audio_out_type == 5 && opts->pulse_digi_rate_out == 48000 && opts->pulse_digi_out_channels == 1) && (opts->frame_provoice == 1 || opts->monitor_input_audio == 1) )
printw (" - Monitor RMS: %04ld ", opts->rtl_rms);
printw (" \n");
if (opts->udp_sockfdA != 0) //Analog Output on udp port +2
{
printw ("| UDP Audio Output: %s:%d; 48 kHz 1 Ch; Analog Output; ", opts->udp_hostname, opts->udp_portno+2);
printw (" \n");
}
}
// if (opts->monitor_input_audio == 1)

View File

@ -31,6 +31,7 @@ void error(char *msg) {
}
struct sockaddr_in address;
struct sockaddr_in addressA;
//
// Connect
@ -316,6 +317,23 @@ int udp_socket_blaster(dsd_opts * opts, dsd_state * state, size_t nsam, void * d
if (err < nsam) fprintf (stderr, "\n UDP Underflow %ld", err); //I'm not even sure if this is possible
}
//Analog UDP port on +2 of normal open socket
int udp_socket_blasterA(dsd_opts * opts, dsd_state * state, size_t nsam, void * data)
{
UNUSED(state);
size_t err = 0;
//listen with:
//short 48k/1
//socat stdio udp-listen:23456 | play --buffer 960*2 -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));
if (err < 0) fprintf (stderr, "\n UDP SENDTO ERR %ld", err); //return value here is size_t number of characters sent, or -1 for failure
if (err < nsam) fprintf (stderr, "\n UDP Underflow %ld", err); //I'm not even sure if this is possible
}
int udp_socket_connect(dsd_opts * opts, dsd_state * state)
{
UNUSED(state);
@ -354,3 +372,42 @@ int udp_socket_connect(dsd_opts * opts, dsd_state * state)
}
}
int udp_socket_connectA(dsd_opts * opts, dsd_state * state)
{
UNUSED(state);
long int err = 0;
err = opts->udp_sockfdA = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (err < 0)
{
fprintf (stderr, " UDP Socket Error %ld\n", err);
return (err);
}
// Don't think this is needed, but doesn't seem to hurt to keep it here either
int broadcastEnable = 1;
err = setsockopt(opts->udp_sockfdA, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
if (err < 0)
{
fprintf (stderr, " UDP Broadcast Set Error %ld\n", err);
return (err);
}
memset((char * ) & addressA, 0, sizeof(addressA));
addressA.sin_family = AF_INET;
err = addressA.sin_addr.s_addr = inet_addr(opts->udp_hostname);
if (err < 0) //error in this context reports back 32-bit inet_addr reversed order byte pairs
{
fprintf (stderr, " UDP inet_addr Error %ld\n", err);
return (err);
}
addressA.sin_port = htons(opts->udp_portno+2); //plus 2 to current port assignment for the analog port value
if (err < 0)
{
fprintf (stderr, " UDP htons Error %ld\n", err);
return (err);
}
}

View File

@ -311,7 +311,7 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
pa_simple_write(opts->pulse_raw_dev_out, state->analog_out, 960*2, NULL);
if (opts->audio_out_type == 8)
udp_socket_blaster (opts, state, 960*2, state->analog_out);
udp_socket_blasterA (opts, state, 960*2, state->analog_out);
//NOTE: Worked okay earlier in Cygwin, so should be fine -- can only operate at 48k1, else slow mode lag

View File

@ -338,9 +338,9 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn
if (opts->audio_out_type == 8) //UDP Audio
{
udp_socket_blaster (opts, state, 960*2, analog1);
udp_socket_blaster (opts, state, 960*2, analog2);
udp_socket_blaster (opts, state, 960*2, analog3);
udp_socket_blasterA (opts, state, 960*2, analog1);
udp_socket_blasterA (opts, state, 960*2, analog2);
udp_socket_blasterA (opts, state, 960*2, analog3);
}
//added a condition check so that if OSS output and 8K, switches to 48K when opening OSS
@ -798,9 +798,9 @@ void edacs(dsd_opts * opts, dsd_state * state)
// goto ENDPV;
// #endif
//skip analog calls on UDP Audio Output
if (command == 0xEE && opts->audio_out_type == 8)
goto ENDPV;
//this is working now with the new import setup
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0) ) //DE is digital encrypted, B is block
@ -865,7 +865,7 @@ void edacs(dsd_opts * opts, dsd_state * state)
}
ENDPV:
free (timestr); //free allocated memory to prevent memory leak
fprintf (stderr, "\n");