e1c97ab582
- regen patches
262 lines
6.9 KiB
Plaintext
262 lines
6.9 KiB
Plaintext
$OpenBSD: patch-libogleao_obsd_audio_c,v 1.3 2009/12/09 10:19:33 jakemsr Exp $
|
|
--- libogleao/obsd_audio.c.orig Sat Feb 22 07:06:51 2003
|
|
+++ libogleao/obsd_audio.c Wed Oct 28 11:48:59 2009
|
|
@@ -18,45 +18,54 @@
|
|
|
|
#ifdef LIBOGLEAO_OBSD
|
|
|
|
+#include <errno.h>
|
|
+#include <poll.h>
|
|
+#include <sndio.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
-#include <sys/ioctl.h>
|
|
+#include <string.h>
|
|
#include <unistd.h>
|
|
-#include <inttypes.h>
|
|
|
|
-#include <fcntl.h>
|
|
-#include <sys/audioio.h>
|
|
-
|
|
-#include <sys/types.h>
|
|
-#include <sys/conf.h>
|
|
-
|
|
-#include <string.h>
|
|
-
|
|
#include "ogle_ao.h"
|
|
#include "ogle_ao_private.h"
|
|
|
|
typedef struct obsd_instance_s {
|
|
ogle_ao_instance_t ao;
|
|
- int fd;
|
|
+ struct sio_hdl *hdl;
|
|
int sample_rate;
|
|
int samples_written;
|
|
+ int samples_played;
|
|
int sample_frame_size;
|
|
int initialized;
|
|
+ int started;
|
|
} obsd_instance_t;
|
|
|
|
+static
|
|
+void obsd_onmove(void *addr, int delta)
|
|
+{
|
|
+ obsd_instance_t *instance = (obsd_instance_t *)addr;
|
|
+ instance->samples_played += delta;
|
|
+}
|
|
|
|
static
|
|
int obsd_init(ogle_ao_instance_t *_instance,
|
|
ogle_ao_audio_info_t *audio_info)
|
|
{
|
|
- int single_sample_size;
|
|
- audio_info_t info;
|
|
obsd_instance_t *instance = (obsd_instance_t *)_instance;
|
|
-
|
|
- AUDIO_INITINFO(&info);
|
|
- info.play.sample_rate = audio_info->sample_rate;
|
|
- info.play.precision = audio_info->sample_resolution;
|
|
+ struct sio_par par, askpar;
|
|
+ int single_sample_size;
|
|
+ int reinit;
|
|
|
|
+ reinit = 0;
|
|
+ if (instance->started == 1) {
|
|
+ reinit = 1;
|
|
+ if (!sio_stop(instance->hdl)) {
|
|
+ fprintf(stderr, "sio_stop failed\n");
|
|
+ return -1;
|
|
+ }
|
|
+ instance->started = 0;
|
|
+ }
|
|
+
|
|
if(audio_info->chtypes != OGLE_AO_CHTYPE_UNSPECIFIED) {
|
|
// do this only if we have requested specific channels in chtypes
|
|
// otherwise trust the nr channels
|
|
@@ -69,40 +78,57 @@ int obsd_init(ogle_ao_instance_t *_instance,
|
|
}
|
|
audio_info->chlist = NULL;
|
|
|
|
- info.play.channels = audio_info->channels;
|
|
- info.lowat = 5;
|
|
- switch(audio_info->encoding) {
|
|
- case OGLE_AO_ENCODING_LINEAR:
|
|
- default:
|
|
- info.play.encoding = AUDIO_ENCODING_LINEAR;
|
|
- break;
|
|
+ sio_initpar(&par);
|
|
+
|
|
+ par.bits = audio_info->sample_resolution;
|
|
+ par.sig = 1;
|
|
+ par.le = 1;
|
|
+ par.pchan = audio_info->channels;
|
|
+ par.rate = audio_info->sample_rate;
|
|
+ par.appbufsz = par.rate / 4;
|
|
+
|
|
+ askpar = par;
|
|
+
|
|
+ if (!sio_setpar(instance->hdl, &par)) {
|
|
+ fprintf(stderr, "sio_setpar failed\n");
|
|
+ return -1;
|
|
}
|
|
-
|
|
- /* set the audio format */
|
|
- if(ioctl(instance->fd, AUDIO_SETINFO, &info) == -1) {
|
|
- perror("setinfo");
|
|
+ if (!sio_getpar(instance->hdl, &par)) {
|
|
+ fprintf(stderr, "sio_getpar failed\n");
|
|
return -1;
|
|
}
|
|
-
|
|
- /* Check that we actually got the requested nuber of channles,
|
|
- * the frequency and precision that we asked for? */
|
|
+ if (par.pchan != askpar.pchan ||
|
|
+ par.bits != askpar.bits ||
|
|
+ (par.rate * 100 > askpar.rate * 105 || par.rate * 100 < askpar.rate * 95)) {
|
|
+ fprintf(stderr, "could not configure audio device as desired\n");
|
|
+ return -1;
|
|
+ }
|
|
|
|
if(audio_info->chtypes != OGLE_AO_CHTYPE_UNSPECIFIED) {
|
|
- audio_info->chlist = malloc(info.play.channels * sizeof(ogle_ao_chtype_t));
|
|
+ audio_info->chlist = malloc(par.pchan * sizeof(ogle_ao_chtype_t));
|
|
|
|
audio_info->chlist[0] = OGLE_AO_CHTYPE_LEFT;
|
|
audio_info->chlist[1] = OGLE_AO_CHTYPE_RIGHT;
|
|
}
|
|
|
|
- /* Stored as 8bit, 16bit, or 32bit */
|
|
- single_sample_size = (info.play.precision + 7) / 8;
|
|
- if(single_sample_size > 2) {
|
|
- single_sample_size = 4;
|
|
+ single_sample_size = par.bps;
|
|
+ instance->sample_frame_size = single_sample_size * par.pchan;
|
|
+ instance->sample_rate = par.rate;
|
|
+
|
|
+ if (!reinit)
|
|
+ sio_onmove(instance->hdl, obsd_onmove, instance);
|
|
+ instance->samples_played = 0;
|
|
+ instance->samples_written = 0;
|
|
+
|
|
+ if (!sio_start(instance->hdl)) {
|
|
+ fprintf(stderr, "sio_start failed\n");
|
|
+ return -1;
|
|
}
|
|
- instance->sample_frame_size = single_sample_size*info.play.channels;
|
|
+ instance->started = 1;
|
|
+
|
|
+ audio_info->sample_frame_size = instance->sample_frame_size;
|
|
instance->initialized = 1;
|
|
|
|
- audio_info->sample_frame_size = instance->sample_frame_size;
|
|
return 0;
|
|
}
|
|
|
|
@@ -112,9 +138,9 @@ int obsd_play(ogle_ao_instance_t *_instance, void *sam
|
|
obsd_instance_t *instance = (obsd_instance_t *)_instance;
|
|
int written;
|
|
|
|
- written = write(instance->fd, samples, nbyte);
|
|
- if(written == -1) {
|
|
- perror("audio write");
|
|
+ written = sio_write(instance->hdl, samples, nbyte);
|
|
+ if(written != nbyte) {
|
|
+ fprintf(stderr, "sio_write failed\n");
|
|
return -1;
|
|
}
|
|
|
|
@@ -126,15 +152,20 @@ static
|
|
int obsd_odelay(ogle_ao_instance_t *_instance, uint32_t *samples_return)
|
|
{
|
|
obsd_instance_t *instance = (obsd_instance_t *)_instance;
|
|
- audio_info_t info;
|
|
+ struct pollfd pfd;
|
|
+ int revents, n;
|
|
int odelay;
|
|
|
|
- if (ioctl(instance->fd, AUDIO_GETINFO, &info) == -1) {
|
|
- perror("AUDIO_GETINFO");
|
|
- return -1;
|
|
- }
|
|
+ // update counters
|
|
+ n = sio_pollfd(instance->hdl, &pfd, POLLOUT);
|
|
+ while(poll(&pfd, n, 0) < 0 && errno == EINTR)
|
|
+ ;
|
|
+ revents = sio_revents(instance->hdl, &pfd);
|
|
|
|
- odelay = info.play.seek / instance->sample_frame_size;
|
|
+ odelay = instance->samples_written - instance->samples_played;
|
|
+
|
|
+ if (odelay < 0)
|
|
+ odelay = 0;
|
|
*samples_return = odelay;
|
|
|
|
return 0;
|
|
@@ -145,31 +176,18 @@ void obsd_close(ogle_ao_instance_t *_instance)
|
|
{
|
|
obsd_instance_t *instance = (obsd_instance_t *)_instance;
|
|
|
|
- close(instance->fd);
|
|
+ sio_close(instance->hdl);
|
|
}
|
|
|
|
static
|
|
-int obsd_flush(ogle_ao_instance_t *_instance)
|
|
+int obsd_drain(ogle_ao_instance_t *_instance)
|
|
{
|
|
- obsd_instance_t *instance = (obsd_instance_t *)_instance;
|
|
-
|
|
- fprintf(stderr, "AUDIO_FLUSH called\n");
|
|
- ioctl(instance->fd, AUDIO_FLUSH, NULL);
|
|
-
|
|
- instance->samples_written = 0;
|
|
-
|
|
- ioctl(instance->fd, AUDIO_DRAIN, 0);
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
static
|
|
-int obsd_drain(ogle_ao_instance_t *_instance)
|
|
+int obsd_flush(ogle_ao_instance_t *_instance)
|
|
{
|
|
- obsd_instance_t *instance = (obsd_instance_t *)_instance;
|
|
-
|
|
- ioctl(instance->fd, AUDIO_DRAIN, 0);
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -184,22 +202,28 @@ ogle_ao_instance_t *obsd_open(char *dev)
|
|
|
|
instance->ao.init = obsd_init;
|
|
instance->ao.play = obsd_play;
|
|
- instance->ao.close = obsd_close;
|
|
instance->ao.odelay = obsd_odelay;
|
|
instance->ao.flush = obsd_flush;
|
|
instance->ao.drain = obsd_drain;
|
|
+ instance->ao.close = obsd_close;
|
|
|
|
instance->initialized = 0;
|
|
instance->sample_rate = 0;
|
|
instance->samples_written = 0;
|
|
+ instance->samples_played = 0;
|
|
instance->sample_frame_size = 0;
|
|
+
|
|
+ if(strncmp(dev, "ao_obsd_default", 15) == 0)
|
|
+ instance->hdl = sio_open(NULL, SIO_PLAY, 0);
|
|
+ else
|
|
+ instance->hdl = sio_open(dev, SIO_PLAY, 0);
|
|
|
|
- instance->fd = open(dev, O_WRONLY);
|
|
- if(instance->fd < 0) {
|
|
+ if(instance->hdl == NULL) {
|
|
fprintf(stderr, "Can not open %s\n", dev);
|
|
free(instance);
|
|
return NULL;
|
|
}
|
|
+ instance->started = 0;
|
|
|
|
return (ogle_ao_instance_t *)instance;
|
|
}
|