On Fri, Jun 01, 2012 at 12:50:14AM +0600, Alexandr Shadchin wrote: > > * Simplify sndio backend > (+ fix sthen@ segfault, but resampling still does not work for him) >
Hi, The sndio backend is fine. Below are few -- mostly aesthetic -- suggestions: - the device-side buffer is par.appbufsz frames, so it's not necessary to allocate such a large buffer in deadbeef as well. For instance a single block (par.round) would be ok. - sndiod and many devices use 48kHz as default sample rate, so it could be used in .fmt.samplerate as well; but it seems this is not used by deadbeef - Setting the volume in sndiod would save few cpu cycles and allows deadbeef to update its slider whenever the volume is changed externally. -- Alexandre --- sndio.c.old Thu May 24 20:12:36 2012 +++ sndio.c Fri Jun 8 16:45:59 2012 @@ -34,6 +34,8 @@ static uintptr_t sndio_mutex; static struct sio_hdl *hdl; static size_t bufsz; static char *buf = NULL; +static unsigned int vol; +static float min_db; static int sndio_init(void); static int sndio_free(void); @@ -46,6 +48,15 @@ static void sndio_thread(void *context); static int sndio_callback(char *stream, int len); static void +vol_cb(void *unused, unsigned int newvol) +{ + if (newvol == vol) + return; + vol = newvol; + deadbeef->volume_set_db(min_db * (1 - (float)vol / SIO_MAXVOL)); +} + +static void pause_do(void) { if (!hdl) @@ -98,13 +109,15 @@ sndio_init(void) /* not support float format */ plugin.fmt.is_float = 0; - bufsz = par.bps * par.pchan * par.appbufsz; + bufsz = par.bps * par.pchan * par.round; buf = malloc(bufsz); if (!buf) { fprintf(stderr, "sndio: failed malloc buf\n"); goto error; } + min_db = deadbeef->volume_get_min_db(); + sio_onvol(hdl, vol_cb, NULL); if (!sio_start(hdl)) { fprintf(stderr, "sndio: failed to start audio device\n"); goto error; @@ -205,7 +218,7 @@ sndio_unpause(void) static void sndio_thread(void *context) { - int size, write_size; + int newvol, size, write_size; while (!sndio_terminate) { if (state != OUTPUT_STATE_PLAYING || @@ -216,6 +229,11 @@ sndio_thread(void *context) write_size = 0; deadbeef->mutex_lock(sndio_mutex); + newvol = (1 - deadbeef->volume_get_db() / min_db) * SIO_MAXVOL; + if (newvol != vol) { + vol = newvol; + sio_setvol(hdl, vol); + } size = sndio_callback(buf, bufsz); if (size > 0) write_size = sio_write(hdl, buf, size); @@ -326,7 +344,8 @@ static DB_output_t plugin = { .pause = sndio_pause, .unpause = sndio_unpause, .state = sndio_get_state, - .fmt.samplerate = 44100, + .has_volume = 1, + .fmt.samplerate = 48000, .fmt.channels = 2, .fmt.bps = 16, .fmt.is_float = 0,