FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

SDL_mixer

 
Post new topic   Reply to topic     Forum Index -> Derelict
View previous topic :: View next topic  
Author Message
Jaymz031602



Joined: 18 Aug 2004
Posts: 14

PostPosted: Wed Aug 18, 2004 8:20 am    Post subject: SDL_mixer Reply with quote

SDL_mixer would be nice; looks small too! Very Happy

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. Cool
_________________
"Yeah, well you're hogging all the ... UGLY!" - Chris (Family Guy)
Back to top
View user's profile Send private message AIM Address
Jaymz031602



Joined: 18 Aug 2004
Posts: 14

PostPosted: Wed Aug 18, 2004 9:18 am    Post subject: SDL_mixer here! Reply with quote

So, I got ambitious and impatient at the same time Wink.

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! Very Happy
_________________
"Yeah, well you're hogging all the ... UGLY!" - Chris (Family Guy)
Back to top
View user's profile Send private message AIM Address
aldacron



Joined: 05 May 2004
Posts: 1322
Location: Seoul, South Korea

PostPosted: Wed Aug 18, 2004 10:52 am    Post subject: Reply with quote

Excellent work Smile 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
View user's profile Send private message Send e-mail
Jaymz031602



Joined: 18 Aug 2004
Posts: 14

PostPosted: Wed Aug 18, 2004 11:02 am    Post subject: Reply with quote

You're very welcome! Thanks for the timeliness of your response and the integration into the main trunk. All in an hour's work. Smile

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
View user's profile Send private message AIM Address
aldacron



Joined: 05 May 2004
Posts: 1322
Location: Seoul, South Korea

PostPosted: Thu Aug 19, 2004 7:40 pm    Post subject: Reply with quote

When interacting with C code you should always zero terminate your char arrays. toStringz() does the trick nicely.
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Derelict All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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