zenilib: zenilib/jni/external/sdl/src/audio/fusionsound/SDL_fsaudio.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_fsaudio.c
Go to the documentation of this file.
1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22
23 #if SDL_AUDIO_DRIVER_FUSIONSOUND
24
25 /* Allow access to a raw mixing buffer */
26
27 #ifdef HAVE_SIGNAL_H
28 #include <signal.h>
29 #endif
30 #include <unistd.h>
31
32 #include "SDL_timer.h"
33 #include "SDL_audio.h"
34 #include "../SDL_audiomem.h"
35 #include "../SDL_audio_c.h"
36 #include "SDL_fsaudio.h"
37
38 #include <fusionsound/fusionsound_version.h>
39
40 /* #define SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC "libfusionsound.so" */
41
42 #ifdef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC
43 #include "SDL_name.h"
44 #include "SDL_loadso.h"
45 #else
46 #define SDL_NAME(X) X
47 #endif
48
49 #if (FUSIONSOUND_MAJOR_VERSION == 1) && (FUSIONSOUND_MINOR_VERSION < 1)
50 typedef DFBResult DirectResult;
51 #endif
52
53 /* Buffers to use - more than 2 gives a lot of latency */
54 #define FUSION_BUFFERS (2)
55
56 #ifdef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC
57
58 static const char *fs_library = SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC;
59 static void *fs_handle = NULL;
60
61 static DirectResult (*SDL_NAME(FusionSoundInit)) (int *argc, char *(*argv[]));
62 static DirectResult (*SDL_NAME(FusionSoundCreate)) (IFusionSound **
63 ret_interface);
64
65 #define SDL_FS_SYM(x) { #x, (void **) (char *) &SDL_NAME(x) }
66 static struct
67 {
68 const char *name;
69 void **func;
70 } fs_functions[] = {
71 /* *INDENT-OFF* */
72 SDL_FS_SYM(FusionSoundInit),
73 SDL_FS_SYM(FusionSoundCreate),
74 /* *INDENT-ON* */
75 };
76
77 #undef SDL_FS_SYM
78
79 static void
80 UnloadFusionSoundLibrary()
81 {
82 if (fs_handle != NULL) {
83 SDL_UnloadObject(fs_handle);
84 fs_handle = NULL;
85 }
86 }
87
88 static int
89 LoadFusionSoundLibrary(void)
90 {
91 int i, retval = -1;
92
93 if (fs_handle == NULL) {
94 fs_handle = SDL_LoadObject(fs_library);
95 if (fs_handle != NULL) {
96 retval = 0;
97 for (i = 0; i < SDL_arraysize(fs_functions); ++i) {
98 *fs_functions[i].func =
99 SDL_LoadFunction(fs_handle, fs_functions[i].name);
100 if (!*fs_functions[i].func) {
101 retval = -1;
102 UnloadFusionSoundLibrary();
103 break;
104 }
105 }
106 }
107 }
108
109 return retval;
110 }
111
112 #else
113
114 static void
115 UnloadFusionSoundLibrary()
116 {
117 return;
118 }
119
120 static int
121 LoadFusionSoundLibrary(void)
122 {
123 return 0;
124 }
125
126 #endif /* SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC */
127
128 /* This function waits until it is possible to write a full sound buffer */
129 static void
130 SDL_FS_WaitDevice(_THIS)
131 {
132 this->hidden->stream->Wait(this->hidden->stream,
133 this->hidden->mixsamples);
134 }
135
136 static void
137 SDL_FS_PlayDevice(_THIS)
138 {
139 DirectResult ret;
140
141 ret = this->hidden->stream->Write(this->hidden->stream,
142 this->hidden->mixbuf,
143 this->hidden->mixsamples);
144 /* If we couldn't write, assume fatal error for now */
145 if (ret) {
146 this->enabled = 0;
147 }
148 #ifdef DEBUG_AUDIO
149 fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen);
150 #endif
151 }
152
153 static void
154 SDL_FS_WaitDone(_THIS)
155 {
156 this->hidden->stream->Wait(this->hidden->stream,
157 this->hidden->mixsamples * FUSION_BUFFERS);
158 }
159
160
161 static Uint8 *
162 SDL_FS_GetDeviceBuf(_THIS)
163 {
164 return (this->hidden->mixbuf);
165 }
166
167
168 static void
169 SDL_FS_CloseDevice(_THIS)
170 {
171 if (this->hidden != NULL) {
172 SDL_FreeAudioMem(this->hidden->mixbuf);
173 this->hidden->mixbuf = NULL;
174 if (this->hidden->stream) {
175 this->hidden->stream->Release(this->hidden->stream);
176 this->hidden->stream = NULL;
177 }
178 if (this->hidden->fs) {
179 this->hidden->fs->Release(this->hidden->fs);
180 this->hidden->fs = NULL;
181 }
182 SDL_free(this->hidden);
183 this->hidden = NULL;
184 }
185 }
186
187
188 static int
189 SDL_FS_OpenDevice(_THIS, const char *devname, int iscapture)
190 {
191 int bytes;
192 SDL_AudioFormat test_format = 0, format = 0;
193 FSSampleFormat fs_format;
194 FSStreamDescription desc;
195 DirectResult ret;
196
197 /* Initialize all variables that we clean on shutdown */
198 this->hidden = (struct SDL_PrivateAudioData *)
199 SDL_malloc((sizeof *this->hidden));
200 if (this->hidden == NULL) {
201 return SDL_OutOfMemory();
202 }
203 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
204
205 /* Try for a closest match on audio format */
206 for (test_format = SDL_FirstAudioFormat(this->spec.format);
207 !format && test_format;) {
208 #ifdef DEBUG_AUDIO
209 fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
210 #endif
211 switch (test_format) {
212 case AUDIO_U8:
213 fs_format = FSSF_U8;
214 bytes = 1;
215 format = 1;
216 break;
217 case AUDIO_S16SYS:
218 fs_format = FSSF_S16;
219 bytes = 2;
220 format = 1;
221 break;
222 case AUDIO_S32SYS:
223 fs_format = FSSF_S32;
224 bytes = 4;
225 format = 1;
226 break;
227 case AUDIO_F32SYS:
228 fs_format = FSSF_FLOAT;
229 bytes = 4;
230 format = 1;
231 break;
232 default:
233 format = 0;
234 break;
235 }
236 if (!format) {
237 test_format = SDL_NextAudioFormat();
238 }
239 }
240
241 if (format == 0) {
242 SDL_FS_CloseDevice(this);
243 return SDL_SetError("Couldn't find any hardware audio formats");
244 }
245 this->spec.format = test_format;
246
247 /* Retrieve the main sound interface. */
248 ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs);
249 if (ret) {
250 SDL_FS_CloseDevice(this);
251 return SDL_SetError("Unable to initialize FusionSound: %d", ret);
252 }
253
254 this->hidden->mixsamples = this->spec.size / bytes / this->spec.channels;
255
256 /* Fill stream description. */
257 desc.flags = FSSDF_SAMPLERATE | FSSDF_BUFFERSIZE |
258 FSSDF_CHANNELS | FSSDF_SAMPLEFORMAT | FSSDF_PREBUFFER;
259 desc.samplerate = this->spec.freq;
260 desc.buffersize = this->spec.size * FUSION_BUFFERS;
261 desc.channels = this->spec.channels;
262 desc.prebuffer = 10;
263 desc.sampleformat = fs_format;
264
265 ret =
266 this->hidden->fs->CreateStream(this->hidden->fs, &desc,
267 &this->hidden->stream);
268 if (ret) {
269 SDL_FS_CloseDevice(this);
270 return SDL_SetError("Unable to create FusionSoundStream: %d", ret);
271 }
272
273 /* See what we got */
274 desc.flags = FSSDF_SAMPLERATE | FSSDF_BUFFERSIZE |
275 FSSDF_CHANNELS | FSSDF_SAMPLEFORMAT;
276 ret = this->hidden->stream->GetDescription(this->hidden->stream, &desc);
277
278 this->spec.freq = desc.samplerate;
279 this->spec.size =
280 desc.buffersize / FUSION_BUFFERS * bytes * desc.channels;
281 this->spec.channels = desc.channels;
282
283 /* Calculate the final parameters for this audio specification */
284 SDL_CalculateAudioSpec(&this->spec);
285
286 /* Allocate mixing buffer */
287 this->hidden->mixlen = this->spec.size;
288 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
289 if (this->hidden->mixbuf == NULL) {
290 SDL_FS_CloseDevice(this);
291 return SDL_OutOfMemory();
292 }
293 SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
294
295 /* We're ready to rock and roll. :-) */
296 return 0;
297 }
298
299
300 static void
301 SDL_FS_Deinitialize(void)
302 {
303 UnloadFusionSoundLibrary();
304 }
305
306
307 static int
308 SDL_FS_Init(SDL_AudioDriverImpl * impl)
309 {
310 if (LoadFusionSoundLibrary() < 0) {
311 return 0;
312 } else {
313 DirectResult ret;
314
315 ret = SDL_NAME(FusionSoundInit) (NULL, NULL);
316 if (ret) {
317 UnloadFusionSoundLibrary();
318 SDL_SetError
319 ("FusionSound: SDL_FS_init failed (FusionSoundInit: %d)",
320 ret);
321 return 0;
322 }
323 }
324
325 /* Set the function pointers */
326 impl->OpenDevice = SDL_FS_OpenDevice;
327 impl->PlayDevice = SDL_FS_PlayDevice;
328 impl->WaitDevice = SDL_FS_WaitDevice;
329 impl->GetDeviceBuf = SDL_FS_GetDeviceBuf;
330 impl->CloseDevice = SDL_FS_CloseDevice;
331 impl->WaitDone = SDL_FS_WaitDone;
332 impl->Deinitialize = SDL_FS_Deinitialize;
333 impl->OnlyHasDefaultOutputDevice = 1;
334
335 return 1; /* this audio target is available. */
336 }
337
338
339 AudioBootStrap FUSIONSOUND_bootstrap = {
340 "fusionsound", "FusionSound", SDL_FS_Init, 0
341 };
342
343 #endif /* SDL_AUDIO_DRIVER_FUSIONSOUND */
344
345 /* vi: set ts=4 sw=4 expandtab: */
SDL_AudioDriverImpl::CloseDevice
void(* CloseDevice)(_THIS)
Definition: SDL_sysaudio.h:45
SDL_fsaudio.h
SDL_FirstAudioFormat
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
Definition: SDL_audio.c:1226
SDL_AudioDriverImpl::WaitDevice
void(* WaitDevice)(_THIS)
Definition: SDL_sysaudio.h:41
NULL
#define NULL
Definition: ftobjs.h:61
enabled
GLenum GLsizei const GLuint GLboolean enabled
Definition: glew.h:2538
SDL_AudioDriverImpl::GetDeviceBuf
Uint8 *(* GetDeviceBuf)(_THIS)
Definition: SDL_sysaudio.h:43
SDL_FreeAudioMem
#define SDL_FreeAudioMem
Definition: SDL_audiomem.h:24
SDL_free
DECLSPEC void SDLCALL SDL_free(void *mem)
SDL_name.h
name
EGLImageKHR EGLint * name
Definition: eglext.h:284
SDL_AudioFormat
Uint16 SDL_AudioFormat
Audio format flags.
Definition: SDL_audio.h:64
SDL_AudioDriverImpl::WaitDone
void(* WaitDone)(_THIS)
Definition: SDL_sysaudio.h:44
AUDIO_S16SYS
#define AUDIO_S16SYS
Definition: SDL_audio.h:123
func
GLenum func
Definition: SDL_opengl.h:5654
SDL_AudioDriverImpl::OpenDevice
int(* OpenDevice)(_THIS, const char *devname, int iscapture)
Definition: SDL_sysaudio.h:39
SDL_PrivateAudioData
Definition: SDL_alsa_audio.h:33
SDL_config.h
ret
ret
Definition: glew_str_glx.c:2
SDL_NextAudioFormat
SDL_AudioFormat SDL_NextAudioFormat(void)
Definition: SDL_audio.c:1238
SDL_AudioDriverImpl::PlayDevice
void(* PlayDevice)(_THIS)
Definition: SDL_sysaudio.h:42
AUDIO_U8
#define AUDIO_U8
Definition: SDL_audio.h:89
AudioBootStrap
Definition: SDL_sysaudio.h:128
SDL_AudioDriverImpl::OnlyHasDefaultOutputDevice
int OnlyHasDefaultOutputDevice
Definition: SDL_sysaudio.h:56
AUDIO_F32SYS
#define AUDIO_F32SYS
Definition: SDL_audio.h:125
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_LoadObject
DECLSPEC void *SDLCALL SDL_LoadObject(const char *sofile)
SDL_AudioDriverImpl
Definition: SDL_sysaudio.h:36
SDL_memset
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
Definition: SDL_string.c:261
SDL_UnloadObject
DECLSPEC void SDLCALL SDL_UnloadObject(void *handle)
format
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
SDL_SetError
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
SDL_malloc
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
SDL_CalculateAudioSpec
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
Definition: SDL_audio.c:1247
SDL_AudioDriverImpl::Deinitialize
void(* Deinitialize)(void)
Definition: SDL_sysaudio.h:48
SDL_AllocAudioMem
#define SDL_AllocAudioMem
Definition: SDL_audiomem.h:23
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:83
SDL_NAME
#define SDL_NAME(X)
Definition: SDL_name.h:9
SDL_loadso.h
SDL_audio.h
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
AUDIO_S32SYS
#define AUDIO_S32SYS
Definition: SDL_audio.h:124
i
int i
Definition: pngrutil.c:1377
SDL_LoadFunction
DECLSPEC void *SDLCALL SDL_LoadFunction(void *handle, const char *name)
SDL_timer.h
FUSIONSOUND_bootstrap
AudioBootStrap FUSIONSOUND_bootstrap