src/audio/mint/SDL_mintaudio_gsxb.c
changeset 3283 1ed5d432e468
parent 3282 10a12f77f597
child 3284 2b95b2c0b6d4
     1.1 --- a/src/audio/mint/SDL_mintaudio_gsxb.c	Sun Sep 20 04:13:23 2009 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,443 +0,0 @@
     1.4 -/*
     1.5 -    SDL - Simple DirectMedia Layer
     1.6 -    Copyright (C) 1997-2009 Sam Lantinga
     1.7 -
     1.8 -    This library is free software; you can redistribute it and/or
     1.9 -    modify it under the terms of the GNU Library General Public
    1.10 -    License as published by the Free Software Foundation; either
    1.11 -    version 2 of the License, or (at your option) any later version.
    1.12 -
    1.13 -    This library is distributed in the hope that it will be useful,
    1.14 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16 -    Library General Public License for more details.
    1.17 -
    1.18 -    You should have received a copy of the GNU Library General Public
    1.19 -    License along with this library; if not, write to the Free
    1.20 -    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.21 -
    1.22 -    Sam Lantinga
    1.23 -    slouken@libsdl.org
    1.24 -*/
    1.25 -#include "SDL_config.h"
    1.26 -
    1.27 -/*
    1.28 -	MiNT audio driver
    1.29 -	using XBIOS functions (GSXB compatible driver)
    1.30 -
    1.31 -	Patrice Mandin
    1.32 -*/
    1.33 -
    1.34 -/* Mint includes */
    1.35 -#include <mint/osbind.h>
    1.36 -#include <mint/falcon.h>
    1.37 -#include <mint/cookie.h>
    1.38 -
    1.39 -#include "SDL_audio.h"
    1.40 -#include "../SDL_audio_c.h"
    1.41 -#include "../SDL_sysaudio.h"
    1.42 -
    1.43 -#include "../../video/ataricommon/SDL_atarimxalloc_c.h"
    1.44 -
    1.45 -#include "SDL_mintaudio.h"
    1.46 -#include "SDL_mintaudio_gsxb.h"
    1.47 -
    1.48 -/*--- Defines ---*/
    1.49 -
    1.50 -#define MINT_AUDIO_DRIVER_NAME "mint_gsxb"
    1.51 -
    1.52 -/* Debug print info */
    1.53 -#define DEBUG_NAME "audio:gsxb: "
    1.54 -#if 0
    1.55 -#define DEBUG_PRINT(what) \
    1.56 -	{ \
    1.57 -		printf what; \
    1.58 -	}
    1.59 -#else
    1.60 -#define DEBUG_PRINT(what)
    1.61 -#endif
    1.62 -
    1.63 -/*--- Static variables ---*/
    1.64 -
    1.65 -static unsigned long cookie_snd, cookie_gsxb;
    1.66 -
    1.67 -/*--- Audio driver functions ---*/
    1.68 -
    1.69 -/* GSXB callbacks */
    1.70 -static void MINTGSXB_GsxbInterrupt(void);
    1.71 -static void MINTGSXB_GsxbNullInterrupt(void);
    1.72 -
    1.73 -static void
    1.74 -MINTGSXB_LockDevice(_THIS)
    1.75 -{
    1.76 -    /* Stop replay */
    1.77 -    Buffoper(0);
    1.78 -}
    1.79 -
    1.80 -static void
    1.81 -MINTGSXB_UnlockDevice(_THIS)
    1.82 -{
    1.83 -    /* Restart replay */
    1.84 -    Buffoper(SB_PLA_ENA | SB_PLA_RPT);
    1.85 -}
    1.86 -
    1.87 -static void
    1.88 -MINTGSXB_CloseDevice(_THIS)
    1.89 -{
    1.90 -    if (this->hidden != NULL) {
    1.91 -        /* Stop replay */
    1.92 -        Buffoper(0);
    1.93 -
    1.94 -        /* Uninstall interrupt */
    1.95 -        if (NSetinterrupt(2, SI_NONE, MINTGSXB_GsxbNullInterrupt) < 0) {
    1.96 -            DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n"));
    1.97 -        }
    1.98 -
    1.99 -        /* Wait if currently playing sound */
   1.100 -        while (SDL_MintAudio_mutex != 0) {
   1.101 -        }
   1.102 -
   1.103 -        /* Clear buffers */
   1.104 -        if (SDL_MintAudio_audiobuf[0]) {
   1.105 -            Mfree(SDL_MintAudio_audiobuf[0]);
   1.106 -            SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
   1.107 -        }
   1.108 -
   1.109 -        /* Unlock sound system */
   1.110 -        Unlocksnd();
   1.111 -
   1.112 -        SDL_free(this->hidden);
   1.113 -        this->hidden = NULL;
   1.114 -    }
   1.115 -}
   1.116 -
   1.117 -static int
   1.118 -MINTGSXB_CheckAudio(_THIS)
   1.119 -{
   1.120 -    long snd_format;
   1.121 -    int i, resolution, format_signed, format_bigendian;
   1.122 -    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
   1.123 -    int valid_datatype = 0;
   1.124 -
   1.125 -    resolution = SDL_AUDIO_BITSIZE(this->spec.format);
   1.126 -    format_signed = SDL_AUDIO_ISSIGNED(this->spec.format);
   1.127 -    format_bigendian = SDL_AUDIO_ISBIGENDIAN(this->spec.format);
   1.128 -
   1.129 -    DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", resolution));
   1.130 -    DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
   1.131 -    DEBUG_PRINT(("signed=%d, ", format_signed));
   1.132 -    DEBUG_PRINT(("big endian=%d, ", format_bigendian));
   1.133 -    DEBUG_PRINT(("channels=%d, ", this->spec.channels));
   1.134 -    DEBUG_PRINT(("freq=%d\n", this->spec.freq));
   1.135 -
   1.136 -    if (this->spec.channels > 2) {
   1.137 -        this->spec.channels = 2;        /* no more than stereo! */
   1.138 -    }
   1.139 -
   1.140 -    while ((!valid_datatype) && (test_format)) {
   1.141 -        /* Check formats available */
   1.142 -        snd_format = Sndstatus(SND_QUERYFORMATS);
   1.143 -        this->spec.format = test_format;
   1.144 -        resolution = SDL_AUDIO_BITSIZE(this->spec.format);
   1.145 -        format_signed = SDL_AUDIO_ISSIGNED(this->spec.format);
   1.146 -        format_bigendian = SDL_AUDIO_ISBIGENDIAN(this->spec.format);
   1.147 -        switch (test_format) {
   1.148 -        case AUDIO_U8:
   1.149 -        case AUDIO_S8:
   1.150 -            if (snd_format & SND_FORMAT8) {
   1.151 -                valid_datatype = 1;
   1.152 -                snd_format = Sndstatus(SND_QUERY8BIT);
   1.153 -            }
   1.154 -            break;
   1.155 -
   1.156 -        case AUDIO_U16LSB:
   1.157 -        case AUDIO_S16LSB:
   1.158 -        case AUDIO_U16MSB:
   1.159 -        case AUDIO_S16MSB:
   1.160 -            if (snd_format & SND_FORMAT16) {
   1.161 -                valid_datatype = 1;
   1.162 -                snd_format = Sndstatus(SND_QUERY16BIT);
   1.163 -            }
   1.164 -            break;
   1.165 -
   1.166 -        case AUDIO_S32LSB:
   1.167 -        case AUDIO_S32MSB:
   1.168 -            if (snd_format & SND_FORMAT32) {
   1.169 -                valid_datatype = 1;
   1.170 -                snd_format = Sndstatus(SND_QUERY32BIT);
   1.171 -            }
   1.172 -            break;
   1.173 -
   1.174 -            /* no float support... */
   1.175 -
   1.176 -        default:
   1.177 -            test_format = SDL_NextAudioFormat();
   1.178 -            break;
   1.179 -        }
   1.180 -    }
   1.181 -
   1.182 -    if (!valid_datatype) {
   1.183 -        SDL_SetError("Unsupported audio format");
   1.184 -        return (-1);
   1.185 -    }
   1.186 -
   1.187 -    /* Check signed/unsigned format */
   1.188 -    if (format_signed) {
   1.189 -        if (snd_format & SND_FORMATSIGNED) {
   1.190 -            /* Ok */
   1.191 -        } else if (snd_format & SND_FORMATUNSIGNED) {
   1.192 -            /* Give unsigned format */
   1.193 -            this->spec.format = this->spec.format & (~SDL_AUDIO_MASK_SIGNED);
   1.194 -        }
   1.195 -    } else {
   1.196 -        if (snd_format & SND_FORMATUNSIGNED) {
   1.197 -            /* Ok */
   1.198 -        } else if (snd_format & SND_FORMATSIGNED) {
   1.199 -            /* Give signed format */
   1.200 -            this->spec.format |= SDL_AUDIO_MASK_SIGNED;
   1.201 -        }
   1.202 -    }
   1.203 -
   1.204 -    if (format_bigendian) {
   1.205 -        if (snd_format & SND_FORMATBIGENDIAN) {
   1.206 -            /* Ok */
   1.207 -        } else if (snd_format & SND_FORMATLITTLEENDIAN) {
   1.208 -            /* Give little endian format */
   1.209 -            this->spec.format = this->spec.format & (~SDL_AUDIO_MASK_ENDIAN);
   1.210 -        }
   1.211 -    } else {
   1.212 -        if (snd_format & SND_FORMATLITTLEENDIAN) {
   1.213 -            /* Ok */
   1.214 -        } else if (snd_format & SND_FORMATBIGENDIAN) {
   1.215 -            /* Give big endian format */
   1.216 -            this->spec.format |= SDL_AUDIO_MASK_ENDIAN;
   1.217 -        }
   1.218 -    }
   1.219 -
   1.220 -    /* Calculate and select the closest frequency */
   1.221 -    MINTAUDIO_freqcount = 0;
   1.222 -    for (i = 1; i < 4; i++) {
   1.223 -        SDL_MintAudio_AddFrequency(this,
   1.224 -                                   MASTERCLOCK_44K / (MASTERPREDIV_MILAN *
   1.225 -                                                      (1 << i)),
   1.226 -                                   MASTERCLOCK_44K, (1 << i) - 1, -1);
   1.227 -    }
   1.228 -
   1.229 -#if 1
   1.230 -    for (i = 0; i < MINTAUDIO_freqcount; i++) {
   1.231 -        DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n",
   1.232 -                     i, MINTAUDIO_frequencies[i].frequency,
   1.233 -                     MINTAUDIO_frequencies[i].masterclock,
   1.234 -                     MINTAUDIO_frequencies[i].predivisor));
   1.235 -    }
   1.236 -#endif
   1.237 -
   1.238 -    MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq);
   1.239 -    this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
   1.240 -
   1.241 -    DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
   1.242 -                 SDL_AUDIO_BITSIZE(this->spec.format)));
   1.243 -    DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
   1.244 -    DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
   1.245 -    DEBUG_PRINT(("big endian=%d, ",
   1.246 -                 SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
   1.247 -    DEBUG_PRINT(("channels=%d, ", this->spec.channels));
   1.248 -    DEBUG_PRINT(("freq=%d\n", this->spec.freq));
   1.249 -
   1.250 -    return 0;
   1.251 -}
   1.252 -
   1.253 -static void
   1.254 -MINTGSXB_InitAudio(_THIS)
   1.255 -{
   1.256 -    int channels_mode, prediv;
   1.257 -    void *buffer;
   1.258 -
   1.259 -    /* Stop currently playing sound */
   1.260 -    Buffoper(0);
   1.261 -
   1.262 -    /* Set replay tracks */
   1.263 -    Settracks(0, 0);
   1.264 -    Setmontracks(0);
   1.265 -
   1.266 -    /* Select replay format */
   1.267 -    switch (SDL_AUDIO_BITSIZE(this->spec.format)) {
   1.268 -    case 8:
   1.269 -        if (this->spec.channels == 2) {
   1.270 -            channels_mode = STEREO8;
   1.271 -        } else {
   1.272 -            channels_mode = MONO8;
   1.273 -        }
   1.274 -        break;
   1.275 -    case 16:
   1.276 -        if (this->spec.channels == 2) {
   1.277 -            channels_mode = STEREO16;
   1.278 -        } else {
   1.279 -            channels_mode = MONO16;
   1.280 -        }
   1.281 -        break;
   1.282 -    case 32:
   1.283 -        if (this->spec.channels == 2) {
   1.284 -            channels_mode = STEREO32;
   1.285 -        } else {
   1.286 -            channels_mode = MONO32;
   1.287 -        }
   1.288 -        break;
   1.289 -    default:
   1.290 -        channels_mode = STEREO16;
   1.291 -        break;
   1.292 -    }
   1.293 -    if (Setmode(channels_mode) < 0) {
   1.294 -        DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n"));
   1.295 -    }
   1.296 -
   1.297 -    prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
   1.298 -    Devconnect(DMAPLAY, DAC, CLKEXT, prediv, 1);
   1.299 -
   1.300 -    /* Set buffer */
   1.301 -    buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
   1.302 -    if (Setbuffer(0, buffer, buffer + this->spec.size) < 0) {
   1.303 -        DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
   1.304 -    }
   1.305 -
   1.306 -    /* Install interrupt */
   1.307 -    if (NSetinterrupt(2, SI_PLAY, MINTGSXB_GsxbInterrupt) < 0) {
   1.308 -        DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed\n"));
   1.309 -    }
   1.310 -
   1.311 -    /* Go */
   1.312 -    Buffoper(SB_PLA_ENA | SB_PLA_RPT);
   1.313 -    DEBUG_PRINT((DEBUG_NAME "hardware initialized\n"));
   1.314 -}
   1.315 -
   1.316 -static int
   1.317 -MINTGSXB_OpenDevice(_THIS, const char *devname, int iscapture)
   1.318 -{
   1.319 -    /* Lock sound system */
   1.320 -    if (Locksnd() != 1) {
   1.321 -        SDL_SetError("MINTGSXB_OpenDevice: Audio system already in use");
   1.322 -        return 0;
   1.323 -    }
   1.324 -
   1.325 -    SDL_MintAudio_device = this;
   1.326 -
   1.327 -    /* Check audio capabilities */
   1.328 -    if (MINTGSXB_CheckAudio(this) == -1) {
   1.329 -        return 0;
   1.330 -    }
   1.331 -
   1.332 -    /* Initialize all variables that we clean on shutdown */
   1.333 -    this->hidden = (struct SDL_PrivateAudioData *)
   1.334 -        SDL_malloc((sizeof *this->hidden));
   1.335 -    if (this->hidden == NULL) {
   1.336 -        SDL_OutOfMemory();
   1.337 -        return 0;
   1.338 -    }
   1.339 -    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
   1.340 -
   1.341 -    SDL_CalculateAudioSpec(&this->spec);
   1.342 -
   1.343 -    /* Allocate memory for audio buffers in DMA-able RAM */
   1.344 -    DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size));
   1.345 -
   1.346 -    SDL_MintAudio_audiobuf[0] =
   1.347 -        Atari_SysMalloc(this->spec.size * 2, MX_STRAM);
   1.348 -    if (SDL_MintAudio_audiobuf[0] == NULL) {
   1.349 -        SDL_free(this->hidden);
   1.350 -        this->hidden = NULL;
   1.351 -        SDL_OutOfMemory();
   1.352 -        return 0;
   1.353 -    }
   1.354 -    SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size;
   1.355 -    SDL_MintAudio_numbuf = 0;
   1.356 -    SDL_memset(SDL_MintAudio_audiobuf[0], this->spec.silence,
   1.357 -               this->spec.size * 2);
   1.358 -    SDL_MintAudio_audiosize = this->spec.size;
   1.359 -    SDL_MintAudio_mutex = 0;
   1.360 -
   1.361 -    DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n",
   1.362 -                 SDL_MintAudio_audiobuf[0]));
   1.363 -    DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n",
   1.364 -                 SDL_MintAudio_audiobuf[1]));
   1.365 -
   1.366 -    SDL_MintAudio_CheckFpu();
   1.367 -
   1.368 -    /* Setup audio hardware */
   1.369 -    MINTGSXB_InitAudio(this);
   1.370 -
   1.371 -    return 1;                   /* good to go. */
   1.372 -}
   1.373 -
   1.374 -static void
   1.375 -MINTGSXB_GsxbInterrupt(void)
   1.376 -{
   1.377 -    Uint8 *newbuf;
   1.378 -
   1.379 -    if (SDL_MintAudio_mutex)
   1.380 -        return;
   1.381 -
   1.382 -    SDL_MintAudio_mutex = 1;
   1.383 -
   1.384 -    SDL_MintAudio_numbuf ^= 1;
   1.385 -    SDL_MintAudio_Callback();
   1.386 -    newbuf = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
   1.387 -    Setbuffer(0, newbuf, newbuf + SDL_MintAudio_audiosize);
   1.388 -
   1.389 -    SDL_MintAudio_mutex = 0;
   1.390 -}
   1.391 -
   1.392 -static void
   1.393 -MINTGSXB_GsxbNullInterrupt(void)
   1.394 -{
   1.395 -}
   1.396 -
   1.397 -static int
   1.398 -MINTGSXB_Init(SDL_AudioDriverImpl * impl)
   1.399 -{
   1.400 -    /* Cookie _SND present ? if not, assume ST machine */
   1.401 -    if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
   1.402 -        cookie_snd = SND_PSG;
   1.403 -    }
   1.404 -
   1.405 -    /* Check if we have 16 bits audio */
   1.406 -    if ((cookie_snd & SND_16BIT) == 0) {
   1.407 -        SDL_SetError(DEBUG_NAME "no 16-bit sound");
   1.408 -        return 0;
   1.409 -    }
   1.410 -
   1.411 -    /* Cookie GSXB present ? */
   1.412 -    cookie_gsxb = (Getcookie(C_GSXB, &cookie_gsxb) == C_FOUND);
   1.413 -
   1.414 -    /* Is it GSXB ? */
   1.415 -    if (((cookie_snd & SND_GSXB) == 0) || (cookie_gsxb == 0)) {
   1.416 -        SDL_SetError(DEBUG_NAME "no GSXB audio");
   1.417 -        return 0;
   1.418 -    }
   1.419 -
   1.420 -    /* Check if audio is lockable */
   1.421 -    if (Locksnd() != 1) {
   1.422 -        SDL_SetError(DEBUG_NAME "audio locked by other application");
   1.423 -        return 0;
   1.424 -    }
   1.425 -
   1.426 -    Unlocksnd();
   1.427 -
   1.428 -    DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n"));
   1.429 -
   1.430 -    /* Set the function pointers */
   1.431 -    impl->OpenDevice = MINTGSXB_OpenDevice;
   1.432 -    impl->CloseDevice = MINTGSXB_CloseDevice;
   1.433 -    impl->LockDevice = MINTGSXB_LockDevice;
   1.434 -    impl->UnlockDevice = MINTGSXB_UnlockDevice;
   1.435 -    impl->OnlyHasDefaultOutputDevice = 1;
   1.436 -    impl->ProvidesOwnCallbackThread = 1;
   1.437 -    impl->SkipMixerLock = 1;
   1.438 -
   1.439 -    return 2;                   /* 2 == definitely has an audio device. */
   1.440 -}
   1.441 -
   1.442 -AudioBootStrap MINTAUDIO_GSXB_bootstrap = {
   1.443 -    MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver", MINTGSXB_Init, 0
   1.444 -};
   1.445 -
   1.446 -/* vi: set ts=4 sw=4 expandtab: */