test/loopwave.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 23 May 2019 14:19:00 -0700
changeset 12756 4116bf232fe7
parent 12503 806492103856
permissions -rw-r--r--
Added a function to get the current Android SDK version at runtime
     1 /*
     2   Copyright (C) 1997-2019 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: */