sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

loopwave.c (4308B)


      1 /*
      2   Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
      3 
      4   This software is provided 'as-is', without any express or implied
      5   warranty.  In no event will the authors be held liable for any damages
      6   arising from the use of this software.
      7 
      8   Permission is granted to anyone to use this software for any purpose,
      9   including commercial applications, and to alter it and redistribute it
     10   freely.
     11 */
     12 
     13 /* Program to load a wave file and loop playing it using SDL audio */
     14 
     15 /* loopwaves.c is much more robust in handling WAVE files --
     16     This is only for simple WAVEs
     17 */
     18 #include "SDL_config.h"
     19 
     20 #include <stdio.h>
     21 #include <stdlib.h>
     22 
     23 #ifdef __EMSCRIPTEN__
     24 #include <emscripten/emscripten.h>
     25 #endif
     26 
     27 #include "SDL.h"
     28 
     29 static struct
     30 {
     31     SDL_AudioSpec spec;
     32     Uint8 *sound;               /* Pointer to wave data */
     33     Uint32 soundlen;            /* Length of wave data */
     34     int soundpos;               /* Current play position */
     35 } wave;
     36 
     37 static SDL_AudioDeviceID device;
     38 
     39 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
     40 static void
     41 quit(int rc)
     42 {
     43     SDL_Quit();
     44     exit(rc);
     45 }
     46 
     47 static void
     48 close_audio()
     49 {
     50     if (device != 0) {
     51         SDL_CloseAudioDevice(device);
     52         device = 0;
     53     }
     54 }
     55 
     56 static void
     57 open_audio()
     58 {
     59     /* Initialize fillerup() variables */
     60     device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wave.spec, NULL, 0);
     61     if (!device) {
     62         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
     63         SDL_FreeWAV(wave.sound);
     64         quit(2);
     65     }
     66 
     67 
     68     /* Let the audio run */
     69     SDL_PauseAudioDevice(device, SDL_FALSE);
     70 }
     71 
     72 static void reopen_audio()
     73 {
     74     close_audio();
     75     open_audio();
     76 }
     77 
     78 
     79 void SDLCALL
     80 fillerup(void *unused, Uint8 * stream, int len)
     81 {
     82     Uint8 *waveptr;
     83     int waveleft;
     84 
     85     /* Set up the pointers */
     86     waveptr = wave.sound + wave.soundpos;
     87     waveleft = wave.soundlen - wave.soundpos;
     88 
     89     /* Go! */
     90     while (waveleft <= len) {
     91         SDL_memcpy(stream, waveptr, waveleft);
     92         stream += waveleft;
     93         len -= waveleft;
     94         waveptr = wave.sound;
     95         waveleft = wave.soundlen;
     96         wave.soundpos = 0;
     97     }
     98     SDL_memcpy(stream, waveptr, len);
     99     wave.soundpos += len;
    100 }
    101 
    102 static int done = 0;
    103 
    104 #ifdef __EMSCRIPTEN__
    105 void
    106 loop()
    107 {
    108     if(done || (SDL_GetAudioDeviceStatus(device) != SDL_AUDIO_PLAYING))
    109         emscripten_cancel_main_loop();
    110 }
    111 #endif
    112 
    113 int
    114 main(int argc, char *argv[])
    115 {
    116     int i;
    117     char filename[4096];
    118 
    119     /* Enable standard application logging */
    120     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    121 
    122     /* Load the SDL library */
    123     if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_EVENTS) < 0) {
    124         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
    125         return (1);
    126     }
    127 
    128     if (argc > 1) {
    129         SDL_strlcpy(filename, argv[1], sizeof(filename));
    130     } else {
    131         SDL_strlcpy(filename, "sample.wav", sizeof(filename));
    132     }
    133     /* Load the wave file into memory */
    134     if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
    135         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
    136         quit(1);
    137     }
    138 
    139     wave.spec.callback = fillerup;
    140 
    141     /* Show the list of available drivers */
    142     SDL_Log("Available audio drivers:");
    143     for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
    144         SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
    145     }
    146 
    147     SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
    148 
    149     open_audio();
    150 
    151     SDL_FlushEvents(SDL_AUDIODEVICEADDED, SDL_AUDIODEVICEREMOVED);
    152 
    153 #ifdef __EMSCRIPTEN__
    154     emscripten_set_main_loop(loop, 0, 1);
    155 #else
    156     while (!done) {
    157         SDL_Event event;
    158 
    159         while (SDL_PollEvent(&event) > 0) {
    160             if (event.type == SDL_QUIT) {
    161                 done = 1;
    162             }
    163             if ((event.type == SDL_AUDIODEVICEADDED && !event.adevice.iscapture) ||
    164                 (event.type == SDL_AUDIODEVICEREMOVED && !event.adevice.iscapture && event.adevice.which == device)) {
    165                 reopen_audio();
    166             }
    167         }
    168         SDL_Delay(100);
    169     }
    170 #endif
    171 
    172     /* Clean up on signal */
    173     close_audio();
    174     SDL_FreeWAV(wave.sound);
    175     SDL_Quit();
    176     return (0);
    177 }
    178 
    179 /* vi: set ts=4 sw=4 expandtab: */