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: */