diff options
-rw-r--r-- | deadbeef.h | 1 | ||||
-rw-r--r-- | plugins/alsa/alsa.c | 5 | ||||
-rw-r--r-- | plugins/oss/oss.c | 145 | ||||
-rwxr-xr-x | scripts/configure_minimal.sh | 2 |
4 files changed, 81 insertions, 72 deletions
@@ -650,7 +650,6 @@ enum { typedef struct { int bps; int is_float; // bps must be 32 if this is true - int is_multichannel; // usually 0, in which case channels=1 is mono, and channels=2 is stereo int channels; int samplerate; uint32_t channelmask; diff --git a/plugins/alsa/alsa.c b/plugins/alsa/alsa.c index 15b8a539..755981fa 100644 --- a/plugins/alsa/alsa.c +++ b/plugins/alsa/alsa.c @@ -255,7 +255,6 @@ palsa_set_hw_params (ddb_waveformat_t *fmt) { trace ("chosen bps: %d (%s)\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int"); plugin.fmt.channels = nchan; - plugin.fmt.is_multichannel = 0; plugin.fmt.channelmask = 0; if (nchan == 1) { plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT; @@ -390,7 +389,7 @@ open_error: void palsa_setformat (ddb_waveformat_t *fmt) { memcpy (&requested_fmt, fmt, sizeof (ddb_waveformat_t)); - trace ("palsa_setformat %dbit %s %s %dch %dHz channelmask=%X\n", fmt->bps, fmt->is_float ? "float" : "int", fmt->is_multichannel ? "multichannel" : "", fmt->channels, fmt->samplerate, fmt->channelmask); + trace ("palsa_setformat %dbit %s %dch %dHz channelmask=%X\n", fmt->bps, fmt->is_float ? "float" : "int", fmt->channels, fmt->samplerate, fmt->channelmask); if (!audio) { return; } @@ -425,7 +424,7 @@ palsa_setformat (ddb_waveformat_t *fmt) { trace ("palsa_change_rate: impossible to set requested format\n"); return; } - trace ("new format %dbit %s %s %dch %dHz channelmask=%X\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int", plugin.fmt.is_multichannel ? "multichannel" : "", plugin.fmt.channels, plugin.fmt.samplerate, plugin.fmt.channelmask); + trace ("new format %dbit %s %dch %dHz channelmask=%X\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int", plugin.fmt.channels, plugin.fmt.samplerate, plugin.fmt.channelmask); } int diff --git a/plugins/oss/oss.c b/plugins/oss/oss.c index 15ed7fb2..0f837c43 100644 --- a/plugins/oss/oss.c +++ b/plugins/oss/oss.c @@ -56,70 +56,90 @@ oss_thread (void *context); static int oss_callback (char *stream, int len); -static int -oss_init (void) { - trace ("oss_init\n"); - state = OUTPUT_STATE_STOPPED; - oss_terminate = 0; - mutex = 0; - - // prepare oss for playback - const char *name = deadbeef->conf_get_str ("oss.device", "/dev/dsp"); - fd = open (name, O_WRONLY); - if (fd == -1) { - fprintf (stderr, "oss: failed to open file %s\n", name); - perror (name); - plugin.free (); - return -1; +int +oss_set_hwparams (ddb_waveformat_t *fmt) { + int samplefmt; + switch (fmt->bps) { + case 8: + samplefmt = AFMT_S8; + break; + case 16: + samplefmt = AFMT_S16_NE; + break; + default: + samplefmt = AFMT_S16_NE; + break; } - -#if OSS_VERSION>=0x040000 -/* - int cooked = 1; - ioctl (fd, SNDCTL_DSP_COOKEDMODE, &cooked); - trace ("oss: cooked_mode=%d\n", cooked); - - int policy = 3; - ioctl (fd, SNDCTL_DSP_POLICY, &policy); - trace ("oss: policy=%d\n", policy); -*/ -#endif - - int fmt = AFMT_S16_NE; - if (ioctl (fd, SNDCTL_DSP_SETFMT, &fmt) == -1) { + if (ioctl (fd, SNDCTL_DSP_SETFMT, &samplefmt) == -1) { fprintf (stderr, "oss: failed to set format\n"); perror ("SNDCTL_DSP_SETFMT"); - plugin.free (); - return -1; - } - - if (fmt != AFMT_S16_NE) { - fprintf (stderr, "oss: device doesn't support 16 bit sample format\n"); - plugin.free (); return -1; } - int channels = 2; + int channels = fmt->channels; if (ioctl (fd, SNDCTL_DSP_CHANNELS, &channels) == -1) { - fprintf (stderr, "oss: failed to set channels\n"); + if (channels != 2) { + fprintf (stderr, "oss: failed to set %d channels, trying fallback to stereo\n", fmt->channels); + channels = 2; + if (ioctl (fd, SNDCTL_DSP_CHANNELS, &channels) == -1) { + fprintf (stderr, "oss: stereo fallback failed\n"); + perror ("SNDCTL_DSP_CHANNELS"); + return -1; + } + } + else { + fprintf (stderr, "oss: failed to set %d channels\n", fmt->channels); + perror ("SNDCTL_DSP_CHANNELS"); + return -1; + } + } + int rate = fmt->samplerate; + if (ioctl (fd, SNDCTL_DSP_SPEED, &rate) == -1) { + fprintf (stderr, "oss: can't switch to %d samplerate\n", rate); perror ("SNDCTL_DSP_CHANNELS"); - plugin.free (); return -1; } - if (channels != 2) { - fprintf (stderr, "oss: device doesn't support stereo output\n"); - plugin.free (); + + plugin.fmt.samplerate = rate; + plugin.fmt.channels = channels; + switch (samplefmt) { + case AFMT_S8: + plugin.fmt.bps = 8; + break; + case AFMT_S16_LE: + case AFMT_S16_BE: + plugin.fmt.bps = 16; + break; + default: + fprintf (stderr, "oss: unsupported output format: 0x%X\n", samplefmt); return -1; } + plugin.fmt.channelmask = 0; + for (int i = 0; i < plugin.fmt.channels; i++) { + plugin.fmt.channelmask |= 1 << i; + } - if (ioctl (fd, SNDCTL_DSP_SPEED, &oss_rate) == -1) { - fprintf (stderr, "oss: failed to set samplerate\n"); - perror ("SNDCTL_DSP_CHANNELS"); + return 0; +} + +static int +oss_init (void) { + trace ("oss_init\n"); + state = OUTPUT_STATE_STOPPED; + oss_terminate = 0; + mutex = 0; + + // prepare oss for playback + const char *name = deadbeef->conf_get_str ("oss.device", "/dev/dsp"); + fd = open (name, O_WRONLY); + if (fd == -1) { + fprintf (stderr, "oss: failed to open file %s\n", name); + perror (name); plugin.free (); return -1; } - trace ("oss: samplerate: %d\n", oss_rate); + oss_set_hwparams (&plugin.fmt); mutex = deadbeef->mutex_create (); @@ -127,26 +147,20 @@ oss_init (void) { return 0; } -static int -oss_change_rate (int rate) { +static void +oss_setformat (ddb_waveformat_t *fmt) { + trace ("oss_setformat\n"); if (!fd) { - oss_rate = rate; - return oss_rate; + memcpy (&plugin.fmt, fmt, sizeof (ddb_waveformat_t)); } - if (rate == oss_rate) { - trace ("oss_change_rate %d: ignored\n", rate); - return rate; + if (!memcmp (fmt, &plugin.fmt, sizeof (ddb_waveformat_t))) { + return; } deadbeef->mutex_lock (mutex); - if (ioctl (fd, SNDCTL_DSP_SPEED, &rate) == -1) { - fprintf (stderr, "oss: can't switch to %d samplerate\n", rate); - perror ("SNDCTL_DSP_CHANNELS"); - plugin.free (); - return -1; - } - oss_rate = rate; + + oss_set_hwparams (fmt); + deadbeef->mutex_unlock (mutex); - return oss_rate; } static int @@ -311,14 +325,11 @@ static DB_output_t plugin = { .plugin.stop = oss_plugin_stop, .init = oss_init, .free = oss_free, - .change_rate = oss_change_rate, + .setformat = oss_setformat, .play = oss_play, .stop = oss_stop, .pause = oss_pause, .unpause = oss_unpause, .state = oss_get_state, - .samplerate = oss_get_rate, - .bitspersample = oss_get_bps, - .channels = oss_get_channels, - .endianness = oss_get_endianness, + .fmt = {-1}, }; diff --git a/scripts/configure_minimal.sh b/scripts/configure_minimal.sh index 7724f20a..192cfe89 100755 --- a/scripts/configure_minimal.sh +++ b/scripts/configure_minimal.sh @@ -1 +1 @@ -./configure --enable-maintainer-mode --disable-oss --disable-mms --disable-artwork --disable-lfm --disable-vfs-curl --disable-hotkeys --disable-notify --disable-shellexec +./configure --enable-maintainer-mode --disable-mms --disable-artwork --disable-lfm --disable-vfs-curl --disable-hotkeys --disable-notify --disable-shellexec |