Commits

Marcus von Appen committed 7decf1e

- added new module sdl2.sdlmixer, which wraps SDL_mixer
- updated some references on the pygamers document (still incomplete)

  • Participants
  • Parent commits 7572957

Comments (0)

Files changed (11)

 # built documents.
 #
 # The short X.Y version.
-version = '0.3'
+version = '0.4'
 # The full version, including alpha/beta/rc tags.
-release = '0.3.0'
+release = '0.4.0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

File doc/install.rst

 PySDL2 also offers support for the following SDL-related libraries:
 
 * SDL_image             (http://www.libsdl.org/projects/SDL_image/)
+* SDL_mixer             (http://www.libsdl.org/projects/SDL_mixer/)
 * SDL_ttf               (http://www.libsdl.org/projects/SDL_ttf/)
 * SDL_gfx               (http://www.ferzkopp.net/Software/SDL_gfx-2.0/)
 
 Those are optional though and only necessary, if you want to use
-:mod:`sdl2.sdlimage`, :mod:`sdl2.sdlttf` or :mod:`sdl2.sdlgfx`.
+:mod:`sdl2.sdlimage`, :mod:`sdl2.sdlmixer`, :mod:`sdl2.sdlttf` or
+:mod:`sdl2.sdlgfx`.
 
 .. note::
 
-   Neither SDL2 nor the related versions for SDL_image, SDL_ttf or SDL_gfx are
-   officially released yet. Thus, a binary version is not available. You can
-   obtain a set of unofficial binaries (based on the current development
-   version of those projects) from http://bitbucket.org/marcusva/py-sdl2/downloads.
+   Neither SDL2 nor the related versions for SDL_image, SDL_mixer,
+   SDL_ttf or SDL_gfx are officially released yet. Thus, a binary
+   version is not available. You can obtain a set of unofficial binaries
+   (based on the current development version of those projects) from
+   http://bitbucket.org/marcusva/py-sdl2/downloads.
 
 
 Installation

File doc/modules/index.rst

    sdl2.rst
    sdl2_sdlgfx.rst
    sdl2_sdlimage.rst
+   sdl2_sdlmixer.rst
    sdl2_sdlttf.rst
    sdl2ext.rst

File doc/modules/sdl2_sdlmixer.rst

+.. module:: sdl2.sdlmixer
+   :synopsis: SDL2_mixer library wrapper
+
+sd2.sdlmixer - SDL2_mixer library wrapper
+=========================================
+The :mod:`sdl2.sdlmixer` module is a :mod:`ctypes`-based wrapper around
+the SDL2_mixer library. It wraps nearly all publicly accessible
+structures and functions of the SDL2_mixer library to be accessible from
+Python code.
+
+A detailled documentation about the behaviour of the different functions
+can found within the `SDL2_mixer documentation
+<http://www.libsdl.org/projects/SDL_mixer/docs/index.html>`_.

File doc/modules/sdl2_sdlttf.rst

 sd2.sdlttf - SDL2_ttf library wrapper
 =====================================
 The :mod:`sdl2.sdlttf` module is a :mod:`ctypes`-based wrapper
-around the SDL2_image library. It wraps nearly all publicly accessible
+around the SDL2_ttf library. It wraps nearly all publicly accessible
 structures and functions of the SDL2_ttf library to be accessible from
 Python code.
 

File doc/news.rst

 -----
 Released on 2013-XX-XX.
 
+* new :mod:`sdl2.sdlmixer` module, which provides access to the
+  SDL2_mixer library
 * issue #1: fixed libc loading for cases where libc.so is a ld script
 
 0.3.0
 * :mod:`sdl2.ext.SpriteFactory` methods do not use a default ``size`` argument
   anymore; it has to provided by the caller
 
-
 0.2.0
 -----
 Released on 2013-05-03.

File doc/tutorial/pygamers.rst

 contrast is written in pure Python, using :mod:`ctypes` to interface
 with the C interfaces of 3rd party libraries.
 
-
 API differences
 ---------------
 
 ======================= =================================================
 pygame                  sdl2
 ======================= =================================================
-``init()``              :func:`sdl2.init()` where appropriate
-``quit()``              :func:`sdl2.quit()` where appropriate
+``init()``              :func:`sdl2.SDL_init()` where appropriate
+``quit()``              :func:`sdl2.SDL_quit()` where appropriate
 ``error``               No equivalent
-``get_error()``         :func:`sdl2.get_error()`
-``set_error()``         :func:`sdl2.set_error()`
-``get_sdl_version()``   :func:`sdl2.version.get_version()`
-``get_sdl_byteorder()`` :data:`sdl2.endian.SDL_BYTEORDER`
+``get_error()``         :func:`sdl2.SDL_GetError()`
+``set_error()``         :func:`sdl2.SDL_SetError()`
+``get_sdl_version()``   :func:`sdl2.SDL_GetVersion()`
+``get_sdl_byteorder()`` :data:`sdl2.SDL_BYTEORDER`
 ``register_quit()``     No equivalent planned
-``encode_string()``     Encoding and decoding strings is done implicitly,
-                        where necessary
-``encode_file_path()``  Encoding and decoding strings is done implicitly,
-                        where necessary
+``encode_string()``     No equivalent planned
+``encode_file_path()``  No equivalent planned
 ======================= =================================================
 
 pygame.cdrom
 ``init()``              :func:`sdl2.ext.init()`
 ``quit()``              :func:`sdl2.ext.quit()`
 ``get_init()``          :func:`sdl2.SDL_WasInit()`
-``set_mode()``          :class:`mule.video.window.Window`
-``get_surface()``       :meth:`mule.video.window.Window.get_surface()`
-``flip()``              :meth:`mule.video.window.Window.refresh()`
-``update()``            :meth:`mule.sdl2.video.update_window_surface_rects()`
-``get_driver()``        :func:`mule.sdl2.video.get_current_video_driver()`
-``Info``                No equivalent yet
-``get_wm_info()``       :func:`mule.sdl2.syswm.get_window_wm_info()`
-``list_modes()``        :func:`mule.sdl2.video.get_num_display_modes()`
-``mode_ok()``           :func:`mule.sdl2.video.get_closest_display_mode()`
-``gl_get_attribute()``  :func:`mule.sdl2.video.gl_get_attribute()`
-``gl_set_attribute()``  :func:`mule.sdl2.video.gl_set_attribute()`
-``get_active()``        No equivalent yet
-``iconify()``           :meth:`mule.video.window.Window.minimize()`
-``toggle_fullscreen()`` :func:`mule.sdl2.video.set_window_fullscreen()`
-``set_gamma()``         :func:`mule.sdl2.video.set_window_brightness()`
-``set_gamma_ramp()``    :func:`mule.sdl2.video.set_window_gamma_ramp()`
-``set_icon()``          :func:`mule.sdl2.video.set_window_icon()`
-``set_caption()``       :attr:`mule.video.window.Window.title`
-``get_caption()``       :attr:`mule.video.window.Window.title`
-``set_palette()``       :func:`mule.sdl2.surface.set_surface_palette()`
+``set_mode()``          :class:`sdl2.ext.Window`
+``get_surface()``       :meth:`sdl2.ext.Window.get_surface()`
+``flip()``              :meth:`sdl2.ext.Window.refresh()`
+``update()``            :meth:`sdl2.ext.Window.refresh()`
+``get_driver()``        :func:`sdl2.SDL_GetCurrentVideoDriver()`
+``Info``                No equivalent
+``get_wm_info()``       :func:`sdl2.SDL_GetWindowWMInfo()`
+``list_modes()``        :func:`sdl2.SDL_GetNumDisplayModes()`
+``mode_ok()``           :func:`sdl2.SDL_GetClosestDisplayMode()`
+``gl_get_attribute()``  :func:`sdl2.SDL_GL_GetAttribute()`
+``gl_set_attribute()``  :func:`sdl2.SDL_GL_SetAttribute()`
+``get_active()``        No equivalent
+``iconify()``           :meth:`sdl2.ext.Window.minimize()`
+``toggle_fullscreen()`` :func:`sdl2.SDL_SetWindowFullscreen()`
+``set_gamma()``         :func:`sdl2.SDL_SetWindowBrightness()`
+``set_gamma_ramp()``    :func:`sdl2.SDL_SetWindowGammaRamp.()`
+``set_icon()``          :func:`sdl2.SDL_SetWindowIcon()`
+``set_caption()``       :attr:`sdl2.ext.Window.title`
+``get_caption()``       :attr:`sdl2.ext.Window.title`
+``set_palette()``       :func:`sdl2.SDL_SetSurfacePalette()`
 ======================= =================================================
 
 pygame.draw
 ^^^^^^^^^^^
-============== =================================================
-pygame.draw    mule
-============== =================================================
-``rect()``     :func:`mule.sdl2.render.render_draw_rect()`,
-               :func:`mule.video.draw.fill()`
-``polygon()``  No equivalent yet
-``circle()``   No equivalent yet
-``ellipse()``  No equivalent yet
-``arc()``      No equivalent yet
-``lines()``    :func:`mule.sdl2.render.render_draw_lines()`,
-               :func:`mule.video.draw.line()`
-``aaline()``   No equivalent yet
-``aalines()``  No equivalent yet
-============== =================================================
+Drawing primitives can be accessed through either the
+``sdl2.SDL_RenderDraw*()`` and ``sdl2.SDL_RenderFill*()`` functions or
+the more powerful :mod:`sdl2.sdlgfx` module,
 
 pygame.event
 ^^^^^^^^^^^^
 ================= =================================================
 pygame.event      mule
 ================= =================================================
-``pump()``        :func:`mule.sdl2.events.pump_events()`
-``get()``         :func:`mule.sdl2.events.poll_event()`
-``poll()``        :func:`mule.sdl2.events.poll_event()`
-``wait()``        :func:`mule.sdl2.events.wait_event()`
-``peek()``        :func:`mule.sdl2.events.peep_events()`
-``clear()``       :func:`mule.sdl2.events.flush_events()`
-``event_name()``  No equivalent planned
-``set_blocked()`` :func:`mule.sdl2.events.event_state()`
-``get_blocked()`` :func:`mule.sdl2.events.event_state()`
-``set_allowed()`` :func:`mule.sdl2.events.event_state()`
-``set_grab()``    :func:`mule.sdl2.video.set_window_grab()`
-``get_grab()``    :func:`mule.sdl2.video.get_window_grab()`
-``post()``        :func:`mule.sdl2.events.peep_events()`
-``Event``         :class:`mule.sdl2.events.SDL_Event`
+``pump()``        :func:`sdl2.SDL_PumpEvents()`
+``get()``         :func:`sdl2.SDL_PollEvent()` or :func:`sdl2.ext.get_events()`
+``poll()``        :func:`sdl2.SDL_PollEvent()`
+``wait()``        :func:`sdl2.SDL_WaitEvent()`
+``peek()``        :func:`sdl2.SDL_PeepEvents()`
+``clear()``       :func:`sdl2.SDL_FlushEvents()`
+``event_name()``  No equivalent
+``set_blocked()`` :func:`sdl2.SDL_EventState()`
+``get_blocked()`` :func:`sdl2.SDL_EventState()`
+``set_allowed()`` :func:`sdl2.SDL_EventState()`
+``set_grab()``    :func:`sdl2.SDL_SetWindowGrab()`
+``get_grab()``    :func:`sdl2.SDL_GetWindowGrab()`
+``post()``        :func:`sdl2.SDL_PeepEvents()`
+``Event``         :class:`sdl2.SDL_Event`
 ================= =================================================
 
 pygame.font
 
 pygame.freetype
 ^^^^^^^^^^^^^^^
-mule does not feature direct FreeType support at the moment.
+PySDL2 does not feature direct FreeType support.
 
 pygame.gfxdraw
 ^^^^^^^^^^^^^^
-mule does not feature SDL_gfx support at the moment.
+PySDL2 offers SDL_gfx support through the :mod:`sdl2.sdlgfx` module.
 
 pygame.image
 ^^^^^^^^^^^^

File sdl2/__init__.py

 from .dll import get_dll_file, _bind
 from ctypes import c_int as _cint
 
-
-#__all__ = ["SDL_INIT_TIMER", "SDL_INIT_AUDIO", "SDL_INIT_VIDEO",
-#           "SDL_INIT_JOYSTICK", "SDL_INIT_HAPTIC", "SDL_INIT_GAMECONTROLLER",
-#           "SDL_INIT_NOPARACHUTE", "SDL_INIT_EVERYTHING", "SDL_Init",
-#           "SDL_InitSubSystem", "SDL_QuitSubSystem", "SDL_WasInit", "SDL_Quit",
-#           "version_info"
-#           ]
-
-
 from .audio import *
 from .blendmode import *
 from .clipboard import *
 SDL_WasInit = _bind("SDL_WasInit", [Uint32], Uint32)
 SDL_Quit = _bind("SDL_Quit")
 
-__version__ = "0.3.0"
-version_info = (0, 3, 0, "")
+__version__ = "0.4.0"
+version_info = (0, 4, 0, "")

File sdl2/sdlmixer.py

+import os
+from ctypes import Structure, POINTER, CFUNCTYPE, c_int, c_char_p, c_void_p, \
+    c_double
+from .dll import _DLL
+from .version import SDL_version
+from .audio import AUDIO_S16LSB, AUDIO_S16MSB
+from .stdinc import Uint8, Uint16, Uint32, Sint16
+from .endian import SDL_LIL_ENDIAN, SDL_BYTEORDER
+from .rwops import SDL_RWops, SDL_RWFromFile
+from .error import SDL_SetError, SDL_GetError
+
+__all__ = ["get_dll_file", "SDL_MIXER_MAJOR_VERSION", "SDL_MIXER_MINOR_VERSION",
+           "SDL_MIXER_PATCHLEVEL", "SDL_MIXER_VERSION", "MIX_MAJOR_VERSION",
+           "MIX_MINOR_VERSION", "MIX_PATCHLEVEL", "MIX_VERSION",
+           "Mix_Linked_Version", "MIX_InitFlags", "MIX_INIT_FLAC",
+           "MIX_INIT_MOD", "MIX_INIT_MP3", "MIX_INIT_OGG",
+           "MIX_INIT_FLUIDSYNTH", "Mix_Init", "Mix_Quit", "MIX_CHANNELS",
+           "MIX_DEFAULT_FREQUENCY" , "MIX_DEFAULT_FORMAT",
+           "MIX_DEFAULT_CHANNELS", "MIX_MAX_VOLUME", "Mix_Chunk", "Mix_Fading",
+           "MIX_NO_FADING", "MIX_FADING_OUT", "MIX_FADING_IN", "Mix_MusicType",
+           "MUS_NONE", "MUS_CMD", "MUS_WAV", "MUS_MOD", "MUS_MID", "MUS_OGG",
+           "MUS_MP3", "MUS_MP3_MAD", "MUS_FLAC", "MUS_MODPLUG", "Mix_Music",
+           "Mix_OpenAudio", "Mix_AllocateChannels", "Mix_QuerySpec",
+           "Mix_LoadWAV_RW", "Mix_LoadWAV", "Mix_LoadMUS", "Mix_LoadMUS_RW",
+           "Mix_LoadMUSType_RW", "Mix_QuickLoad_WAV", "Mix_QuickLoad_RAW",
+           "Mix_FreeChunk", "Mix_FreeMusic", "Mix_GetNumChunkDecoders",
+           "Mix_GetChunkDecoder", "Mix_GetNumMusicDecoders",
+           "Mix_GetMusicDecoder", "Mix_GetMusicType", "mix_func",
+           "Mix_SetPostMix", "Mix_HookMusic", "music_finished",
+           "Mix_HookMusicFinished", "Mix_GetMusicHookData", "channel_finished",
+           "Mix_ChannelFinished", "MIX_CHANNEL_POST", "Mix_EffectFunc_t",
+           "Mix_EffectDone_t", "Mix_RegisterEffect", "Mix_UnregisterEffect",
+           "Mix_UnregisterAllEffects", "MIX_EFFECTSMAXSPEED", "Mix_SetPanning",
+           "Mix_SetPosition", "Mix_SetDistance", "Mix_SetReverseStereo",
+           "Mix_ReserveChannels", "Mix_GroupChannel", "Mix_GroupChannels",
+           "Mix_GroupAvailable", "Mix_GroupCount", "Mix_GroupOldest",
+           "Mix_GroupNewer", "Mix_PlayChannel", "Mix_PlayChannelTimed",
+           "Mix_PlayMusic", "Mix_FadeInMusic", "Mix_FadeInMusicPos",
+           "Mix_FadeInChannel", "Mix_FadeInChannelTimed", "Mix_Volume",
+           "Mix_VolumeChunk", "Mix_VolumeMusic", "Mix_HaltChannel",
+           "Mix_HaltGroup", "Mix_HaltMusic", "Mix_ExpireChannel",
+           "Mix_FadeOutChannel", "Mix_FadeOutGroup", "Mix_FadeOutMusic",
+           "Mix_FadingMusic", "Mix_FadingChannel", "Mix_Pause", "Mix_Resume",
+           "Mix_Paused", "Mix_PauseMusic", "Mix_ResumeMusic", "Mix_RewindMusic",
+           "Mix_PausedMusic", "Mix_SetMusicPosition", "Mix_Playing",
+           "Mix_PlayingMusic", "Mix_SetMusicCMD", "Mix_SetSynchroValue",
+           "Mix_GetSynchroValue", "Mix_SetSoundFonts", "Mix_GetSoundFonts",
+           "soundfont_function", "Mix_EachSoundFont", "Mix_GetChunk",
+           "Mix_CloseAudio", "Mix_SetError", "Mix_GetError"
+          ]
+
+
+dll = _DLL("SDL2_mixer", ["SDL2_mixer", "SDL2_mixer-2.0"],
+           os.getenv("PYSDL2_DLL_PATH"))
+
+
+def get_dll_file():
+    """Gets the file name of the loaded SDL2_mixer library."""
+    return dll.libfile
+
+_bind = dll.bind_function
+
+SDL_MIXER_MAJOR_VERSION = 2
+SDL_MIXER_MINOR_VERSION = 0
+SDL_MIXER_PATCHLEVEL = 0
+
+
+def SDL_MIXER_VERSION(x):
+    x.major = SDL_TTF_MAJOR_VERSION
+    x.minor = SDL_TTF_MINOR_VERSION
+    x.patch = SDL_TTF_PATCHLEVEL
+
+MIX_MAJOR_VERSION = SDL_MIXER_MAJOR_VERSION
+MIX_MINOR_VERSION = SDL_MIXER_MINOR_VERSION
+MIX_PATCHLEVEL = SDL_MIXER_PATCHLEVEL
+MIX_VERSION = SDL_MIXER_VERSION
+
+Mix_Linked_Version = _bind("Mix_Linked_Version", None, POINTER(SDL_version))
+MIX_InitFlags = c_int
+MIX_INIT_FLAC = 0x00000001
+MIX_INIT_MOD = 0x00000002
+MIX_INIT_MP3 = 0x00000004
+MIX_INIT_OGG = 0x00000008
+MIX_INIT_FLUIDSYNTH = 0x00000010
+
+Mix_Init = _bind("Mix_Init", [c_int], c_int)
+Mix_Quit = _bind("Mix_Quit")
+
+MIX_CHANNELS = 8
+MIX_DEFAULT_FREQUENCY = 22050
+if SDL_BYTEORDER == SDL_LIL_ENDIAN:
+    MIX_DEFAULT_FORMAT = AUDIO_S16LSB
+else:
+    MIX_DEFAULT_FORMAT = AUDIO_S16MSB
+MIX_DEFAULT_CHANNELS = 2
+MIX_MAX_VOLUME = 128
+
+class Mix_Chunk(Structure):
+    _fields_ = [("allocated", c_int),
+                ("abuf", POINTER(Uint8)),
+                ("alen", Uint32),
+                ("volume", Uint8)]
+
+Mix_Fading = c_int
+MIX_NO_FADING = 0
+MIX_FADING_OUT = 1
+MIX_FADING_IN = 2
+Mix_MusicType = c_int
+MUS_NONE = 0
+MUS_CMD = 1
+MUS_WAV = 2
+MUS_MOD = 3
+MUS_MID = 4
+MUS_OGG = 5
+MUS_MP3 = 6
+MUS_MP3_MAD = 7
+MUS_FLAC = 8
+MUS_MODPLUG = 9
+
+class Mix_Music(Structure):
+    pass
+
+Mix_OpenAudio = _bind("Mix_OpenAudio", [c_int, Uint16, c_int, c_int], c_int)
+Mix_AllocateChannels = _bind("Mix_AllocateChannels", [c_int], c_int)
+Mix_QuerySpec = _bind("Mix_QuerySpec", [POINTER(c_int), POINTER(Uint16), POINTER(c_int)], c_int)
+Mix_LoadWAV_RW = _bind("Mix_LoadWAV_RW", [POINTER(SDL_RWops), c_int], POINTER(Mix_Chunk))
+Mix_LoadWAV = lambda fname: Mix_LoadWAV_RW(SDL_RWFromFile(fname, b"rb"), 1)
+Mix_LoadMUS = _bind("Mix_LoadMUS", [c_char_p], POINTER(Mix_Music))
+Mix_LoadMUS_RW = _bind("Mix_LoadMUS_RW", [POINTER(SDL_RWops)], POINTER(Mix_Music))
+Mix_LoadMUSType_RW = _bind("Mix_LoadMUSType_RW", [POINTER(SDL_RWops), Mix_MusicType, c_int], POINTER(Mix_Music))
+Mix_QuickLoad_WAV = _bind("Mix_QuickLoad_WAV", [POINTER(Uint8)], POINTER(Mix_Chunk))
+Mix_QuickLoad_RAW = _bind("Mix_QuickLoad_RAW", [POINTER(Uint8), Uint32], POINTER(Mix_Chunk))
+Mix_FreeChunk = _bind("Mix_FreeChunk", [POINTER(Mix_Chunk)])
+Mix_FreeMusic = _bind("Mix_FreeMusic", [POINTER(Mix_Music)])
+Mix_GetNumChunkDecoders = _bind("Mix_GetNumChunkDecoders", None, c_int)
+Mix_GetChunkDecoder = _bind("Mix_GetChunkDecoder", [c_int], c_char_p)
+Mix_GetNumMusicDecoders = _bind("Mix_GetNumMusicDecoders", None, c_int)
+Mix_GetMusicDecoder = _bind("Mix_GetMusicDecoder", [c_int], c_char_p)
+Mix_GetMusicType = _bind("Mix_GetMusicType", [POINTER(Mix_Music)], Mix_MusicType)
+mix_func = CFUNCTYPE(None, c_void_p, POINTER(Uint8), c_int)
+Mix_SetPostMix = _bind("Mix_SetPostMix", [mix_func, c_void_p])
+Mix_HookMusic = _bind("Mix_HookMusic", [mix_func, c_void_p])
+music_finished = CFUNCTYPE(None)
+Mix_HookMusicFinished = _bind("Mix_HookMusicFinished", [music_finished])
+Mix_GetMusicHookData = _bind("Mix_GetMusicHookData", None, c_void_p)
+channel_finished = CFUNCTYPE(None, c_int)
+Mix_ChannelFinished = _bind("Mix_ChannelFinished", [channel_finished])
+MIX_CHANNEL_POST = -2
+Mix_EffectFunc_t = CFUNCTYPE(None, c_int, c_void_p, c_int, c_void_p)
+Mix_EffectDone_t = CFUNCTYPE(None, c_int, c_void_p)
+Mix_RegisterEffect = _bind("Mix_RegisterEffect", [c_int, Mix_EffectFunc_t, Mix_EffectDone_t, c_void_p], c_int)
+Mix_UnregisterEffect = _bind("Mix_UnregisterEffect", [c_int, Mix_EffectFunc_t], c_int)
+Mix_UnregisterAllEffects = _bind("Mix_UnregisterAllEffects", [c_int])
+MIX_EFFECTSMAXSPEED = "MIX_EFFECTSMAXSPEED"
+Mix_SetPanning = _bind("Mix_SetPanning", [c_int, Uint8, Uint8], c_int)
+Mix_SetPosition = _bind("Mix_SetPosition", [c_int, Sint16, Uint8], c_int)
+Mix_SetDistance = _bind("Mix_SetDistance", [c_int, Uint8])
+Mix_SetReverseStereo = _bind("Mix_SetReverseStereo", [c_int, c_int], c_int)
+Mix_ReserveChannels = _bind("Mix_ReserveChannels", [c_int], c_int)
+Mix_GroupChannel = _bind("Mix_GroupChannel", [c_int, c_int], c_int)
+Mix_GroupChannels = _bind("Mix_GroupChannels", [c_int, c_int, c_int], c_int)
+Mix_GroupAvailable = _bind("Mix_GroupAvailable", [c_int], c_int)
+Mix_GroupCount = _bind("Mix_GroupCount", [c_int], c_int)
+Mix_GroupOldest = _bind("Mix_GroupOldest", [c_int], c_int)
+Mix_GroupNewer = _bind("Mix_GroupNewer", [c_int], c_int)
+Mix_PlayChannel = lambda channel, chunk, loops: Mix_PlayChannelTimed(channel, chunk, loops, -1)
+Mix_PlayChannelTimed = _bind("Mix_PlayChannelTimed", [c_int, POINTER(Mix_Chunk), c_int, c_int], c_int)
+Mix_PlayMusic = _bind("Mix_PlayMusic", [POINTER(Mix_Music), c_int], c_int)
+Mix_FadeInMusic = _bind("Mix_FadeInMusic", [POINTER(Mix_Music), c_int, c_int], c_int)
+Mix_FadeInMusicPos = _bind("Mix_FadeInMusicPos", [POINTER(Mix_Music), c_int, c_int, c_double], c_int)
+Mix_FadeInChannel = lambda channel, chunk, loops, ms: Mix_FadeInChannelTimed(channel, chunk, loops, ms, -1)
+Mix_FadeInChannelTimed = _bind("Mix_FadeInChannelTimed", [c_int, POINTER(Mix_Chunk), c_int, c_int, c_int], c_int)
+Mix_Volume = _bind("Mix_Volume", [c_int, c_int], c_int)
+Mix_VolumeChunk = _bind("Mix_VolumeChunk", [POINTER(Mix_Chunk), c_int], c_int)
+Mix_VolumeMusic = _bind("Mix_VolumeMusic", [c_int], c_int)
+Mix_HaltChannel = _bind("Mix_HaltChannel", [c_int], c_int)
+Mix_HaltGroup = _bind("Mix_HaltGroup", [c_int], c_int)
+Mix_HaltMusic = _bind("Mix_HaltMusic", None, c_int)
+Mix_ExpireChannel = _bind("Mix_ExpireChannel", [c_int, c_int], c_int)
+Mix_FadeOutChannel = _bind("Mix_FadeOutChannel", [c_int, c_int], c_int)
+Mix_FadeOutGroup = _bind("Mix_FadeOutGroup", [c_int, c_int], c_int)
+Mix_FadeOutMusic = _bind("Mix_FadeOutMusic", [c_int], c_int)
+Mix_FadingMusic = _bind("Mix_FadingMusic", None, Mix_Fading)
+Mix_FadingChannel = _bind("Mix_FadingChannel", [c_int], Mix_Fading)
+Mix_Pause = _bind("Mix_Pause", [c_int])
+Mix_Resume = _bind("Mix_Resume", [c_int])
+Mix_Paused = _bind("Mix_Paused", [c_int], c_int)
+Mix_PauseMusic = _bind("Mix_PauseMusic")
+Mix_ResumeMusic = _bind("Mix_ResumeMusic")
+Mix_RewindMusic = _bind("Mix_RewindMusic")
+Mix_PausedMusic = _bind("Mix_PauseMusic", None, c_int)
+Mix_SetMusicPosition = _bind("Mix_SetMusicPosition", [c_double], c_int)
+Mix_Playing = _bind("Mix_Playing", [c_int], c_int)
+Mix_PlayingMusic = _bind("Mix_PlayingMusic", None, c_int)
+Mix_SetMusicCMD = _bind("Mix_SetMusicCMD", [c_char_p], c_int)
+Mix_SetSynchroValue = _bind("Mix_SetSynchroValue", [c_int], c_int)
+Mix_GetSynchroValue = _bind("Mix_GetSynchroValue", None, c_int)
+Mix_SetSoundFonts = _bind("Mix_SetSoundFonts", [c_char_p], c_int)
+Mix_GetSoundFonts = _bind("Mix_GetSoundFonts", None, c_char_p)
+soundfont_function = CFUNCTYPE(c_int, c_char_p, c_void_p)
+Mix_EachSoundFont = _bind("Mix_EachSoundFont", [soundfont_function, c_void_p], c_int)
+Mix_GetChunk = _bind("Mix_GetChunk", [c_int], POINTER(Mix_Chunk))
+Mix_CloseAudio = _bind("Mix_CloseAudio")
+Mix_SetError = SDL_SetError
+Mix_GetError = SDL_GetError

File sdl2/test/sdlmixer_test.py

+import os
+import sys
+import unittest
+import ctypes
+from .. import SDL_Init, SDL_Quit, sdlmixer, rwops, version
+
+
+class SDLMixerTest(unittest.TestCase):
+    __tags__ = ["sdl", "sdlmixer"]
+
+    def setUp(self):
+        sdlmixer.Mix_Init(0)
+
+    def tearDown(self):
+        sdlmixer.Mix_Quit()
+
+    def test_Mix_Linked_Version(self):
+        v = sdlmixer.Mix_Linked_Version()
+        self.assertIsInstance(v.contents, version.SDL_version)
+        self.assertEqual(v.contents.major, 2)
+        self.assertEqual(v.contents.minor, 0)
+        self.assertEqual(v.contents.patch, 0)
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())
 import sys
 from distutils.core import setup
 
-VERSION = "0.3.0"
+VERSION = "0.4.0"
 
 if __name__ == "__main__":
 
             ],
         }
     setup(**setupdata)
-