Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Moved NAS audio driver to 1.3 API.

  • Loading branch information
icculus committed Oct 7, 2006
1 parent 7970e95 commit b42b8d33ef3bdb165e039e34f7199c21728572ec
Showing with 75 additions and 98 deletions.
  1. +74 −95 src/audio/nas/SDL_nasaudio.c
  2. +1 −3 src/audio/nas/SDL_nasaudio.h
@@ -36,22 +36,15 @@
#include "../SDL_audio_c.h"
#include "SDL_nasaudio.h"

/* The tag name used by artsc audio */
/* The tag name used by nas audio */
#define NAS_DRIVER_NAME "nas"

static struct SDL_PrivateAudioData *this2 = NULL;

/* Audio driver functions */
static int NAS_OpenAudio(_THIS, SDL_AudioSpec * spec);
static void NAS_WaitAudio(_THIS);
static void NAS_PlayAudio(_THIS);
static Uint8 *NAS_GetAudioBuf(_THIS);
static void NAS_CloseAudio(_THIS);

/* Audio driver bootstrap functions */
/* !!! FIXME: dynamic loading? */

static int
Audio_Available(void)
NAS_Available(void)
{
AuServer *aud = AuOpenServer("", 0, NULL, 0, NULL, NULL);
if (!aud)
@@ -61,54 +54,9 @@ Audio_Available(void)
return 1;
}

static void
Audio_DeleteDevice(SDL_AudioDevice * device)
{
SDL_free(device->hidden);
SDL_free(device);
}

static SDL_AudioDevice *
Audio_CreateDevice(int devindex)
{
SDL_AudioDevice *this;

/* Initialize all variables that we clean on shutdown */
this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
if (this) {
SDL_memset(this, 0, (sizeof *this));
this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc((sizeof *this->hidden));
}
if ((this == NULL) || (this->hidden == NULL)) {
SDL_OutOfMemory();
if (this) {
SDL_free(this);
}
return (0);
}
SDL_memset(this->hidden, 0, (sizeof *this->hidden));

/* Set the function pointers */
this->OpenAudio = NAS_OpenAudio;
this->WaitAudio = NAS_WaitAudio;
this->PlayAudio = NAS_PlayAudio;
this->GetAudioBuf = NAS_GetAudioBuf;
this->CloseAudio = NAS_CloseAudio;

this->free = Audio_DeleteDevice;

return this;
}

AudioBootStrap NAS_bootstrap = {
NAS_DRIVER_NAME, "Network Audio System",
Audio_Available, Audio_CreateDevice, 0
};

/* This function waits until it is possible to write a full sound buffer */
static void
NAS_WaitAudio(_THIS)
NAS_WaitDevice(_THIS)
{
while (this->hidden->buf_free < this->hidden->mixlen) {
AuEvent ev;
@@ -118,11 +66,14 @@ NAS_WaitAudio(_THIS)
}

static void
NAS_PlayAudio(_THIS)
NAS_PlayDevice(_THIS)
{
while (this->hidden->mixlen > this->hidden->buf_free) { /* We think the buffer is full? Yikes! Ask the server for events,
in the hope that some of them is LowWater events telling us more
of the buffer is free now than what we think. */
while (this->hidden->mixlen > this->hidden->buf_free) {
/*
* We think the buffer is full? Yikes! Ask the server for events,
* in the hope that some of them is LowWater events telling us more
* of the buffer is free now than what we think.
*/
AuEvent ev;
AuNextEvent(this->hidden->aud, AuTrue, &ev);
AuDispatchEvent(this->hidden->aud, &ev);
@@ -141,21 +92,25 @@ NAS_PlayAudio(_THIS)
}

static Uint8 *
NAS_GetAudioBuf(_THIS)
NAS_GetDeviceBuf(_THIS)
{
return (this->hidden->mixbuf);
}

static void
NAS_CloseAudio(_THIS)
NAS_CloseDevice(_THIS)
{
if (this->hidden->mixbuf != NULL) {
SDL_FreeAudioMem(this->hidden->mixbuf);
this->hidden->mixbuf = NULL;
}
if (this->hidden->aud) {
AuCloseServer(this->hidden->aud);
this->hidden->aud = 0;
if (this->hidden != NULL) {
if (this->hidden->mixbuf != NULL) {
SDL_FreeAudioMem(this->hidden->mixbuf);
this->hidden->mixbuf = NULL;
}
if (this->hidden->aud) {
AuCloseServer(this->hidden->aud);
this->hidden->aud = 0;
}
SDL_free(this->hidden);
this->hidden = NULL;
}
}

@@ -232,82 +187,106 @@ find_device(_THIS, int nch)
}

static int
NAS_OpenAudio(_THIS, SDL_AudioSpec * spec)
NAS_OpenDevice(_THIS, const char *devname, int iscapture)
{
AuElement elms[3];
int buffer_size;
SDL_AudioFormat test_format, format;

this->hidden->mixbuf = NULL;
/* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc((sizeof *this->hidden));
if (this->hidden == NULL) {
SDL_OutOfMemory();
return 0;
}
SDL_memset(this->hidden, 0, (sizeof *this->hidden));

/* Try for a closest match on audio format */
format = 0;
for (test_format = SDL_FirstAudioFormat(spec->format);
for (test_format = SDL_FirstAudioFormat(this->spec.format);
!format && test_format;) {
format = sdlformat_to_auformat(test_format);

if (format == AuNone) {
test_format = SDL_NextAudioFormat();
}
}
if (format == 0) {
SDL_SetError("Couldn't find any hardware audio formats");
return (-1);
NAS_CloseDevice(this);
SDL_SetError("NAS: Couldn't find any hardware audio formats");
return 0;
}
spec->format = test_format;
this->spec.format = test_format;

this->hidden->aud = AuOpenServer("", 0, NULL, 0, NULL, NULL);
if (this->hidden->aud == 0) {
SDL_SetError("Couldn't open connection to NAS server");
return (-1);
NAS_CloseDevice(this);
SDL_SetError("NAS: Couldn't open connection to NAS server");
return 0;
}

this->hidden->dev = find_device(this, spec->channels);
this->hidden->dev = find_device(this, this->spec.channels);
if ((this->hidden->dev == AuNone)
|| (!(this->hidden->flow = AuCreateFlow(this->hidden->aud, NULL)))) {
AuCloseServer(this->hidden->aud);
this->hidden->aud = 0;
SDL_SetError("Couldn't find a fitting playback device on NAS server");
return (-1);
NAS_CloseDevice(this);
SDL_SetError("NAS: Couldn't find a fitting device on NAS server");
return 0;
}

buffer_size = spec->freq;
buffer_size = this->spec.freq;
if (buffer_size < 4096)
buffer_size = 4096;

if (buffer_size > 32768)
buffer_size = 32768; /* So that the buffer won't get unmanageably big. */

/* Calculate the final parameters for this audio specification */
SDL_CalculateAudioSpec(spec);
SDL_CalculateAudioSpec(&this->spec);

this2 = this->hidden;

AuMakeElementImportClient(elms, spec->freq, format, spec->channels,
AuMakeElementImportClient(elms,this->spec.freq,format,this->spec.channels,
AuTrue, buffer_size, buffer_size / 4, 0, NULL);
AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, spec->freq,
AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq,
AuUnlimitedSamples, 0, NULL);
AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, 2, elms,
NULL);
AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, 2, elms, NULL);
AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0,
this->hidden->flow, event_handler,
(AuPointer) NULL);

AuStartFlow(this->hidden->aud, this->hidden->flow, NULL);

/* Allocate mixing buffer */
this->hidden->mixlen = spec->size;
this->hidden->mixlen = this->spec.size;
this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
if (this->hidden->mixbuf == NULL) {
NAS_CloseDevice(this);
SDL_OutOfMemory();
return (-1);
}
SDL_memset(this->hidden->mixbuf, spec->silence, spec->size);

/* Get the parent process id (we're the parent of the audio thread) */
this->hidden->parent = getpid();
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);

/* We're ready to rock and roll. :-) */
return (0);
return 1;
}

static int
NAS_Init(SDL_AudioDriverImpl *impl)
{
/* Set the function pointers */
impl->OpenDevice = NAS_OpenDevice;
impl->PlayDevice = NAS_PlayDevice;
impl->WaitDevice = NAS_WaitDevice;
impl->GetDeviceBuf = NAS_GetDeviceBuf;
impl->CloseDevice = NAS_CloseDevice;
impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this true? */

return 1;
}

AudioBootStrap NAS_bootstrap = {
NAS_DRIVER_NAME, "Network Audio System",
NAS_Available, NAS_Init, 0
};

/* vi: set ts=4 sw=4 expandtab: */
@@ -46,9 +46,6 @@ struct SDL_PrivateAudioData
AuFlowID flow;
AuDeviceID dev;

/* The parent process id, to detect when application quits */
pid_t parent;

/* Raw mixing buffer */
Uint8 *mixbuf;
int mixlen;
@@ -60,4 +57,5 @@ struct SDL_PrivateAudioData
int buf_free;
};
#endif /* _SDL_nasaudio_h */

/* vi: set ts=4 sw=4 expandtab: */

0 comments on commit b42b8d3

Please sign in to comment.