You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

113 lines
2.4 KiB

/*
* Copyright (c) 2009 Thomas Pfaff <tpfaff@tp76.info>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sndio.h>
#include "sound.h"
static struct sio_hdl *hdl;
static int init(struct options *options)
{
struct sio_par par, askpar;
hdl = sio_open(NULL, SIO_PLAY, 0);
if (hdl == NULL) {
fprintf(stderr, "%s: failed to open audio device\n", __func__);
return -1;
}
sio_initpar(&par);
par.pchan = options->format & XMP_FORMAT_MONO ? 1 : 2;
par.rate = options->rate;
par.le = SIO_LE_NATIVE;
par.appbufsz = par.rate / 4;
if (options->format & XMP_FORMAT_8BIT) {
par.bits = 8;
par.sig = 0;
options->format |= XMP_FORMAT_UNSIGNED;
} else {
par.bits = 16;
par.sig = 1;
options->format &= ~XMP_FORMAT_UNSIGNED;
}
askpar = par;
if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
fprintf(stderr, "%s: failed to set parameters\n", __func__);
goto error;
}
if ((par.bits == 16 && par.le != askpar.le) ||
par.bits != askpar.bits ||
par.sig != askpar.sig ||
par.pchan != askpar.pchan ||
((par.rate * 1000 < askpar.rate * 995) ||
(par.rate * 1000 > askpar.rate * 1005))) {
fprintf(stderr, "%s: parameters not supported\n", __func__);
goto error;
}
if (!sio_start(hdl)) {
fprintf(stderr, "%s: failed to start audio device\n", __func__);
goto error;
}
return 0;
error:
sio_close(hdl);
return -1;
}
static void deinit(void)
{
sio_close(hdl);
hdl = NULL;
}
static void play(void *buf, int len)
{
if (buf != NULL) {
sio_write(hdl, buf, len);
}
}
static void flush(void)
{
}
static void onpause(void)
{
}
static void onresume(void)
{
}
struct sound_driver sound_sndio = {
"sndio",
"OpenBSD sndio",
NULL,
init,
deinit,
play,
flush,
onpause,
onresume
};