SDL_mixer.h
author Sam Lantinga <slouken@libsdl.org>
Wed, 27 Feb 2008 07:31:03 +0000
changeset 382 50501e45c57b
parent 357 d6d0cfdbea65
child 384 51d7d7729faf
permissions -rw-r--r--
Austen Dicken - Tue Feb 26 23:28:27 PST 2008

Ok, here is the patch I made for FLAC support.

I have tested it relatively thoroughly and currently the patch allows:
1. Pre-loading FLAC files and playing them via LoadWAV
2. The patch allows for FLAC support in the LoadMUS setting as well as:
* Pause / Resume
* Volume control
* Seeking

I also did a little benchmarking by comparing memory/cpu usage of playmus to
that of mplayer, and the results were very good. playmus typically took about
half the RAM as mplayer, though that may be attributed to mplayer being a more
"bulky" program. As such I would say that the two are probably about equal in
efficiency.

Also, it is important to note that, similar to the OGG support currently
built-in, my FLAC patch only supports 16 bit stereo-encoded sound. Also, it
is only for Native FLAC (standard) and not the derivative, Ogg-FLAC.

I have tried to find a simple way to detect Ogg-FLAC files, as the only
difference between Ogg-FLAC and Native FLAC support is changing the init_
function call, but after digging a little deeper it seems that Ogg-FLAC is
basically FLAC wrapped in an Ogg transport layer, so it would be better to have
a way to read the Ogg transport layer which then reads the inner audio files
according to the proper codec.

But anyway, that's another job for another day! For now this should provide
Native FLAC support!
slouken@34
     1
/*
slouken@137
     2
    SDL_mixer:  An audio mixer library based on the SDL library
slouken@241
     3
    Copyright (C) 1997-2004 Sam Lantinga
slouken@34
     4
slouken@34
     5
    This library is free software; you can redistribute it and/or
slouken@34
     6
    modify it under the terms of the GNU Library General Public
slouken@34
     7
    License as published by the Free Software Foundation; either
slouken@34
     8
    version 2 of the License, or (at your option) any later version.
slouken@34
     9
slouken@34
    10
    This library is distributed in the hope that it will be useful,
slouken@34
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@34
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@34
    13
    Library General Public License for more details.
slouken@34
    14
slouken@34
    15
    You should have received a copy of the GNU Library General Public
slouken@34
    16
    License along with this library; if not, write to the Free
slouken@34
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@34
    18
slouken@34
    19
    Sam Lantinga
slouken@137
    20
    slouken@libsdl.org
slouken@34
    21
*/
slouken@34
    22
slouken@140
    23
/* $Id$ */
slouken@137
    24
slouken@229
    25
#ifndef _SDL_MIXER_H
slouken@229
    26
#define _SDL_MIXER_H
slouken@34
    27
slouken@34
    28
#include "SDL_types.h"
slouken@34
    29
#include "SDL_rwops.h"
slouken@34
    30
#include "SDL_audio.h"
icculus@343
    31
#include "SDL_endian.h"
slouken@113
    32
#include "SDL_version.h"
slouken@40
    33
#include "begin_code.h"
slouken@34
    34
slouken@34
    35
/* Set up for C function definitions, even when using C++ */
slouken@34
    36
#ifdef __cplusplus
slouken@34
    37
extern "C" {
slouken@34
    38
#endif
slouken@34
    39
slouken@113
    40
/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
slouken@113
    41
*/
slouken@227
    42
#define SDL_MIXER_MAJOR_VERSION	1
slouken@227
    43
#define SDL_MIXER_MINOR_VERSION	2
slouken@349
    44
#define SDL_MIXER_PATCHLEVEL	8
slouken@113
    45
slouken@113
    46
/* This macro can be used to fill a version structure with the compile-time
slouken@113
    47
 * version of the SDL_mixer library.
slouken@113
    48
 */
slouken@227
    49
#define SDL_MIXER_VERSION(X)						\
slouken@113
    50
{									\
slouken@227
    51
	(X)->major = SDL_MIXER_MAJOR_VERSION;				\
slouken@227
    52
	(X)->minor = SDL_MIXER_MINOR_VERSION;				\
slouken@227
    53
	(X)->patch = SDL_MIXER_PATCHLEVEL;				\
slouken@113
    54
}
slouken@113
    55
slouken@227
    56
/* Backwards compatibility */
slouken@227
    57
#define MIX_MAJOR_VERSION	SDL_MIXER_MAJOR_VERSION
slouken@227
    58
#define MIX_MINOR_VERSION	SDL_MIXER_MINOR_VERSION
slouken@227
    59
#define MIX_PATCHLEVEL		SDL_MIXER_PATCHLEVEL
slouken@227
    60
#define MIX_VERSION(X)		SDL_MIXER_VERSION(X)
slouken@227
    61
slouken@113
    62
/* This function gets the version of the dynamically linked SDL_mixer library.
slouken@113
    63
   it should NOT be used to fill a version structure, instead you should
slouken@227
    64
   use the SDL_MIXER_VERSION() macro.
slouken@113
    65
 */
slouken@165
    66
extern DECLSPEC const SDL_version * SDLCALL Mix_Linked_Version(void);
slouken@113
    67
slouken@113
    68
slouken@34
    69
/* The default mixer has 8 simultaneous mixing channels */
slouken@34
    70
#ifndef MIX_CHANNELS
slouken@34
    71
#define MIX_CHANNELS	8
slouken@34
    72
#endif
slouken@34
    73
slouken@34
    74
/* Good default values for a PC soundcard */
slouken@34
    75
#define MIX_DEFAULT_FREQUENCY	22050
slouken@70
    76
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
slouken@70
    77
#define MIX_DEFAULT_FORMAT	AUDIO_S16LSB
slouken@70
    78
#else
slouken@70
    79
#define MIX_DEFAULT_FORMAT	AUDIO_S16MSB
slouken@70
    80
#endif
slouken@34
    81
#define MIX_DEFAULT_CHANNELS	2
slouken@34
    82
#define MIX_MAX_VOLUME		128	/* Volume of a chunk */
slouken@34
    83
slouken@34
    84
/* The internal format for an audio chunk */
icculus@267
    85
typedef struct Mix_Chunk {
slouken@34
    86
	int allocated;
slouken@34
    87
	Uint8 *abuf;
slouken@34
    88
	Uint32 alen;
slouken@34
    89
	Uint8 volume;		/* Per-sample volume, 0-128 */
slouken@34
    90
} Mix_Chunk;
slouken@34
    91
slouken@34
    92
/* The different fading types supported */
slouken@34
    93
typedef enum {
slouken@34
    94
	MIX_NO_FADING,
slouken@34
    95
	MIX_FADING_OUT,
slouken@34
    96
	MIX_FADING_IN
slouken@34
    97
} Mix_Fading;
slouken@34
    98
slouken@177
    99
typedef enum {
slouken@177
   100
	MUS_NONE,
slouken@177
   101
	MUS_CMD,
slouken@177
   102
	MUS_WAV,
slouken@177
   103
	MUS_MOD,
slouken@177
   104
	MUS_MID,
slouken@177
   105
	MUS_OGG,
slouken@382
   106
	MUS_FLAC,
slouken@357
   107
	MUS_MP3,
slouken@357
   108
	MUS_MP3_MAD
slouken@177
   109
} Mix_MusicType;
slouken@177
   110
slouken@34
   111
/* The internal format for a music chunk interpreted via mikmod */
slouken@34
   112
typedef struct _Mix_Music Mix_Music;
slouken@34
   113
slouken@34
   114
/* Open the mixer with a certain audio format */
slouken@165
   115
extern DECLSPEC int SDLCALL Mix_OpenAudio(int frequency, Uint16 format, int channels,
slouken@34
   116
							int chunksize);
slouken@34
   117
slouken@34
   118
/* Dynamically change the number of channels managed by the mixer.
slouken@34
   119
   If decreasing the number of channels, the upper channels are
slouken@34
   120
   stopped.
slouken@34
   121
   This function returns the new number of allocated channels.
slouken@34
   122
 */
slouken@165
   123
extern DECLSPEC int SDLCALL Mix_AllocateChannels(int numchans);
slouken@34
   124
slouken@34
   125
/* Find out what the actual audio device parameters are.
slouken@34
   126
   This function returns 1 if the audio has been opened, 0 otherwise.
slouken@34
   127
 */
slouken@165
   128
extern DECLSPEC int SDLCALL Mix_QuerySpec(int *frequency,Uint16 *format,int *channels);
slouken@34
   129
slouken@34
   130
/* Load a wave file or a music (.mod .s3m .it .xm) file */
slouken@165
   131
extern DECLSPEC Mix_Chunk * SDLCALL Mix_LoadWAV_RW(SDL_RWops *src, int freesrc);
slouken@34
   132
#define Mix_LoadWAV(file)	Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1)
slouken@165
   133
extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS(const char *file);
slouken@34
   134
slouken@254
   135
/* Load a music file from an SDL_RWop object (Ogg and MikMod specific currently)
slouken@59
   136
   Matt Campbell (matt@campbellhome.dhs.org) April 2000 */
slouken@226
   137
extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS_RW(SDL_RWops *rw);
slouken@59
   138
slouken@34
   139
/* Load a wave file of the mixer format from a memory buffer */
slouken@165
   140
extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_WAV(Uint8 *mem);
slouken@34
   141
slouken@174
   142
/* Load raw audio data of the mixer format from a memory buffer */
slouken@174
   143
extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len);
slouken@174
   144
slouken@34
   145
/* Free an audio chunk previously loaded */
slouken@165
   146
extern DECLSPEC void SDLCALL Mix_FreeChunk(Mix_Chunk *chunk);
slouken@165
   147
extern DECLSPEC void SDLCALL Mix_FreeMusic(Mix_Music *music);
slouken@34
   148
slouken@177
   149
/* Find out the music format of a mixer music, or the currently playing
slouken@177
   150
   music, if 'music' is NULL.
slouken@177
   151
*/
slouken@180
   152
extern DECLSPEC Mix_MusicType SDLCALL Mix_GetMusicType(const Mix_Music *music);
slouken@177
   153
slouken@34
   154
/* Set a function that is called after all mixing is performed.
slouken@34
   155
   This can be used to provide real-time visual display of the audio stream
slouken@34
   156
   or add a custom mixer filter for the stream data.
slouken@34
   157
*/
slouken@165
   158
extern DECLSPEC void SDLCALL Mix_SetPostMix(void (*mix_func)
slouken@34
   159
                             (void *udata, Uint8 *stream, int len), void *arg);
slouken@34
   160
slouken@34
   161
/* Add your own music player or additional mixer function.
slouken@34
   162
   If 'mix_func' is NULL, the default music player is re-enabled.
slouken@34
   163
 */
slouken@165
   164
extern DECLSPEC void SDLCALL Mix_HookMusic(void (*mix_func)
slouken@34
   165
                          (void *udata, Uint8 *stream, int len), void *arg);
slouken@34
   166
slouken@173
   167
/* Add your own callback when the music has finished playing.
slouken@173
   168
   This callback is only called if the music finishes naturally.
slouken@173
   169
 */
slouken@165
   170
extern DECLSPEC void SDLCALL Mix_HookMusicFinished(void (*music_finished)(void));
slouken@34
   171
slouken@34
   172
/* Get a pointer to the user data for the current music hook */
slouken@165
   173
extern DECLSPEC void * SDLCALL Mix_GetMusicHookData(void);
slouken@34
   174
slouken@164
   175
/*
slouken@164
   176
 * Add your own callback when a channel has finished playing. NULL
slouken@164
   177
 *  to disable callback. The callback may be called from the mixer's audio 
slouken@164
   178
 *  callback or it could be called as a result of Mix_HaltChannel(), etc.
slouken@164
   179
 *  do not call SDL_LockAudio() from this callback; you will either be 
slouken@164
   180
 *  inside the audio callback, or SDL_mixer will explicitly lock the audio
slouken@164
   181
 *  before calling your callback.
slouken@92
   182
 */
slouken@165
   183
extern DECLSPEC void SDLCALL Mix_ChannelFinished(void (*channel_finished)(int channel));
slouken@92
   184
slouken@113
   185
icculus@339
   186
/* Special Effects API by ryan c. gordon. (icculus@icculus.org) */
slouken@113
   187
slouken@113
   188
#define MIX_CHANNEL_POST  -2
slouken@113
   189
slouken@113
   190
/* This is the format of a special effect callback:
slouken@113
   191
 *
slouken@113
   192
 *   myeffect(int chan, void *stream, int len, void *udata);
slouken@113
   193
 *
slouken@113
   194
 * (chan) is the channel number that your effect is affecting. (stream) is
slouken@113
   195
 *  the buffer of data to work upon. (len) is the size of (stream), and
slouken@113
   196
 *  (udata) is a user-defined bit of data, which you pass as the last arg of
slouken@113
   197
 *  Mix_RegisterEffect(), and is passed back unmolested to your callback.
slouken@113
   198
 *  Your effect changes the contents of (stream) based on whatever parameters
slouken@113
   199
 *  are significant, or just leaves it be, if you prefer. You can do whatever
slouken@113
   200
 *  you like to the buffer, though, and it will continue in its changed state
slouken@113
   201
 *  down the mixing pipeline, through any other effect functions, then finally
slouken@113
   202
 *  to be mixed with the rest of the channels and music for the final output
slouken@113
   203
 *  stream.
slouken@164
   204
 *
slouken@164
   205
 * DO NOT EVER call SDL_LockAudio() from your callback function!
slouken@113
   206
 */
slouken@113
   207
typedef void (*Mix_EffectFunc_t)(int chan, void *stream, int len, void *udata);
slouken@113
   208
slouken@113
   209
/*
slouken@113
   210
 * This is a callback that signifies that a channel has finished all its
slouken@113
   211
 *  loops and has completed playback. This gets called if the buffer
slouken@113
   212
 *  plays out normally, or if you call Mix_HaltChannel(), implicitly stop
slouken@113
   213
 *  a channel via Mix_AllocateChannels(), or unregister a callback while
slouken@113
   214
 *  it's still playing.
slouken@164
   215
 *
slouken@164
   216
 * DO NOT EVER call SDL_LockAudio() from your callback function!
slouken@113
   217
 */
slouken@113
   218
typedef void (*Mix_EffectDone_t)(int chan, void *udata);
slouken@113
   219
slouken@113
   220
slouken@113
   221
/* Register a special effect function. At mixing time, the channel data is
slouken@113
   222
 *  copied into a buffer and passed through each registered effect function.
slouken@113
   223
 *  After it passes through all the functions, it is mixed into the final
slouken@113
   224
 *  output stream. The copy to buffer is performed once, then each effect
slouken@113
   225
 *  function performs on the output of the previous effect. Understand that
slouken@113
   226
 *  this extra copy to a buffer is not performed if there are no effects
slouken@113
   227
 *  registered for a given chunk, which saves CPU cycles, and any given
slouken@113
   228
 *  effect will be extra cycles, too, so it is crucial that your code run
slouken@113
   229
 *  fast. Also note that the data that your function is given is in the
slouken@113
   230
 *  format of the sound device, and not the format you gave to Mix_OpenAudio(),
slouken@113
   231
 *  although they may in reality be the same. This is an unfortunate but
slouken@113
   232
 *  necessary speed concern. Use Mix_QuerySpec() to determine if you can
slouken@113
   233
 *  handle the data before you register your effect, and take appropriate
slouken@113
   234
 *  actions.
slouken@113
   235
 * You may also specify a callback (Mix_EffectDone_t) that is called when
slouken@113
   236
 *  the channel finishes playing. This gives you a more fine-grained control
slouken@113
   237
 *  than Mix_ChannelFinished(), in case you need to free effect-specific
slouken@113
   238
 *  resources, etc. If you don't need this, you can specify NULL.
slouken@113
   239
 * You may set the callbacks before or after calling Mix_PlayChannel().
slouken@113
   240
 * Things like Mix_SetPanning() are just internal special effect functions,
slouken@113
   241
 *  so if you are using that, you've already incurred the overhead of a copy
slouken@113
   242
 *  to a separate buffer, and that these effects will be in the queue with
slouken@113
   243
 *  any functions you've registered. The list of registered effects for a
slouken@113
   244
 *  channel is reset when a chunk finishes playing, so you need to explicitly
slouken@113
   245
 *  set them with each call to Mix_PlayChannel*().
slouken@113
   246
 * You may also register a special effect function that is to be run after
slouken@113
   247
 *  final mixing occurs. The rules for these callbacks are identical to those
slouken@113
   248
 *  in Mix_RegisterEffect, but they are run after all the channels and the
slouken@113
   249
 *  music have been mixed into a single stream, whereas channel-specific
slouken@113
   250
 *  effects run on a given channel before any other mixing occurs. These
slouken@113
   251
 *  global effect callbacks are call "posteffects". Posteffects only have
slouken@113
   252
 *  their Mix_EffectDone_t function called when they are unregistered (since
slouken@113
   253
 *  the main output stream is never "done" in the same sense as a channel).
slouken@113
   254
 *  You must unregister them manually when you've had enough. Your callback
slouken@113
   255
 *  will be told that the channel being mixed is (MIX_CHANNEL_POST) if the
slouken@113
   256
 *  processing is considered a posteffect.
slouken@113
   257
 *
slouken@113
   258
 * After all these effects have finished processing, the callback registered
slouken@113
   259
 *  through Mix_SetPostMix() runs, and then the stream goes to the audio
slouken@113
   260
 *  device. 
slouken@113
   261
 *
slouken@164
   262
 * DO NOT EVER call SDL_LockAudio() from your callback function!
slouken@164
   263
 *
slouken@113
   264
 * returns zero if error (no such channel), nonzero if added.
slouken@113
   265
 *  Error messages can be retrieved from Mix_GetError().
slouken@113
   266
 */
slouken@165
   267
extern DECLSPEC int SDLCALL Mix_RegisterEffect(int chan, Mix_EffectFunc_t f,
slouken@164
   268
					Mix_EffectDone_t d, void *arg);
slouken@113
   269
slouken@113
   270
slouken@113
   271
/* You may not need to call this explicitly, unless you need to stop an
slouken@113
   272
 *  effect from processing in the middle of a chunk's playback.
slouken@113
   273
 * Posteffects are never implicitly unregistered as they are for channels,
slouken@113
   274
 *  but they may be explicitly unregistered through this function by
slouken@113
   275
 *  specifying MIX_CHANNEL_POST for a channel.
slouken@113
   276
 * returns zero if error (no such channel or effect), nonzero if removed.
slouken@113
   277
 *  Error messages can be retrieved from Mix_GetError().
slouken@113
   278
 */
slouken@165
   279
extern DECLSPEC int SDLCALL Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f);
slouken@113
   280
slouken@113
   281
slouken@113
   282
/* You may not need to call this explicitly, unless you need to stop all
slouken@113
   283
 *  effects from processing in the middle of a chunk's playback. Note that
slouken@113
   284
 *  this will also shut off some internal effect processing, since
slouken@113
   285
 *  Mix_SetPanning() and others may use this API under the hood. This is
slouken@113
   286
 *  called internally when a channel completes playback.
slouken@113
   287
 * Posteffects are never implicitly unregistered as they are for channels,
slouken@113
   288
 *  but they may be explicitly unregistered through this function by
slouken@113
   289
 *  specifying MIX_CHANNEL_POST for a channel.
slouken@113
   290
 * returns zero if error (no such channel), nonzero if all effects removed.
slouken@113
   291
 *  Error messages can be retrieved from Mix_GetError().
slouken@113
   292
 */
slouken@165
   293
extern DECLSPEC int SDLCALL Mix_UnregisterAllEffects(int channel);
slouken@113
   294
slouken@113
   295
slouken@113
   296
#define MIX_EFFECTSMAXSPEED  "MIX_EFFECTSMAXSPEED"
slouken@113
   297
slouken@113
   298
/*
slouken@113
   299
 * These are the internally-defined mixing effects. They use the same API that
slouken@113
   300
 *  effects defined in the application use, but are provided here as a
slouken@113
   301
 *  convenience. Some effects can reduce their quality or use more memory in
slouken@113
   302
 *  the name of speed; to enable this, make sure the environment variable
slouken@113
   303
 *  MIX_EFFECTSMAXSPEED (see above) is defined before you call
slouken@113
   304
 *  Mix_OpenAudio().
slouken@113
   305
 */
slouken@113
   306
slouken@113
   307
slouken@113
   308
/* Set the panning of a channel. The left and right channels are specified
slouken@113
   309
 *  as integers between 0 and 255, quietest to loudest, respectively.
slouken@113
   310
 *
slouken@113
   311
 * Technically, this is just individual volume control for a sample with
slouken@113
   312
 *  two (stereo) channels, so it can be used for more than just panning.
slouken@113
   313
 *  If you want real panning, call it like this:
slouken@113
   314
 *
slouken@113
   315
 *   Mix_SetPanning(channel, left, 255 - left);
slouken@113
   316
 *
slouken@113
   317
 * ...which isn't so hard.
slouken@113
   318
 *
slouken@113
   319
 * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
slouken@113
   320
 *  the panning will be done to the final mixed stream before passing it on
slouken@113
   321
 *  to the audio device.
slouken@113
   322
 *
slouken@113
   323
 * This uses the Mix_RegisterEffect() API internally, and returns without
slouken@113
   324
 *  registering the effect function if the audio device is not configured
slouken@113
   325
 *  for stereo output. Setting both (left) and (right) to 255 causes this
slouken@113
   326
 *  effect to be unregistered, since that is the data's normal state.
slouken@113
   327
 *
slouken@113
   328
 * returns zero if error (no such channel or Mix_RegisterEffect() fails),
slouken@113
   329
 *  nonzero if panning effect enabled. Note that an audio device in mono
slouken@113
   330
 *  mode is a no-op, but this call will return successful in that case.
slouken@113
   331
 *  Error messages can be retrieved from Mix_GetError().
slouken@113
   332
 */
slouken@165
   333
extern DECLSPEC int SDLCALL Mix_SetPanning(int channel, Uint8 left, Uint8 right);
slouken@113
   334
slouken@113
   335
slouken@113
   336
/* Set the position of a channel. (angle) is an integer from 0 to 360, that
slouken@113
   337
 *  specifies the location of the sound in relation to the listener. (angle)
slouken@113
   338
 *  will be reduced as neccesary (540 becomes 180 degrees, -100 becomes 260).
slouken@113
   339
 *  Angle 0 is due north, and rotates clockwise as the value increases.
slouken@113
   340
 *  For efficiency, the precision of this effect may be limited (angles 1
slouken@113
   341
 *  through 7 might all produce the same effect, 8 through 15 are equal, etc).
slouken@113
   342
 *  (distance) is an integer between 0 and 255 that specifies the space
slouken@113
   343
 *  between the sound and the listener. The larger the number, the further
slouken@113
   344
 *  away the sound is. Using 255 does not guarantee that the channel will be
slouken@113
   345
 *  culled from the mixing process or be completely silent. For efficiency,
slouken@113
   346
 *  the precision of this effect may be limited (distance 0 through 5 might
slouken@113
   347
 *  all produce the same effect, 6 through 10 are equal, etc). Setting (angle)
slouken@113
   348
 *  and (distance) to 0 unregisters this effect, since the data would be
slouken@113
   349
 *  unchanged.
slouken@113
   350
 *
slouken@113
   351
 * If you need more precise positional audio, consider using OpenAL for
slouken@113
   352
 *  spatialized effects instead of SDL_mixer. This is only meant to be a
slouken@113
   353
 *  basic effect for simple "3D" games.
slouken@113
   354
 *
slouken@113
   355
 * If the audio device is configured for mono output, then you won't get
slouken@113
   356
 *  any effectiveness from the angle; however, distance attenuation on the
slouken@113
   357
 *  channel will still occur. While this effect will function with stereo
slouken@113
   358
 *  voices, it makes more sense to use voices with only one channel of sound,
slouken@113
   359
 *  so when they are mixed through this effect, the positioning will sound
slouken@113
   360
 *  correct. You can convert them to mono through SDL before giving them to
slouken@113
   361
 *  the mixer in the first place if you like.
slouken@113
   362
 *
slouken@113
   363
 * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
slouken@113
   364
 *  the positioning will be done to the final mixed stream before passing it
slouken@113
   365
 *  on to the audio device.
slouken@113
   366
 *
slouken@113
   367
 * This is a convenience wrapper over Mix_SetDistance() and Mix_SetPanning().
slouken@113
   368
 *
slouken@113
   369
 * returns zero if error (no such channel or Mix_RegisterEffect() fails),
slouken@113
   370
 *  nonzero if position effect is enabled.
slouken@113
   371
 *  Error messages can be retrieved from Mix_GetError().
slouken@113
   372
 */
slouken@165
   373
extern DECLSPEC int SDLCALL Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
slouken@113
   374
slouken@113
   375
slouken@113
   376
/* Set the "distance" of a channel. (distance) is an integer from 0 to 255
slouken@113
   377
 *  that specifies the location of the sound in relation to the listener.
slouken@113
   378
 *  Distance 0 is overlapping the listener, and 255 is as far away as possible
slouken@113
   379
 *  A distance of 255 does not guarantee silence; in such a case, you might
slouken@113
   380
 *  want to try changing the chunk's volume, or just cull the sample from the
slouken@113
   381
 *  mixing process with Mix_HaltChannel().
slouken@113
   382
 * For efficiency, the precision of this effect may be limited (distances 1
slouken@113
   383
 *  through 7 might all produce the same effect, 8 through 15 are equal, etc).
slouken@113
   384
 *  (distance) is an integer between 0 and 255 that specifies the space
slouken@113
   385
 *  between the sound and the listener. The larger the number, the further
slouken@113
   386
 *  away the sound is.
slouken@113
   387
 * Setting (distance) to 0 unregisters this effect, since the data would be
slouken@113
   388
 *  unchanged.
slouken@113
   389
 * If you need more precise positional audio, consider using OpenAL for
slouken@113
   390
 *  spatialized effects instead of SDL_mixer. This is only meant to be a
slouken@113
   391
 *  basic effect for simple "3D" games.
slouken@113
   392
 *
slouken@113
   393
 * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
slouken@113
   394
 *  the distance attenuation will be done to the final mixed stream before
slouken@113
   395
 *  passing it on to the audio device.
slouken@113
   396
 *
slouken@113
   397
 * This uses the Mix_RegisterEffect() API internally.
slouken@113
   398
 *
slouken@113
   399
 * returns zero if error (no such channel or Mix_RegisterEffect() fails),
slouken@113
   400
 *  nonzero if position effect is enabled.
slouken@113
   401
 *  Error messages can be retrieved from Mix_GetError().
slouken@113
   402
 */
slouken@165
   403
extern DECLSPEC int SDLCALL Mix_SetDistance(int channel, Uint8 distance);
slouken@113
   404
slouken@113
   405
slouken@113
   406
/*
slouken@113
   407
 * !!! FIXME : Haven't implemented, since the effect goes past the
slouken@113
   408
 *              end of the sound buffer. Will have to think about this.
slouken@113
   409
 *               --ryan.
slouken@113
   410
 */
slouken@113
   411
#if 0
slouken@113
   412
/* Causes an echo effect to be mixed into a sound. (echo) is the amount
slouken@113
   413
 *  of echo to mix. 0 is no echo, 255 is infinite (and probably not
slouken@113
   414
 *  what you want).
slouken@113
   415
 *
slouken@113
   416
 * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
slouken@113
   417
 *  the reverbing will be done to the final mixed stream before passing it on
slouken@113
   418
 *  to the audio device.
slouken@113
   419
 *
slouken@113
   420
 * This uses the Mix_RegisterEffect() API internally. If you specify an echo
slouken@113
   421
 *  of zero, the effect is unregistered, as the data is already in that state.
slouken@113
   422
 *
slouken@113
   423
 * returns zero if error (no such channel or Mix_RegisterEffect() fails),
slouken@113
   424
 *  nonzero if reversing effect is enabled.
slouken@113
   425
 *  Error messages can be retrieved from Mix_GetError().
slouken@113
   426
 */
slouken@165
   427
extern no_parse_DECLSPEC int SDLCALL Mix_SetReverb(int channel, Uint8 echo);
slouken@113
   428
#endif
slouken@113
   429
slouken@113
   430
/* Causes a channel to reverse its stereo. This is handy if the user has his
slouken@113
   431
 *  speakers hooked up backwards, or you would like to have a minor bit of
slouken@113
   432
 *  psychedelia in your sound code.  :)  Calling this function with (flip)
slouken@113
   433
 *  set to non-zero reverses the chunks's usual channels. If (flip) is zero,
slouken@113
   434
 *  the effect is unregistered.
slouken@113
   435
 *
slouken@113
   436
 * This uses the Mix_RegisterEffect() API internally, and thus is probably
slouken@113
   437
 *  more CPU intensive than having the user just plug in his speakers
slouken@113
   438
 *  correctly. Mix_SetReverseStereo() returns without registering the effect
slouken@113
   439
 *  function if the audio device is not configured for stereo output.
slouken@113
   440
 *
slouken@113
   441
 * If you specify MIX_CHANNEL_POST for (channel), then this the effect is used
slouken@113
   442
 *  on the final mixed stream before sending it on to the audio device (a
slouken@113
   443
 *  posteffect).
slouken@113
   444
 *
slouken@113
   445
 * returns zero if error (no such channel or Mix_RegisterEffect() fails),
slouken@113
   446
 *  nonzero if reversing effect is enabled. Note that an audio device in mono
slouken@113
   447
 *  mode is a no-op, but this call will return successful in that case.
slouken@113
   448
 *  Error messages can be retrieved from Mix_GetError().
slouken@113
   449
 */
slouken@165
   450
extern DECLSPEC int SDLCALL Mix_SetReverseStereo(int channel, int flip);
slouken@113
   451
slouken@113
   452
/* end of effects API. --ryan. */
slouken@113
   453
slouken@113
   454
slouken@34
   455
/* Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
slouken@34
   456
   them dynamically to the next sample if requested with a -1 value below.
slouken@34
   457
   Returns the number of reserved channels.
slouken@34
   458
 */
slouken@165
   459
extern DECLSPEC int SDLCALL Mix_ReserveChannels(int num);
slouken@34
   460
slouken@34
   461
/* Channel grouping functions */
slouken@34
   462
slouken@34
   463
/* Attach a tag to a channel. A tag can be assigned to several mixer
slouken@34
   464
   channels, to form groups of channels.
slouken@34
   465
   If 'tag' is -1, the tag is removed (actually -1 is the tag used to
slouken@34
   466
   represent the group of all the channels).
slouken@34
   467
   Returns true if everything was OK.
slouken@34
   468
 */
slouken@165
   469
extern DECLSPEC int SDLCALL Mix_GroupChannel(int which, int tag);
slouken@34
   470
/* Assign several consecutive channels to a group */
slouken@165
   471
extern DECLSPEC int SDLCALL Mix_GroupChannels(int from, int to, int tag);
slouken@136
   472
/* Finds the first available channel in a group of channels,
slouken@136
   473
   returning -1 if none are available.
slouken@136
   474
 */
slouken@165
   475
extern DECLSPEC int SDLCALL Mix_GroupAvailable(int tag);
slouken@34
   476
/* Returns the number of channels in a group. This is also a subtle
slouken@34
   477
   way to get the total number of channels when 'tag' is -1
slouken@34
   478
 */
slouken@165
   479
extern DECLSPEC int SDLCALL Mix_GroupCount(int tag);
slouken@34
   480
/* Finds the "oldest" sample playing in a group of channels */
slouken@165
   481
extern DECLSPEC int SDLCALL Mix_GroupOldest(int tag);
slouken@34
   482
/* Finds the "most recent" (i.e. last) sample playing in a group of channels */
slouken@165
   483
extern DECLSPEC int SDLCALL Mix_GroupNewer(int tag);
slouken@34
   484
slouken@34
   485
/* Play an audio chunk on a specific channel.
slouken@34
   486
   If the specified channel is -1, play on the first free channel.
slouken@34
   487
   If 'loops' is greater than zero, loop the sound that many times.
slouken@34
   488
   If 'loops' is -1, loop inifinitely (~65000 times).
slouken@34
   489
   Returns which channel was used to play the sound.
slouken@34
   490
*/
slouken@34
   491
#define Mix_PlayChannel(channel,chunk,loops) Mix_PlayChannelTimed(channel,chunk,loops,-1)
slouken@34
   492
/* The same as above, but the sound is played at most 'ticks' milliseconds */
slouken@165
   493
extern DECLSPEC int SDLCALL Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks);
slouken@165
   494
extern DECLSPEC int SDLCALL Mix_PlayMusic(Mix_Music *music, int loops);
slouken@34
   495
slouken@34
   496
/* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions */
slouken@165
   497
extern DECLSPEC int SDLCALL Mix_FadeInMusic(Mix_Music *music, int loops, int ms);
slouken@165
   498
extern DECLSPEC int SDLCALL Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position);
slouken@34
   499
#define Mix_FadeInChannel(channel,chunk,loops,ms) Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1)
slouken@165
   500
extern DECLSPEC int SDLCALL Mix_FadeInChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ms, int ticks);
slouken@34
   501
slouken@34
   502
/* Set the volume in the range of 0-128 of a specific channel or chunk.
slouken@34
   503
   If the specified channel is -1, set volume for all channels.
slouken@34
   504
   Returns the original volume.
slouken@34
   505
   If the specified volume is -1, just return the current volume.
slouken@34
   506
*/
slouken@165
   507
extern DECLSPEC int SDLCALL Mix_Volume(int channel, int volume);
slouken@165
   508
extern DECLSPEC int SDLCALL Mix_VolumeChunk(Mix_Chunk *chunk, int volume);
slouken@165
   509
extern DECLSPEC int SDLCALL Mix_VolumeMusic(int volume);
slouken@34
   510
slouken@34
   511
/* Halt playing of a particular channel */
slouken@165
   512
extern DECLSPEC int SDLCALL Mix_HaltChannel(int channel);
slouken@165
   513
extern DECLSPEC int SDLCALL Mix_HaltGroup(int tag);
slouken@165
   514
extern DECLSPEC int SDLCALL Mix_HaltMusic(void);
slouken@34
   515
slouken@34
   516
/* Change the expiration delay for a particular channel.
slouken@34
   517
   The sample will stop playing after the 'ticks' milliseconds have elapsed,
slouken@34
   518
   or remove the expiration if 'ticks' is -1
slouken@34
   519
*/
slouken@165
   520
extern DECLSPEC int SDLCALL Mix_ExpireChannel(int channel, int ticks);
slouken@34
   521
slouken@34
   522
/* Halt a channel, fading it out progressively till it's silent
slouken@34
   523
   The ms parameter indicates the number of milliseconds the fading
slouken@34
   524
   will take.
slouken@34
   525
 */
slouken@165
   526
extern DECLSPEC int SDLCALL Mix_FadeOutChannel(int which, int ms);
slouken@165
   527
extern DECLSPEC int SDLCALL Mix_FadeOutGroup(int tag, int ms);
slouken@165
   528
extern DECLSPEC int SDLCALL Mix_FadeOutMusic(int ms);
slouken@34
   529
slouken@34
   530
/* Query the fading status of a channel */
slouken@165
   531
extern DECLSPEC Mix_Fading SDLCALL Mix_FadingMusic(void);
slouken@165
   532
extern DECLSPEC Mix_Fading SDLCALL Mix_FadingChannel(int which);
slouken@34
   533
slouken@34
   534
/* Pause/Resume a particular channel */
slouken@165
   535
extern DECLSPEC void SDLCALL Mix_Pause(int channel);
slouken@165
   536
extern DECLSPEC void SDLCALL Mix_Resume(int channel);
slouken@167
   537
extern DECLSPEC int SDLCALL Mix_Paused(int channel);
slouken@34
   538
slouken@34
   539
/* Pause/Resume the music stream */
slouken@165
   540
extern DECLSPEC void SDLCALL Mix_PauseMusic(void);
slouken@165
   541
extern DECLSPEC void SDLCALL Mix_ResumeMusic(void);
slouken@165
   542
extern DECLSPEC void SDLCALL Mix_RewindMusic(void);
slouken@167
   543
extern DECLSPEC int SDLCALL Mix_PausedMusic(void);
slouken@34
   544
slouken@154
   545
/* Set the current position in the music stream.
slouken@154
   546
   This returns 0 if successful, or -1 if it failed or isn't implemented.
slouken@155
   547
   This function is only implemented for MOD music formats (set pattern
slouken@155
   548
   order number) and for OGG music (set position in seconds), at the
slouken@155
   549
   moment.
slouken@154
   550
*/
slouken@165
   551
extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position);
slouken@154
   552
slouken@34
   553
/* Check the status of a specific channel.
slouken@34
   554
   If the specified channel is -1, check all channels.
slouken@34
   555
*/
slouken@165
   556
extern DECLSPEC int SDLCALL Mix_Playing(int channel);
slouken@165
   557
extern DECLSPEC int SDLCALL Mix_PlayingMusic(void);
slouken@34
   558
slouken@34
   559
/* Stop music and set external music playback command */
slouken@165
   560
extern DECLSPEC int SDLCALL Mix_SetMusicCMD(const char *command);
slouken@34
   561
slouken@154
   562
/* Synchro value is set by MikMod from modules while playing */
slouken@165
   563
extern DECLSPEC int SDLCALL Mix_SetSynchroValue(int value);
slouken@165
   564
extern DECLSPEC int SDLCALL Mix_GetSynchroValue(void);
slouken@154
   565
slouken@92
   566
/* Get the Mix_Chunk currently associated with a mixer channel
slouken@92
   567
    Returns NULL if it's an invalid channel, or there's no chunk associated.
slouken@92
   568
*/
slouken@165
   569
extern DECLSPEC Mix_Chunk * SDLCALL Mix_GetChunk(int channel);
slouken@92
   570
slouken@34
   571
/* Close the mixer, halting all playing audio */
slouken@165
   572
extern DECLSPEC void SDLCALL Mix_CloseAudio(void);
slouken@34
   573
slouken@34
   574
/* We'll use SDL for reporting errors */
slouken@34
   575
#define Mix_SetError	SDL_SetError
slouken@34
   576
#define Mix_GetError	SDL_GetError
slouken@34
   577
slouken@34
   578
/* Ends C function definitions when using C++ */
slouken@34
   579
#ifdef __cplusplus
slouken@78
   580
}
slouken@34
   581
#endif
slouken@40
   582
#include "close_code.h"
slouken@34
   583
slouken@229
   584
#endif /* _SDL_MIXER_H */