View previous topic :: View next topic |
Author |
Message |
Jaymz031602
Joined: 18 Aug 2004 Posts: 14
|
Posted: Wed Aug 18, 2004 8:20 am Post subject: SDL_mixer |
|
|
SDL_mixer would be nice; looks small too!
If you're too busy, I could tackle it for you and send you the module. It'd take me a good day or so to look at your model of implementing SDL for D and conform, but I could handle it. _________________ "Yeah, well you're hogging all the ... UGLY!" - Chris (Family Guy) |
|
Back to top |
|
|
Jaymz031602
Joined: 18 Aug 2004 Posts: 14
|
Posted: Wed Aug 18, 2004 9:18 am Post subject: SDL_mixer here! |
|
|
So, I got ambitious and impatient at the same time .
Here's the mixer.d file to go into the SVN trunk. I have not tested it in an application, but it compiles with the current version of D (0.97). Also, it conforms to your standards (I peeked at image.d).
An IDE with RegEx find & replace is a sweet thing indeed. Enjoy!
Code: | /*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
private import derelict.sdl.types;
private import derelict.sdl.rwops;
private import derelict.sdl.audio;
private import derelict.sdl.byteorder;
private import derelict.sdl.sdlversion;
private import derelict.sdl.error;
private import std.loader;
//==============================================================================
// Types
//==============================================================================
alias SDL_SetError Mix_SetError;
alias SDL_GetError Mix_GetError;
struct Mix_Chunk {
int allocated;
Uint8 *abuf;
Uint32 alen;
Uint8 volume;
};
enum Mix_Fading {
MIX_NO_FADING,
MIX_FADING_OUT,
MIX_FADING_IN
};
enum Mix_MusicType {
MUS_NONE,
MUS_CMD,
MUS_WAV,
MUS_MOD,
MUS_MID,
MUS_OGG,
MUS_MP3
};
extern (C) struct _Mix_Music;
typedef _Mix_Music Mix_Music;
const int MIX_MAJOR_VERSION = 1;
const int MIX_MINOR_VERSION = 2;
const int MIX_PATCHLEVEL = 5;
const int MIX_CHANNELS = 8;
/* Good default values for a PC soundcard */
const int MIX_DEFAULT_FREQUENCY = 22050;
version (LittleEndian) {
const int MIX_DEFAULT_FORMAT = AUDIO_S16LSB;
} else {
const int MIX_DEFAULT_FORMAT = AUDIO_S16MSB;
}
const int MIX_DEFAULT_CHANNELS = 2;
const int MIX_MAX_VOLUME = 128;
const int MIX_CHANNEL_POST = -2;
const char[] MIX_EFFECTSMAXSPEED = "MIX_EFFECTSMAXSPEED";
//==============================================================================
// Macros
//==============================================================================
alias SDL_VERSION MIX_VERSION;
// FIXME: Need to append \0 to file?
Mix_Chunk *Mix_LoadWAV(char[] file) {
return Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1);
}
int Mix_PlayChannel(int channel, Mix_Chunk *chunk, int loops) {
return Mix_PlayChannelTimed(channel, chunk, loops, -1);
}
int Mix_FadeInChannel(int channel, Mix_Chunk *chunk, int loops, int ms) {
return Mix_FadeInChannelTimed(channel, chunk, loops, ms, -1);
}
//==============================================================================
// Functions
//==============================================================================
extern (C)
{
// GENERAL FIXME: Use char[] or char * ?
typedef SDL_version * function() pfMix_Linked_Version;
typedef int function (int frequency, Uint16 format, int channels, int chunksize) pfMix_OpenAudio;
typedef int function(int numchans) pfMix_AllocateChannels;
typedef int function(int *frequency, Uint16 *format, int *channels) pfMix_QuerySpec;
typedef Mix_Chunk * function(SDL_RWops *src, int freesrc) pfMix_LoadWAV_RW;
typedef Mix_Music * function(char[] file) pfMix_LoadMUS;
typedef Mix_Chunk * function(Uint8 *mem) pfMix_QuickLoad_WAV;
typedef Mix_Chunk * function(Uint8 *mem, Uint32 len) pfMix_QuickLoad_RAW;
typedef void function(Mix_Chunk *chunk) pfMix_FreeChunk;
typedef void function(Mix_Music *music) pfMix_FreeMusic;
typedef Mix_MusicType function(Mix_Music *music) pfMix_GetMusicType;
// FIXME: How to handle these callbacks?
typedef void function(void (*mix_func)(void *udata, Uint8 *stream, int len), void *arg) pfMix_SetPostMix;
typedef void function(void (*mix_func)(void *udata, Uint8 *stream, int len), void *arg) pfMix_HookMusic;
typedef void function(void (*music_finished)()) pfMix_HookMusicFinished;
// END FIXME
typedef void * function() pfMix_GetMusicHookData;
typedef void function(void (*channel_finished)(int channel)) pfMix_ChannelFinished;
// Straight from C (more or less, adopted 'function(...) identifier' style):
typedef void function(int chan, void *stream, int len, void *udata) Mix_EffectFunc_t;
typedef void function(int chan, void *udata) Mix_EffectDone_t;
// End straight from C
typedef int function(int chan, Mix_EffectFunc_t f, Mix_EffectDone_t d, void *arg) pfMix_RegisterEffect;
typedef int function(int channel, Mix_EffectFunc_t f) pfMix_UnregisterEffect;
typedef int function(int channel) pfMix_UnregisterAllEffects;
typedef int function(int channel, Uint8 left, Uint8 right) pfMix_SetPanning;
typedef int function(int channel, Sint16 angle, Uint8 distance) pfMix_SetPosition;
typedef int function(int channel, Uint8 distance) pfMix_SetDistance;
typedef int function(int channel, int flip) pfMix_SetReverseStereo;
typedef int function(int num) pfMix_ReserveChannels;
typedef int function(int which, int tag) pfMix_GroupChannel;
typedef int function(int from, int to, int tag) pfMix_GroupChannels;
typedef int function(int tag) pfMix_GroupAvailable;
typedef int function(int tag) pfMix_GroupCount;
typedef int function(int tag) pfMix_GroupOldest;
typedef int function(int tag) pfMix_GroupNewer;
typedef int function(int channel, Mix_Chunk *chunk, int loops, int ticks) pfMix_PlayChannelTimed;
typedef int function(Mix_Music *music, int loops) pfMix_PlayMusic;
typedef int function(Mix_Music *music, int loops, int ms) pfMix_FadeInMusic;
typedef int function(Mix_Music *music, int loops, int ms, double position) pfMix_FadeInMusicPos;
typedef int function(int channel, Mix_Chunk *chunk, int loops, int ms, int ticks) pfMix_FadeInChannelTimed;
typedef int function(int channel, int volume) pfMix_Volume;
typedef int function(Mix_Chunk *chunk, int volume) pfMix_VolumeChunk;
typedef int function(int volume) pfMix_VolumeMusic;
typedef int function(int channel) pfMix_HaltChannel;
typedef int function(int tag) pfMix_HaltGroup;
typedef int function() pfMix_HaltMusic;
typedef int function(int channel, int ticks) pfMix_ExpireChannel;
typedef int function(int which, int ms) pfMix_FadeOutChannel;
typedef int function(int tag, int ms) pfMix_FadeOutGroup;
typedef int function(int ms) pfMix_FadeOutMusic;
typedef Mix_Fading function() pfMix_FadingMusic;
typedef Mix_Fading function(int which) pfMix_FadingChannel;
typedef void function(int channel) pfMix_Pause;
typedef void function(int channel) pfMix_Resume;
typedef int function(int channel) pfMix_Paused;
typedef void function() pfMix_PauseMusic;
typedef void function() pfMix_ResumeMusic;
typedef void function() pfMix_RewindMusic;
typedef int function() pfMix_PausedMusic;
typedef int function(double position) pfMix_SetMusicPosition;
typedef int function(int channel) pfMix_Playing;
typedef int function() pfMix_PlayingMusic;
typedef int function(char[] command) pfMix_SetMusicCMD;
typedef int function(int value) pfMix_SetSynchroValue;
typedef int function() pfMix_GetSynchroValue;
typedef Mix_Chunk * function(int channel) pfMix_GetChunk;
typedef void function() pfMix_CloseAudio;
pfMix_OpenAudio Mix_OpenAudio;
pfMix_AllocateChannels Mix_AllocateChannels;
pfMix_QuerySpec Mix_QuerySpec;
pfMix_LoadWAV_RW Mix_LoadWAV_RW;
pfMix_LoadMUS Mix_LoadMUS;
pfMix_QuickLoad_WAV Mix_QuickLoad_WAV;
pfMix_QuickLoad_RAW Mix_QuickLoad_RAW;
pfMix_FreeChunk Mix_FreeChunk;
pfMix_FreeMusic Mix_FreeMusic;
pfMix_GetMusicType Mix_GetMusicType;
pfMix_SetPostMix Mix_SetPostMix;
pfMix_HookMusic Mix_HookMusic;
pfMix_HookMusicFinished Mix_HookMusicFinished;
pfMix_GetMusicHookData Mix_GetMusicHookData;
pfMix_ChannelFinished Mix_ChannelFinished;
pfMix_RegisterEffect Mix_RegisterEffect;
pfMix_UnregisterEffect Mix_UnregisterEffect;
pfMix_UnregisterAllEffects Mix_UnregisterAllEffects;
pfMix_SetPanning Mix_SetPanning;
pfMix_SetPosition Mix_SetPosition;
pfMix_SetDistance Mix_SetDistance;
pfMix_SetReverseStereo Mix_SetReverseStereo;
pfMix_ReserveChannels Mix_ReserveChannels;
pfMix_GroupChannel Mix_GroupChannel;
pfMix_GroupChannels Mix_GroupChannels;
pfMix_GroupAvailable Mix_GroupAvailable;
pfMix_GroupCount Mix_GroupCount;
pfMix_GroupOldest Mix_GroupOldest;
pfMix_GroupNewer Mix_GroupNewer;
pfMix_PlayChannelTimed Mix_PlayChannelTimed;
pfMix_PlayMusic Mix_PlayMusic;
pfMix_FadeInMusic Mix_FadeInMusic;
pfMix_FadeInMusicPos Mix_FadeInMusicPos;
pfMix_FadeInChannelTimed Mix_FadeInChannelTimed;
pfMix_Volume Mix_Volume;
pfMix_VolumeChunk Mix_VolumeChunk;
pfMix_VolumeMusic Mix_VolumeMusic;
pfMix_HaltChannel Mix_HaltChannel;
pfMix_HaltGroup Mix_HaltGroup;
pfMix_HaltMusic Mix_HaltMusic;
pfMix_ExpireChannel Mix_ExpireChannel;
pfMix_FadeOutChannel Mix_FadeOutChannel;
pfMix_FadeOutGroup Mix_FadeOutGroup;
pfMix_FadeOutMusic Mix_FadeOutMusic;
pfMix_FadingMusic Mix_FadingMusic;
pfMix_FadingChannel Mix_FadingChannel;
pfMix_Pause Mix_Pause;
pfMix_Resume Mix_Resume;
pfMix_Paused Mix_Paused;
pfMix_PauseMusic Mix_PauseMusic;
pfMix_ResumeMusic Mix_ResumeMusic;
pfMix_RewindMusic Mix_RewindMusic;
pfMix_PausedMusic Mix_PausedMusic;
pfMix_SetMusicPosition Mix_SetMusicPosition;
pfMix_Playing Mix_Playing;
pfMix_PlayingMusic Mix_PlayingMusic;
pfMix_SetMusicCMD Mix_SetMusicCMD;
pfMix_SetSynchroValue Mix_SetSynchroValue;
pfMix_GetSynchroValue Mix_GetSynchroValue;
pfMix_GetChunk Mix_GetChunk;
pfMix_CloseAudio Mix_CloseAudio;
}
//==============================================================================
// Loader
//==============================================================================
private HXModule hsdlMixer;
private void* getProc(char[] procname)
{
void *symbol = ExeModule_GetSymbol(hsdlMixer, procname);
if (symbol is null)
throw new Exception("Failed to load SDLMixer proc address " ~ procname);
return symbol;
}
private void load()
{
Mix_OpenAudio = cast(pfMix_OpenAudio)getProc("Mix_OpenAudio");
Mix_AllocateChannels = cast(pfMix_AllocateChannels)getProc("Mix_AllocateChannels");
Mix_QuerySpec = cast(pfMix_QuerySpec)getProc("Mix_QuerySpec");
Mix_LoadWAV_RW = cast(pfMix_LoadWAV_RW)getProc("Mix_LoadWAV_RW");
Mix_LoadMUS = cast(pfMix_LoadMUS)getProc("Mix_LoadMUS");
Mix_QuickLoad_WAV = cast(pfMix_QuickLoad_WAV)getProc("Mix_QuickLoad_WAV");
Mix_QuickLoad_RAW = cast(pfMix_QuickLoad_RAW)getProc("Mix_QuickLoad_RAW");
Mix_FreeChunk = cast(pfMix_FreeChunk)getProc("Mix_FreeChunk");
Mix_FreeMusic = cast(pfMix_FreeMusic)getProc("Mix_FreeMusic");
Mix_GetMusicType = cast(pfMix_GetMusicType)getProc("Mix_GetMusicType");
Mix_SetPostMix = cast(pfMix_SetPostMix)getProc("Mix_SetPostMix");
Mix_HookMusic = cast(pfMix_HookMusic)getProc("Mix_HookMusic");
Mix_HookMusicFinished = cast(pfMix_HookMusicFinished)getProc("Mix_HookMusicFinished");
Mix_GetMusicHookData = cast(pfMix_GetMusicHookData)getProc("Mix_GetMusicHookData");
Mix_ChannelFinished = cast(pfMix_ChannelFinished)getProc("Mix_ChannelFinished");
Mix_RegisterEffect = cast(pfMix_RegisterEffect)getProc("Mix_RegisterEffect");
Mix_UnregisterEffect = cast(pfMix_UnregisterEffect)getProc("Mix_UnregisterEffect");
Mix_UnregisterAllEffects = cast(pfMix_UnregisterAllEffects)getProc("Mix_UnregisterAllEffects");
Mix_SetPanning = cast(pfMix_SetPanning)getProc("Mix_SetPanning");
Mix_SetPosition = cast(pfMix_SetPosition)getProc("Mix_SetPosition");
Mix_SetDistance = cast(pfMix_SetDistance)getProc("Mix_SetDistance");
Mix_SetReverseStereo = cast(pfMix_SetReverseStereo)getProc("Mix_SetReverseStereo");
Mix_ReserveChannels = cast(pfMix_ReserveChannels)getProc("Mix_ReserveChannels");
Mix_GroupChannel = cast(pfMix_GroupChannel)getProc("Mix_GroupChannel");
Mix_GroupChannels = cast(pfMix_GroupChannels)getProc("Mix_GroupChannels");
Mix_GroupAvailable = cast(pfMix_GroupAvailable)getProc("Mix_GroupAvailable");
Mix_GroupCount = cast(pfMix_GroupCount)getProc("Mix_GroupCount");
Mix_GroupOldest = cast(pfMix_GroupOldest)getProc("Mix_GroupOldest");
Mix_GroupNewer = cast(pfMix_GroupNewer)getProc("Mix_GroupNewer");
Mix_PlayChannelTimed = cast(pfMix_PlayChannelTimed)getProc("Mix_PlayChannelTimed");
Mix_PlayMusic = cast(pfMix_PlayMusic)getProc("Mix_PlayMusic");
Mix_FadeInMusic = cast(pfMix_FadeInMusic)getProc("Mix_FadeInMusic");
Mix_FadeInMusicPos = cast(pfMix_FadeInMusicPos)getProc("Mix_FadeInMusicPos");
Mix_FadeInChannelTimed = cast(pfMix_FadeInChannelTimed)getProc("Mix_FadeInChannelTimed");
Mix_Volume = cast(pfMix_Volume)getProc("Mix_Volume");
Mix_VolumeChunk = cast(pfMix_VolumeChunk)getProc("Mix_VolumeChunk");
Mix_VolumeMusic = cast(pfMix_VolumeMusic)getProc("Mix_VolumeMusic");
Mix_HaltChannel = cast(pfMix_HaltChannel)getProc("Mix_HaltChannel");
Mix_HaltGroup = cast(pfMix_HaltGroup)getProc("Mix_HaltGroup");
Mix_HaltMusic = cast(pfMix_HaltMusic)getProc("Mix_HaltMusic");
Mix_ExpireChannel = cast(pfMix_ExpireChannel)getProc("Mix_ExpireChannel");
Mix_FadeOutChannel = cast(pfMix_FadeOutChannel)getProc("Mix_FadeOutChannel");
Mix_FadeOutGroup = cast(pfMix_FadeOutGroup)getProc("Mix_FadeOutGroup");
Mix_FadeOutMusic = cast(pfMix_FadeOutMusic)getProc("Mix_FadeOutMusic");
Mix_FadingMusic = cast(pfMix_FadingMusic)getProc("Mix_FadingMusic");
Mix_FadingChannel = cast(pfMix_FadingChannel)getProc("Mix_FadingChannel");
Mix_Pause = cast(pfMix_Pause)getProc("Mix_Pause");
Mix_Resume = cast(pfMix_Resume)getProc("Mix_Resume");
Mix_Paused = cast(pfMix_Paused)getProc("Mix_Paused");
Mix_PauseMusic = cast(pfMix_PauseMusic)getProc("Mix_PauseMusic");
Mix_ResumeMusic = cast(pfMix_ResumeMusic)getProc("Mix_ResumeMusic");
Mix_RewindMusic = cast(pfMix_RewindMusic)getProc("Mix_RewindMusic");
Mix_PausedMusic = cast(pfMix_PausedMusic)getProc("Mix_PausedMusic");
Mix_SetMusicPosition = cast(pfMix_SetMusicPosition)getProc("Mix_SetMusicPosition");
Mix_Playing = cast(pfMix_Playing)getProc("Mix_Playing");
Mix_PlayingMusic = cast(pfMix_PlayingMusic)getProc("Mix_PlayingMusic");
Mix_SetMusicCMD = cast(pfMix_SetMusicCMD)getProc("Mix_SetMusicCMD");
Mix_SetSynchroValue = cast(pfMix_SetSynchroValue)getProc("Mix_SetSynchroValue");
Mix_GetSynchroValue = cast(pfMix_GetSynchroValue)getProc("Mix_GetSynchroValue");
Mix_GetChunk = cast(pfMix_GetChunk)getProc("Mix_GetChunk");
Mix_CloseAudio = cast(pfMix_CloseAudio)getProc("Mix_CloseAudio");
}
public void DerelictSDLMixer_Load()
{
if (hsdlMixer !== null)
return;
version (Windows)
hsdlMixer = ExeModule_Load("SDL_mixer.dll");
load();
}
static ~this()
{
ExeModule_Release(hsdlMixer);
} |
Hope this works, cuz that would be embarassing if not! _________________ "Yeah, well you're hogging all the ... UGLY!" - Chris (Family Guy) |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Wed Aug 18, 2004 10:52 am Post subject: |
|
|
Excellent work I'm a bit tied up right now, but I'll try to get this integrated and committed within the next 24 hours. As to your FIXMES:
Quote: |
// GENERAL FIXME: Use char[] or char * ?
|
I will always use char* when interfacing with C code.
Quote: |
// FIXME: How to handle these callbacks?
|
Those should be fine as-is. Alternatively, you could typedef them:
Code: |
// mix func callback
typedef void function(void*,Uint8*,int) mix_func;
// then you can do this
typedef void function(mix_func, void*) pfMix_SetPostMix;
|
I'll fix up the char* stuff when I get around to integrating it. Thanks for the work! |
|
Back to top |
|
|
Jaymz031602
Joined: 18 Aug 2004 Posts: 14
|
Posted: Wed Aug 18, 2004 11:02 am Post subject: |
|
|
You're very welcome! Thanks for the timeliness of your response and the integration into the main trunk. All in an hour's work.
So, the char * convention forces the D programmer to append a \0? Or does D handle that automagically?
I haven't been doing much / any D programming, but I'm really excited to start developing with it , as soon as I get some free time. _________________ "Yeah, well you're hogging all the ... UGLY!" - Chris (Family Guy) |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Thu Aug 19, 2004 7:40 pm Post subject: |
|
|
When interacting with C code you should always zero terminate your char arrays. toStringz() does the trick nicely. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|