Rewrite OSS Handling (depending on use case);

This commit is contained in:
lwvmobile 2023-07-28 16:06:58 -04:00
parent aa49e5869b
commit 50d707a8e3
6 changed files with 170 additions and 127 deletions

View File

@ -460,7 +460,7 @@ playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
{
if (opts->audio_out_type == 5) //OSS
{
//OSS
//OSS 48k/1
result = write (opts->audio_out_fd, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2));
state->audio_out_idx = 0;
}
@ -496,8 +496,8 @@ playSynthesizedVoiceR (dsd_opts * opts, dsd_state * state)
// output synthesized speech to sound card
if (opts->audio_out_type == 5) //OSS
{
//OSS
result = write (opts->audio_out_fdR, (state->audio_out_buf_pR - state->audio_out_idxR), (state->audio_out_idxR * 2));
//OSS 48k/1
result = write (opts->audio_out_fd, (state->audio_out_buf_pR - state->audio_out_idxR), (state->audio_out_idxR * 2));
state->audio_out_idxR = 0;
}
else if (opts->audio_out_type == 0)

View File

@ -903,7 +903,7 @@ void playSynthesizedVoiceSS (dsd_opts * opts, dsd_state * state)
if (opts->audio_out_type == 0) //Pulse Audio
pa_simple_write(opts->pulse_digi_dev_out, stereo_samp1, 320*2, NULL);
if (opts->audio_out_type == 1 || opts->audio_out_type == 5) //STDOUT or OSS
if (opts->audio_out_type == 1 || opts->audio_out_type == 2) //STDOUT or OSS 8k/2
write (opts->audio_out_fd, stereo_samp1, 320*2);
@ -1042,7 +1042,7 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state)
}
if (opts->audio_out_type == 1 || opts->audio_out_type == 5) //STDOUT or OSS
if (opts->audio_out_type == 1 || opts->audio_out_type == 2) //STDOUT or OSS 8k/2channel
{
write (opts->audio_out_fd, stereo_samp1, 320*2);
write (opts->audio_out_fd, stereo_samp2, 320*2);
@ -1192,11 +1192,11 @@ void playSynthesizedVoiceSS4 (dsd_opts * opts, dsd_state * state)
}
if (opts->audio_out_type == 1 || opts->audio_out_type == 5) //STDOUT or OSS
if (opts->audio_out_type == 1 || opts->audio_out_type == 2) //STDOUT or OSS 8k/2channel
{
write (opts->audio_out_fd, stereo_samp1, 320*2);
write (opts->audio_out_fd, stereo_samp2, 320*2);
//only play these two if not a single 2v or double 2v (minor skip can still occur on a 4v and 2v combo, but will probably only be perceivable if one is a tone)
//only play these two if not a single 2v or double 2v
if (memcmp(empty, stereo_samp3, sizeof(empty)) != 0)
write (opts->audio_out_fd, stereo_samp3, 320*2);
if (memcmp(empty, stereo_samp4, sizeof(empty)) != 0)

View File

@ -2594,22 +2594,39 @@ main (int argc, char **argv)
#endif
}
//moved these to be checked prior to checking OSS for the split for 1-48k, or variable configurations
if((strncmp(opts.audio_in_dev, "pulse", 5) == 0))
{
opts.audio_in_type = 0;
}
if((strncmp(opts.audio_out_dev, "pulse", 5) == 0))
{
opts.audio_out_type = 0;
}
if((strncmp(opts.audio_out_dev, "null", 4) == 0))
{
opts.audio_out_type = 9; //9 for NULL, or mute output
opts.audio_out = 0; //turn off so we won't playSynthesized
}
if((strncmp(opts.audio_out_dev, "-", 1) == 0))
{
opts.audio_out_fd = fileno(stdout); //STDOUT_FILENO;
opts.audio_out_type = 1; //using 1 for stdout to match input stdin as 1
fprintf(stderr, "Audio Out Device: -\n");
}
int fmt;
int speed;
//The long of the short is that PADSP can open multiple virtual /dev/dsp devices each with different sampling rates and channel configurations
//but the instance inside of Cygwin is a single instance tied to one sample rate AND one channel configuration, so if you change it on the output, it
//also changes on the input, and the way dsd handles this is to upsample output to make it work correctly, so if we were to make a true short stereo mix,
//we would have to handle upsampling for it as well in Cygwin (alternatively, find another output method, like RTAudio, or something else)
//also changes on the input, and the way dsd handles this is to upsample output to make it work correctly, so in order to be able to change the output
//to a variable config, it cannot be the input as well
//It should be noted that Pulse Audio instances do not have this same issue, and can run at different input/rate and output/rate/channel configurations
//TL:DR; the only reason /dev/dsp works as both input and output in Cygwin is because both input and output are exactly 1 channel - 48k
//TODO: Test opening OSS input as 2-channel 48k, and see if we can read it in, if not, then double samplespersymble and center
//doing so will break the filters though
speed = 48000;
if((strncmp(opts.audio_in_dev, "/dev/audio", 10) == 0))
{
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
@ -2622,6 +2639,7 @@ main (int argc, char **argv)
fprintf (stderr, "Switching to /dev/dsp.\n");
}
speed = 48000; //hardset to 48000
if((strncmp(opts.audio_in_dev, "/dev/dsp", 8) == 0))
{
fprintf (stderr, "OSS Input %s.\n", opts.audio_in_dev);
@ -2668,72 +2686,108 @@ main (int argc, char **argv)
fprintf (stderr, "Switching to /dev/dsp.\n");
}
if((strncmp(opts.audio_out_dev, "/dev/dsp", 8) == 0))
if (opts.audio_in_type == 5) //if((strncmp(opts.audio_in_dev, "/dev/dsp", 8) == 0)) or 'split' == 0
{
fprintf (stderr, "OSS Output %s.\n", opts.audio_out_dev);
opts.audio_out_fd = open (opts.audio_out_dev, O_RDWR);
if (opts.audio_out_fd == -1)
if((strncmp(opts.audio_out_dev, "/dev/dsp", 8) == 0))
{
fprintf (stderr, "Error, couldn't open #1 %s\n", opts.audio_out_dev);
opts.audio_out = 0;
exit(1);
fprintf (stderr, "OSS Output %s.\n", opts.audio_out_dev);
opts.audio_out_fd = open (opts.audio_out_dev, O_RDWR);
if (opts.audio_out_fd == -1)
{
fprintf (stderr, "Error, couldn't open #1 %s\n", opts.audio_out_dev);
opts.audio_out = 0;
exit(1);
}
fmt = 0;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_RESET) < 0)
{
fprintf (stderr, "ioctl reset error \n");
}
fmt = speed;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
{
fprintf (stderr, "ioctl speed error \n");
}
fmt = 0; //this seems okay to be 1 or 0, not sure what the difference really is (works in stereo on 0)
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
{
fprintf (stderr, "ioctl stereo error \n");
}
fmt = AFMT_S16_LE;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
{
fprintf (stderr, "ioctl setfmt error \n");
}
opts.audio_out_type = 5; //5 for 1 channel - 48k OSS 16-bit short output (matching with input)
opts.pulse_digi_rate_out = 48000; //this is used to force to upsample
opts.pulse_digi_out_channels = 1;
opts.audio_gain = 0;
}
fmt = 0;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_RESET) < 0)
{
fprintf (stderr, "ioctl reset error \n");
}
fmt = speed;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
{
fprintf (stderr, "ioctl speed error \n");
}
fmt = 0; //this seems okay to be 1 or 0, not sure what the difference really is (works in stereo on 0)
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
{
fprintf (stderr, "ioctl stereo error \n");
}
fmt = AFMT_S16_LE;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
{
fprintf (stderr, "ioctl setfmt error \n");
}
//setup for one or two-channel configuration -- OSS -- cygwin OSS does not like this at all, even when set to 1
// fmt = opts.pulse_digi_out_channels; //number of channels is also be a problem for Cygwin...
// if (ioctl (opts.audio_out_fd, SNDCTL_DSP_CHANNELS, &fmt) < 0)
// {
// fprintf (stderr, "ioctl channels error \n");
// }
opts.audio_out_type = 5; //5 will become OSS output type
}
if((strncmp(opts.audio_in_dev, "pulse", 5) == 0))
if (opts.audio_in_type != 5) //split == 1
{
opts.audio_in_type = 0;
}
if((strncmp(opts.audio_out_dev, "pulse", 5) == 0))
{
opts.audio_out_type = 0;
}
if((strncmp(opts.audio_out_dev, "/dev/dsp", 8) == 0))
{
fprintf (stderr, "OSS Output %s.\n", opts.audio_out_dev);
opts.audio_out_fd = open (opts.audio_out_dev, O_WRONLY);
if (opts.audio_out_fd == -1)
{
fprintf (stderr, "Error, couldn't open %s\n", opts.audio_out_dev);
opts.audio_out = 0;
exit(1);
}
if((strncmp(opts.audio_out_dev, "null", 4) == 0))
{
opts.audio_out_type = 9; //9 for NULL, or mute output
opts.audio_out = 0; //turn off so we won't playSynthesized
}
//Setup the device. Note that it's important to set the sample format, number of channels and sample rate exactly in this order. Some devices depend on the order.
if((strncmp(opts.audio_out_dev, "-", 1) == 0))
{
opts.audio_out_fd = fileno(stdout); //STDOUT_FILENO;
opts.audio_out_type = 1; //using 1 for stdout to match input stdin as 1
fprintf(stderr, "Audio Out Device: -\n");
fmt = 0;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_RESET) < 0)
{
fprintf (stderr, "ioctl reset error \n");
}
fmt = AFMT_S16_LE; //Sample Format
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
{
fprintf (stderr, "ioctl setfmt error \n");
}
fmt = opts.pulse_digi_out_channels; //number of channels //was 2
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_CHANNELS, &fmt) < 0)
{
fprintf (stderr, "ioctl channel error \n");
}
speed = opts.pulse_digi_rate_out; //since we have split input/output, we want 2-channel/8k //8000 -- mirror pulse rate instead
fmt = speed; //output rate
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
{
fprintf (stderr, "ioctl speed error \n");
}
if (opts.pulse_digi_out_channels == 2)
fmt = 1;
else fmt = 0;
if (ioctl (opts.audio_out_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
{
fprintf (stderr, "ioctl stereo error \n");
}
//TODO: Multiple output returns based on 8k/1, 8k/2, or maybe 48k/1? (2,3,5)??
if (opts.pulse_digi_out_channels == 2)
opts.audio_out_type = 2; //2 for 2 channel 8k OSS 16-bit short output
else opts.audio_out_type = 5;
//debug
fprintf (stderr, "Using OSS Output with %dk/%d channel configuration.\n", opts.pulse_digi_rate_out, opts.pulse_digi_out_channels);
}
}
if (opts.playfiles == 1) //redo?

View File

@ -245,8 +245,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
}
//set flag to not play audio this time, but won't prevent writing to wav files
if (strcmp(mode, "B") == 0) opts->audio_out = 0;
//set flag to not play audio this time, but won't prevent writing to wav files -- disabled for now
// if (strcmp(mode, "B") == 0) opts->audio_out = 0; //causes a buzzing now (probably due to not running processAudio before the SS3 or SS4)
//end set playback mode for this frame
@ -1058,30 +1058,29 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
//end reverse mute test
//No more Slot Pre-emption...ever
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
// if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstR == 16 || state->dmrburstR == 21) )
// {
// opts->audio_out = 0;
// preempt = 1;
// if (opts->payload == 0)
// fprintf (stderr, " *MUTED*");
// }
// #endif
//OSS 48k/1 Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstR == 16 || state->dmrburstR == 21) )
{
opts->audio_out = 0;
preempt = 1;
if (opts->payload == 0 && opts->slot1_on == 1)
fprintf (stderr, " *MUTED*");
else if (opts->payload == 0 && opts->slot1_on == 0)
fprintf (stderr, " *OFF*");
}
state->debug_audio_errors += state->errs2 + state->errs;
if (state->dmr_encL == 0 || opts->dmr_mute_encL == 0)
{
if (opts->audio_out == 1 && opts->floating_point == 0 ) //&& opts->pulse_digi_rate_out == 8000
if (opts->audio_out == 1 && opts->floating_point == 0 ) //&& opts->slot1_on == 1
{
processAudio(opts, state);
}
// if (opts->audio_out == 1)
// {
// playSynthesizedVoice (opts, state);
// }
if (opts->audio_out == 1 && opts->floating_point == 0 && opts->audio_out_type == 5 && opts->slot1_on == 1) //for OSS 48k 1 channel configs -- relocate later if possible
{
playSynthesizedVoice (opts, state); //it may be more beneficial to move this to each individual decoding type to handle, but ultimately, let's just simpifly mbe handling instead
}
}
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l)); //these are for mono or FDMA where we don't need to buffer and wait for a stereo mix
@ -1134,29 +1133,29 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
//end reverse mute test
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
// if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstL == 16 || state->dmrburstL == 21) )
// {
// opts->audio_out = 0;
// preempt = 1;
// if (opts->payload == 0)
// fprintf (stderr, " *MUTED*");
// }
// #endif
//OSS 48k/1 Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && (state->dmrburstL == 16 || state->dmrburstL == 21) )
{
opts->audio_out = 0;
preempt = 1;
if (opts->payload == 0 && opts->slot2_on == 1)
fprintf (stderr, " *MUTED*");
else if (opts->payload == 0 && opts->slot2_on == 0)
fprintf (stderr, " *OFF*");
}
state->debug_audio_errorsR += state->errs2R + state->errsR;
if (state->dmr_encR == 0 || opts->dmr_mute_encR == 0)
{
if (opts->audio_out == 1 && opts->floating_point == 0 ) //&& opts->pulse_digi_rate_out == 8000
if (opts->audio_out == 1 && opts->floating_point == 0) //&& opts->slot2_on == 1
{
processAudioR(opts, state);
}
// if (opts->audio_out == 1)
// {
// playSynthesizedVoiceR (opts, state);
// }
if (opts->audio_out == 1 && opts->floating_point == 0 && opts->audio_out_type == 5 && opts->slot2_on == 1) //for OSS 48k 1 channel configs -- relocate later if possible
{
playSynthesizedVoiceR (opts, state);
}
}
memcpy (state->f_r, state->audio_out_temp_bufR, sizeof(state->f_r));
@ -1215,8 +1214,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
preempt = 0;
}
//reset audio out flag for next repitition
if (strcmp(mode, "B") == 0) opts->audio_out = 1;
//reset audio out flag for next repitition --disabled for now
// if (strcmp(mode, "B") == 0) opts->audio_out = 1;
//restore flag for null output type
if (opts->audio_out_type == 9) opts->audio_out = 0;
}

View File

@ -2320,9 +2320,9 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw (" \n");
}
if (opts->audio_out_type == 5)
if (opts->audio_out_type == 5 || opts->audio_out_type == 2)
{
printw ("| Pulse Audio Output: %i kHz; %i Channel; G: %.1f%%", opts->pulse_digi_rate_out/1000, opts->pulse_digi_out_channels, state->aout_gain*2);
printw ("| OSS Audio Output: %i kHz; %i Channel; G: %.1f%%", opts->pulse_digi_rate_out/1000, opts->pulse_digi_out_channels, state->aout_gain*2);
if (opts->pulse_digi_out_channels == 2) printw (" G: %.1f%%", state->aout_gainR*2);
if (state->audio_smoothing == 1 && opts->floating_point == 0) printw (" Smoothing On;"); //nly on short
if (opts->floating_point == 1) printw (" Floating Point;");
@ -2839,17 +2839,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
attron(COLOR_PAIR(3));
}
//REMUS! THIS IS THE OLD ONE
// printw ("FID: [%02X] SVC: [%02X] ", state->dmr_fid, state->dmr_so);
//This is the new one
printw ("%s | ", state->call_string[0]);
printw ("%s ", DMRBusrtTypes[state->dmrburstL]);
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //
// if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21)) printw ("*M*");
// //
// #endif
if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21)) printw ("*M*");
printw ("\n");
@ -3043,16 +3037,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
attron(COLOR_PAIR(3));
}
//REMUS! THIS IS THE OLD ONE
// printw ("FID: [%02X] SVC: [%02X] ", state->dmr_fidR, state->dmr_soR);
//THIS IS THE NEW ONE
printw ("%s | ", state->call_string[1]);
printw ("%s ", DMRBusrtTypes[state->dmrburstR]);
// #ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
// //
// if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21) ) printw ("*M*");
// //
// #endif
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21) ) printw ("*M*");
printw ("\n");
printw ("| V XTRA | "); //10 spaces

View File

@ -92,7 +92,7 @@ void nxdn_voice (dsd_opts * opts, dsd_state * state, int voice, uint8_t dbuf[182
memcpy (state->f_l, state->audio_out_temp_buf, sizeof(state->f_l));
if (opts->floating_point == 0)
if (opts->floating_point == 0 )
playSynthesizedVoice(opts, state);
if (opts->floating_point == 1)
playSynthesizedVoiceFM(opts, state);