/
loopwave.c
188 lines (153 loc) · 4.12 KB
1
/*
2
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
3
4
5
6
7
8
9
10
11
12
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
13
/* Program to load a wave file and loop playing it using SDL audio */
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/* loopwaves.c is much more robust in handling WAVE files --
This is only for simple WAVEs
*/
#include "SDL_config.h"
#include <stdio.h>
#include <stdlib.h>
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
#include "SDL.h"
33
static struct
34
35
36
37
38
39
40
{
SDL_AudioSpec spec;
Uint8 *sound; /* Pointer to wave data */
Uint32 soundlen; /* Length of wave data */
int soundpos; /* Current play position */
} wave;
41
static SDL_AudioDeviceID device;
42
43
44
45
46
47
48
49
50
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void
quit(int rc)
{
SDL_Quit();
exit(rc);
}
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
static void
close_audio()
{
if (device != 0) {
SDL_CloseAudioDevice(device);
device = 0;
}
}
static void
open_audio()
{
/* Initialize fillerup() variables */
device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wave.spec, NULL, 0);
if (!device) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
SDL_FreeWAV(wave.sound);
quit(2);
}
/* Let the audio run */
SDL_PauseAudioDevice(device, SDL_FALSE);
}
static void reopen_audio()
{
close_audio();
open_audio();
}
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
void SDLCALL
fillerup(void *unused, Uint8 * stream, int len)
{
Uint8 *waveptr;
int waveleft;
/* Set up the pointers */
waveptr = wave.sound + wave.soundpos;
waveleft = wave.soundlen - wave.soundpos;
/* Go! */
while (waveleft <= len) {
SDL_memcpy(stream, waveptr, waveleft);
stream += waveleft;
len -= waveleft;
waveptr = wave.sound;
waveleft = wave.soundlen;
wave.soundpos = 0;
}
SDL_memcpy(stream, waveptr, len);
wave.soundpos += len;
}
static int done = 0;
void
poked(int sig)
{
done = 1;
}
#ifdef __EMSCRIPTEN__
void
loop()
{
117
if(done || (SDL_GetAudioDeviceStatus(device) != SDL_AUDIO_PLAYING))
118
119
120
121
122
123
124
125
126
127
emscripten_cancel_main_loop();
}
#endif
int
main(int argc, char *argv[])
{
int i;
char filename[4096];
128
129
/* Enable standard application logging */
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
130
131
/* Load the SDL library */
132
if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_EVENTS) < 0) {
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
return (1);
}
if (argc > 1) {
SDL_strlcpy(filename, argv[1], sizeof(filename));
} else {
SDL_strlcpy(filename, "sample.wav", sizeof(filename));
}
/* Load the wave file into memory */
if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
quit(1);
}
wave.spec.callback = fillerup;
/* Show the list of available drivers */
SDL_Log("Available audio drivers:");
for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
153
SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
154
}
155
156
SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
157
158
open_audio();
159
160
SDL_FlushEvents(SDL_AUDIODEVICEADDED, SDL_AUDIODEVICEREMOVED);
161
162
163
164
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(loop, 0, 1);
#else
165
166
167
168
169
170
171
172
173
174
175
176
177
178
while (!done) {
SDL_Event event;
while (SDL_PollEvent(&event) > 0) {
if (event.type == SDL_QUIT) {
done = 1;
}
if ((event.type == SDL_AUDIODEVICEADDED && !event.adevice.iscapture) ||
(event.type == SDL_AUDIODEVICEREMOVED && !event.adevice.iscapture && event.adevice.which == device)) {
reopen_audio();
}
}
SDL_Delay(100);
}
179
180
181
#endif
/* Clean up on signal */
182
close_audio();
183
184
185
186
187
188
SDL_FreeWAV(wave.sound);
SDL_Quit();
return (0);
}
/* vi: set ts=4 sw=4 expandtab: */