Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

SDL_sound_internal.h

Go to the documentation of this file.
00001 /*
00002  * SDL_sound -- An abstract sound format decoding API.
00003  * Copyright (C) 2001  Ryan C. Gordon.
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 /*
00021  * Internal function/structure declaration. Do NOT include in your
00022  *  application.
00023  *
00024  * Please see the file COPYING in the source's root directory.
00025  *
00026  *  This file written by Ryan C. Gordon. (icculus@clutteredmind.org)
00027  */
00028 
00029 #ifndef _INCLUDE_SDL_SOUND_INTERNAL_H_
00030 #define _INCLUDE_SDL_SOUND_INTERNAL_H_
00031 
00032 #ifndef __SDL_SOUND_INTERNAL__
00033 #error Do not include this header from your applications.
00034 #endif
00035 
00036 #include "SDL.h"
00037 
00038 /* SDL 1.2.4 defines this, but better safe than sorry. */
00039 #if (!defined(__inline__))
00040 #  define __inline__
00041 #endif
00042 
00043 #if (defined DEBUG_CHATTER)
00044 #define SNDDBG(x) printf x
00045 #else
00046 #define SNDDBG(x)
00047 #endif
00048 
00049 #if HAVE_ASSERT_H
00050 #  include <assert.h>
00051 #endif
00052 
00053 #ifdef _WIN32_WCE
00054     extern char *strrchr(const char *s, int c);
00055 #   ifdef NDEBUG
00056 #       define assert(x)
00057 #   else
00058 #       define assert(x) if(!x) { fprintf(stderr,"Assertion failed in %s, line %s.\n",__FILE__,__LINE__); fclose(stderr); fclose(stdout); exit(1); }
00059 #   endif
00060 #endif
00061  
00062 
00063 #if (!defined assert)  /* if all else fails. */
00064 #  define assert(x)
00065 #endif
00066 
00067 
00068 typedef struct __SOUND_DECODERFUNCTIONS__
00069 {
00070         /* This is a block of info about your decoder. See SDL_sound.h. */
00071     const Sound_DecoderInfo info;
00072 
00073         /*
00074          * This is called during the Sound_Init() function. Use this to
00075          *  set up any global state that your decoder needs, such as
00076          *  initializing an external library, etc.
00077          *
00078          * Return non-zero if initialization is successful, zero if there's
00079          *  a fatal error. If this method fails, then this decoder is
00080          *  flagged as unavailable until SDL_sound() is shut down and
00081          *  reinitialized, in which case this method will be tried again.
00082          *
00083          * Note that the decoders quit() method won't be called if this
00084          *  method fails, so if you can't intialize, you'll have to clean
00085          *  up the half-initialized state in this method.
00086          */
00087     int (*init)(void);
00088 
00089         /*
00090          * This is called during the Sound_Quit() function. Use this to
00091          *  clean up any global state that your decoder has used during its
00092          *  lifespan.
00093          */
00094     void (*quit)(void);
00095 
00096         /*
00097          * Returns non-zero if (sample) has a valid fileformat that this
00098          *  driver can handle. Zero if this driver can NOT handle the data.
00099          *
00100          * Extension, which may be NULL, is just a hint as to the form of
00101          *  data that is being passed in. Most decoders should determine if
00102          *  they can handle the data by the data itself, but others, like
00103          *  the raw data handler, need this hint to know if they should
00104          *  accept the data in the first place.
00105          *
00106          * (sample)'s (opaque) field should be cast to a Sound_SampleInternal
00107          *  pointer:
00108          *
00109          *   Sound_SampleInternal *internal;
00110          *   internal = (Sound_SampleInternal *) sample->opaque;
00111          *
00112          * Certain fields of sample will be filled in for the decoder before
00113          *  this call, and others should be filled in by the decoder. Some
00114          *  fields are offlimits, and should NOT be modified. The list:
00115          *
00116          * in Sound_SampleInternal section:
00117          *    Sound_Sample *next;  (offlimits)
00118          *    Sound_Sample *prev;  (offlimits)
00119          *    SDL_RWops *rw;       (can use, but do NOT close it)
00120          *    const Sound_DecoderFunctions *funcs; (that's this structure)
00121          *    Sound_AudioCVT sdlcvt; (offlimits)
00122          *    void *buffer;        (offlimits until read() method)
00123          *    Uint32 buffer_size;  (offlimits until read() method)
00124          *    void *decoder_private; (read and write access)
00125          *
00126          * in rest of Sound_Sample:
00127          *    void *opaque;        (this was internal section, above)
00128          *    const Sound_DecoderInfo *decoder;  (read only)
00129          *    Sound_AudioInfo desired; (read only, usually not needed here)
00130          *    Sound_AudioInfo actual;  (please fill this in)
00131          *    void *buffer;            (offlimits)
00132          *    Uint32 buffer_size;      (offlimits)
00133          *    Sound_SampleFlags flags; (set appropriately)
00134          */
00135     int (*open)(Sound_Sample *sample, const char *ext);
00136 
00137         /*
00138          * Clean up. SDL_sound is done with this sample, so the decoder should
00139          *  clean up any resources it allocated. Anything that wasn't
00140          *  explicitly allocated by the decoder should be LEFT ALONE, since
00141          *  the higher-level SDL_sound layer will clean up its own mess.
00142          */
00143     void (*close)(Sound_Sample *sample);
00144 
00145         /*
00146          * Get more data from (sample). The decoder should get a pointer to
00147          *  the internal structure...
00148          *
00149          *   Sound_SampleInternal *internal;
00150          *   internal = (Sound_SampleInternal *) sample->opaque;
00151          *
00152          *  ...and then start decoding. Fill in up to internal->buffer_size
00153          *  bytes of decoded sound in the space pointed to by
00154          *  internal->buffer. The encoded data is read in from internal->rw.
00155          *  Data should be decoded in the format specified during the
00156          *  decoder's open() method in the sample->actual field. The
00157          *  conversion to the desired format is done at a higher level.
00158          *
00159          * The return value is the number of bytes decoded into
00160          *  internal->buffer, which can be no more than internal->buffer_size,
00161          *  but can be less. If it is less, you should set a state flag:
00162          *
00163          *   If there's just no more data (end of file, etc), then do:
00164          *      sample->flags |= SOUND_SAMPLEFLAG_EOF;
00165          *
00166          *   If there's an unrecoverable error, then do:
00167          *      __Sound_SetError(ERR_EXPLAIN_WHAT_WENT_WRONG);
00168          *      sample->flags |= SOUND_SAMPLEFLAG_ERROR;
00169          *
00170          *   If there's more data, but you'd have to block for considerable
00171          *    amounts of time to get at it, or there's a recoverable error,
00172          *    then do:
00173          *      __Sound_SetError(ERR_EXPLAIN_WHAT_WENT_WRONG);
00174          *      sample->flags |= SOUND_SAMPLEFLAG_EAGAIN;
00175          *
00176          * SDL_sound will not call your read() method for any samples with
00177          *  SOUND_SAMPLEFLAG_EOF or SOUND_SAMPLEFLAG_ERROR set. The
00178          *  SOUND_SAMPLEFLAG_EAGAIN flag is reset before each call to this
00179          *  method.
00180          */
00181     Uint32 (*read)(Sound_Sample *sample);
00182 
00183         /*
00184          * Reset the decoding to the beginning of the stream. Nonzero on
00185          *  success, zero on failure.
00186          *  
00187          * The purpose of this method is to allow for higher efficiency than
00188          *  an application could get by just recreating the sample externally;
00189          *  not only do they not have to reopen the RWops, reallocate buffers,
00190          *  and potentially pass the data through several rejecting decoders,
00191          *  but certain decoders will not have to recreate their existing
00192          *  state (search for metadata, etc) since they already know they
00193          *  have a valid audio stream with a given set of characteristics.
00194          *
00195          * The decoder is responsible for calling seek() on the associated
00196          *  SDL_RWops. A failing call to seek() should be the ONLY reason that
00197          *  this method should ever fail!
00198          */
00199     int (*rewind)(Sound_Sample *sample);
00200 
00201         /*
00202          * Reposition the decoding to an arbitrary point. Nonzero on
00203          *  success, zero on failure.
00204          *  
00205          * The purpose of this method is to allow for higher efficiency than
00206          *  an application could get by just rewinding the sample and 
00207          *  decoding to a given point.
00208          *
00209          * The decoder is responsible for calling seek() on the associated
00210          *  SDL_RWops.
00211          *
00212          * If there is an error, try to recover so that the next read will
00213          *  continue as if nothing happened.
00214          */
00215     int (*seek)(Sound_Sample *sample, Uint32 ms);
00216 } Sound_DecoderFunctions;
00217 
00218 
00219 /* A structure to hold a set of audio conversion filters and buffers */
00220 #if (defined SOUND_USE_ALTCVT)
00221 #include "alt_audio_convert.h"
00222 #else
00223 typedef struct Sound_AudioCVT
00224 {
00225     int    needed;                  /* Set to 1 if conversion possible */
00226     Uint16 src_format;              /* Source audio format */
00227     Uint16 dst_format;              /* Target audio format */
00228     double rate_incr;               /* Rate conversion increment */
00229     Uint8  *buf;                    /* Buffer to hold entire audio data */
00230     int    len;                     /* Length of original audio buffer */
00231     int    len_cvt;                 /* Length of converted audio buffer */
00232     int    len_mult;                /* buffer must be len*len_mult big */
00233     double len_ratio;       /* Given len, final size is len*len_ratio */
00234     void   (*filters[20])(struct Sound_AudioCVT *cvt, Uint16 *format);
00235     int    filter_index;            /* Current audio conversion function */
00236 } Sound_AudioCVT;
00237 #endif
00238 
00239 extern SNDDECLSPEC int Sound_BuildAudioCVT(Sound_AudioCVT *cvt,
00240                         Uint16 src_format, Uint8 src_channels, Uint32 src_rate,
00241                         Uint16 dst_format, Uint8 dst_channels, Uint32 dst_rate,
00242                         Uint32 dst_size);
00243 
00244 extern SNDDECLSPEC int Sound_ConvertAudio(Sound_AudioCVT *cvt);
00245 
00246 
00247 
00248 typedef struct __SOUND_SAMPLEINTERNAL__
00249 {
00250     Sound_Sample *next;
00251     Sound_Sample *prev;
00252     SDL_RWops *rw;
00253     const Sound_DecoderFunctions *funcs;
00254     Sound_AudioCVT sdlcvt;
00255     void *buffer;
00256     Uint32 buffer_size;
00257     void *decoder_private;
00258 } Sound_SampleInternal;
00259 
00260 
00261 /* error messages... */
00262 #define ERR_IS_INITIALIZED       "Already initialized"
00263 #define ERR_NOT_INITIALIZED      "Not initialized"
00264 #define ERR_INVALID_ARGUMENT     "Invalid argument"
00265 #define ERR_OUT_OF_MEMORY        "Out of memory"
00266 #define ERR_NOT_SUPPORTED        "Operation not supported"
00267 #define ERR_UNSUPPORTED_FORMAT   "Sound format unsupported"
00268 #define ERR_NOT_A_HANDLE         "Not a file handle"
00269 #define ERR_NO_SUCH_FILE         "No such file"
00270 #define ERR_PAST_EOF             "Past end of file"
00271 #define ERR_IO_ERROR             "I/O error"
00272 #define ERR_COMPRESSION          "(De)compression error"
00273 #define ERR_PREV_ERROR           "Previous decoding already caused an error"
00274 #define ERR_PREV_EOF             "Previous decoding already triggered EOF"
00275 #define ERR_CANNOT_SEEK          "Sample is not seekable"
00276 
00277 /*
00278  * Call this to set the message returned by Sound_GetError().
00279  *  Please only use the ERR_* constants above, or add new constants to the
00280  *  above group, but I want these all in one place.
00281  *
00282  * Calling this with a NULL argument is a safe no-op.
00283  */
00284 void __Sound_SetError(const char *err);
00285 
00286 /*
00287  * Call this to convert milliseconds to an actual byte position, based on
00288  *  audio data characteristics.
00289  */
00290 Uint32 __Sound_convertMsToBytePos(Sound_AudioInfo *info, Uint32 ms);
00291 
00292 /*
00293  * Use this if you need a cross-platform stricmp().
00294  */
00295 int __Sound_strcasecmp(const char *x, const char *y);
00296 
00297 
00298 /* These get used all over for lessening code clutter. */
00299 #define BAIL_MACRO(e, r) { __Sound_SetError(e); return r; }
00300 #define BAIL_IF_MACRO(c, e, r) if (c) { __Sound_SetError(e); return r; }
00301 
00302 
00303 
00304 
00305 /*--------------------------------------------------------------------------*/
00306 /*--------------------------------------------------------------------------*/
00307 /*------------                                              ----------------*/
00308 /*------------  You MUST implement the following functions  ----------------*/
00309 /*------------        if porting to a new platform.         ----------------*/
00310 /*------------     (see platform/unix.c for an example)     ----------------*/
00311 /*------------                                              ----------------*/
00312 /*--------------------------------------------------------------------------*/
00313 /*--------------------------------------------------------------------------*/
00314 
00315 
00316 /* (None, right now.)  */
00317 
00318 
00319 #ifdef __cplusplus
00320 extern "C" {
00321 #endif
00322 
00323 #endif /* defined _INCLUDE_SDL_SOUND_INTERNAL_H_ */
00324 
00325 /* end of SDL_sound_internal.h ... */
00326 

Generated on Tue Jun 24 01:27:51 2008 for Advanced Strategic Command by  doxygen 1.4.2