summaryrefslogtreecommitdiff
path: root/plugins/oss
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2010-11-28 18:38:20 +0100
committerGravatar waker <wakeroid@gmail.com>2010-11-28 18:38:20 +0100
commit81776338c82b82f86f0837f2ce69d43bf58b375d (patch)
tree070a04f6478b37f68ea65cd58f7ad86c48136107 /plugins/oss
parent0c23a5d82d6f37c29dcbd65d0a4ce40c7abeb998 (diff)
ported OSS plugin to new API
Diffstat (limited to 'plugins/oss')
-rw-r--r--plugins/oss/oss.c145
1 files changed, 78 insertions, 67 deletions
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},
};