test/loopwave.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Dec 2017 16:08:09 -0800
changeset 11730 ac6c607e065c
parent 11020 3b993dbe4cf9
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Enable building the Metal renderer by default, and weak link the Metal framework so the SDL library is safe to use on older Macs
Also generate iOS versions of the Metal shaders
     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 #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: */