SDL  2.0
loopwave.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 1997-2018 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 {
32  Uint8 *sound; /* Pointer to wave data */
33  Uint32 soundlen; /* Length of wave data */
34  int soundpos; /* Current play position */
35 } wave;
36 
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
49 {
50  if (device != 0) {
52  device = 0;
53  }
54 }
55 
56 static void
58 {
59  /* Initialize fillerup() variables */
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 */
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 {
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 */
121 
122  /* Load the SDL library */
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 
152 
153 #ifdef __EMSCRIPTEN__
154  emscripten_set_main_loop(loop, 0, 1);
155 #else
156  while (!done) {
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: */
#define SDL_GetNumAudioDrivers
#define SDL_strlcpy
void loop()
Definition: checkkeys.c:152
#define SDL_INIT_EVENTS
Definition: SDL.h:82
#define SDL_PollEvent
#define SDL_GetError
#define SDL_CloseAudioDevice
#define SDL_OpenAudioDevice
Uint32 soundlen
Definition: loopwave.c:33
int main(int argc, char *argv[])
Definition: loopwave.c:114
Uint8 * sound
Definition: loopwave.c:32
#define SDL_FreeWAV
uint32_t Uint32
Definition: SDL_stdinc.h:181
GLenum GLsizei len
#define SDL_LogError
SDL_AudioSpec spec
Definition: loopwave.c:31
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define SDL_Log
#define SDL_memcpy
int soundpos
Definition: loopwave.c:34
GLuint GLuint stream
void fillerup(void *unused, Uint8 *stream, int len)
Definition: loopwave.c:80
uint8_t Uint8
Definition: SDL_stdinc.h:157
struct _cl_event * event
static void quit(int rc)
Definition: loopwave.c:41
#define SDL_FlushEvents
#define SDL_Quit
static void reopen_audio()
Definition: loopwave.c:72
#define SDL_LoadWAV(file, spec, audio_buf, audio_len)
Definition: SDL_audio.h:450
#define SDL_GetAudioDeviceStatus
#define SDL_GetAudioDriver
static int done
Definition: loopwave.c:102
#define SDL_Delay
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define SDL_LogSetPriority
#define SDL_GetCurrentAudioDriver
#define NULL
Definition: begin_code.h:164
SDL_AudioDeviceEvent adevice
Definition: SDL_events.h:544
#define SDL_INIT_AUDIO
Definition: SDL.h:77
static struct @51 wave
static void close_audio()
Definition: loopwave.c:48
Uint32 SDL_AudioDeviceID
Definition: SDL_audio.h:329
#define SDL_Init
General event structure.
Definition: SDL_events.h:525
#define SDLCALL
Definition: SDL_internal.h:45
Uint32 type
Definition: SDL_events.h:527
static void open_audio()
Definition: loopwave.c:57
#define SDL_PauseAudioDevice