mirror of
https://github.com/Laex/Delphi-OpenCV.git
synced 2024-11-17 08:45:54 +01:00
562a25f50e
Signed-off-by: Laentir Valetov <laex@bk.ru>
807 lines
36 KiB
ObjectPascal
807 lines
36 KiB
ObjectPascal
unit SDL2_Mixer;
|
|
{*******************************************************************************
|
|
|
|
SDL2_Mixer.pas v1.0 29/07/2013 first version for DelphiXE
|
|
v1.1 27/08/2013 add MACOS compability
|
|
v1.2 31/05/2014 delete sdl2.inc
|
|
|
|
Simple DirectMedia Layer
|
|
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
|
|
|
Pascal-Header-Conversion SDL from the JEDI-Team written by Domenique Louis and others.
|
|
|
|
convert SDL/SDL2 to SDL2 for DelphiXE by Kotai 2013/2014 www.remakesonline.com
|
|
|
|
The initial developer of this Pascal code was :
|
|
Dominqiue Louis <Dominique@SavageSoftware.com.au>
|
|
|
|
|
|
*******************************************************************************}
|
|
|
|
|
|
interface
|
|
|
|
uses
|
|
SDL2;
|
|
|
|
const
|
|
|
|
{$IFDEF MSWINDOWS}
|
|
SDL_MixerLibName = 'SDL2_mixer.dll';
|
|
{$ENDIF}
|
|
|
|
{$IFDEF ANDROID}
|
|
SDL_MixerLibName = 'libSDL2_mixer.so';
|
|
{$ENDIF}
|
|
|
|
{$IFDEF MACOS}
|
|
{$IFDEF IOS}
|
|
SDL_MixerLibName = 'libSDL2_mixer.a';
|
|
{$ELSE}
|
|
SDL_MixerLibName = 'SDL2_mixer';
|
|
// SDL_MixerLibName = '../Frameworks/SDL2_mixer.framework/Versions/A/SDL2_mixer';
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
{* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *}
|
|
const
|
|
SDL_MIXER_MAJOR_VERSION = 2;
|
|
SDL_MIXER_MINOR_VERSION = 0;
|
|
SDL_MIXER_PATCHLEVEL = 0;
|
|
|
|
{* This macro can be used to fill a version structure with the compile-time
|
|
* version of the SDL_mixer library.
|
|
*}
|
|
procedure SDL_MIXER_VERSION(X: PSDL_Version);
|
|
|
|
{* Backwards compatibility *}
|
|
const
|
|
MIX_MAJOR_VERSION = SDL_MIXER_MAJOR_VERSION;
|
|
MIX_MINOR_VERSION = SDL_MIXER_MINOR_VERSION;
|
|
MIX_PATCHLEVEL = SDL_MIXER_PATCHLEVEL;
|
|
|
|
procedure MIX_VERSION(X: PSDL_Version);
|
|
|
|
{* This function gets the version of the dynamically linked SDL_mixer library.
|
|
it should NOT be used to fill a version structure, instead you should
|
|
use the SDL_MIXER_VERSION() macro.
|
|
*}
|
|
function Mix_Linked_Version(): PSDL_Version;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_Linked_Version' {$ENDIF} {$ENDIF};
|
|
|
|
const
|
|
MIX_INIT_FLAC = $00000001;
|
|
MIX_INIT_MOD = $00000002;
|
|
MIX_INIT_MODPLUG = $00000004;
|
|
MIX_INIT_MP3 = $00000008;
|
|
MIX_INIT_OGG = $00000010;
|
|
MIX_INIT_FLUIDSYNTH = $00000020;
|
|
type
|
|
TMIX_InitFlags = Byte;
|
|
|
|
{* Loads dynamic libraries and prepares them for use. Flags should be
|
|
one or more flags from MIX_InitFlags OR'd together.
|
|
It returns the flags successfully initialized, or 0 on failure.
|
|
*}
|
|
function Mix_Init(flags: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_Init' {$ENDIF} {$ENDIF};
|
|
|
|
{* Unloads libraries loaded with Mix_Init *}
|
|
procedure Mix_Quit();
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_Quit' {$ENDIF} {$ENDIF};
|
|
|
|
|
|
{* The default mixer has 8 simultaneous mixing channels *}
|
|
{$IFNDEF MIX_CHANNELS}
|
|
const
|
|
MIX_CHANNELS = 8;
|
|
{$ENDIF}
|
|
|
|
{* Good default values for a PC soundcard *}
|
|
const
|
|
MIX_DEFAULT_FREQUENCY = 22050;
|
|
MIX_DEFAULT_FORMAT = AUDIO_S16LSB;
|
|
MIX_DEFAULT_CHANNELS = 2;
|
|
MIX_MAX_VOLUME = 128; {* Volume of a chunk *}
|
|
|
|
{* The internal format for an audio chunk *}
|
|
type
|
|
PMix_Chunk = ^TMix_Chunk;
|
|
TMix_Chunk = record
|
|
allocated: Integer;
|
|
abuf: PUInt8;
|
|
alen: UInt32;
|
|
volume: UInt8; {* Per-sample volume, 0-128 *}
|
|
end;
|
|
|
|
{* The different fading types supported *}
|
|
type
|
|
TMix_Fading = (MIX_NO_FADING, MIX_FADING_OUT, MIX_FADING_IN);
|
|
|
|
TMix_MusicType = (MUS_NONE,
|
|
MUS_CMD,
|
|
MUS_WAV,
|
|
MUS_MOD,
|
|
MUS_MID,
|
|
MUS_OGG,
|
|
MUS_MP3,
|
|
MUS_MP3_MAD,
|
|
MUS_FLAC,
|
|
MUS_MODPLUG);
|
|
|
|
{* The internal format for a music chunk interpreted via mikmod *}
|
|
PMix_Music = ^TMix_Music;
|
|
TMix_Music = record end;
|
|
|
|
{* Open the mixer with a certain audio format *}
|
|
function Mix_OpenAudio(frequency: Integer; format: UInt16; channels: Integer; chunksize: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_OpenAudio' {$ENDIF} {$ENDIF};
|
|
|
|
{* Dynamically change the number of channels managed by the mixer.
|
|
If decreasing the number of channels, the upper channels are
|
|
stopped.
|
|
This function returns the new number of allocated channels.
|
|
*}
|
|
function Mix_AllocateChannels(numchans: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_AllocateChannels' {$ENDIF} {$ENDIF};
|
|
|
|
{* Find out what the actual audio device parameters are.
|
|
This function returns 1 if the audio has been opened, 0 otherwise.
|
|
*}
|
|
function Mix_QuerySpec(frequency: PInt; format: PUInt16; channels: PInt): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_QuerySpec' {$ENDIF} {$ENDIF};
|
|
|
|
{* Load a wave file or a music (.mod .s3m .it .xm) file *}
|
|
function Mix_LoadWAV_RW(src: PSDL_RWops; freesrc: Integer): PMix_Chunk;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_LoadWAV_RW' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_LoadWAV(_file: PChar): PMix_Chunk;
|
|
|
|
function Mix_LoadMUS(_file: PChar): PMix_Music;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_LoadMUS' {$ENDIF} {$ENDIF};
|
|
|
|
{* Load a music file from an SDL_RWop object (Ogg and MikMod specific currently)
|
|
Matt Campbell (matt@campbellhome.dhs.org) April 2000 *}
|
|
function Mix_LoadMUS_RW(src: PSDL_RWops; freesrc: Integer): PMix_Music;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_LoadMUS_RW' {$ENDIF} {$ENDIF};
|
|
|
|
{* Load a music file from an SDL_RWop object assuming a specific format *}
|
|
function Mix_LoadMUSType_RW(src: PSDL_RWops; _type: TMix_MusicType; freesrc: Integer): PMix_Music;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_LoadMUSType_RW' {$ENDIF} {$ENDIF};
|
|
|
|
{* Load a wave file of the mixer format from a memory buffer *}
|
|
function Mix_QuickLoad_WAV(mem: PUInt8): PMix_Chunk;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_QuickLoad_WAV' {$ENDIF} {$ENDIF};
|
|
|
|
{* Load raw audio data of the mixer format from a memory buffer *}
|
|
function Mix_QuickLoad_RAW(mem: PUInt8; len: UInt32): PMix_Chunk;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_QuickLoad_RAW' {$ENDIF} {$ENDIF};
|
|
|
|
{* Free an audio chunk previously loaded *}
|
|
procedure Mix_FreeChunk(chunk: PMix_Chunk);
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FreeChunk' {$ENDIF} {$ENDIF};
|
|
|
|
procedure Mix_FreeMusic(music: PMix_Music);
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FreeMusic' {$ENDIF} {$ENDIF};
|
|
|
|
{* Get a list of chunk/music decoders that this build of SDL_mixer provides.
|
|
This list can change between builds AND runs of the program, if external
|
|
libraries that add functionality become available.
|
|
You must successfully call Mix_OpenAudio() before calling these functions.
|
|
This API is only available in SDL_mixer 1.2.9 and later.
|
|
|
|
// usage...
|
|
int i;
|
|
const int total = Mix_GetNumChunkDecoders();
|
|
for (i = 0; i < total; i++)
|
|
printf("Supported chunk decoder: [%s]\n", Mix_GetChunkDecoder(i));
|
|
|
|
Appearing in this list doesn't promise your specific audio file will
|
|
decode...but it's handy to know if you have, say, a functioning Timidity
|
|
install.
|
|
|
|
These return values are static, read-only data; do not modify or free it.
|
|
The pointers remain valid until you call Mix_CloseAudio().
|
|
*}
|
|
function Mix_GetNumChunkDecoders: Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GetNumChunkDecoders' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_GetChunkDecoder(index: Integer): PChar;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GetChunkDecoder' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_GetNumMusicDecoders: Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GetNumMusicDecoders' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_GetMusicDecoder(index: Integer): PChar;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GetMusicDecoder' {$ENDIF} {$ENDIF};
|
|
|
|
{* Find out the music format of a mixer music, or the currently playing
|
|
music, if 'music' is NULL.
|
|
*}
|
|
function Mix_GetMusicType(music: TMix_Music): TMix_MusicType;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GetMusicType' {$ENDIF} {$ENDIF};
|
|
|
|
{* Set a function that is called after all mixing is performed.
|
|
This can be used to provide real-time visual display of the audio stream
|
|
or add a custom mixer filter for the stream data.
|
|
*}
|
|
type
|
|
TMix_Func = procedure(udata: Pointer; stream: PUInt8; len: Integer);
|
|
|
|
procedure Mix_SetPostMix(func: TMix_Func; arg: Pointer);
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_SetPostMix' {$ENDIF} {$ENDIF};
|
|
|
|
{* Add your own music player or additional mixer function.
|
|
If 'mix_func' is NULL, the default music player is re-enabled.
|
|
*}
|
|
procedure Mix_HookMusic(func: TMix_Func; arg: Pointer);
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_HookMusic' {$ENDIF} {$ENDIF};
|
|
|
|
{* Add your own callback when the music has finished playing.
|
|
This callback is only called if the music finishes naturally.
|
|
*}
|
|
type
|
|
PMix_Music_Finished = ^TMix_Music_Finished;
|
|
TMix_Music_Finished = procedure();
|
|
|
|
procedure Mix_HookMusicFinished(music_finished: PMix_Music_Finished);
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_HookMusicFinished' {$ENDIF} {$ENDIF};
|
|
|
|
{* Get a pointer to the user data for the current music hook *}
|
|
function Mix_GetMusicHookData(): Pointer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GetMusicHookData' {$ENDIF} {$ENDIF};
|
|
|
|
{*
|
|
* Add your own callback when a channel has finished playing. NULL
|
|
* to disable callback. The callback may be called from the mixer's audio
|
|
* callback or it could be called as a result of Mix_HaltChannel(), etc.
|
|
* do not call SDL_LockAudio() from this callback; you will either be
|
|
* inside the audio callback, or SDL_mixer will explicitly lock the audio
|
|
* before calling your callback.
|
|
*}
|
|
type
|
|
TMix_Channel_Finished = procedure(channel: Integer);
|
|
|
|
procedure Mix_ChannelFinished(channel_finished: TMix_Channel_Finished);
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_ChannelFinished' {$ENDIF} {$ENDIF};
|
|
|
|
{* Special Effects API by ryan c. gordon. (icculus@icculus.org) *}
|
|
const
|
|
MIX_CHANNEL_POST = -2;
|
|
|
|
{* This is the format of a special effect callback:
|
|
*
|
|
* myeffect(int chan, void *stream, int len, void *udata);
|
|
*
|
|
* (chan) is the channel number that your effect is affecting. (stream) is
|
|
* the buffer of data to work upon. (len) is the size of (stream), and
|
|
* (udata) is a user-defined bit of data, which you pass as the last arg of
|
|
* Mix_RegisterEffect(), and is passed back unmolested to your callback.
|
|
* Your effect changes the contents of (stream) based on whatever parameters
|
|
* are significant, or just leaves it be, if you prefer. You can do whatever
|
|
* you like to the buffer, though, and it will continue in its changed state
|
|
* down the mixing pipeline, through any other effect functions, then finally
|
|
* to be mixed with the rest of the channels and music for the final output
|
|
* stream.
|
|
*
|
|
* DO NOT EVER call SDL_LockAudio() from your callback function!
|
|
*}
|
|
type
|
|
TMix_EffectFunc_t = procedure(chan: Integer; stream: Pointer; len: Integer; udata: Pointer);
|
|
|
|
{*
|
|
* This is a callback that signifies that a channel has finished all its
|
|
* loops and has completed playback. This gets called if the buffer
|
|
* plays out normally, or if you call Mix_HaltChannel(), implicitly stop
|
|
* a channel via Mix_AllocateChannels(), or unregister a callback while
|
|
* it's still playing.
|
|
*
|
|
* DO NOT EVER call SDL_LockAudio() from your callback function!
|
|
*}
|
|
type
|
|
TMix_EffectDone_t = procedure(chan: Integer; udata: Pointer);
|
|
|
|
{* Register a special effect function. At mixing time, the channel data is
|
|
* copied into a buffer and passed through each registered effect function.
|
|
* After it passes through all the functions, it is mixed into the final
|
|
* output stream. The copy to buffer is performed once, then each effect
|
|
* function performs on the output of the previous effect. Understand that
|
|
* this extra copy to a buffer is not performed if there are no effects
|
|
* registered for a given chunk, which saves CPU cycles, and any given
|
|
* effect will be extra cycles, too, so it is crucial that your code run
|
|
* fast. Also note that the data that your function is given is in the
|
|
* format of the sound device, and not the format you gave to Mix_OpenAudio(),
|
|
* although they may in reality be the same. This is an unfortunate but
|
|
* necessary speed concern. Use Mix_QuerySpec() to determine if you can
|
|
* handle the data before you register your effect, and take appropriate
|
|
* actions.
|
|
* You may also specify a callback (Mix_EffectDone_t) that is called when
|
|
* the channel finishes playing. This gives you a more fine-grained control
|
|
* than Mix_ChannelFinished(), in case you need to free effect-specific
|
|
* resources, etc. If you don't need this, you can specify NULL.
|
|
* You may set the callbacks before or after calling Mix_PlayChannel().
|
|
* Things like Mix_SetPanning() are just internal special effect functions,
|
|
* so if you are using that, you've already incurred the overhead of a copy
|
|
* to a separate buffer, and that these effects will be in the queue with
|
|
* any functions you've registered. The list of registered effects for a
|
|
* channel is reset when a chunk finishes playing, so you need to explicitly
|
|
* set them with each call to Mix_PlayChannel*().
|
|
* You may also register a special effect function that is to be run after
|
|
* final mixing occurs. The rules for these callbacks are identical to those
|
|
* in Mix_RegisterEffect, but they are run after all the channels and the
|
|
* music have been mixed into a single stream, whereas channel-specific
|
|
* effects run on a given channel before any other mixing occurs. These
|
|
* global effect callbacks are call "posteffects". Posteffects only have
|
|
* their Mix_EffectDone_t function called when they are unregistered (since
|
|
* the main output stream is never "done" in the same sense as a channel).
|
|
* You must unregister them manually when you've had enough. Your callback
|
|
* will be told that the channel being mixed is (MIX_CHANNEL_POST) if the
|
|
* processing is considered a posteffect.
|
|
*
|
|
* After all these effects have finished processing, the callback registered
|
|
* through Mix_SetPostMix() runs, and then the stream goes to the audio
|
|
* device.
|
|
*
|
|
* DO NOT EVER call SDL_LockAudio() from your callback function!
|
|
*
|
|
* returns zero if error (no such channel), nonzero if added.
|
|
* Error messages can be retrieved from Mix_GetError().
|
|
*}
|
|
function Mix_RegisterEffect(chan: Integer; f: TMix_EffectFunc_t; d: TMix_EffectDone_t; arg: Pointer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_RegisterEffect' {$ENDIF} {$ENDIF};
|
|
|
|
{* You may not need to call this explicitly, unless you need to stop an
|
|
* effect from processing in the middle of a chunk's playback.
|
|
* Posteffects are never implicitly unregistered as they are for channels,
|
|
* but they may be explicitly unregistered through this function by
|
|
* specifying MIX_CHANNEL_POST for a channel.
|
|
* returns zero if error (no such channel or effect), nonzero if removed.
|
|
* Error messages can be retrieved from Mix_GetError().
|
|
*}
|
|
function Mix_UnregisterEffect(channel: Integer; f: TMix_EffectFunc_t): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_UnregisterEffect' {$ENDIF} {$ENDIF};
|
|
|
|
{* You may not need to call this explicitly, unless you need to stop all
|
|
* effects from processing in the middle of a chunk's playback. Note that
|
|
* this will also shut off some internal effect processing, since
|
|
* Mix_SetPanning() and others may use this API under the hood. This is
|
|
* called internally when a channel completes playback.
|
|
* Posteffects are never implicitly unregistered as they are for channels,
|
|
* but they may be explicitly unregistered through this function by
|
|
* specifying MIX_CHANNEL_POST for a channel.
|
|
* returns zero if error (no such channel), nonzero if all effects removed.
|
|
* Error messages can be retrieved from Mix_GetError().
|
|
*}
|
|
function Mix_UnregisterAllEffects(channel: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_UnregisterEffects' {$ENDIF} {$ENDIF};
|
|
|
|
const
|
|
MIX_EFFECTSMAXSPEED = 'MIX_EFFECTSMAXSPEED';
|
|
|
|
{*
|
|
* These are the internally-defined mixing effects. They use the same API that
|
|
* effects defined in the application use, but are provided here as a
|
|
* convenience. Some effects can reduce their quality or use more memory in
|
|
* the name of speed; to enable this, make sure the environment variable
|
|
* MIX_EFFECTSMAXSPEED (see above) is defined before you call
|
|
* Mix_OpenAudio().
|
|
*}
|
|
|
|
{* Set the panning of a channel. The left and right channels are specified
|
|
* as integers between 0 and 255, quietest to loudest, respectively.
|
|
*
|
|
* Technically, this is just individual volume control for a sample with
|
|
* two (stereo) channels, so it can be used for more than just panning.
|
|
* If you want real panning, call it like this:
|
|
*
|
|
* Mix_SetPanning(channel, left, 255 - left);
|
|
*
|
|
* ...which isn't so hard.
|
|
*
|
|
* Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
|
|
* the panning will be done to the final mixed stream before passing it on
|
|
* to the audio device.
|
|
*
|
|
* This uses the Mix_RegisterEffect() API internally, and returns without
|
|
* registering the effect function if the audio device is not configured
|
|
* for stereo output. Setting both (left) and (right) to 255 causes this
|
|
* effect to be unregistered, since that is the data's normal state.
|
|
*
|
|
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
|
|
* nonzero if panning effect enabled. Note that an audio device in mono
|
|
* mode is a no-op, but this call will return successful in that case.
|
|
* Error messages can be retrieved from Mix_GetError().
|
|
*}
|
|
function Mix_SetPanning(channel: Integer; left: UInt8; right: UInt8): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_SetPanning' {$ENDIF} {$ENDIF};
|
|
|
|
{* Set the position of a channel. (angle) is an integer from 0 to 360, that
|
|
* specifies the location of the sound in relation to the listener. (angle)
|
|
* will be reduced as neccesary (540 becomes 180 degrees, -100 becomes 260).
|
|
* Angle 0 is due north, and rotates clockwise as the value increases.
|
|
* For efficiency, the precision of this effect may be limited (angles 1
|
|
* through 7 might all produce the same effect, 8 through 15 are equal, etc).
|
|
* (distance) is an integer between 0 and 255 that specifies the space
|
|
* between the sound and the listener. The larger the number, the further
|
|
* away the sound is. Using 255 does not guarantee that the channel will be
|
|
* culled from the mixing process or be completely silent. For efficiency,
|
|
* the precision of this effect may be limited (distance 0 through 5 might
|
|
* all produce the same effect, 6 through 10 are equal, etc). Setting (angle)
|
|
* and (distance) to 0 unregisters this effect, since the data would be
|
|
* unchanged.
|
|
*
|
|
* If you need more precise positional audio, consider using OpenAL for
|
|
* spatialized effects instead of SDL_mixer. This is only meant to be a
|
|
* basic effect for simple "3D" games.
|
|
*
|
|
* If the audio device is configured for mono output, then you won't get
|
|
* any effectiveness from the angle; however, distance attenuation on the
|
|
* channel will still occur. While this effect will function with stereo
|
|
* voices, it makes more sense to use voices with only one channel of sound,
|
|
* so when they are mixed through this effect, the positioning will sound
|
|
* correct. You can convert them to mono through SDL before giving them to
|
|
* the mixer in the first place if you like.
|
|
*
|
|
* Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
|
|
* the positioning will be done to the final mixed stream before passing it
|
|
* on to the audio device.
|
|
*
|
|
* This is a convenience wrapper over Mix_SetDistance() and Mix_SetPanning().
|
|
*
|
|
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
|
|
* nonzero if position effect is enabled.
|
|
* Error messages can be retrieved from Mix_GetError().
|
|
*}
|
|
function Mix_SetPosition(channel: Integer; angle: SInt16; distance: UInt8): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_SetPosition' {$ENDIF} {$ENDIF};
|
|
|
|
{* Set the "distance" of a channel. (distance) is an integer from 0 to 255
|
|
* that specifies the location of the sound in relation to the listener.
|
|
* Distance 0 is overlapping the listener, and 255 is as far away as possible
|
|
* A distance of 255 does not guarantee silence; in such a case, you might
|
|
* want to try changing the chunk's volume, or just cull the sample from the
|
|
* mixing process with Mix_HaltChannel().
|
|
* For efficiency, the precision of this effect may be limited (distances 1
|
|
* through 7 might all produce the same effect, 8 through 15 are equal, etc).
|
|
* (distance) is an integer between 0 and 255 that specifies the space
|
|
* between the sound and the listener. The larger the number, the further
|
|
* away the sound is.
|
|
* Setting (distance) to 0 unregisters this effect, since the data would be
|
|
* unchanged.
|
|
* If you need more precise positional audio, consider using OpenAL for
|
|
* spatialized effects instead of SDL_mixer. This is only meant to be a
|
|
* basic effect for simple "3D" games.
|
|
*
|
|
* Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
|
|
* the distance attenuation will be done to the final mixed stream before
|
|
* passing it on to the audio device.
|
|
*
|
|
* This uses the Mix_RegisterEffect() API internally.
|
|
*
|
|
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
|
|
* nonzero if position effect is enabled.
|
|
* Error messages can be retrieved from Mix_GetError().
|
|
*}
|
|
function Mix_SetDistance(channel: Integer; distance: UInt8): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_SetDistance' {$ENDIF} {$ENDIF};
|
|
|
|
{*
|
|
* !!! FIXME : Haven't implemented, since the effect goes past the
|
|
* end of the sound buffer. Will have to think about this.
|
|
* --ryan.
|
|
*}
|
|
//#if 0
|
|
{* Causes an echo effect to be mixed into a sound. (echo) is the amount
|
|
* of echo to mix. 0 is no echo, 255 is infinite (and probably not
|
|
* what you want).
|
|
*
|
|
* Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
|
|
* the reverbing will be done to the final mixed stream before passing it on
|
|
* to the audio device.
|
|
*
|
|
* This uses the Mix_RegisterEffect() API internally. If you specify an echo
|
|
* of zero, the effect is unregistered, as the data is already in that state.
|
|
*
|
|
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
|
|
* nonzero if reversing effect is enabled.
|
|
* Error messages can be retrieved from Mix_GetError().
|
|
*}
|
|
//extern no_parse_DECLSPEC int SDLCALL Mix_SetReverb(int channel, Uint8 echo);
|
|
//#endif
|
|
|
|
{* Causes a channel to reverse its stereo. This is handy if the user has his
|
|
* speakers hooked up backwards, or you would like to have a minor bit of
|
|
* psychedelia in your sound code. :) Calling this function with (flip)
|
|
* set to non-zero reverses the chunks's usual channels. If (flip) is zero,
|
|
* the effect is unregistered.
|
|
*
|
|
* This uses the Mix_RegisterEffect() API internally, and thus is probably
|
|
* more CPU intensive than having the user just plug in his speakers
|
|
* correctly. Mix_SetReverseStereo() returns without registering the effect
|
|
* function if the audio device is not configured for stereo output.
|
|
*
|
|
* If you specify MIX_CHANNEL_POST for (channel), then this the effect is used
|
|
* on the final mixed stream before sending it on to the audio device (a
|
|
* posteffect).
|
|
*
|
|
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
|
|
* nonzero if reversing effect is enabled. Note that an audio device in mono
|
|
* mode is a no-op, but this call will return successful in that case.
|
|
* Error messages can be retrieved from Mix_GetError().
|
|
*}
|
|
function Mix_SetReverseStereo(channel: Integer; flip: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_SetReverseStereo' {$ENDIF} {$ENDIF};
|
|
|
|
{* end of effects API. --ryan. *}
|
|
|
|
{* Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
|
|
them dynamically to the next sample if requested with a -1 value below.
|
|
Returns the number of reserved channels.
|
|
*}
|
|
function Mix_ReserveChannels(num: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_ReverseChannels' {$ENDIF} {$ENDIF};
|
|
|
|
{* Channel grouping functions *}
|
|
|
|
{* Attach a tag to a channel. A tag can be assigned to several mixer
|
|
channels, to form groups of channels.
|
|
If 'tag' is -1, the tag is removed (actually -1 is the tag used to
|
|
represent the group of all the channels).
|
|
Returns true if everything was OK.
|
|
*}
|
|
function Mix_GroupChannel(which: Integer; tag: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GroupChannel' {$ENDIF} {$ENDIF};
|
|
|
|
{* Assign several consecutive channels to a group *}
|
|
function Mix_GroupChannels(from: Integer; _to: Integer; tag: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GroupChannels' {$ENDIF} {$ENDIF};
|
|
|
|
{* Finds the first available channel in a group of channels,
|
|
returning -1 if none are available.
|
|
*}
|
|
function Mix_GroupAvailable(tag: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GroupAvailable' {$ENDIF} {$ENDIF};
|
|
|
|
{* Returns the number of channels in a group. This is also a subtle
|
|
way to get the total number of channels when 'tag' is -1
|
|
*}
|
|
function Mix_GroupCount(tag: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GroupCount' {$ENDIF} {$ENDIF};
|
|
|
|
{* Finds the "oldest" sample playing in a group of channels *}
|
|
function Mix_GroupOldest(tag: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GroupOldest' {$ENDIF} {$ENDIF};
|
|
|
|
{* Finds the "most recent" (i.e. last) sample playing in a group of channels *}
|
|
function Mix_GroupNewer(tag: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GroupNewer' {$ENDIF} {$ENDIF};
|
|
|
|
{* Play an audio chunk on a specific channel.
|
|
If the specified channel is -1, play on the first free channel.
|
|
If 'loops' is greater than zero, loop the sound that many times.
|
|
If 'loops' is -1, loop inifinitely (~65000 times).
|
|
Returns which channel was used to play the sound.
|
|
*}
|
|
function Mix_PlayChannel(channel: Integer; chunk: PMix_Chunk; loops: Integer): Integer;
|
|
|
|
{* The same as above, but the sound is played at most 'ticks' milliseconds *}
|
|
function Mix_PlayChannelTimed(channel: Integer; chunk: PMix_Chunk; loops: Integer; ticks: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_PlayChannelTimed' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_PlayMusic(music: PMix_Music; loops: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_PlayMusic' {$ENDIF} {$ENDIF};
|
|
|
|
{* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions *}
|
|
function Mix_FadeInMusic(music: PMix_Music; loops: Integer; ms: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FadeInMusic' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_FadeInMusicPos(music: PMix_Music; loops: Integer; ms: Integer; position: Double): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FadeInMusicPos' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_FadeInChannel(channel: Integer; chunk: PMix_Chunk; loops: Integer; ms: Integer): Integer;
|
|
|
|
function Mix_FadeInChannelTimed(channel: Integer; chunk: PMix_Chunk; loops: Integer; ms: Integer; ticks: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FadeInChannelTimed' {$ENDIF} {$ENDIF};
|
|
|
|
{* Set the volume in the range of 0-128 of a specific channel or chunk.
|
|
If the specified channel is -1, set volume for all channels.
|
|
Returns the original volume.
|
|
If the specified volume is -1, just return the current volume.
|
|
*}
|
|
function Mix_Volume(channel: Integer; volume: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_Volume' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_VolumeChunk(chunk: PMix_Chunk; volume: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_VolumeChunk' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_VolumeMusic(volume: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_VolumeMusic' {$ENDIF} {$ENDIF};
|
|
|
|
{* Halt playing of a particular channel *}
|
|
function Mix_HaltChannel(channel: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_HaltChannel' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_HaltGroup(tag: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_HaltGroup' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_HaltMusic(): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_HaltMusic' {$ENDIF} {$ENDIF};
|
|
|
|
{* Change the expiration delay for a particular channel.
|
|
The sample will stop playing after the 'ticks' milliseconds have elapsed,
|
|
or remove the expiration if 'ticks' is -1
|
|
*}
|
|
function Mix_ExpireChannel(channel: Integer; ticks: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_ExpireChannel' {$ENDIF} {$ENDIF};
|
|
|
|
{* Halt a channel, fading it out progressively till it's silent
|
|
The ms parameter indicates the number of milliseconds the fading
|
|
will take.
|
|
*}
|
|
function Mix_FadeOutChannel(which: Integer; ms: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FadeOutChannel' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_FadeOutGroup(tag: Integer; ms: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FadeOutGroup' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_FadeOutMusic(ms: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FadeOutMusic' {$ENDIF} {$ENDIF};
|
|
|
|
{* Query the fading status of a channel *}
|
|
function Mix_FadingMusic(): TMix_Fading;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FadingMusic' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_FadingChannel(which: Integer): TMix_Fading;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_FadingChannel' {$ENDIF} {$ENDIF};
|
|
|
|
{* Pause/Resume a particular channel *}
|
|
procedure Mix_Pause(channel: Integer);
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_Pause' {$ENDIF} {$ENDIF};
|
|
|
|
procedure Mix_Resume(channel: Integer);
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_Resume' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_Paused(channel: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_Paused' {$ENDIF} {$ENDIF};
|
|
|
|
{* Pause/Resume the music stream *}
|
|
procedure Mix_PauseMusic();
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_PauseMusic' {$ENDIF} {$ENDIF};
|
|
|
|
procedure Mix_ResumeMusic();
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_ResumeMusic' {$ENDIF} {$ENDIF};
|
|
|
|
procedure Mix_RewindMusic();
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_RewindMusic' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_PausedMusic(): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_PausedMusic' {$ENDIF} {$ENDIF};
|
|
|
|
{* Set the current position in the music stream.
|
|
This returns 0 if successful, or -1 if it failed or isn't implemented.
|
|
This function is only implemented for MOD music formats (set pattern
|
|
order number) and for OGG, FLAC, MP3_MAD, and MODPLUG music (set
|
|
position in seconds), at the moment.
|
|
*}
|
|
function Mix_SetMusicPosition(position: Double): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_SetMusicPosition' {$ENDIF} {$ENDIF};
|
|
|
|
{* Check the status of a specific channel.
|
|
If the specified channel is -1, check all channels.
|
|
*}
|
|
function Mix_Playing(channel: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_Playing' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_PlayingMusic(): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_PlayingMusic' {$ENDIF} {$ENDIF};
|
|
|
|
{* Stop music and set external music playback command *}
|
|
function Mix_SetMusicCMD(command: PChar): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_SetMusicCMD' {$ENDIF} {$ENDIF};
|
|
|
|
{* Synchro value is set by MikMod from modules while playing *}
|
|
function Mix_SetSynchroValue(value: Integer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_SetSynchroValue' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_GetSynchroValue(): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GetSynchroValue' {$ENDIF} {$ENDIF};
|
|
|
|
{* Set/Get/Iterate SoundFonts paths to use by supported MIDI backends *}
|
|
function Mix_SetSoundFonts(paths: PChar): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_SetSoundFonts' {$ENDIF} {$ENDIF};
|
|
|
|
function Mix_GetSoundFonts(): PChar;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GetSoundFonts' {$ENDIF} {$ENDIF};
|
|
|
|
type
|
|
TMix_SoundFunc = function(c: PChar; p: Pointer): Integer;
|
|
|
|
function Mix_EachSoundFont(func: TMix_SoundFunc; data: Pointer): Integer;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_EachSoundFont' {$ENDIF} {$ENDIF};
|
|
|
|
{* Get the Mix_Chunk currently associated with a mixer channel
|
|
Returns NULL if it's an invalid channel, or there's no chunk associated.
|
|
*}
|
|
function Mix_GetChunk(channel: Integer): PMix_Chunk;
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_GetChunk' {$ENDIF} {$ENDIF};
|
|
|
|
{* Close the mixer, halting all playing audio *}
|
|
procedure Mix_CloseAudio();
|
|
cdecl; external SDL_MixerLibName {$IFDEF MACOS} {$IFNDEF IOS} name '_MIX_CloseAudio' {$ENDIF} {$ENDIF};
|
|
|
|
{* We'll use SDL for reporting errors *}
|
|
function Mix_SetError(const fmt: PChar): SInt32;
|
|
function Mix_GetError: PChar;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//******************************************************************************
|
|
//******************************************************************************
|
|
//******************************************************************************
|
|
//******************************************************************************
|
|
//******************************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
//******************************************************************************
|
|
|
|
procedure SDL_MIXER_VERSION(X: PSDL_Version);
|
|
begin
|
|
X.major := SDL_MIXER_MAJOR_VERSION;
|
|
X.minor := SDL_MIXER_MINOR_VERSION;
|
|
X.patch := SDL_MIXER_PATCHLEVEL;
|
|
end;
|
|
|
|
//******************************************************************************
|
|
|
|
procedure MIX_VERSION(X: PSDL_Version);
|
|
begin
|
|
SDL_MIXER_VERSION(X);
|
|
end;
|
|
|
|
//******************************************************************************
|
|
|
|
function Mix_FadeInChannel(channel: Integer; chunk: PMix_Chunk; loops: Integer; ms: Integer): Integer;
|
|
begin
|
|
Result := Mix_FadeInChannelTimed(channel, chunk, loops, ms, -1);
|
|
end;
|
|
|
|
//******************************************************************************
|
|
|
|
function Mix_PlayChannel(channel: Integer; chunk: PMix_Chunk; loops: Integer): Integer;
|
|
begin
|
|
Result := Mix_PlayChannelTimed(channel, chunk, loops, -1);
|
|
end;
|
|
|
|
//******************************************************************************
|
|
|
|
function Mix_LoadWAV(_file: PChar): PMix_Chunk;
|
|
begin
|
|
Result := Mix_LoadWAV_RW(SDL_RWFromFile(_file, 'rb'), 1);
|
|
end;
|
|
|
|
//******************************************************************************
|
|
|
|
function Mix_SetError(const fmt: PChar): SInt32;
|
|
begin
|
|
Result := SDL_SetError(fmt);
|
|
end;
|
|
|
|
//******************************************************************************
|
|
|
|
function Mix_GetError: PChar;
|
|
begin
|
|
Result := SDL_GetError;
|
|
end;
|
|
|
|
end.
|