test/loopwave.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 09 Mar 2017 15:12:19 -0800
changeset 10933 a9ce2bbd76e1
parent 10932 98b94b9e3e8c
child 11020 3b993dbe4cf9
permissions -rw-r--r--
Fixed tabs to spaces
     1 /*
     2   Copyright (C) 1997-2017 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 #if HAVE_SIGNAL_H
    24 #include <signal.h>
    25 #endif
    26 
    27 #ifdef __EMSCRIPTEN__
    28 #include <emscripten/emscripten.h>
    29 #endif
    30 
    31 #include "SDL.h"
    32 
    33 static struct
    34 {
    35     SDL_AudioSpec spec;
    36     Uint8 *sound;               /* Pointer to wave data */
    37     Uint32 soundlen;            /* Length of wave data */
    38     int soundpos;               /* Current play position */
    39 } wave;
    40 
    41 static SDL_AudioDeviceID device;
    42 
    43 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    44 static void
    45 quit(int rc)
    46 {
    47     SDL_Quit();
    48     exit(rc);
    49 }
    50 
    51 static void
    52 close_audio()
    53 {
    54     if (device != 0) {
    55         SDL_CloseAudioDevice(device);
    56         device = 0;
    57     }
    58 }
    59 
    60 static void
    61 open_audio()
    62 {
    63     /* Initialize fillerup() variables */
    64     device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wave.spec, NULL, 0);
    65     if (!device) {
    66         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
    67         SDL_FreeWAV(wave.sound);
    68         quit(2);
    69     }
    70 
    71 
    72     /* Let the audio run */
    73     SDL_PauseAudioDevice(device, SDL_FALSE);
    74 }
    75 
    76 static void reopen_audio()
    77 {
    78     close_audio();
    79     open_audio();
    80 }
    81 
    82 
    83 void SDLCALL
    84 fillerup(void *unused, Uint8 * stream, int len)
    85 {
    86     Uint8 *waveptr;
    87     int waveleft;
    88 
    89     /* Set up the pointers */
    90     waveptr = wave.sound + wave.soundpos;
    91     waveleft = wave.soundlen - wave.soundpos;
    92 
    93     /* Go! */
    94     while (waveleft <= len) {
    95         SDL_memcpy(stream, waveptr, waveleft);
    96         stream += waveleft;
    97         len -= waveleft;
    98         waveptr = wave.sound;
    99         waveleft = wave.soundlen;
   100         wave.soundpos = 0;
   101     }
   102     SDL_memcpy(stream, waveptr, len);
   103     wave.soundpos += len;
   104 }
   105 
   106 static int done = 0;
   107 void
   108 poked(int sig)
   109 {
   110     done = 1;
   111 }
   112 
   113 #ifdef __EMSCRIPTEN__
   114 void
   115 loop()
   116 {
   117     if(done || (SDL_GetAudioDeviceStatus(device) != SDL_AUDIO_PLAYING))
   118         emscripten_cancel_main_loop();
   119 }
   120 #endif
   121 
   122 int
   123 main(int argc, char *argv[])
   124 {
   125     int i;
   126     char filename[4096];
   127 
   128     /* Enable standard application logging */
   129     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
   130 
   131     /* Load the SDL library */
   132     if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_EVENTS) < 0) {
   133         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
   134         return (1);
   135     }
   136 
   137     if (argc > 1) {
   138         SDL_strlcpy(filename, argv[1], sizeof(filename));
   139     } else {
   140         SDL_strlcpy(filename, "sample.wav", sizeof(filename));
   141     }
   142     /* Load the wave file into memory */
   143     if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
   144         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
   145         quit(1);
   146     }
   147 
   148     wave.spec.callback = fillerup;
   149 
   150     /* Show the list of available drivers */
   151     SDL_Log("Available audio drivers:");
   152     for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
   153         SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
   154     }
   155 
   156     SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
   157 
   158     open_audio();
   159 
   160     SDL_FlushEvents(SDL_AUDIODEVICEADDED, SDL_AUDIODEVICEREMOVED);
   161 
   162 #ifdef __EMSCRIPTEN__
   163     emscripten_set_main_loop(loop, 0, 1);
   164 #else
   165     while (!done) {
   166         SDL_Event event;
   167 
   168         while (SDL_PollEvent(&event) > 0) {
   169             if (event.type == SDL_QUIT) {
   170                 done = 1;
   171             }
   172             if ((event.type == SDL_AUDIODEVICEADDED && !event.adevice.iscapture) ||
   173                 (event.type == SDL_AUDIODEVICEREMOVED && !event.adevice.iscapture && event.adevice.which == device)) {
   174                 reopen_audio();
   175             }
   176         }
   177         SDL_Delay(100);
   178     }
   179 #endif
   180 
   181     /* Clean up on signal */
   182     close_audio();
   183     SDL_FreeWAV(wave.sound);
   184     SDL_Quit();
   185     return (0);
   186 }
   187 
   188 /* vi: set ts=4 sw=4 expandtab: */