21#include "../../SDL_internal.h"
23#if SDL_AUDIO_DRIVER_NAS
33#include "../SDL_audio_c.h"
36static void (*NAS_AuCloseServer) (AuServer *);
37static void (*NAS_AuNextEvent) (AuServer *, AuBool, AuEvent *);
38static AuBool(*NAS_AuDispatchEvent) (AuServer *, AuEvent *);
39static void (*NAS_AuHandleEvents) (AuServer *);
40static AuFlowID(*NAS_AuCreateFlow) (AuServer *, AuStatus *);
41static void (*NAS_AuStartFlow) (AuServer *, AuFlowID, AuStatus *);
42static void (*NAS_AuSetElements)
43 (AuServer *, AuFlowID, AuBool, int, AuElement *, AuStatus *);
44static void (*NAS_AuWriteElement)
45 (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuBool, AuStatus *);
46static AuUint32 (*NAS_AuReadElement)
47 (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuStatus *);
48static AuServer *(*NAS_AuOpenServer)
49 (_AuConst
char *, int, _AuConst
char *, int, _AuConst
char *,
char **);
50static AuEventHandlerRec *(*NAS_AuRegisterEventHandler)
51 (AuServer *, AuMask, int, AuID, AuEventHandlerCallback, AuPointer);
54#ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC
56static const char *nas_library = SDL_AUDIO_DRIVER_NAS_DYNAMIC;
57static void *nas_handle =
NULL;
60load_nas_sym(
const char *fn,
void **
addr)
70#define SDL_NAS_SYM(x) \
71 if (!load_nas_sym(#x, (void **) (char *) &NAS_##x)) return -1
73#define SDL_NAS_SYM(x) NAS_##x = x
79 SDL_NAS_SYM(AuCloseServer);
80 SDL_NAS_SYM(AuNextEvent);
81 SDL_NAS_SYM(AuDispatchEvent);
82 SDL_NAS_SYM(AuHandleEvents);
83 SDL_NAS_SYM(AuCreateFlow);
84 SDL_NAS_SYM(AuStartFlow);
85 SDL_NAS_SYM(AuSetElements);
86 SDL_NAS_SYM(AuWriteElement);
87 SDL_NAS_SYM(AuReadElement);
88 SDL_NAS_SYM(AuOpenServer);
89 SDL_NAS_SYM(AuRegisterEventHandler);
95#ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC
100 if (nas_handle !=
NULL) {
110 if (nas_handle ==
NULL) {
112 if (nas_handle ==
NULL) {
116 char *err = (
char *) alloca(
len);
134UnloadNASLibrary(
void)
151 while (this->hidden->buf_free < this->hidden->mixlen) {
153 NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev);
154 NAS_AuDispatchEvent(this->hidden->aud, &ev);
161 while (this->hidden->mixlen > this->hidden->buf_free) {
168 NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev);
169 NAS_AuDispatchEvent(this->hidden->aud, &ev);
171 this->hidden->buf_free -= this->hidden->mixlen;
174 NAS_AuWriteElement(this->hidden->aud, this->hidden->flow, 0,
175 this->hidden->mixlen, this->hidden->mixbuf, AuFalse,
178 this->hidden->written += this->hidden->mixlen;
181 fprintf(stderr,
"Wrote %d bytes of audio data\n", this->hidden->mixlen);
186NAS_GetDeviceBuf(
_THIS)
188 return (this->hidden->mixbuf);
192NAS_CaptureFromDevice(
_THIS,
void *
buffer,
int buflen)
199 NAS_AuHandleEvents(
h->aud);
214NAS_FlushCapture(
_THIS)
223 NAS_AuHandleEvents(
h->aud);
224 br = NAS_AuReadElement(
h->aud,
h->flow, 1, sizeof (
buf),
buf,
NULL);
227 }
while ((br ==
sizeof (
buf)) && (total < this->
spec.
size));
231NAS_CloseDevice(
_THIS)
233 if (this->hidden->aud) {
234 NAS_AuCloseServer(this->hidden->aud);
241sdlformat_to_auformat(
unsigned int fmt)
245 return AuFormatLinearUnsigned8;
247 return AuFormatLinearSigned8;
249 return AuFormatLinearUnsigned16LSB;
251 return AuFormatLinearUnsigned16MSB;
253 return AuFormatLinearSigned16LSB;
255 return AuFormatLinearSigned16MSB;
261event_handler(AuServer *
aud, AuEvent * ev, AuEventHandlerRec * hnd)
270 case AuEventTypeElementNotify:
272 AuElementNotifyEvent *
event = (AuElementNotifyEvent *) ev;
274 switch (
event->kind) {
275 case AuElementNotifyKindLowWater:
276 if (
h->buf_free >= 0) {
278 gettimeofday(&
h->last_tv, 0);
279 h->buf_free +=
event->num_bytes;
281 h->buf_free =
event->num_bytes;
284 case AuElementNotifyKindState:
285 switch (
event->cur_state) {
287 if (
event->reason != AuReasonUser) {
288 if (
h->buf_free >= 0) {
289 h->really +=
event->num_bytes;
290 gettimeofday(&
h->last_tv, 0);
291 h->buf_free +=
event->num_bytes;
293 h->buf_free =
event->num_bytes;
309 const unsigned int devicekind = this->
iscapture ? AuComponentKindPhysicalInput : AuComponentKindPhysicalOutput;
310 const int numdevs = AuServerNumDevices(
h->aud);
315 for (i = 0;
i < numdevs;
i++) {
316 const AuDeviceAttributes *
dev = AuServerDevice(
h->aud,
i);
317 if ((AuDeviceKind(
dev) == devicekind) && (AuDeviceNumTracks(
dev) == nch)) {
318 return AuDeviceIdentifier(
dev);
323 for (
i = 0;
i < numdevs;
i++) {
324 const AuDeviceAttributes *
dev = AuServerDevice(
h->aud,
i);
325 if (AuDeviceKind(
dev) == devicekind) {
327 return AuDeviceIdentifier(
dev);
343 if (this->hidden ==
NULL) {
351 !format && test_format;) {
352 format = sdlformat_to_auformat(test_format);
358 return SDL_SetError(
"NAS: Couldn't find any hardware audio formats");
362 this->hidden->aud = NAS_AuOpenServer(
"", 0,
NULL, 0,
NULL,
NULL);
363 if (this->hidden->aud == 0) {
364 return SDL_SetError(
"NAS: Couldn't open connection to NAS server");
367 this->hidden->dev = find_device(
this);
368 if ((this->hidden->dev == AuNone)
369 || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, 0)))) {
370 return SDL_SetError(
"NAS: Couldn't find a fitting device on NAS server");
374 if (buffer_size < 4096)
377 if (buffer_size > 32768)
384 AuMakeElementImportDevice(elms, this->
spec.
freq, this->hidden->dev,
385 AuUnlimitedSamples, 0,
NULL);
386 AuMakeElementExportClient(elms + 1, 0, this->
spec.
freq, format,
387 this->spec.channels, AuTrue, buffer_size,
388 buffer_size, 0,
NULL);
390 AuMakeElementImportClient(elms, this->
spec.
freq, format,
391 this->spec.channels, AuTrue, buffer_size,
392 buffer_size / 4, 0,
NULL);
393 AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq,
394 AuUnlimitedSamples, 0,
NULL);
397 NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue,
400 NAS_AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0,
401 this->hidden->flow, event_handler,
404 NAS_AuStartFlow(this->hidden->aud, this->hidden->flow,
NULL);
408 this->hidden->mixlen = this->
spec.
size;
410 if (this->hidden->mixbuf ==
NULL) {
413 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
421NAS_Deinitialize(
void)
429 if (LoadNASLibrary() < 0) {
434 SDL_SetError(
"NAS: AuOpenServer() failed (no audio server?)");
437 NAS_AuCloseServer(
aud);
458 "nas",
"Network Audio System", NAS_Init, 0
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
SDL_AudioFormat SDL_NextAudioFormat(void)
Uint16 SDL_AudioFormat
Audio format flags.
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
#define SDL_OutOfMemory()
void * SDL_LoadFunction(void *handle, const char *name)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
GLenum GLuint GLenum GLsizei const GLchar * buf
GLfloat GLfloat GLfloat GLfloat h
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)
EGLImageKHR EGLint EGLint * handle
void(* PlayDevice)(_THIS)
void(* WaitDevice)(_THIS)
void(* CloseDevice)(_THIS)
void(* FlushCapture)(_THIS)
int OnlyHasDefaultCaptureDevice
int OnlyHasDefaultOutputDevice
void(* Deinitialize)(void)
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
Uint8 *(* GetDeviceBuf)(_THIS)