src/audio/sun/SDL_sunaudio.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 26 May 2015 21:19:23 -0400
changeset 9649 d7762e30ba24
parent 9619 b94b6d0bff0f
child 10000 acd714e378f4
permissions -rw-r--r--
Stack hint should look for 0, not -1, and not care about environment variables.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@9619
     3
  Copyright (C) 1997-2015 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 */
eviltypeguy@6967
    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@0
   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;
slouken@1895
   174
    }
slouken@0
   175
}
slouken@0
   176
eviltypeguy@6967
   177
static Uint8 *
eviltypeguy@6967
   178
SUNAUDIO_GetDeviceBuf(_THIS)
slouken@0
   179
{
eviltypeguy@6967
   180
    return (this->hidden->mixbuf);
slouken@0
   181
}
slouken@0
   182
eviltypeguy@6967
   183
static void
eviltypeguy@6967
   184
SUNAUDIO_CloseDevice(_THIS)
slouken@0
   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
        }
eviltypeguy@6967
   214
    }
eviltypeguy@6967
   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@0
   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@0
   250
#ifdef AUDIO_SETINFO
slouken@1895
   251
            enc = AUDIO_ENCODING_LINEAR;
slouken@0
   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@0
   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: */