src/audio/sun/SDL_sunaudio.c
author Ryan C. Gordon
Wed, 18 Mar 2015 02:01:17 -0400
changeset 9394 bb28e5281770
parent 9393 ed79a66e57e5
child 9619 b94b6d0bff0f
permissions -rw-r--r--
Bunch of reworking to how we manage audio devices.

Device enumeration now happens at startup and then is managed exclusively
through hotplugging instead of full redetection. The device name list now has
a unique "handle" associated with each item and SDL will pass this to the
backend so they don't have to figure out how a human readable name maps to
real hardware for a second time.

Other cleanups, fixes, improvements, plus all the audio backends updated to
the new interface...largely untested at this point, though.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@8149
     3
  Copyright (C) 1997-2014 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_SUNAUDIO
slouken@6044
    24
slouken@0
    25
/* Allow access to a raw mixing buffer */
slouken@0
    26
slouken@0
    27
#include <fcntl.h>
slouken@0
    28
#include <errno.h>
slouken@1402
    29
#ifdef __NETBSD__
slouken@0
    30
#include <sys/ioctl.h>
slouken@0
    31
#include <sys/audioio.h>
slouken@0
    32
#endif
slouken@0
    33
#ifdef __SVR4
slouken@0
    34
#include <sys/audioio.h>
slouken@0
    35
#else
slouken@0
    36
#include <sys/time.h>
slouken@0
    37
#include <sys/types.h>
slouken@0
    38
#endif
slouken@0
    39
#include <unistd.h>
slouken@0
    40
slouken@1358
    41
#include "SDL_timer.h"
slouken@0
    42
#include "SDL_audio.h"
slouken@1361
    43
#include "../SDL_audiomem.h"
slouken@1361
    44
#include "../SDL_audio_c.h"
slouken@1361
    45
#include "../SDL_audiodev_c.h"
slouken@0
    46
#include "SDL_sunaudio.h"
slouken@0
    47
slouken@0
    48
/* Open the audio device for playback, and don't block if busy */
slouken@0
    49
slouken@7191
    50
#if defined(AUDIO_GETINFO) && !defined(AUDIO_GETBUFINFO)
slouken@6456
    51
#define AUDIO_GETBUFINFO AUDIO_GETINFO
slouken@6456
    52
#endif
slouken@6456
    53
slouken@0
    54
/* Audio driver functions */
slouken@1464
    55
static Uint8 snd2au(int sample);
slouken@1464
    56
slouken@0
    57
/* Audio driver bootstrap functions */
slouken@1895
    58
static void
icculus@9394
    59
SUNAUDIO_DetectDevices(void)
slouken@0
    60
{
icculus@9394
    61
    SDL_EnumUnixAudioDevices(1, (int (*)(int)) NULL);
slouken@0
    62
}
slouken@0
    63
slouken@0
    64
#ifdef DEBUG_AUDIO
slouken@1895
    65
void
slouken@1895
    66
CheckUnderflow(_THIS)
slouken@0
    67
{
slouken@6456
    68
#ifdef AUDIO_GETBUFINFO
slouken@1895
    69
    audio_info_t info;
slouken@1895
    70
    int left;
slouken@0
    71
eviltypeguy@6967
    72
    ioctl(this->hidden->audio_fd, AUDIO_GETBUFINFO, &info);
eviltypeguy@6967
    73
    left = (this->hidden->written - info.play.samples);
eviltypeguy@6967
    74
    if (this->hidden->written && (left == 0)) {
slouken@1895
    75
        fprintf(stderr, "audio underflow!\n");
slouken@1895
    76
    }
slouken@0
    77
#endif
slouken@0
    78
}
slouken@0
    79
#endif
slouken@0
    80
eviltypeguy@6967
    81
static void
eviltypeguy@6967
    82
SUNAUDIO_WaitDevice(_THIS)
slouken@0
    83
{
slouken@6456
    84
#ifdef AUDIO_GETBUFINFO
slouken@7191
    85
#define SLEEP_FUDGE 10      /* 10 ms scheduling fudge factor */
slouken@1895
    86
    audio_info_t info;
slouken@1895
    87
    Sint32 left;
slouken@0
    88
eviltypeguy@6967
    89
    ioctl(this->hidden->audio_fd, AUDIO_GETBUFINFO, &info);
eviltypeguy@6967
    90
    left = (this->hidden->written - info.play.samples);
eviltypeguy@6967
    91
    if (left > this->hidden->fragsize) {
slouken@1895
    92
        Sint32 sleepy;
slouken@0
    93
eviltypeguy@6967
    94
        sleepy = ((left - this->hidden->fragsize) / this->hidden->frequency);
slouken@1895
    95
        sleepy -= SLEEP_FUDGE;
slouken@1895
    96
        if (sleepy > 0) {
slouken@1895
    97
            SDL_Delay(sleepy);
slouken@1895
    98
        }
slouken@1895
    99
    }
slouken@0
   100
#else
slouken@1895
   101
    fd_set fdset;
slouken@0
   102
slouken@1895
   103
    FD_ZERO(&fdset);
eviltypeguy@6967
   104
    FD_SET(this->hidden->audio_fd, &fdset);
eviltypeguy@6967
   105
    select(this->hidden->audio_fd + 1, NULL, &fdset, NULL, NULL);
slouken@0
   106
#endif
slouken@0
   107
}
slouken@0
   108
eviltypeguy@6967
   109
static void
eviltypeguy@6967
   110
SUNAUDIO_PlayDevice(_THIS)
slouken@0
   111
{
slouken@1895
   112
    /* Write the audio data */
eviltypeguy@6967
   113
    if (this->hidden->ulaw_only) {
slouken@1895
   114
        /* Assuming that this->spec.freq >= 8000 Hz */
slouken@1895
   115
        int accum, incr, pos;
slouken@1895
   116
        Uint8 *aubuf;
slouken@0
   117
slouken@1895
   118
        accum = 0;
slouken@1895
   119
        incr = this->spec.freq / 8;
eviltypeguy@6967
   120
        aubuf = this->hidden->ulaw_buf;
eviltypeguy@6967
   121
        switch (this->hidden->audio_fmt & 0xFF) {
slouken@1895
   122
        case 8:
slouken@1895
   123
            {
slouken@1895
   124
                Uint8 *sndbuf;
slouken@0
   125
eviltypeguy@6967
   126
                sndbuf = this->hidden->mixbuf;
eviltypeguy@6967
   127
                for (pos = 0; pos < this->hidden->fragsize; ++pos) {
slouken@1895
   128
                    *aubuf = snd2au((0x80 - *sndbuf) * 64);
slouken@1895
   129
                    accum += incr;
slouken@1895
   130
                    while (accum > 0) {
slouken@1895
   131
                        accum -= 1000;
slouken@1895
   132
                        sndbuf += 1;
slouken@1895
   133
                    }
slouken@1895
   134
                    aubuf += 1;
slouken@1895
   135
                }
slouken@1895
   136
            }
slouken@1895
   137
            break;
slouken@1895
   138
        case 16:
slouken@1895
   139
            {
slouken@1895
   140
                Sint16 *sndbuf;
slouken@1895
   141
eviltypeguy@6967
   142
                sndbuf = (Sint16 *) this->hidden->mixbuf;
eviltypeguy@6967
   143
                for (pos = 0; pos < this->hidden->fragsize; ++pos) {
slouken@1895
   144
                    *aubuf = snd2au(*sndbuf / 4);
slouken@1895
   145
                    accum += incr;
slouken@1895
   146
                    while (accum > 0) {
slouken@1895
   147
                        accum -= 1000;
slouken@1895
   148
                        sndbuf += 1;
slouken@1895
   149
                    }
slouken@1895
   150
                    aubuf += 1;
slouken@1895
   151
                }
slouken@1895
   152
            }
slouken@1895
   153
            break;
slouken@1895
   154
        }
slouken@0
   155
#ifdef DEBUG_AUDIO
slouken@1895
   156
        CheckUnderflow(this);
slouken@0
   157
#endif
eviltypeguy@6967
   158
        if (write(this->hidden->audio_fd, this->hidden->ulaw_buf,
eviltypeguy@6967
   159
            this->hidden->fragsize) < 0) {
slouken@1895
   160
            /* Assume fatal error, for now */
icculus@9394
   161
            SDL_OpenedAudioDeviceDisconnected(this);
slouken@1895
   162
        }
eviltypeguy@6967
   163
        this->hidden->written += this->hidden->fragsize;
slouken@1895
   164
    } else {
slouken@0
   165
#ifdef DEBUG_AUDIO
slouken@1895
   166
        CheckUnderflow(this);
slouken@0
   167
#endif
eviltypeguy@6967
   168
        if (write(this->hidden->audio_fd, this->hidden->mixbuf,
eviltypeguy@6967
   169
            this->spec.size) < 0) {
slouken@1895
   170
            /* Assume fatal error, for now */
icculus@9394
   171
            SDL_OpenedAudioDeviceDisconnected(this);
slouken@1895
   172
        }
eviltypeguy@6967
   173
        this->hidden->written += this->hidden->fragsize;
eviltypeguy@6967
   174
    }
eviltypeguy@6967
   175
}
eviltypeguy@6967
   176
eviltypeguy@6967
   177
static Uint8 *
eviltypeguy@6967
   178
SUNAUDIO_GetDeviceBuf(_THIS)
eviltypeguy@6967
   179
{
eviltypeguy@6967
   180
    return (this->hidden->mixbuf);
eviltypeguy@6967
   181
}
eviltypeguy@6967
   182
eviltypeguy@6967
   183
static void
eviltypeguy@6967
   184
SUNAUDIO_CloseDevice(_THIS)
eviltypeguy@6967
   185
{
eviltypeguy@6967
   186
    if (this->hidden != NULL) {
slouken@7719
   187
        SDL_FreeAudioMem(this->hidden->mixbuf);
slouken@7719
   188
        this->hidden->mixbuf = NULL;
slouken@7719
   189
        SDL_free(this->hidden->ulaw_buf);
slouken@7719
   190
        this->hidden->ulaw_buf = NULL;
eviltypeguy@6967
   191
        if (this->hidden->audio_fd >= 0) {
eviltypeguy@6967
   192
            close(this->hidden->audio_fd);
eviltypeguy@6967
   193
            this->hidden->audio_fd = -1;
eviltypeguy@6967
   194
        }
eviltypeguy@6967
   195
        SDL_free(this->hidden);
eviltypeguy@6967
   196
        this->hidden = NULL;
slouken@1895
   197
    }
slouken@0
   198
}
slouken@0
   199
eviltypeguy@6967
   200
static int
icculus@9394
   201
SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
slouken@0
   202
{
eviltypeguy@6967
   203
    const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
eviltypeguy@6967
   204
    SDL_AudioFormat format = 0;
eviltypeguy@6967
   205
    audio_info_t info;
eviltypeguy@6967
   206
eviltypeguy@6967
   207
    /* We don't care what the devname is...we'll try to open anything. */
eviltypeguy@6967
   208
    /*  ...but default to first name in the list... */
eviltypeguy@6967
   209
    if (devname == NULL) {
eviltypeguy@6967
   210
        devname = SDL_GetAudioDeviceName(0, iscapture);
eviltypeguy@6967
   211
        if (devname == NULL) {
icculus@7038
   212
            return SDL_SetError("No such audio device");
eviltypeguy@6967
   213
        }
slouken@1895
   214
    }
slouken@0
   215
eviltypeguy@6967
   216
    /* Initialize all variables that we clean on shutdown */
eviltypeguy@6967
   217
    this->hidden = (struct SDL_PrivateAudioData *)
eviltypeguy@6967
   218
        SDL_malloc((sizeof *this->hidden));
eviltypeguy@6967
   219
    if (this->hidden == NULL) {
icculus@7038
   220
        return SDL_OutOfMemory();
eviltypeguy@6967
   221
    }
eviltypeguy@6967
   222
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
eviltypeguy@6967
   223
eviltypeguy@6967
   224
    /* Open the audio device */
eviltypeguy@6967
   225
    this->hidden->audio_fd = open(devname, flags, 0);
eviltypeguy@6967
   226
    if (this->hidden->audio_fd < 0) {
icculus@7038
   227
        return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
eviltypeguy@6967
   228
    }
eviltypeguy@6967
   229
slouken@0
   230
#ifdef AUDIO_SETINFO
slouken@1895
   231
    int enc;
slouken@0
   232
#endif
eviltypeguy@6967
   233
    int desired_freq = this->spec.freq;
slouken@0
   234
slouken@1895
   235
    /* Determine the audio parameters from the AudioSpec */
eviltypeguy@6967
   236
    switch (SDL_AUDIO_BITSIZE(this->spec.format)) {
slouken@1895
   237
slouken@1895
   238
    case 8:
slouken@1895
   239
        {                       /* Unsigned 8 bit audio data */
eviltypeguy@6967
   240
            this->spec.format = AUDIO_U8;
slouken@0
   241
#ifdef AUDIO_SETINFO
slouken@1895
   242
            enc = AUDIO_ENCODING_LINEAR8;
slouken@0
   243
#endif
slouken@1895
   244
        }
slouken@1895
   245
        break;
slouken@0
   246
slouken@1895
   247
    case 16:
slouken@1895
   248
        {                       /* Signed 16 bit audio data */
eviltypeguy@6967
   249
            this->spec.format = AUDIO_S16SYS;
slouken@1895
   250
#ifdef AUDIO_SETINFO
slouken@1895
   251
            enc = AUDIO_ENCODING_LINEAR;
slouken@1895
   252
#endif
slouken@1895
   253
        }
slouken@1895
   254
        break;
slouken@0
   255
slouken@1895
   256
    default:
slouken@1895
   257
        {
icculus@2015
   258
            /* !!! FIXME: fallback to conversion on unsupported types! */
icculus@7038
   259
            return SDL_SetError("Unsupported audio format");
slouken@1895
   260
        }
slouken@1895
   261
    }
eviltypeguy@6967
   262
    this->hidden->audio_fmt = this->spec.format;
slouken@0
   263
eviltypeguy@6967
   264
    this->hidden->ulaw_only = 0;    /* modern Suns do support linear audio */
slouken@0
   265
#ifdef AUDIO_SETINFO
slouken@1895
   266
    for (;;) {
slouken@1895
   267
        audio_info_t info;
slouken@1895
   268
        AUDIO_INITINFO(&info);  /* init all fields to "no change" */
slouken@0
   269
slouken@1895
   270
        /* Try to set the requested settings */
eviltypeguy@6967
   271
        info.play.sample_rate = this->spec.freq;
eviltypeguy@6967
   272
        info.play.channels = this->spec.channels;
slouken@1895
   273
        info.play.precision = (enc == AUDIO_ENCODING_ULAW)
eviltypeguy@6967
   274
            ? 8 : this->spec.format & 0xff;
slouken@1895
   275
        info.play.encoding = enc;
eviltypeguy@6967
   276
        if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) {
slouken@0
   277
slouken@1895
   278
            /* Check to be sure we got what we wanted */
eviltypeguy@6967
   279
            if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
icculus@7038
   280
                return SDL_SetError("Error getting audio parameters: %s",
icculus@7038
   281
                                    strerror(errno));
slouken@1895
   282
            }
slouken@1895
   283
            if (info.play.encoding == enc
eviltypeguy@6967
   284
                && info.play.precision == (this->spec.format & 0xff)
eviltypeguy@6967
   285
                && info.play.channels == this->spec.channels) {
slouken@1895
   286
                /* Yow! All seems to be well! */
eviltypeguy@6967
   287
                this->spec.freq = info.play.sample_rate;
slouken@1895
   288
                break;
slouken@1895
   289
            }
slouken@1895
   290
        }
slouken@0
   291
slouken@1895
   292
        switch (enc) {
slouken@1895
   293
        case AUDIO_ENCODING_LINEAR8:
slouken@1895
   294
            /* unsigned 8bit apparently not supported here */
slouken@1895
   295
            enc = AUDIO_ENCODING_LINEAR;
eviltypeguy@6967
   296
            this->spec.format = AUDIO_S16SYS;
slouken@1895
   297
            break;              /* try again */
slouken@0
   298
slouken@1895
   299
        case AUDIO_ENCODING_LINEAR:
slouken@1895
   300
            /* linear 16bit didn't work either, resort to -law */
slouken@1895
   301
            enc = AUDIO_ENCODING_ULAW;
eviltypeguy@6967
   302
            this->spec.channels = 1;
eviltypeguy@6967
   303
            this->spec.freq = 8000;
eviltypeguy@6967
   304
            this->spec.format = AUDIO_U8;
eviltypeguy@6967
   305
            this->hidden->ulaw_only = 1;
slouken@1895
   306
            break;
slouken@1895
   307
slouken@1895
   308
        default:
slouken@1895
   309
            /* oh well... */
icculus@7038
   310
            return SDL_SetError("Error setting audio parameters: %s",
icculus@7038
   311
                                strerror(errno));
slouken@1895
   312
        }
slouken@1895
   313
    }
slouken@0
   314
#endif /* AUDIO_SETINFO */
eviltypeguy@6967
   315
    this->hidden->written = 0;
slouken@0
   316
slouken@1895
   317
    /* We can actually convert on-the-fly to U-Law */
eviltypeguy@6967
   318
    if (this->hidden->ulaw_only) {
eviltypeguy@6967
   319
        this->spec.freq = desired_freq;
eviltypeguy@6967
   320
        this->hidden->fragsize = (this->spec.samples * 1000) /
eviltypeguy@6967
   321
            (this->spec.freq / 8);
eviltypeguy@6967
   322
        this->hidden->frequency = 8;
eviltypeguy@6967
   323
        this->hidden->ulaw_buf = (Uint8 *) SDL_malloc(this->hidden->fragsize);
eviltypeguy@6967
   324
        if (this->hidden->ulaw_buf == NULL) {
icculus@7037
   325
            return SDL_OutOfMemory();
slouken@1895
   326
        }
eviltypeguy@6967
   327
        this->spec.channels = 1;
slouken@1895
   328
    } else {
eviltypeguy@6967
   329
        this->hidden->fragsize = this->spec.samples;
eviltypeguy@6967
   330
        this->hidden->frequency = this->spec.freq / 1000;
slouken@1895
   331
    }
slouken@0
   332
#ifdef DEBUG_AUDIO
slouken@1895
   333
    fprintf(stderr, "Audio device %s U-Law only\n",
eviltypeguy@6967
   334
            this->hidden->ulaw_only ? "is" : "is not");
slouken@1895
   335
    fprintf(stderr, "format=0x%x chan=%d freq=%d\n",
eviltypeguy@6967
   336
            this->spec.format, this->spec.channels, this->spec.freq);
slouken@0
   337
#endif
slouken@0
   338
slouken@1895
   339
    /* Update the fragment size as size in bytes */
eviltypeguy@6967
   340
    SDL_CalculateAudioSpec(&this->spec);
slouken@0
   341
slouken@1895
   342
    /* Allocate mixing buffer */
eviltypeguy@6967
   343
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->spec.size);
eviltypeguy@6967
   344
    if (this->hidden->mixbuf == NULL) {
icculus@7037
   345
        return SDL_OutOfMemory();
slouken@1895
   346
    }
eviltypeguy@6967
   347
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
slouken@0
   348
slouken@1895
   349
    /* We're ready to rock and roll. :-) */
icculus@7038
   350
    return 0;
slouken@0
   351
}
slouken@0
   352
slouken@0
   353
/************************************************************************/
slouken@0
   354
/* This function (snd2au()) copyrighted:                                */
slouken@0
   355
/************************************************************************/
slouken@0
   356
/*      Copyright 1989 by Rich Gopstein and Harris Corporation          */
slouken@0
   357
/*                                                                      */
slouken@0
   358
/*      Permission to use, copy, modify, and distribute this software   */
slouken@0
   359
/*      and its documentation for any purpose and without fee is        */
slouken@0
   360
/*      hereby granted, provided that the above copyright notice        */
slouken@0
   361
/*      appears in all copies and that both that copyright notice and   */
slouken@0
   362
/*      this permission notice appear in supporting documentation, and  */
slouken@0
   363
/*      that the name of Rich Gopstein and Harris Corporation not be    */
slouken@0
   364
/*      used in advertising or publicity pertaining to distribution     */
slouken@0
   365
/*      of the software without specific, written prior permission.     */
slouken@0
   366
/*      Rich Gopstein and Harris Corporation make no representations    */
slouken@0
   367
/*      about the suitability of this software for any purpose.  It     */
slouken@0
   368
/*      provided "as is" without express or implied warranty.           */
slouken@0
   369
/************************************************************************/
slouken@0
   370
slouken@1895
   371
static Uint8
slouken@1895
   372
snd2au(int sample)
slouken@0
   373
{
slouken@0
   374
slouken@1895
   375
    int mask;
slouken@0
   376
slouken@1895
   377
    if (sample < 0) {
slouken@1895
   378
        sample = -sample;
slouken@1895
   379
        mask = 0x7f;
slouken@1895
   380
    } else {
slouken@1895
   381
        mask = 0xff;
slouken@1895
   382
    }
slouken@0
   383
slouken@1895
   384
    if (sample < 32) {
slouken@1895
   385
        sample = 0xF0 | (15 - sample / 2);
slouken@1895
   386
    } else if (sample < 96) {
slouken@1895
   387
        sample = 0xE0 | (15 - (sample - 32) / 4);
slouken@1895
   388
    } else if (sample < 224) {
slouken@1895
   389
        sample = 0xD0 | (15 - (sample - 96) / 8);
slouken@1895
   390
    } else if (sample < 480) {
slouken@1895
   391
        sample = 0xC0 | (15 - (sample - 224) / 16);
slouken@1895
   392
    } else if (sample < 992) {
slouken@1895
   393
        sample = 0xB0 | (15 - (sample - 480) / 32);
slouken@1895
   394
    } else if (sample < 2016) {
slouken@1895
   395
        sample = 0xA0 | (15 - (sample - 992) / 64);
slouken@1895
   396
    } else if (sample < 4064) {
slouken@1895
   397
        sample = 0x90 | (15 - (sample - 2016) / 128);
slouken@1895
   398
    } else if (sample < 8160) {
slouken@1895
   399
        sample = 0x80 | (15 - (sample - 4064) / 256);
slouken@1895
   400
    } else {
slouken@1895
   401
        sample = 0x80;
slouken@1895
   402
    }
slouken@1895
   403
    return (mask & sample);
slouken@0
   404
}
slouken@1895
   405
eviltypeguy@6967
   406
static int
eviltypeguy@6967
   407
SUNAUDIO_Init(SDL_AudioDriverImpl * impl)
eviltypeguy@6967
   408
{
eviltypeguy@6967
   409
    /* Set the function pointers */
eviltypeguy@6967
   410
    impl->DetectDevices = SUNAUDIO_DetectDevices;
eviltypeguy@6967
   411
    impl->OpenDevice = SUNAUDIO_OpenDevice;
eviltypeguy@6967
   412
    impl->PlayDevice = SUNAUDIO_PlayDevice;
eviltypeguy@6967
   413
    impl->WaitDevice = SUNAUDIO_WaitDevice;
eviltypeguy@6967
   414
    impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf;
eviltypeguy@6967
   415
    impl->CloseDevice = SUNAUDIO_CloseDevice;
eviltypeguy@6967
   416
icculus@9394
   417
    impl->AllowsArbitraryDeviceNames = 1;
icculus@9394
   418
eviltypeguy@6967
   419
    return 1; /* this audio target is available. */
eviltypeguy@6967
   420
}
eviltypeguy@6967
   421
eviltypeguy@6967
   422
AudioBootStrap SUNAUDIO_bootstrap = {
eviltypeguy@6967
   423
    "audio", "UNIX /dev/audio interface", SUNAUDIO_Init, 0
eviltypeguy@6967
   424
};
eviltypeguy@6967
   425
slouken@6044
   426
#endif /* SDL_AUDIO_DRIVER_SUNAUDIO */
slouken@6044
   427
slouken@1895
   428
/* vi: set ts=4 sw=4 expandtab: */