diff --git a/include/dsd.h b/include/dsd.h index a8a2272..decdfa0 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -891,6 +891,7 @@ void processAudio (dsd_opts * opts, dsd_state * state); void processAudioR (dsd_opts * opts, dsd_state * state); void openPulseInput (dsd_opts * opts); void openPulseOutput (dsd_opts * opts); +void openOSSOutput (dsd_opts * opts); void closePulseInput (dsd_opts * opts); void closePulseOutput (dsd_opts * opts); void writeSynthesizedVoice (dsd_opts * opts, dsd_state * state); diff --git a/src/dsd_audio.c b/src/dsd_audio.c index c2cb7c7..7008848 100644 --- a/src/dsd_audio.c +++ b/src/dsd_audio.c @@ -85,6 +85,117 @@ void openPulseInput(dsd_opts * opts) } +void openOSSOutput (dsd_opts * opts) +{ + int fmt; + int speed = 48000; + if (opts->audio_in_type == 5) //if((strncmp(opts->audio_in_dev, "/dev/dsp", 8) == 0)) or 'split' == 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_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; + } + } + + if (opts->audio_in_type != 5) //split == 1 + { + + 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); + } + + //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. + + 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 to mirror pulse rate out + 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 if (opts->frame_m17 == 1) + opts->audio_out_type = 2; + 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); + } + } +} + void processAudio (dsd_opts * opts, dsd_state * state) { diff --git a/src/dsd_audio2.c b/src/dsd_audio2.c index c5f84c3..cdf3f3a 100644 --- a/src/dsd_audio2.c +++ b/src/dsd_audio2.c @@ -11,8 +11,8 @@ #include "dsd.h" -//TODO: Test All voice decoders with all combos 'short mono, short stereo, float mono, float stereo) -//TODO: Clean comments and unused code in here +//TODO: Test All voice decoders with all combos (short mono, short stereo, float mono, float stereo) +//TODO: Need Method To Dynamically Close and Open any OSS instances when changing decoding classes from Ncurses Menu (particularly rate and/or channel configs) //CHECKLIST(PULSE): DMR BS(OK) DMR MS (OK) P25p1 (OK) P25p2 (OK) YSF (OK) NXDN (OK) M17 (short only!) pV (OK) dPMR (OK) MBEplayback (OK) X2-TDMA (who cares lol) D-STAR (WIP) //TODO: WAV File saving (works fine on shorts, but on float, writing short to wav is not auto-gained, diff --git a/src/dsd_main.c b/src/dsd_main.c index a8f7673..08f3094 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -2703,111 +2703,9 @@ main (int argc, char **argv) fprintf (stderr, "Switching to /dev/dsp.\n"); } - if (opts.audio_in_type == 5) //if((strncmp(opts.audio_in_dev, "/dev/dsp", 8) == 0)) or 'split' == 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_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; - } - } - - if (opts.audio_in_type != 5) //split == 1 - { - - 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); - } - - //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. - - 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 if (opts.frame_m17 == 1) - opts.audio_out_type = 2; - 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); - } - } + //this will only open OSS output if its listed as a type + //changed to this so I could call it freely inside of ncurses terminal + openOSSOutput(&opts); if (opts.playfiles == 1) //redo? { diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index 32f99ff..ac88201 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -464,6 +464,12 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) closePulseOutput (opts); } + //close OSS output + if (opts->audio_out_type == 2 || opts->audio_out_type == 5) + { + close (opts->audio_out_fd); + } + if (opts->audio_in_type == 0) //close pulse input if it is the specified input method { closePulseInput(opts); @@ -1271,7 +1277,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 0; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 48000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 1; opts->frame_dstar = 0; opts->frame_x2tdma = 0; @@ -1300,7 +1306,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 0; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 48000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 1; opts->frame_dstar = 1; opts->frame_x2tdma = 0; @@ -1340,7 +1346,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 0; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 48000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 1; opts->frame_dstar = 0; opts->frame_x2tdma = 0; @@ -1378,7 +1384,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 1; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 24000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 2; opts->frame_dstar = 0; opts->frame_x2tdma = 0; @@ -1405,7 +1411,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 1; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 24000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 2; opts->frame_dmr = 0; opts->frame_dstar = 0; @@ -1434,7 +1440,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 0; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 48000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 1; opts->frame_dstar = 0; opts->frame_x2tdma = 0; @@ -1465,7 +1471,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 0; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 48000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 1; opts->frame_dstar = 0; opts->frame_x2tdma = 0; @@ -1493,7 +1499,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 0; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 48000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 1; opts->frame_dstar = 0; opts->frame_x2tdma = 0; @@ -1522,7 +1528,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 1; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 24000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 2; opts->frame_dstar = 0; opts->frame_x2tdma = 0; @@ -1550,7 +1556,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) opts->dmr_mono = 0; opts->dmr_stereo = 0; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling - opts->pulse_digi_rate_out = 48000; + opts->pulse_digi_rate_out = 8000; opts->pulse_digi_out_channels = 1; opts->frame_dstar = 0; opts->frame_x2tdma = 0; @@ -1792,6 +1798,11 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) { openPulseOutput (opts); } + + if (opts->audio_out_type == 2 || opts->audio_out_type == 5) + { + openOSSOutput (opts); + } if (opts->audio_in_type == 0) //reopen pulse input if it is the specified input method