21 #include "../../SDL_internal.h" 23 #if SDL_AUDIO_DRIVER_NAS 33 #include "../SDL_audiomem.h" 34 #include "../SDL_audio_c.h" 40 static void (*NAS_AuCloseServer) (AuServer *);
41 static void (*NAS_AuNextEvent) (AuServer *, AuBool, AuEvent *);
42 static AuBool(*NAS_AuDispatchEvent) (AuServer *, AuEvent *);
43 static AuFlowID(*NAS_AuCreateFlow) (AuServer *, AuStatus *);
44 static void (*NAS_AuStartFlow) (AuServer *, AuFlowID, AuStatus *);
45 static void (*NAS_AuSetElements)
46 (AuServer *, AuFlowID, AuBool, int, AuElement *, AuStatus *);
47 static void (*NAS_AuWriteElement)
48 (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuBool, AuStatus *);
49 static AuServer *(*NAS_AuOpenServer)
50 (_AuConst
char *, int, _AuConst
char *, int, _AuConst
char *,
char **);
51 static AuEventHandlerRec *(*NAS_AuRegisterEventHandler)
52 (AuServer *, AuMask, int, AuID, AuEventHandlerCallback, AuPointer);
55 #ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC 57 static const char *nas_library = SDL_AUDIO_DRIVER_NAS_DYNAMIC;
58 static void *nas_handle =
NULL;
61 load_nas_sym(
const char *fn,
void **
addr)
71 #define SDL_NAS_SYM(x) \ 72 if (!load_nas_sym(#x, (void **) (char *) &NAS_##x)) return -1 74 #define SDL_NAS_SYM(x) NAS_##x = x 80 SDL_NAS_SYM(AuCloseServer);
81 SDL_NAS_SYM(AuNextEvent);
82 SDL_NAS_SYM(AuDispatchEvent);
83 SDL_NAS_SYM(AuCreateFlow);
84 SDL_NAS_SYM(AuStartFlow);
85 SDL_NAS_SYM(AuSetElements);
86 SDL_NAS_SYM(AuWriteElement);
87 SDL_NAS_SYM(AuOpenServer);
88 SDL_NAS_SYM(AuRegisterEventHandler);
94 #ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC 97 UnloadNASLibrary(
void)
99 if (nas_handle !=
NULL) {
109 if (nas_handle ==
NULL) {
111 if (nas_handle ==
NULL) {
115 char *err = (
char *) alloca(len);
121 retval = load_nas_syms();
133 UnloadNASLibrary(
void)
148 NAS_WaitDevice(
_THIS)
150 while (this->hidden->buf_free < this->hidden->mixlen) {
152 NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev);
153 NAS_AuDispatchEvent(this->hidden->aud, &ev);
158 NAS_PlayDevice(
_THIS)
160 while (this->hidden->mixlen > this->hidden->buf_free) {
167 NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev);
168 NAS_AuDispatchEvent(this->hidden->aud, &ev);
170 this->hidden->buf_free -= this->hidden->mixlen;
173 NAS_AuWriteElement(this->hidden->aud, this->hidden->flow, 0,
174 this->hidden->mixlen, this->hidden->mixbuf, AuFalse,
177 this->hidden->written += this->hidden->mixlen;
180 fprintf(stderr,
"Wrote %d bytes of audio data\n", this->hidden->mixlen);
185 NAS_GetDeviceBuf(
_THIS)
187 return (this->hidden->mixbuf);
191 NAS_CloseDevice(
_THIS)
193 if (this->hidden !=
NULL) {
195 this->hidden->mixbuf =
NULL;
196 if (this->hidden->aud) {
197 NAS_AuCloseServer(this->hidden->aud);
198 this->hidden->aud = 0;
201 this2 = this->hidden =
NULL;
206 sdlformat_to_auformat(
unsigned int fmt)
210 return AuFormatLinearUnsigned8;
212 return AuFormatLinearSigned8;
214 return AuFormatLinearUnsigned16LSB;
216 return AuFormatLinearUnsigned16MSB;
218 return AuFormatLinearSigned16LSB;
220 return AuFormatLinearSigned16MSB;
226 event_handler(AuServer *
aud, AuEvent * ev, AuEventHandlerRec * hnd)
229 case AuEventTypeElementNotify:
231 AuElementNotifyEvent *
event = (AuElementNotifyEvent *) ev;
233 switch (
event->kind) {
234 case AuElementNotifyKindLowWater:
236 this2->
really +=
event->num_bytes;
237 gettimeofday(&this2->
last_tv, 0);
238 this2->
buf_free +=
event->num_bytes;
243 case AuElementNotifyKindState:
244 switch (
event->cur_state) {
246 if (
event->reason != AuReasonUser) {
248 this2->
really +=
event->num_bytes;
249 gettimeofday(&this2->
last_tv, 0);
250 this2->
buf_free +=
event->num_bytes;
264 find_device(
_THIS,
int nch)
268 for (i = 0; i < AuServerNumDevices(this->hidden->aud); i++) {
269 if ((AuDeviceKind(AuServerDevice(this->hidden->aud, i)) ==
270 AuComponentKindPhysicalOutput) &&
271 AuDeviceNumTracks(AuServerDevice(this->hidden->aud, i)) == nch) {
272 return AuDeviceIdentifier(AuServerDevice(this->hidden->aud, i));
279 NAS_OpenDevice(
_THIS,
void *handle,
const char *devname,
int iscapture)
288 if (this->hidden ==
NULL) {
291 SDL_memset(this->hidden, 0, (
sizeof *this->hidden));
296 !format && test_format;) {
297 format = sdlformat_to_auformat(test_format);
298 if (format == AuNone) {
303 NAS_CloseDevice(
this);
304 return SDL_SetError(
"NAS: Couldn't find any hardware audio formats");
308 this->hidden->aud = NAS_AuOpenServer(
"", 0,
NULL, 0,
NULL,
NULL);
309 if (this->hidden->aud == 0) {
310 NAS_CloseDevice(
this);
311 return SDL_SetError(
"NAS: Couldn't open connection to NAS server");
314 this->hidden->dev = find_device(
this, this->
spec.
channels);
315 if ((this->hidden->dev == AuNone)
316 || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, 0)))) {
317 NAS_CloseDevice(
this);
318 return SDL_SetError(
"NAS: Couldn't find a fitting device on NAS server");
322 if (buffer_size < 4096)
325 if (buffer_size > 32768)
331 this2 = this->hidden;
333 AuMakeElementImportClient(elms, this->
spec.
freq, format,
334 this->spec.channels, AuTrue, buffer_size,
335 buffer_size / 4, 0,
NULL);
336 AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq,
337 AuUnlimitedSamples, 0,
NULL);
338 NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, 2, elms,
340 NAS_AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0,
341 this->hidden->flow, event_handler,
344 NAS_AuStartFlow(this->hidden->aud, this->hidden->flow,
NULL);
347 this->hidden->mixlen = this->
spec.
size;
349 if (this->hidden->mixbuf ==
NULL) {
350 NAS_CloseDevice(
this);
353 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
360 NAS_Deinitialize(
void)
368 if (LoadNASLibrary() < 0) {
371 AuServer *aud = NAS_AuOpenServer(
"", 0,
NULL, 0,
NULL,
NULL);
373 SDL_SetError(
"NAS: AuOpenServer() failed (no audio server?)");
376 NAS_AuCloseServer(aud);
392 "nas",
"Network Audio System", NAS_Init, 0
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
void(* PlayDevice)(_THIS)
void(* WaitDevice)(_THIS)
Uint16 SDL_AudioFormat
Audio format flags.
SDL_AudioFormat SDL_NextAudioFormat(void)
int OnlyHasDefaultOutputDevice
uint8_t Uint8
An unsigned 8-bit integer type.
void(* Deinitialize)(void)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
#define SDL_AllocAudioMem
AudioBootStrap NAS_bootstrap
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
#define SDL_OutOfMemory()
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
void(* CloseDevice)(_THIS)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Uint8 *(* GetDeviceBuf)(_THIS)
void * SDL_LoadFunction(void *handle, const char *name)