Freeciv-3.3
Loading...
Searching...
No Matches
audio_sdl.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <string.h>
19
20#ifdef AUDIO_SDL3
21#include <SDL3/SDL.h>
22#include <SDL3_mixer/SDL_mixer.h>
23#else
24#ifdef SDL2_PLAIN_INCLUDE
25#include <SDL.h>
26#include <SDL_mixer.h>
27#else /* SDL2_PLAIN_INCLUDE */
28#include <SDL2/SDL.h>
29#include <SDL2/SDL_mixer.h>
30#endif /* SDL2_PLAIN_INCLUDE */
31#endif /* AUDIO_SDL3 */
32
33/* utility */
34#include "log.h"
35#include "support.h"
36
37/* client */
38#include "audio.h"
39
40#include "audio_sdl.h"
41
42struct sample {
44 const char *tag;
45};
46
47/* Sounds don't sound good on Windows unless the buffer size is 4k,
48 * but this seems to cause strange behaviour on other systems,
49 * such as a delay before playing the sound. */
50#ifdef FREECIV_MSWINDOWS
51const size_t buf_size = 4096;
52#else
53const size_t buf_size = 1024;
54#endif
55
56static Mix_Music *mus = NULL;
58static double sdl_audio_volume;
59
60/**********************************************************************/
69
70/**********************************************************************/
73static double sdl_audio_get_volume(void)
74{
75 return sdl_audio_volume;
76}
77
78/**********************************************************************/
81static bool sdl_audio_play(const char *const tag, const char *const fullpath,
82 bool repeat, audio_finished_callback cb)
83{
84 int i, j;
86
87 if (!fullpath) {
88 return FALSE;
89 }
90
91 if (repeat) {
92 /* unload previous */
95
96 /* load music file */
98 if (mus == NULL) {
99 log_error("Can't open file \"%s\"", fullpath);
100 }
101
102 if (cb == NULL) {
103 Mix_PlayMusic(mus, -1); /* -1 means loop forever */
104 } else {
105 Mix_PlayMusic(mus, 0);
107 }
108 log_verbose("Playing file \"%s\" on music channel", fullpath);
109 /* in case we did a sdl_audio_stop() recently; add volume controls later */
111
112 } else {
113
114 /* see if we can cache on this one */
115 for (j = 0; j < MIX_CHANNELS; j++) {
116 if (samples[j].tag && (strcmp(samples[j].tag, tag) == 0)) {
117 log_debug("Playing file \"%s\" from cache (slot %d)", fullpath, j);
118 Mix_PlayChannel(-1, samples[j].wave, 0);
119 return TRUE;
120 }
121 } /* guess not */
122
123 /* load wave */
125 if (wave == NULL) {
126 log_error("Can't open file \"%s\"", fullpath);
127 }
128
129 /* play sound sample on first available channel, returns -1 if no
130 channel found */
131 i = Mix_PlayChannel(-1, wave, 0);
132 if (i < 0) {
133 log_verbose("No available sound channel to play %s.", tag);
135 return FALSE;
136 }
137 log_verbose("Playing file \"%s\" on channel %d", fullpath, i);
138 /* free previous sample on this channel. it will by definition no
139 longer be playing by the time we get here */
140 if (samples[i].wave) {
142 samples[i].wave = NULL;
143 }
144 /* remember for caching */
145 samples[i].wave = wave;
146 samples[i].tag = tag;
147
148 }
149 return TRUE;
150}
151
152/**********************************************************************/
155static void sdl_audio_pause(void)
156{
158}
159
160/**********************************************************************/
163static void sdl_audio_resume(void)
164{
166}
167
168/**********************************************************************/
171static void sdl_audio_stop(void)
172{
173 /* Fade out over 2 sec */
174 Mix_FadeOutMusic(2000);
175}
176
177/**********************************************************************/
182static void sdl_audio_wait(void)
183{
184 while (Mix_Playing(-1) != 0) {
185 SDL_Delay(100);
186 }
187}
188
189/**********************************************************************/
195static void quit_sdl_audio(void)
196{
199 } else {
200 SDL_Quit();
201 }
202}
203
204/**********************************************************************/
210static bool init_sdl_audio(void)
211{
212#ifdef AUDIO_SDL3
213 return SDL_Init(SDL_INIT_AUDIO);
214#else /* AUDIO_SDL3 */
216
219 } else {
221 }
222#endif /* AUDIO_SDL3 */
223}
224
225/**********************************************************************/
229{
230 int i;
231
232 self->initialized = FALSE;
233
236
237 /* Remove all buffers */
238 for (i = 0; i < MIX_CHANNELS; i++) {
239 if (samples[i].wave) {
241 }
242 }
245
248}
249
250/**********************************************************************/
253static bool sdl_audio_init(struct audio_plugin *self)
254{
255 int i;
256
257 if (!init_sdl_audio()) {
258 return FALSE;
259 }
260
261#ifdef AUDIO_SDL3
262 if (!Mix_OpenAudio(0, NULL)) {
263#else /* AUDIO_SDL3 */
264 /* Initialize variables */
267 const int audio_channels = 2;
268
270#endif /* AUDIO_SDL3 */
271 log_error("Error calling Mix_OpenAudio");
272
273 /* Try something else */
275 return FALSE;
276 }
277
279 for (i = 0; i < MIX_CHANNELS; i++) {
280 samples[i].wave = NULL;
281 }
282
283 /* Sanity check, for now; add volume controls later */
285
286 self->initialized = TRUE;
287
288 return TRUE;
289}
290
291/**********************************************************************/
296{
297 struct audio_plugin self;
298
299 sz_strlcpy(self.name, "sdl");
300 sz_strlcpy(self.descr, "Simple DirectMedia Library (SDL) mixer plugin");
301 self.initialized = FALSE;
302 self.init = sdl_audio_init;
303 self.shutdown = sdl_audio_shutdown;
304 self.stop = sdl_audio_stop;
305 self.wait = sdl_audio_wait;
306 self.play = sdl_audio_play;
307 self.pause = sdl_audio_pause;
308 self.resume = sdl_audio_resume;
309 self.set_volume = sdl_audio_set_volume;
310 self.get_volume = sdl_audio_get_volume;
312 sdl_audio_volume = 1.0;
313}
void audio_add_plugin(struct audio_plugin *p)
Definition audio.c:136
void(* audio_finished_callback)(void)
Definition audio.h:28
static void sdl_audio_shutdown(struct audio_plugin *self)
Definition audio_sdl.c:228
void audio_sdl_init(void)
Definition audio_sdl.c:295
static void sdl_audio_wait(void)
Definition audio_sdl.c:182
static void quit_sdl_audio(void)
Definition audio_sdl.c:195
static void sdl_audio_set_volume(double volume)
Definition audio_sdl.c:63
static bool sdl_audio_play(const char *const tag, const char *const fullpath, bool repeat, audio_finished_callback cb)
Definition audio_sdl.c:81
static void sdl_audio_resume(void)
Definition audio_sdl.c:163
static struct sample samples[MIX_CHANNELS]
Definition audio_sdl.c:57
static bool init_sdl_audio(void)
Definition audio_sdl.c:210
static double sdl_audio_volume
Definition audio_sdl.c:58
static bool sdl_audio_init(struct audio_plugin *self)
Definition audio_sdl.c:253
static Mix_Music * mus
Definition audio_sdl.c:56
const size_t buf_size
Definition audio_sdl.c:53
static void sdl_audio_pause(void)
Definition audio_sdl.c:155
static void sdl_audio_stop(void)
Definition audio_sdl.c:171
static double sdl_audio_get_volume(void)
Definition audio_sdl.c:73
static struct ai_type * self
Definition classicai.c:46
char * incite_cost
Definition comments.c:76
#define log_verbose(message,...)
Definition log.h:110
#define log_debug(message,...)
Definition log.h:116
#define log_error(message,...)
Definition log.h:104
char name[MAX_LEN_NAME]
Definition ai.h:51
Mix_Chunk * wave
Definition audio_sdl.c:43
const char * tag
Definition audio_sdl.c:44
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47