= Audio
* ((<Audio subsystem outline>))
* ((<Audio Format>))
* ((<SDL::Mixer>))
* ((<SDL::Mixer::Wave>))
* ((<SDL::Mixer::Music>))
* Audio methods
  * ((<SDL::Mixer.open>)) -- Initialize the mixer API.
  * ((<SDL::Mixer.spec>)) -- Get the actual audio format in use by the opened audio device
  * ((<SDL::Mixer.driver_name>)) -- Gets the audio device name
  * ((<SDL::Mixer::Wave.load>)) -- Load file for use as a sample.
  * ((<SDL::Mixer::Wave.load_from_io>)) -- Read IO object for use as a sample.
  * ((<SDL::Mixer::Wave#destroy>)) -- Frees an audio chunk.
  * ((<SDL::Mixer::Wave#destroyed?>)) -- Returns whether an audio chunk is destroyed.
  * ((<SDL::Mixer::Music.load>)) -- Load music file.
  * ((<SDL::Mixer::Music.load_from_string>)) -- Convert string into music data.
  * ((<SDL::Mixer::Music#destroy>)) -- Frees an music data.
  * ((<SDL::Mixer::Music#destroyed?>)) -- Returns whether an music data is destroyed.
  * ((<SDL::Mixer::Wave#set_volume>)) -- Set volume 
  * ((<SDL::Mixer.allocate_channels>)) -- Set the number of channels to mix
  * ((<SDL::Mixer.set_volume>)) -- Set the mix volume of a channel
  * ((<SDL::Mixer.play_channel>)) -- Play loop
  * ((<SDL::Mixer.play_channel_timed>)) -- Play loop and limit by time
  * ((<SDL::Mixer.fade_in_channel>)) -- Play loop with fade in
  * ((<SDL::Mixer.fade_in_channel_timed>)) -- Play loop with fade in and limit by time
  * ((<SDL::Mixer.pause>)) -- Pause the channel
  * ((<SDL::Mixer.resume>)) -- Resume a paused channel
  * ((<SDL::Mixer.halt>)) -- Stop playing on a channel
  * ((<SDL::Mixer.expire>)) -- Change the timed stoppage of a channel
  * ((<SDL::Mixer.fade_out>)) -- Stop playing channel after timed fade out
  * ((<SDL::Mixer.play?>)) -- Get the active playing status of a channel
  * ((<SDL::Mixer.playing_channels>)) -- Get the number of active playing channels
  * ((<SDL::Mixer.pause?>)) -- Get the pause status of a channel
  * ((<SDL::Mixer.fading>)) -- Get the fade status of a channel
  * ((<SDL::Mixer.play_music>)) -- Play music, with looping
  * ((<SDL.fade_in_music>)) -- Play music, with looping, and fade in
  * ((<SDL::Mixer.set_volume_music>)) -- Set music volume
  * ((<SDL::Mixer.pause_music>)) -- Pause music
  * ((<SDL::Mixer.resume_music>)) -- Resume paused music
  * ((<SDL::Mixer.rewind_music>)) -- Rewind music to beginning
  * ((<SDL::Mixer.halt_music>)) -- Stop music playback
  * ((<SDL::Mixer.fade_out_music>)) -- Stop music, with fade out
  * ((<SDL::Mixer.play_music?>)) -- Test whether music is playing
  * ((<SDL::Mixer.pause_music?>)) -- Test whether music is paused
  * ((<SDL::Mixer.fading_music>)) -- Get status of current music fade activity

== Audio subsystem outline
SDL has portable and low-level audio playback system. 
Because this system is too low-level to use from Ruby,
you can use only SDL_mixer functions from Ruby.
So you should install SDL_mixer before using audio playback.

Due to popular demand, here is a simple multi-channel audio mixer. It supports 8 channels of 16 bit
stereo audio, plus a single channel of music, mixed by the popular MikMod MOD, Timidity MIDI and SMPEG
MP3 libraries.

The process of mixing MIDI files to wave output is very CPU intensive, so if playing regular WAVE files
sound great, but playing MIDI files sound choppy, try using 8-bit audio, mono audio, or lower
frequencies.

To play MIDI files, you'll need to get a complete set of GUS patches from:
((<Timidity GUS Patches|URL:http://www.libsdl.org/projects/mixer/timidity/timidity.tar.gz>))
and unpack them in /usr/local/lib under UNIX, and C:\ under Win32.


== Available audio formats

Ruby/SDL supports playing music and sound samples from the following formats:
- WAVE/RIFF (.wav)
- AIFF (.aiff)
- VOC (.voc)
- MOD (.mod .xm .s3m .669 .it .med and more) using included mikmod
- MIDI (.mid) using timidity or native midi hardware
- OggVorbis (.ogg) requiring ogg/vorbis libraries on system
- MP3 (.mp3) requiring SMPEG library on system

Some reports from Windows users say that programs playing
MP3 sometimes hung up, so please don't play MP3 on Ruby/SDL.

== SDL::Mixer
Module for audio playback subsystem.

== SDL::Mixer::Wave
Class for sound samples. Ruby/SDL can play those samples with multi-channel.
Support formats are WAVE, AIFF, RIFF, OGG, VOC.

== SDL::Mixer::Music
Class for audio data.
Suppor formats are WAVE, MOD, MIDI, OGG, MP3.

== Audio methods

--- SDL::Mixer.open(frequency=Mixer::DEFAULT_FREQUENCY,format=Mixer::DEFAULT_FORMAT,cannels=Mixer::DEFAULT_CHANNELS,chunksize=4096)

    Initialize the mixer API.
    This must be called before using other functions in this library.
    SDL must be initialized with SDL::INIT_AUDIO before this call. ((|frequency|))
     would be 44100 for 44.1KHz, which is CD audio rate. Most games use 22050, 
    because 44100 requires too much CPU power on older computers.
    ((|chunksize|)) is the size of each mixed sample. The smaller this is the more your hooks will be called. If
    make this too small on a slow system, sound may skip. If made to large, sound effects will lag behind the
    action more. You want a happy medium for your target computer. You also may make this 4096, or larger, if
    you are just playing music. SDL::Mixer::CHANNELS(8)
     mixing channels will be allocated by default. 
    
    ((|format|)) are the values listed there:
    
    :SDL::Mixer::FORMAT_U8
        Unsigned 8-bit samples
    :SDL::Mixer::FORMAT_S8
        Signed 8-bit samples
    :SDL::Mixer::FORMAT_U16LSB
        Unsigned 16-bit samples, in little-endian byte order
    :SDL::Mixer::FORMAT_S16LSB
        Signed 16-bit samples, in little-endian byte order
    :SDL::Mixer::FORMAT_U16MSB
        Unsigned 16-bit samples, in big-endian byte order
    :SDL::Mixer::FORMAT_S16MSB
        Signed 16-bit samples, in big-endian byte order
    :SDL::Mixer::FORMAT_U16
        same as FORMAT_U16LSB (for backwards compatability probably)
    :SDL::Mixer::FORMAT_S16
        same as FORMAT_S16LSB (for backwards compatability probably)
    :SDL::Mixer::FORMAT_U16SYS
        Unsigned 16-bit samples, in system byte order
    :SDL::Mixer::FORMAT_S16SYS
        Signed 16-bit samples, in system byte order
    
    SDL::DEFAULT_FORMAT is SDL::Mixer::FORMAT_S16SYS.
    
    ((|channels|)) is number of sound channels in output.
    Set to 2 for stereo, 1 for mono. This has nothing to do with mixing channels.
    Mixer::DEFAULT_CHANNELS is 2.

    Raises ((<SDL::Error>)) on failure

    EXAMPLE
      # start SDL with audio support
      SDL.init(SDL::INIT_AUDIO)
      # 44.1KHz, signed 16bit, system byte order, stereo audio
      # using 1024 byte chunksize
      SDL::Mixer.open(44100, SDL::Mixer::DEFAULT_FORMAT, 2, 1024)

    * NOTES

      If you observe sound skipping and delaying, you may change some parameters to
      resolve such problems. 
      Please try to change ((|frequency|)), ((|chunksize|)) and ((|format|)) parameter.

    * See Also
      
      ((<SDL::Mixer.spec>)), ((<SDL::Mixer.allocate_channels>))

--- SDL::Mixer.spec

    Returns the actual audio format in use by the opened audio device.
    This may or may not match the parameters you passed to ((<SDL::Mixer.open>)).
    Return value is array of three elements: [frequency, format, channels].

    Raises ((<SDL::Error>)) on failure

    EXAMPLE
      frequency, format, channels = SDL::Mixer.spec
      format_str = case format
      when SDL::Mixer::AUDIO_U8 then "U8"
      when SDL::Mixer::AUDIO_S8 then "S8"
      when SDL::Mixer::AUDIO_U16LSB then "U16LSB"
      when SDL::Mixer::AUDIO_S16LSB then "S16LSB"
      when SDL::Mixer::AUDIO_U16MSB then "U16MSB"
      when SDL::Mixer::AUDIO_S16MSB then "S16MSB"
      end
      
      printf "frequency=%dHz format=%s channels=%d", frequency, format_str, channels

    * See Also
      
      ((<SDL::Mixer.open>))

--- SDL::Mixer.driver_name
--- SDL::Mixer.driverName

    Returns the opened audio device name as String.

    Raises ((<Error] if audio playback system is not @[opened|SDL::Mixer.open>)) yet.

    * See Also
      
      ((<SDL::Mixer.open>))

--- SDL::Mixer::Wave.load(filename)

    Load file for use as a sample and returns the instance of ((<SDL::Mixer::Wave>)).
    ((|filename|)) is name of wave file to use.
    This can load WAVE, AIFF, RIFF, OGG, and VOC files.

    Raises ((<SDL::Error>)) on failure
    * NOTES

      You must call ((<SDL::Mixer.open>)) before calling this method.
      It must know the output characteristics so it can convert the sample for playback, it does
      this conversion at load time. Therefore you should pay attention to memory consumption.

--- SDL::Mixer::Wave.load_from_io(io)
--- SDL::Mixer::Wave.loadFromIO(io)

    Read from Ruby's IO object (IO, StringIO or other objects with read, tell, rewind)
    and returns the instance of ((<SDL::Mixer::Wave>)).
    This can read WAVE, AIFF, RIFF, OGG, and VOC files.

    Raises ((<SDL::Error>)) on failure
    * NOTES

      You must call ((<SDL::Mixer.open>)) before calling this method.
      It must know the output characteristics so it can convert the sample for playback, it does
      this conversion at load time. Therefore you should pay attention to memory consumption.

--- SDL::Mixer::Wave#destroy

    Frees an audio chunk previously loaded.
    If this method is called, all operations are forbidden.

    * See Also
      
      ((<SDL::Mixer::Wave#destroyed?>))

--- SDL::Mixer::Wave#destroyed?

    Returns whether au audio chunk is destroyed by
    ((<SDL::Mixer::Wave#destroy>))

    * See Also
      
      ((<SDL::Mixer::Wave#destroy>))

--- SDL::Mixer::Music.load(filename)

    Load music file to use and returns a instance of ((<SDL::Mixer::Music>)).
    ((|filename|)) is a name of music file to use.
    This can load WAVE, MOD, MIDI, OGG, MP3, and any file that you use a command to
    play with.

    Raises ((<SDL::Error>)) on failure
    * NOTES

      Need SMPEG library to load MP3.

--- SDL::Mixer::Music.load_from_string(str)
--- SDL::Mixer::Music.loadFromString(str)

    Convert ((|str|)) string into music data and returns a instance of ((<SDL::Mixer::Music>)).
    This can load WAVE, MOD and OGG.

    Raises ((<SDL::Error>)) on failure
    * NOTES

      In this method, copy ((|str|)) and store it in returned object.
      Therefore this method may cause the large memory consumption.
      
      On Windows, it may be impossible to use this method.

--- SDL::Mixer::Music#destroy

    Frees an music data previously loaded.
    If this method is called, all operations are forbidden.

    * See Also
      
      ((<SDL::Mixer::Music#destroyed?>)), ((<SDL::Mixer::Wave#destroy>))

--- SDL::Mixer::Music#destroyed?

    Returns whether a music data is destroyed by
    ((<SDL::Mixer::Music#destroy>))

    * See Also
      
      ((<SDL::Mixer::Music#destroy>)), ((<SDL::Mixer::Wave#destroyed?>))

--- SDL::Mixer::Wave#set_volume(volume)
--- SDL::Mixer::Wave#setVolume(volume)

    Set wave volume to ((|volume|)). ((|volume|)) should be in 0..128.

--- SDL::Mixer.allocate_channels(num_channels)
--- SDL::Mixer.allocateChannels(num_channels)

    Set the number of channels being mixed. This can be called
    multiple times, even with sounds playing. If numchans is less
    than the current number of channels, then the higher channels
    will be stopped, freed, and therefore not mixed any longer. It's
    probably not a good idea to change the size 1000 times a second
    though.

    Returns the number of channels allocated.


    EXAMPLE
      # allocate 16 mixing channels
      SDL::Mixer.allocate_channels(16)

    * NOTES

      passing in zero ((*will*)) free all mixing
      channels, however music will still play.

--- SDL::Mixer.set_volume(channel, volume)
--- SDL::Mixer.setVolume(channel, volume)

    Set the ((|volume|)) for any allocated ((|channel|)). 
    If ((|channel|)) is -1 then
    all channels at are set at once. The volume is applied during
    the final mix, along with the sample volume. So setting this
    volume to 64 will halve the output of all samples played on the
    specified channel. All channels default to a volume of 128,
    which is the max. Newly allocated channels will have the max
    volume set, so setting all channels volumes does not affect
    subsequent channel allocations.

    Returns current volume of the channel. If channel is -1, the
    average volume is returned.

    * See Also
      
      ((<SDL::Mixer::Wave#set_volume>)), ((<SDL::Mixer.set_volume_music>))

--- SDL::Mixer.play_channel(channel, wave, loops)
--- SDL::Mixer.playChannel(channel, wave, loops)

    Play ((|wave|))(instance of ((<SDL::Mixer::Wave>))  on ((|channel|)), or 
    if ((|channel|)) is -1, pick the first free
    unreserved channel. The sample will play 
    for ((|loops|))+1 number of
    times, unless stopped by halt, or fade out, or setting a new
    expiration time of less time than it would have originally taken
    to play the loops, or closing the mixer.
    if ((|loops|)) is -1, loops infinitely.

    the channel the sample is played on.


    EXAMPLE
      # play sample on first free unreserved channel
      # play it exactly once through
      SDL::Mixer.play_channel(-1, sample, 0)

    * See Also
      
      ((<SDL::Mixer.play_channel_timed>)), ((<SDL::Mixer.fade_in_channel>)), ((<SDL::Mixer.halt>)), ((<SDL::Mixer.expire>))

--- SDL::Mixer.play_channel_timed(channel, wave, loops, ticks)
--- SDL::Mixer.playChannelTimed(channel, wave, loops, ticks)

    If the ((|wave|)) is long enough and has enough ((|loops|)) then the
    sample will stop after ((|ticks|)) milliseconds. Otherwise this
    function is the same as ((<SDL::Mixer.play_channel>)).


    EXAMPLE
      # play sample on first free unreserved channel
      # play it for half a second
      SDL::Mixer.play_channel(-1, sample, -1, 500)

    * See Also
      
      ((<SDL::Mixer.play_channel>)), ((<SDL::Mixer.fade_in_channel_timed>)), ((<SDL::Mixer.fade_out>)), ((<SDL::Mixer.halt>)), ((<SDL::Mixer.expire>))

--- SDL::Mixer.fade_in_channel(channel, wave, loops, ms)
--- SDL::Mixer.fadeInChannel(channel, wave, loops, ms)

    Play ((|wave|)) on ((|channel|)) with fade in.
    The channel volume starts at 0 and fades up to full volume over
    ((|ms|)) milliseconds of time. The sample may end before the fade-in
    is complete if it is too short or doesn't have enough loops.
    
    Otherwise this function is the same as ((<SDL::Mixer.play_channel>)).


    EXAMPLE
      # play sample on first free unreserved channel
      # play it exactly 3 times through
      # fade in over one second
      SDL::Mixer.fade_in_channel(-1, sample, 2, 1000)

    * See Also
      
      ((<SDL::Mixer.play_channel>)), ((<SDL::Mixer.fade_in_channel_timed>)), ((<SDL::Mixer.fading>)), ((<SDL::Mixer.fade_out>)), ((<SDL::Mixer.halt>)), ((<SDL::Mixer.expire>))

--- SDL::Mixer.fade_in_channel_timed(channel, wave, loops, ms, ticks)
--- SDL::Mixer.fadeInChannelTimed(channel, wave, loops, ms, ticks)

    If the sample is long enough and has enough loops then the
    sample will stop after ticks milliseconds. Otherwise this
    method is the same as ((<SDL::Mixer.play_channel_timed>)).

    * See Also
      
      ((<SDL::Mixer.play_channel_timed>)), ((<SDL::Mixer.fade_in_channel>)), ((<SDL::Mixer.fading>)), ((<SDL::Mixer.fade_out>)), ((<SDL::Mixer.halt>)), ((<SDL::Mixer.expire>))

--- SDL::Mixer.pause(channel)

    Pause ((|channel|)), or all playing channels if -1 is passed in. You
    may still ((|halt|Mixer.halt|)) a paused channel.


    EXAMPLE
      # pause all sample playback
      SDL::Mixer.pause(-1)

    * See Also
      
      ((<SDL::Mixer.resume>)), ((<SDL::Mixer.pause?>)), ((<SDL::Mixer.halt>))

--- SDL::Mixer.resume(channel)

    Unpause ((|channel|)), or all playing and paused channels if -1 is
    passed in.

    * See Also
      
      ((<SDL::Mixer.pause>)), ((<SDL::Mixer.pause?>))

--- SDL::Mixer.halt(channel)

    Halt channel playback, or all channels if -1 is passed in.
    Any callback set by Mix_ChannelFinished will be called.

    * See Also
      
      ((<SDL::Mixer.expire>)), ((<SDL::Mixer.fade_out>))

--- SDL::Mixer.expire(channel, ticks)

    Halt ((|channel|)) playback, or all channels 
    if -1 is passed in, after ((|ticks|)) milliseconds.

    Returns the number of channels set to expire. Whether or not they
    are active.


    EXAMPLE
      # halt playback on all channels in 2 seconds
      SDL::Mixer.expire(-1, 2000)

    * See Also
      
      ((<SDL::Mixer.halt>)), ((<SDL::Mixer.fade_out>))

--- SDL::Mixer.fade_out(channel, ms)
--- SDL::Mixer.fadeOut(channel, ms)

    Gradually fade out which ((|channel|))
     over ((|ms|)) milliseconds starting
    from now. The channel will be halted after the fade out is
    completed. Only channels that are playing are set to fade out,
    including paused channels. 

    Returns the number of channels set to fade out.


    EXAMPLE
      # fade out all channels to finish 3 seconds from now
      printf "starting fade out of %d channels", SDL::Mixer.fade_out(-1, 3000)

    * See Also
      
      ((<SDL::Mixer.fade_in_channel>)), ((<SDL::Mixer.fade_in_channel_timed>)), ((<SDL::Mixer.fading>))

--- SDL::Mixer.play?(channel)

    Returns true if ((|channel|)) is playing, otherwise
    returns false.

    * See Also
      
      ((<SDL::Mixer.pause?>)), ((<SDL::Mixer.fading>)), ((<SDL::Mixer.play_channel>)), ((<SDL::Mixer.pause>))

--- SDL::Mixer.playing_channels
--- SDL::Mixer.playingChannels

    Returns the number of playing.

    * See Also
      
      ((<SDL::Mixer.pause?>)), ((<SDL::Mixer.fading>)), ((<SDL::Mixer.play_channel>)), ((<SDL::Mixer.pause>))

--- SDL::Mixer.pause?(channel)

    Returns true if ((|channel|)) is paused, otherwise 
    returns false.

    * See Also
      
      ((<SDL::Mixer.play?>)), ((<SDL::Mixer.pause>)), ((<SDL::Mixer.resume>))

--- SDL::Mixer.fading(which)

    Tells you if which ((|channel|)) is fading in, out, or not. Does not
    tell you if the channel is playing anything, or paused, so you'd
    need to test that separately.
    Returns the fading status:
    * SDL::Mixer::FADING_OUT
    * SDL::Mixer::FADING_IN
    * SDL::Mixer::NO_FADING

    * See Also
      
      ((<SDL::Mixer.play?>)), ((<SDL::Mixer.pause?>)), ((<SDL::Mixer.fade_in_channel>)), ((<SDL::Mixer.fade_in_channel_timed>)), ((<SDL::Mixer.fade_out>))

--- SDL::Mixer.play_music(music, loops)
--- SDL::Mixer.playMusic(music, loops)

    Play the loaded ((|music|))
    ((|loops|)) times through from start to finish.
    The previous music will be halted, or if fading out it waits
    (blocking) for that to finish.

    Raises ((<SDL::Error>)) on failure
    * See Also
      
      ((<SDL::Mixer.fade_in_music>))

--- SDL.fade_in_music(music, loops, ms)
--- SDL.fadeInMusic(music, loops, ms)

    Fade in over ((|ms|)) milliseconds of time, 
    the loaded ((|music|)), playing
    it ((|loops|)) times through from start to finish.
    The fade in effect only applies to the first loop.
    Any previous music will be halted, or if it is fading out it
    will wait (blocking) for the fade to complete.

    Raises ((<SDL::Error>)) on failure
    * See Also
      
      ((<SDL::Mixer.play_music>))

--- SDL::Mixer.set_volume_music(volume)
--- SDL::Mixer.setVolumeMusic(volume)

    Set the volume to ((|volume|)), if it is 0 or greater.
    Setting the volume during a fade will
    not work, the faders use this function to perform their effect!

    * See Also
      
      ((<SDL::Mixer.fade_in_music>)), ((<SDL::Mixer.fade_out_music>))

--- SDL::Mixer.pause_music
--- SDL::Mixer.pauseMusic

    Pause the music playback. You may ((<halt|SDL::Mixer.halt_music>))
    paused music.

    * See Also
      
      ((<SDL::Mixer.resume_music>)), ((<SDL::Mixer.pause_music?>)), ((<SDL::Mixer.halt_music>))

--- SDL::Mixer.resume_music
--- SDL::Mixer.resumeMusic

    Unpause the music. This is safe to use on halted, paused, and
    already playing music.

    * See Also
      
      ((<SDL::Mixer.pause_music>)), ((<SDL::Mixer.pause_music?>))

--- SDL::Mixer.rewind_music
--- SDL::Mixer.rewindMusic

    Rewind the music to the start. This is safe to use on halted,
    paused, and already playing music. It is not useful to rewind
    the music immediately after starting playback, because it starts
    at the beginning by default.
    
    This function only works for these streams: MOD, OGG, MP3,
    Native MIDI.

--- SDL::Mixer.halt_music
--- SDL::Mixer.haltMusic

    Halt playback of music. This interrupts music fader effects. 

    * See Also
      
      ((<SDL::Mixer.fade_out_music>))

--- SDL::Mixer.fade_out_music(ms)
--- SDL::Mixer.fadeOutMusic(ms)

    Gradually fade out the music over ((|ms|)) milliseconds starting from
    now. The music will be halted after the fade out is completed.
    Only when music is playing and not fading already are set to
    fade out, including paused channels.

--- SDL::Mixer.play_music?
--- SDL::Mixer.playMusic?

    Returns true if music is actively playing, otherwise
    returns false.

    * See Also
      
      ((<SDL::Mixer.pause_music?>)), ((<SDL::Mixer.fading_music>)), ((<SDL::Mixer.play_music>))

--- SDL::Mixer.pause_music?
--- SDL::Mixer.pauseMusic?

    Returns true if music is paused, otherwise returns false.

    * See Also
      
      ((<SDL::Mixer.play_music?>)), ((<SDL::Mixer.pause_music>)), ((<SDL::Mixer.resume_music>))

--- SDL::Mixer.fading_music
--- SDL::Mixer.fadingMusic

    Tells you if music is fading in, out, or not at all. Does not
    tell you if the channel is playing anything, or paused, so you'd
    need to test that separately.
    
    return value is one of follwoing:
    * SDL::Mixer::FADING_OUT
    * SDL::Mixer::FADING_IN
    * SDL::Mixer::NO_FADING

    * See Also
      
      ((<SDL::Mixer.fading>)), ((<SDL::Mixer.pause_music?>)), ((<SDL::Mixer.play_music?>)), ((<SDL::Mixer.fade_out_music>))

