/
SDL_sound_internal.h
273 lines (237 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* SDL_sound -- An abstract sound format decoding API.
* Copyright (C) 2001 Ryan C. Gordon.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Internal function/structure declaration. Do NOT include in your
* application.
*
24
* Please see the file COPYING in the source's root directory.
25
26
27
28
29
30
31
32
33
34
35
36
37
*
* This file written by Ryan C. Gordon. (icculus@clutteredmind.org)
*/
#ifndef _INCLUDE_SDL_SOUND_INTERNAL_H_
#define _INCLUDE_SDL_SOUND_INTERNAL_H_
#ifndef __SDL_SOUND_INTERNAL__
#error Do not include this header from your applications.
#endif
#include "SDL.h"
38
39
40
41
#if ((defined _MSC_VER) && (!defined inline))
# define inline __inline__
#endif
42
#if (defined DEBUG_CHATTER)
43
#define SNDDBG(x) printf x
44
#else
45
#define SNDDBG(x)
46
47
#endif
48
49
50
51
52
typedef struct __SOUND_DECODERFUNCTIONS__
{
/* This is a block of info about your decoder. See SDL_sound.h. */
const Sound_DecoderInfo info;
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*
* This is called during the Sound_Init() function. Use this to
* set up any global state that your decoder needs, such as
* initializing an external library, etc.
*
* Return non-zero if initialization is successful, zero if there's
* a fatal error. If this method fails, then this decoder is
* flagged as unavailable until SDL_sound() is shut down and
* reinitialized, in which case this method will be tried again.
*
* Note that the decoders quit() method won't be called if this
* method fails, so if you can't intialize, you'll have to clean
* up the half-initialized state in this method.
*/
int (*init)(void);
/*
* This is called during the Sound_Quit() function. Use this to
* clean up any global state that your decoder has used during its
* lifespan.
*/
void (*quit)(void);
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
* Returns non-zero if (sample) has a valid fileformat that this
* driver can handle. Zero if this driver can NOT handle the data.
*
* Extension, which may be NULL, is just a hint as to the form of
* data that is being passed in. Most decoders should determine if
* they can handle the data by the data itself, but others, like
* the raw data handler, need this hint to know if they should
* accept the data in the first place.
*
* (sample)'s (opaque) field should be cast to a Sound_SampleInternal
* pointer:
*
* Sound_SampleInternal *internal;
* internal = (Sound_SampleInternal *) sample->opaque;
*
* Certain fields of sample will be filled in for the decoder before
* this call, and others should be filled in by the decoder. Some
* fields are offlimits, and should NOT be modified. The list:
*
* in Sound_SampleInternal section:
* Sound_Sample *next; (offlimits)
* Sound_Sample *prev; (offlimits)
* SDL_RWops *rw; (can use, but do NOT close it)
* const Sound_DecoderFunctions *funcs; (that's this structure)
101
* Sound_AudioCVT sdlcvt; (offlimits)
102
103
* void *buffer; (offlimits until read() method)
* Uint32 buffer_size; (offlimits until read() method)
104
* void *decoder_private; (read and write access)
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
*
* in rest of Sound_Sample:
* void *opaque; (this was internal section, above)
* const Sound_DecoderInfo *decoder; (read only)
* Sound_AudioInfo desired; (read only, usually not needed here)
* Sound_AudioInfo actual; (please fill this in)
* void *buffer; (offlimits)
* Uint32 buffer_size; (offlimits)
* Sound_SampleFlags flags; (set appropriately)
*/
int (*open)(Sound_Sample *sample, const char *ext);
/*
* Clean up. SDL_sound is done with this sample, so the decoder should
* clean up any resources it allocated. Anything that wasn't
* explicitly allocated by the decoder should be LEFT ALONE, since
* the higher-level SDL_sound layer will clean up its own mess.
*/
void (*close)(Sound_Sample *sample);
/*
* Get more data from (sample). The decoder should get a pointer to
* the internal structure...
*
* Sound_SampleInternal *internal;
* internal = (Sound_SampleInternal *) sample->opaque;
*
* ...and then start decoding. Fill in up to internal->buffer_size
* bytes of decoded sound in the space pointed to by
* internal->buffer. The encoded data is read in from internal->rw.
* Data should be decoded in the format specified during the
* decoder's open() method in the sample->actual field. The
* conversion to the desired format is done at a higher level.
*
* The return value is the number of bytes decoded into
* internal->buffer, which can be no more than internal->buffer_size,
* but can be less. If it is less, you should set a state flag:
*
* If there's just no more data (end of file, etc), then do:
* sample->flags |= SOUND_SAMPLEFLAG_EOF;
*
* If there's an unrecoverable error, then do:
* Sound_SetError(ERR_EXPLAIN_WHAT_WENT_WRONG);
* sample->flags |= SOUND_SAMPLEFLAG_ERROR;
*
* If there's more data, but you'd have to block for considerable
* amounts of time to get at it, or there's a recoverable error,
* then do:
* Sound_SetError(ERR_EXPLAIN_WHAT_WENT_WRONG);
* sample->flags |= SOUND_SAMPLEFLAG_EAGAIN;
*
* SDL_sound will not call your read() method for any samples with
* SOUND_SAMPLEFLAG_EOF or SOUND_SAMPLEFLAG_ERROR set. The
* SOUND_SAMPLEFLAG_EAGAIN flag is reset before each call to this
* method.
*/
161
Uint32 (*read)(Sound_Sample *sample);
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
* Reset the decoding to the beginning of the stream. Nonzero on
* success, zero on failure.
*
* The purpose of this method is to allow for higher efficiency than
* an application could get by just recreating the sample externally;
* not only do they not have to reopen the RWops, reallocate buffers,
* and potentially pass the data through several rejecting decoders,
* but certain decoders will not have to recreate their existing
* state (search for metadata, etc) since they already know they
* have a valid audio stream with a given set of characteristics.
*
* The decoder is responsible for calling seek() on the associated
* SDL_RWops. A failing call to seek() should be the ONLY reason that
* this method should ever fail!
*/
int (*rewind)(Sound_Sample *sample);
180
181
182
} Sound_DecoderFunctions;
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* A structure to hold a set of audio conversion filters and buffers */
typedef struct Sound_AudioCVT
{
int needed; /* Set to 1 if conversion possible */
Uint16 src_format; /* Source audio format */
Uint16 dst_format; /* Target audio format */
double rate_incr; /* Rate conversion increment */
Uint8 *buf; /* Buffer to hold entire audio data */
int len; /* Length of original audio buffer */
int len_cvt; /* Length of converted audio buffer */
int len_mult; /* buffer must be len*len_mult big */
double len_ratio; /* Given len, final size is len*len_ratio */
void (*filters[20])(struct Sound_AudioCVT *cvt, Uint16 *format);
int filter_index; /* Current audio conversion function */
} Sound_AudioCVT;
201
202
203
204
205
206
typedef struct __SOUND_SAMPLEINTERNAL__
{
Sound_Sample *next;
Sound_Sample *prev;
SDL_RWops *rw;
const Sound_DecoderFunctions *funcs;
207
Sound_AudioCVT sdlcvt;
208
209
void *buffer;
Uint32 buffer_size;
210
void *decoder_private;
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
} Sound_SampleInternal;
/* error messages... */
#define ERR_IS_INITIALIZED "Already initialized"
#define ERR_NOT_INITIALIZED "Not initialized"
#define ERR_INVALID_ARGUMENT "Invalid argument"
#define ERR_OUT_OF_MEMORY "Out of memory"
#define ERR_NOT_SUPPORTED "Operation not supported"
#define ERR_UNSUPPORTED_FORMAT "Sound format unsupported"
#define ERR_NOT_A_HANDLE "Not a file handle"
#define ERR_NO_SUCH_FILE "No such file"
#define ERR_PAST_EOF "Past end of file"
#define ERR_IO_ERROR "I/O error"
#define ERR_COMPRESSION "(De)compression error"
#define ERR_PREV_ERROR "Previous decoding already caused an error"
#define ERR_PREV_EOF "Previous decoding already triggered EOF"
/*
* Call this to set the message returned by Sound_GetError().
* Please only use the ERR_* constants above, or add new constants to the
* above group, but I want these all in one place.
*
* Calling this with a NULL argument is a safe no-op.
*/
void Sound_SetError(const char *err);
/*
* Use this if you need a cross-platform stricmp().
*/
int __Sound_strcasecmp(const char *x, const char *y);
/* These get used all over for lessening code clutter. */
#define BAIL_MACRO(e, r) { Sound_SetError(e); return r; }
#define BAIL_IF_MACRO(c, e, r) if (c) { Sound_SetError(e); return r; }
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*------------ ----------------*/
/*------------ You MUST implement the following functions ----------------*/
/*------------ if porting to a new platform. ----------------*/
/*------------ (see platform/unix.c for an example) ----------------*/
/*------------ ----------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* (None, right now.) */
#ifdef __cplusplus
extern "C" {
#endif
#endif /* defined _INCLUDE_SDL_SOUND_INTERNAL_H_ */
/* end of SDL_sound_internal.h ... */