SDL 2.0
loopwave.c
Go to the documentation of this file.
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
29static struct
30{
32 Uint8 *sound; /* Pointer to wave data */
33 Uint32 soundlen; /* Length of wave data */
34 int soundpos; /* Current play position */
36
38
39/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
40static void
41quit(int rc)
42{
43 SDL_Quit();
44 exit(rc);
45}
46
47static void
49{
50 if (device != 0) {
52 device = 0;
53 }
54}
55
56static 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
72static void reopen_audio()
73{
75 open_audio();
76}
77
78
79void SDLCALL
80fillerup(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
102static int done = 0;
103
104#ifdef __EMSCRIPTEN__
105void
106loop()
107{
109 emscripten_cancel_main_loop();
110}
111#endif
112
113int
114main(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_INIT_AUDIO
Definition: SDL.h:78
#define SDL_INIT_EVENTS
Definition: SDL.h:83
@ SDL_AUDIO_PLAYING
Definition: SDL_audio.h:398
#define SDL_LoadWAV(file, spec, audio_buf, audio_len)
Definition: SDL_audio.h:484
Uint32 SDL_AudioDeviceID
Definition: SDL_audio.h:330
#define SDL_GetError
#define SDL_PollEvent
#define SDL_GetNumAudioDrivers
#define SDL_GetCurrentAudioDriver
#define SDL_strlcpy
#define SDL_LogSetPriority
#define SDL_OpenAudioDevice
#define SDL_LogError
#define SDL_FreeWAV
#define SDL_PauseAudioDevice
#define SDL_GetAudioDeviceStatus
#define SDL_Delay
#define SDL_Quit
#define SDL_memcpy
#define SDL_Init
#define SDL_CloseAudioDevice
#define SDL_GetAudioDriver
#define SDL_FlushEvents
#define SDL_Log
@ SDL_QUIT
Definition: SDL_events.h:60
@ SDL_AUDIODEVICEREMOVED
Definition: SDL_events.h:148
@ SDL_AUDIODEVICEADDED
Definition: SDL_events.h:147
#define SDLCALL
Definition: SDL_internal.h:49
@ SDL_LOG_PRIORITY_INFO
Definition: SDL_log.h:106
@ SDL_LOG_CATEGORY_APPLICATION
Definition: SDL_log.h:66
GLuint GLuint stream
struct _cl_event * event
GLenum GLsizei len
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint32_t Uint32
Definition: SDL_stdinc.h:203
uint8_t Uint8
Definition: SDL_stdinc.h:179
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 NULL
Definition: begin_code.h:167
void loop()
Definition: checkkeys.c:152
int main(int argc, char *argv[])
Definition: loopwave.c:114
static void open_audio()
Definition: loopwave.c:57
Uint8 * sound
Definition: loopwave.c:32
static struct @285 wave
static void quit(int rc)
Definition: loopwave.c:41
Uint32 soundlen
Definition: loopwave.c:33
SDL_AudioSpec spec
Definition: loopwave.c:31
static int done
Definition: loopwave.c:102
int soundpos
Definition: loopwave.c:34
static void close_audio()
Definition: loopwave.c:48
static SDL_AudioDeviceID device
Definition: loopwave.c:37
void fillerup(void *unused, Uint8 *stream, int len)
Definition: loopwave.c:80
static void reopen_audio()
Definition: loopwave.c:72
General event structure.
Definition: SDL_events.h:558