cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_diskaudio.c (4572B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      4
      5  This software is provided 'as-is', without any express or implied
      6  warranty.  In no event will the authors be held liable for any damages
      7  arising from the use of this software.
      8
      9  Permission is granted to anyone to use this software for any purpose,
     10  including commercial applications, and to alter it and redistribute it
     11  freely, subject to the following restrictions:
     12
     13  1. The origin of this software must not be misrepresented; you must not
     14     claim that you wrote the original software. If you use this software
     15     in a product, an acknowledgment in the product documentation would be
     16     appreciated but is not required.
     17  2. Altered source versions must be plainly marked as such, and must not be
     18     misrepresented as being the original software.
     19  3. This notice may not be removed or altered from any source distribution.
     20*/
     21#include "../../SDL_internal.h"
     22
     23#if SDL_AUDIO_DRIVER_DISK
     24
     25/* Output raw audio data to a file. */
     26
     27#if HAVE_STDIO_H
     28#include <stdio.h>
     29#endif
     30
     31#include "SDL_rwops.h"
     32#include "SDL_timer.h"
     33#include "SDL_audio.h"
     34#include "../SDL_audiomem.h"
     35#include "../SDL_audio_c.h"
     36#include "SDL_diskaudio.h"
     37
     38/* environment variables and defaults. */
     39#define DISKENVR_OUTFILE         "SDL_DISKAUDIOFILE"
     40#define DISKDEFAULT_OUTFILE      "sdlaudio.raw"
     41#define DISKENVR_WRITEDELAY      "SDL_DISKAUDIODELAY"
     42#define DISKDEFAULT_WRITEDELAY   150
     43
     44static const char *
     45DISKAUD_GetOutputFilename(const char *devname)
     46{
     47    if (devname == NULL) {
     48        devname = SDL_getenv(DISKENVR_OUTFILE);
     49        if (devname == NULL) {
     50            devname = DISKDEFAULT_OUTFILE;
     51        }
     52    }
     53    return devname;
     54}
     55
     56/* This function waits until it is possible to write a full sound buffer */
     57static void
     58DISKAUD_WaitDevice(_THIS)
     59{
     60    SDL_Delay(this->hidden->write_delay);
     61}
     62
     63static void
     64DISKAUD_PlayDevice(_THIS)
     65{
     66    size_t written;
     67
     68    /* Write the audio data */
     69    written = SDL_RWwrite(this->hidden->output,
     70                          this->hidden->mixbuf, 1, this->hidden->mixlen);
     71
     72    /* If we couldn't write, assume fatal error for now */
     73    if (written != this->hidden->mixlen) {
     74        this->enabled = 0;
     75    }
     76#ifdef DEBUG_AUDIO
     77    fprintf(stderr, "Wrote %d bytes of audio data\n", written);
     78#endif
     79}
     80
     81static Uint8 *
     82DISKAUD_GetDeviceBuf(_THIS)
     83{
     84    return (this->hidden->mixbuf);
     85}
     86
     87static void
     88DISKAUD_CloseDevice(_THIS)
     89{
     90    if (this->hidden != NULL) {
     91        SDL_FreeAudioMem(this->hidden->mixbuf);
     92        this->hidden->mixbuf = NULL;
     93        if (this->hidden->output != NULL) {
     94            SDL_RWclose(this->hidden->output);
     95            this->hidden->output = NULL;
     96        }
     97        SDL_free(this->hidden);
     98        this->hidden = NULL;
     99    }
    100}
    101
    102static int
    103DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture)
    104{
    105    const char *envr = SDL_getenv(DISKENVR_WRITEDELAY);
    106    const char *fname = DISKAUD_GetOutputFilename(devname);
    107
    108    this->hidden = (struct SDL_PrivateAudioData *)
    109        SDL_malloc(sizeof(*this->hidden));
    110    if (this->hidden == NULL) {
    111        return SDL_OutOfMemory();
    112    }
    113    SDL_memset(this->hidden, 0, sizeof(*this->hidden));
    114
    115    this->hidden->mixlen = this->spec.size;
    116    this->hidden->write_delay =
    117        (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
    118
    119    /* Open the audio device */
    120    this->hidden->output = SDL_RWFromFile(fname, "wb");
    121    if (this->hidden->output == NULL) {
    122        DISKAUD_CloseDevice(this);
    123        return -1;
    124    }
    125
    126    /* Allocate mixing buffer */
    127    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    128    if (this->hidden->mixbuf == NULL) {
    129        DISKAUD_CloseDevice(this);
    130        return -1;
    131    }
    132    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    133
    134#if HAVE_STDIO_H
    135    fprintf(stderr,
    136            "WARNING: You are using the SDL disk writer audio driver!\n"
    137            " Writing to file [%s].\n", fname);
    138#endif
    139
    140    /* We're ready to rock and roll. :-) */
    141    return 0;
    142}
    143
    144static int
    145DISKAUD_Init(SDL_AudioDriverImpl * impl)
    146{
    147    /* Set the function pointers */
    148    impl->OpenDevice = DISKAUD_OpenDevice;
    149    impl->WaitDevice = DISKAUD_WaitDevice;
    150    impl->PlayDevice = DISKAUD_PlayDevice;
    151    impl->GetDeviceBuf = DISKAUD_GetDeviceBuf;
    152    impl->CloseDevice = DISKAUD_CloseDevice;
    153
    154    return 1;   /* this audio target is available. */
    155}
    156
    157AudioBootStrap DISKAUD_bootstrap = {
    158    "disk", "direct-to-disk audio", DISKAUD_Init, 1
    159};
    160
    161#endif /* SDL_AUDIO_DRIVER_DISK */
    162
    163/* vi: set ts=4 sw=4 expandtab: */