src/audio/nas/SDL_nasaudio.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 23 Oct 2018 01:34:03 -0400
branchSDL-ryan-batching-renderer
changeset 12352 2b1707cc57fc
parent 11811 5d94cb6b24d3
child 12503 806492103856
permissions -rw-r--r--
render: Add floating point versions of various draw APIs.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@0
    22
slouken@6044
    23
#if SDL_AUDIO_DRIVER_NAS
slouken@6044
    24
slouken@0
    25
/* Allow access to a raw mixing buffer */
slouken@0
    26
slouken@0
    27
#include <signal.h>
slouken@0
    28
#include <unistd.h>
slouken@0
    29
slouken@1358
    30
#include "SDL_timer.h"
slouken@0
    31
#include "SDL_audio.h"
icculus@2049
    32
#include "SDL_loadso.h"
slouken@1361
    33
#include "../SDL_audio_c.h"
slouken@0
    34
#include "SDL_nasaudio.h"
slouken@0
    35
slouken@2060
    36
static void (*NAS_AuCloseServer) (AuServer *);
slouken@2060
    37
static void (*NAS_AuNextEvent) (AuServer *, AuBool, AuEvent *);
slouken@2060
    38
static AuBool(*NAS_AuDispatchEvent) (AuServer *, AuEvent *);
icculus@10259
    39
static void (*NAS_AuHandleEvents) (AuServer *);
slouken@2060
    40
static AuFlowID(*NAS_AuCreateFlow) (AuServer *, AuStatus *);
slouken@2060
    41
static void (*NAS_AuStartFlow) (AuServer *, AuFlowID, AuStatus *);
icculus@2049
    42
static void (*NAS_AuSetElements)
slouken@2060
    43
  (AuServer *, AuFlowID, AuBool, int, AuElement *, AuStatus *);
icculus@2049
    44
static void (*NAS_AuWriteElement)
slouken@2060
    45
  (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuBool, AuStatus *);
icculus@10259
    46
static AuUint32 (*NAS_AuReadElement)
icculus@10259
    47
  (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuStatus *);
icculus@2049
    48
static AuServer *(*NAS_AuOpenServer)
slouken@2060
    49
  (_AuConst char *, int, _AuConst char *, int, _AuConst char *, char **);
icculus@2049
    50
static AuEventHandlerRec *(*NAS_AuRegisterEventHandler)
slouken@2060
    51
  (AuServer *, AuMask, int, AuID, AuEventHandlerCallback, AuPointer);
icculus@2049
    52
icculus@2049
    53
icculus@6046
    54
#ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC
icculus@2049
    55
icculus@2049
    56
static const char *nas_library = SDL_AUDIO_DRIVER_NAS_DYNAMIC;
icculus@2049
    57
static void *nas_handle = NULL;
slouken@0
    58
slouken@1895
    59
static int
icculus@2049
    60
load_nas_sym(const char *fn, void **addr)
slouken@0
    61
{
icculus@2049
    62
    *addr = SDL_LoadFunction(nas_handle, fn);
icculus@2049
    63
    if (*addr == NULL) {
slouken@1895
    64
        return 0;
icculus@2049
    65
    }
slouken@1895
    66
    return 1;
slouken@0
    67
}
slouken@0
    68
icculus@2049
    69
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
icculus@2049
    70
#define SDL_NAS_SYM(x) \
icculus@2049
    71
    if (!load_nas_sym(#x, (void **) (char *) &NAS_##x)) return -1
icculus@2049
    72
#else
icculus@2049
    73
#define SDL_NAS_SYM(x) NAS_##x = x
icculus@2049
    74
#endif
icculus@2049
    75
slouken@2060
    76
static int
slouken@2060
    77
load_nas_syms(void)
icculus@2049
    78
{
icculus@2049
    79
    SDL_NAS_SYM(AuCloseServer);
icculus@2049
    80
    SDL_NAS_SYM(AuNextEvent);
icculus@2049
    81
    SDL_NAS_SYM(AuDispatchEvent);
icculus@10259
    82
    SDL_NAS_SYM(AuHandleEvents);
icculus@2049
    83
    SDL_NAS_SYM(AuCreateFlow);
icculus@2049
    84
    SDL_NAS_SYM(AuStartFlow);
icculus@2049
    85
    SDL_NAS_SYM(AuSetElements);
icculus@2049
    86
    SDL_NAS_SYM(AuWriteElement);
icculus@10259
    87
    SDL_NAS_SYM(AuReadElement);
icculus@2049
    88
    SDL_NAS_SYM(AuOpenServer);
icculus@2049
    89
    SDL_NAS_SYM(AuRegisterEventHandler);
icculus@2049
    90
    return 0;
icculus@2049
    91
}
slouken@2060
    92
icculus@2049
    93
#undef SDL_NAS_SYM
icculus@2049
    94
icculus@6046
    95
#ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC
icculus@2049
    96
slouken@1895
    97
static void
icculus@2049
    98
UnloadNASLibrary(void)
slouken@0
    99
{
icculus@2049
   100
    if (nas_handle != NULL) {
icculus@2049
   101
        SDL_UnloadObject(nas_handle);
icculus@2049
   102
        nas_handle = NULL;
icculus@2049
   103
    }
slouken@0
   104
}
slouken@0
   105
icculus@2049
   106
static int
icculus@2049
   107
LoadNASLibrary(void)
slouken@0
   108
{
icculus@2049
   109
    int retval = 0;
icculus@2049
   110
    if (nas_handle == NULL) {
icculus@2049
   111
        nas_handle = SDL_LoadObject(nas_library);
icculus@2049
   112
        if (nas_handle == NULL) {
icculus@2049
   113
            /* Copy error string so we can use it in a new SDL_SetError(). */
icculus@5880
   114
            const char *origerr = SDL_GetError();
icculus@5880
   115
            const size_t len = SDL_strlen(origerr) + 1;
icculus@2049
   116
            char *err = (char *) alloca(len);
icculus@2049
   117
            SDL_strlcpy(err, origerr, len);
icculus@2049
   118
            retval = -1;
philipp@10945
   119
            SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s",
slouken@2060
   120
                         nas_library, err);
icculus@2049
   121
        } else {
icculus@2049
   122
            retval = load_nas_syms();
icculus@2049
   123
            if (retval < 0) {
icculus@2049
   124
                UnloadNASLibrary();
icculus@2049
   125
            }
icculus@2049
   126
        }
slouken@1895
   127
    }
icculus@2049
   128
    return retval;
slouken@0
   129
}
slouken@0
   130
icculus@2049
   131
#else
icculus@2049
   132
icculus@2049
   133
static void
icculus@2049
   134
UnloadNASLibrary(void)
icculus@2049
   135
{
icculus@2049
   136
}
icculus@2049
   137
icculus@2049
   138
static int
icculus@2049
   139
LoadNASLibrary(void)
icculus@2049
   140
{
icculus@2049
   141
    load_nas_syms();
icculus@2049
   142
    return 0;
icculus@2049
   143
}
icculus@2049
   144
icculus@2049
   145
#endif /* SDL_AUDIO_DRIVER_NAS_DYNAMIC */
slouken@0
   146
slouken@0
   147
/* This function waits until it is possible to write a full sound buffer */
slouken@1895
   148
static void
icculus@2049
   149
NAS_WaitDevice(_THIS)
slouken@0
   150
{
slouken@1895
   151
    while (this->hidden->buf_free < this->hidden->mixlen) {
slouken@1895
   152
        AuEvent ev;
icculus@2049
   153
        NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev);
icculus@2049
   154
        NAS_AuDispatchEvent(this->hidden->aud, &ev);
slouken@1895
   155
    }
slouken@0
   156
}
slouken@0
   157
slouken@1895
   158
static void
icculus@2049
   159
NAS_PlayDevice(_THIS)
slouken@0
   160
{
icculus@2049
   161
    while (this->hidden->mixlen > this->hidden->buf_free) {
icculus@2049
   162
        /*
icculus@2049
   163
         * We think the buffer is full? Yikes! Ask the server for events,
icculus@2049
   164
         *  in the hope that some of them is LowWater events telling us more
icculus@2049
   165
         *  of the buffer is free now than what we think.
icculus@2049
   166
         */
slouken@1895
   167
        AuEvent ev;
icculus@2049
   168
        NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev);
icculus@2049
   169
        NAS_AuDispatchEvent(this->hidden->aud, &ev);
slouken@1895
   170
    }
slouken@1895
   171
    this->hidden->buf_free -= this->hidden->mixlen;
slouken@0
   172
slouken@1895
   173
    /* Write the audio data */
icculus@2049
   174
    NAS_AuWriteElement(this->hidden->aud, this->hidden->flow, 0,
slouken@2060
   175
                       this->hidden->mixlen, this->hidden->mixbuf, AuFalse,
slouken@2060
   176
                       NULL);
slouken@0
   177
slouken@1895
   178
    this->hidden->written += this->hidden->mixlen;
slouken@1895
   179
slouken@0
   180
#ifdef DEBUG_AUDIO
slouken@1895
   181
    fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen);
slouken@0
   182
#endif
slouken@0
   183
}
slouken@0
   184
slouken@1895
   185
static Uint8 *
icculus@2049
   186
NAS_GetDeviceBuf(_THIS)
slouken@0
   187
{
slouken@1895
   188
    return (this->hidden->mixbuf);
slouken@0
   189
}
slouken@0
   190
icculus@10259
   191
static int
icculus@10259
   192
NAS_CaptureFromDevice(_THIS, void *buffer, int buflen)
icculus@10259
   193
{
icculus@10259
   194
    struct SDL_PrivateAudioData *h = this->hidden;
icculus@10259
   195
    int retval;
icculus@10259
   196
icculus@10259
   197
    while (SDL_TRUE) {
icculus@10259
   198
        /* just keep the event queue moving and the server chattering. */
icculus@10259
   199
        NAS_AuHandleEvents(h->aud);
icculus@10259
   200
    
icculus@10259
   201
        retval = (int) NAS_AuReadElement(h->aud, h->flow, 1, buflen, buffer, NULL);
icculus@10259
   202
        /*printf("read %d capture bytes\n", (int) retval);*/
icculus@10259
   203
        if (retval == 0) {
icculus@10259
   204
            SDL_Delay(10);  /* don't burn the CPU if we're waiting for data. */
icculus@10259
   205
        } else {
icculus@10259
   206
            break;
icculus@10259
   207
        }
icculus@10259
   208
    }
icculus@10259
   209
icculus@10259
   210
    return retval;
icculus@10259
   211
}
icculus@10259
   212
icculus@10259
   213
static void
icculus@10259
   214
NAS_FlushCapture(_THIS)
icculus@10259
   215
{
icculus@10259
   216
    struct SDL_PrivateAudioData *h = this->hidden;
icculus@10259
   217
    AuUint32 total = 0;
icculus@10259
   218
    AuUint32 br;
icculus@10259
   219
    Uint8 buf[512];
icculus@10259
   220
icculus@10259
   221
    do {
icculus@10259
   222
        /* just keep the event queue moving and the server chattering. */
icculus@10259
   223
        NAS_AuHandleEvents(h->aud);
icculus@10259
   224
        br = NAS_AuReadElement(h->aud, h->flow, 1, sizeof (buf), buf, NULL);
icculus@10259
   225
        /*printf("flushed %d capture bytes\n", (int) br);*/
icculus@10259
   226
        total += br;
icculus@10259
   227
    } while ((br == sizeof (buf)) && (total < this->spec.size));
icculus@10259
   228
}
icculus@10259
   229
slouken@1895
   230
static void
icculus@2049
   231
NAS_CloseDevice(_THIS)
slouken@0
   232
{
icculus@10255
   233
    if (this->hidden->aud) {
icculus@10255
   234
        NAS_AuCloseServer(this->hidden->aud);
slouken@1895
   235
    }
icculus@10256
   236
    SDL_free(this->hidden->mixbuf);
icculus@10255
   237
    SDL_free(this->hidden);
slouken@0
   238
}
slouken@0
   239
slouken@1895
   240
static unsigned char
slouken@1895
   241
sdlformat_to_auformat(unsigned int fmt)
slouken@0
   242
{
slouken@1895
   243
    switch (fmt) {
slouken@0
   244
    case AUDIO_U8:
slouken@1895
   245
        return AuFormatLinearUnsigned8;
slouken@0
   246
    case AUDIO_S8:
slouken@1895
   247
        return AuFormatLinearSigned8;
slouken@0
   248
    case AUDIO_U16LSB:
slouken@1895
   249
        return AuFormatLinearUnsigned16LSB;
slouken@0
   250
    case AUDIO_U16MSB:
slouken@1895
   251
        return AuFormatLinearUnsigned16MSB;
slouken@0
   252
    case AUDIO_S16LSB:
slouken@1895
   253
        return AuFormatLinearSigned16LSB;
slouken@0
   254
    case AUDIO_S16MSB:
slouken@1895
   255
        return AuFormatLinearSigned16MSB;
slouken@0
   256
    }
slouken@1895
   257
    return AuNone;
slouken@0
   258
}
slouken@0
   259
slouken@0
   260
static AuBool
slouken@1895
   261
event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd)
slouken@0
   262
{
icculus@10259
   263
    SDL_AudioDevice *this = (SDL_AudioDevice *) hnd->data;
icculus@10259
   264
    struct SDL_PrivateAudioData *h = this->hidden;
icculus@10259
   265
    if (this->iscapture) {
icculus@10259
   266
        return AuTrue;  /* we don't (currently) care about any of this for capture devices */
icculus@10259
   267
    }
icculus@10259
   268
slouken@1895
   269
    switch (ev->type) {
slouken@1895
   270
    case AuEventTypeElementNotify:
slouken@1895
   271
        {
slouken@1895
   272
            AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev;
slouken@0
   273
slouken@1895
   274
            switch (event->kind) {
slouken@1895
   275
            case AuElementNotifyKindLowWater:
icculus@10259
   276
                if (h->buf_free >= 0) {
icculus@10259
   277
                    h->really += event->num_bytes;
icculus@10259
   278
                    gettimeofday(&h->last_tv, 0);
icculus@10259
   279
                    h->buf_free += event->num_bytes;
slouken@1895
   280
                } else {
icculus@10259
   281
                    h->buf_free = event->num_bytes;
slouken@1895
   282
                }
slouken@1895
   283
                break;
slouken@1895
   284
            case AuElementNotifyKindState:
slouken@1895
   285
                switch (event->cur_state) {
slouken@1895
   286
                case AuStatePause:
slouken@1895
   287
                    if (event->reason != AuReasonUser) {
icculus@10259
   288
                        if (h->buf_free >= 0) {
icculus@10259
   289
                            h->really += event->num_bytes;
icculus@10259
   290
                            gettimeofday(&h->last_tv, 0);
icculus@10259
   291
                            h->buf_free += event->num_bytes;
slouken@1895
   292
                        } else {
icculus@10259
   293
                            h->buf_free = event->num_bytes;
slouken@1895
   294
                        }
slouken@1895
   295
                    }
slouken@1895
   296
                    break;
slouken@1895
   297
                }
slouken@1895
   298
            }
slouken@1895
   299
        }
slouken@1895
   300
    }
slouken@1895
   301
    return AuTrue;
slouken@0
   302
}
slouken@0
   303
slouken@0
   304
static AuDeviceID
icculus@10259
   305
find_device(_THIS)
slouken@0
   306
{
icculus@2049
   307
    /* These "Au" things are all macros, not functions... */
icculus@10259
   308
    struct SDL_PrivateAudioData *h = this->hidden;
icculus@10259
   309
    const unsigned int devicekind = this->iscapture ? AuComponentKindPhysicalInput : AuComponentKindPhysicalOutput;
icculus@10259
   310
    const int numdevs = AuServerNumDevices(h->aud);
icculus@10259
   311
    const int nch = this->spec.channels;
slouken@1895
   312
    int i;
icculus@10259
   313
icculus@10259
   314
    /* Try to find exact match on channels first... */
icculus@10259
   315
    for (i = 0; i < numdevs; i++) {
icculus@10259
   316
        const AuDeviceAttributes *dev = AuServerDevice(h->aud, i);
icculus@10259
   317
        if ((AuDeviceKind(dev) == devicekind) && (AuDeviceNumTracks(dev) == nch)) {
icculus@10259
   318
            return AuDeviceIdentifier(dev);
icculus@10259
   319
        }
icculus@10259
   320
    }
icculus@10259
   321
icculus@10259
   322
    /* Take anything, then... */
icculus@10259
   323
    for (i = 0; i < numdevs; i++) {
icculus@10259
   324
        const AuDeviceAttributes *dev = AuServerDevice(h->aud, i);
icculus@10259
   325
        if (AuDeviceKind(dev) == devicekind) {
icculus@10259
   326
            this->spec.channels = AuDeviceNumTracks(dev);
icculus@10259
   327
            return AuDeviceIdentifier(dev);
slouken@1895
   328
        }
slouken@1895
   329
    }
slouken@1895
   330
    return AuNone;
slouken@0
   331
}
slouken@0
   332
slouken@1895
   333
static int
icculus@9394
   334
NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
slouken@0
   335
{
slouken@1895
   336
    AuElement elms[3];
slouken@1895
   337
    int buffer_size;
icculus@1982
   338
    SDL_AudioFormat test_format, format;
slouken@0
   339
icculus@2049
   340
    /* Initialize all variables that we clean on shutdown */
icculus@2049
   341
    this->hidden = (struct SDL_PrivateAudioData *)
slouken@2060
   342
        SDL_malloc((sizeof *this->hidden));
icculus@2049
   343
    if (this->hidden == NULL) {
icculus@7038
   344
        return SDL_OutOfMemory();
icculus@2049
   345
    }
icculus@10257
   346
    SDL_zerop(this->hidden);
slouken@0
   347
slouken@1895
   348
    /* Try for a closest match on audio format */
slouken@1895
   349
    format = 0;
icculus@2049
   350
    for (test_format = SDL_FirstAudioFormat(this->spec.format);
slouken@1895
   351
         !format && test_format;) {
slouken@1895
   352
        format = sdlformat_to_auformat(test_format);
slouken@1895
   353
        if (format == AuNone) {
slouken@1895
   354
            test_format = SDL_NextAudioFormat();
slouken@1895
   355
        }
slouken@1895
   356
    }
slouken@1895
   357
    if (format == 0) {
icculus@7038
   358
        return SDL_SetError("NAS: Couldn't find any hardware audio formats");
slouken@1895
   359
    }
icculus@2049
   360
    this->spec.format = test_format;
slouken@0
   361
icculus@2049
   362
    this->hidden->aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
slouken@1895
   363
    if (this->hidden->aud == 0) {
icculus@7038
   364
        return SDL_SetError("NAS: Couldn't open connection to NAS server");
slouken@1895
   365
    }
slouken@0
   366
icculus@10259
   367
    this->hidden->dev = find_device(this);
slouken@1895
   368
    if ((this->hidden->dev == AuNone)
icculus@2049
   369
        || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, 0)))) {
icculus@7038
   370
        return SDL_SetError("NAS: Couldn't find a fitting device on NAS server");
slouken@1895
   371
    }
slouken@0
   372
icculus@2049
   373
    buffer_size = this->spec.freq;
slouken@1895
   374
    if (buffer_size < 4096)
slouken@1895
   375
        buffer_size = 4096;
slouken@0
   376
slouken@1895
   377
    if (buffer_size > 32768)
slouken@1895
   378
        buffer_size = 32768;    /* So that the buffer won't get unmanageably big. */
slouken@0
   379
slouken@1895
   380
    /* Calculate the final parameters for this audio specification */
icculus@2049
   381
    SDL_CalculateAudioSpec(&this->spec);
slouken@0
   382
icculus@10259
   383
    if (iscapture) {
icculus@10259
   384
        AuMakeElementImportDevice(elms, this->spec.freq, this->hidden->dev,
icculus@10259
   385
                                  AuUnlimitedSamples, 0, NULL);
icculus@10259
   386
        AuMakeElementExportClient(elms + 1, 0, this->spec.freq, format,
icculus@10259
   387
                                  this->spec.channels, AuTrue, buffer_size,
icculus@10259
   388
                                  buffer_size, 0, NULL);
icculus@10259
   389
    } else {
icculus@10259
   390
        AuMakeElementImportClient(elms, this->spec.freq, format,
icculus@10259
   391
                                  this->spec.channels, AuTrue, buffer_size,
icculus@10259
   392
                                  buffer_size / 4, 0, NULL);
icculus@10259
   393
        AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq,
icculus@10259
   394
                                  AuUnlimitedSamples, 0, NULL);
icculus@10259
   395
    }
slouken@0
   396
icculus@10259
   397
    NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue,
icculus@10259
   398
                      2, elms, NULL);
icculus@10259
   399
icculus@2049
   400
    NAS_AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0,
icculus@2049
   401
                               this->hidden->flow, event_handler,
icculus@10259
   402
                               (AuPointer) this);
slouken@0
   403
icculus@2049
   404
    NAS_AuStartFlow(this->hidden->aud, this->hidden->flow, NULL);
slouken@0
   405
slouken@1895
   406
    /* Allocate mixing buffer */
icculus@10259
   407
    if (!iscapture) {
icculus@10259
   408
        this->hidden->mixlen = this->spec.size;
icculus@10259
   409
        this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
icculus@10259
   410
        if (this->hidden->mixbuf == NULL) {
icculus@10259
   411
            return SDL_OutOfMemory();
icculus@10259
   412
        }
icculus@10259
   413
        SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
slouken@1895
   414
    }
slouken@1895
   415
slouken@1895
   416
    /* We're ready to rock and roll. :-) */
icculus@7038
   417
    return 0;
slouken@0
   418
}
slouken@1895
   419
icculus@2049
   420
static void
icculus@2049
   421
NAS_Deinitialize(void)
icculus@2049
   422
{
icculus@2049
   423
    UnloadNASLibrary();
icculus@2049
   424
}
icculus@2049
   425
icculus@2049
   426
static int
slouken@2060
   427
NAS_Init(SDL_AudioDriverImpl * impl)
icculus@2049
   428
{
icculus@2049
   429
    if (LoadNASLibrary() < 0) {
icculus@2049
   430
        return 0;
icculus@2049
   431
    } else {
icculus@2049
   432
        AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
icculus@2049
   433
        if (aud == NULL) {
icculus@2049
   434
            SDL_SetError("NAS: AuOpenServer() failed (no audio server?)");
icculus@2049
   435
            return 0;
icculus@2049
   436
        }
icculus@2049
   437
        NAS_AuCloseServer(aud);
icculus@2049
   438
    }
icculus@2049
   439
icculus@2049
   440
    /* Set the function pointers */
icculus@2049
   441
    impl->OpenDevice = NAS_OpenDevice;
icculus@2049
   442
    impl->PlayDevice = NAS_PlayDevice;
icculus@2049
   443
    impl->WaitDevice = NAS_WaitDevice;
icculus@2049
   444
    impl->GetDeviceBuf = NAS_GetDeviceBuf;
icculus@10259
   445
    impl->CaptureFromDevice = NAS_CaptureFromDevice;
icculus@10259
   446
    impl->FlushCapture = NAS_FlushCapture;
icculus@2049
   447
    impl->CloseDevice = NAS_CloseDevice;
icculus@2049
   448
    impl->Deinitialize = NAS_Deinitialize;
icculus@10259
   449
icculus@10259
   450
    impl->OnlyHasDefaultOutputDevice = 1;
icculus@10259
   451
    impl->OnlyHasDefaultCaptureDevice = 1;
icculus@10259
   452
    impl->HasCaptureSupport = SDL_TRUE;
icculus@2049
   453
icculus@3699
   454
    return 1;   /* this audio target is available. */
icculus@2049
   455
}
icculus@2049
   456
icculus@2049
   457
AudioBootStrap NAS_bootstrap = {
icculus@5594
   458
    "nas", "Network Audio System", NAS_Init, 0
icculus@2049
   459
};
icculus@2049
   460
slouken@6044
   461
#endif /* SDL_AUDIO_DRIVER_NAS */
slouken@6044
   462
slouken@1895
   463
/* vi: set ts=4 sw=4 expandtab: */