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,