
                           AllegroMP3 v2.0.4
                          ===================

               AllegroMP3 (c) 2001 - 2003 Javier Gonzalez

MP3 Decoder part of mpglib that is part of mpg123 available at www.mpg123.com
              see even more credits at decoder/AUTHORS file


#include <std_disclaimer.h>


   "I do not accept responsibility for any effects, adverse or otherwise, 
    that this code may have on you, your computer, your sanity, your dog, 
    and anything else that you can think of. Use it at your own risk."



See README.txt for a general introduction, copyright details, and 
information about how to install AllegroMP3.



Using AllegroMP3
----------------

   To be able to use AllegroMP3 with your program, you just need (once
   compiled the library) to link the generated lib with your program
   (remember that since this lib relies on allegro, you need to add
   almp3 *before* alleg) and include the header "almp3.h", available in
   the lib and include directories respectively. 


Reference
---------

   Note parameters are marked between ' ' markers.


   Differences between ALMP3_MP3 and ALMP3_MP3STREAM:
     With ALMP3_MP3 you will be able to know the mp3 length, seek in the
     file (directly), and multiple other things, BUT you'll need to load
     the whole file in memory and keep it there until you stop playing it.
     With ALMP3_MP3STREAMs you won't be able to do that (well, you will be
     able to do seeking but in a special way), BUT you'll be able to load
     just small chunks of data, very alike Allegro's AUDIOSTREAMs do, saving
     memory and loading time.


   ALMP3_MP3 *almp3_create_mp3(void *data, int data_len);
      Creates an ALMP3_MP3 which you'll have to pass to all the other
      functions, where 'data' will be a pointer to the buffer containing
      the mp3 data and 'data_len' the size of this buffer. Note you aren't
      supposed to free this buffer until you have destroyed the ALMP3_MP3.

     return values:
      NULL if there ocurred an error (mostly an invalid mp3 data was passed).
      Other value ( != NULL ) otherwise.


   void almp3_destroy_mp3(ALMP3_MP3 *mp3);
      Destroys the ALMP3_MP3 automatically stopping it. Note this function
      check if the 'mp3' pointer is pointing to NULL, so for example this:
         ALMP3_MP3 *mp3 = NULL;
         destroy_mp3(mp3);
      won't crash the program.


   int almp3_play_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan);
      Plays the 'mp3' ALMP3_MP3 with the given volume 'vol' (from 0 to 255)
      and panning 'pan' (from 0 to 255, where 0 is full left and 255 is
      full right). 'buffer_len' is the desired size in bytes of the
      buffer where the decoded data will be stored. The bigger, the less
      you'll have to poll the MP3, but the more time you will have to wait
      in order to hear the song start playing. Note that due to some
      mp3 format limitations, the internal (and real) buffer will be
      an aproximation to the 'buffer_len' given. A 'buffer_len' size between
      16384 and 32768 bytes (16kb and 32kb) will do in most cases.

     return values:
      ALMP3_OK if no problems.
      ALMP3_PLAY_BUFFERTOOSMALL if the given 'buffer_len' was not big enough.

     special note:
      This function also works like a "resume" function, since it
      won't rewind the ALMP3_MP3 automatically. Note that once the ALMP3_MP3
      has reached the end when playing, it will rewind though, stoping the
      ALMP3_MP3 if the loop flag was set at FALSE (see almp3_play_ex_mp3())
      or continuing playing it if it was set at TRUE. Also note that this
      automatically stops decoding.


   int almp3_play_ex_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan, int speed, int loop);
      See almp3_play_mp3(). The only new is the 'speed' that will play the
      ALMP3_MP3 at a given speed (being 1000 = normal speed, 2000 = twice
      fast, 500 = half speed and so on) and a loop flag that can be set to
      not stop the ALMP3_MP3 when it has reached the end, but continue it
      playing from the start.

     return values:
      See almp3_play_mp3().

     special note:
      See almp3_play_mp3(). Note that you can change speed, pan, volume, etc
      values to the ALMP3_MP3 many times, but you will need to stop it first.


   void almp3_stop_mp3(ALMP3_MP3 *mp3);
      Stops the ALMP3_MP3 if it was playing.

     special note:
      This function also works like a "pause" function, since it won't
      rewind it automatically.


   void almp3_adjust_mp3(ALMP3_MP3 *mp3, int vol, int pan, int speed, int loop);
      Adjust the ALMP3_MP3 parameters when it is already playing.


   void almp3_rewind_mp3(ALMP3_MP3 *mp3);
      Rewinds the ALMP3_MP3 to its start.

     special note:
      This function won't automatically stop the ALMP3_MP3 if it was
      already playing.


   void almp3_seek_abs_frames_mp3(ALMP3_MP3 *mp3, int frame);
   void almp3_seek_abs_msecs_mp3(ALMP3_MP3 *mp3, int msecs);
   void almp3_seek_abs_secs_mp3(ALMP3_MP3 *mp3, int secs);
   void almp3_seek_abs_bytes_mp3(ALMP3_MP3 *mp3, int bytes);
      Does an absolute seek (from start of the mp3), given the new
      position either in frames, msecs, secs or bytes.

     special note:
      This function won't stop the ALMP3_MP3 if it was already playing.
      

   void almp3_seek_rel_frames_mp3(ALMP3_MP3 *mp3, int frame);
   void almp3_seek_rel_msecs_mp3(ALMP3_MP3 *mp3, int msec);
   void almp3_seek_rel_secs_mp3(ALMP3_MP3 *mp3, int sec);
   void almp3_seek_rel_bytes_mp3(ALMP3_MP3 *mp3, int bytes);
      Does a relative seek (from current position), given the new
      position either in frames, msecs, secs or bytes.

     special note:
      This function won't stop the ALMP3_MP3 if it was already playing.


   int almp3_poll_mp3(ALMP3_MP3 *mp3);
      This functions needs to be called in order to keep the ALMP3_MP3
      playing properly, since the mp3s need to be decoded at real time
      (either that, or to a huge memory buffer).

     return values:
      ALMP3_OK if there were no error.
      ALMP3_POLL_PLAYJUSTFINISHED (only once) when the file has JUST
        finished playing.
      ALMP3_POLL_NOTPLAYING if the file is not playing.
      ALMP3_POLL_FRAMECORRUPT if one of the frames is corrupt.
      ALMP3_POLL_INTERNALERROR if an internal error happened.

    special note:
      If you don't want (or can't) poll all the time, you can use
      automatic polling (see below), but I don't recommend this since
      this can be very unstable, specially under DOS (altought I've
      never experienced such problems myself, but better warn ;).


   void almp3_start_autopoll_mp3(ALMP3_MP3 *mp3, int speed);
      Creates an allegro interrupt that will call poll for this ALMP3_MP3
      each 'speed' msecs. This frees you from calling polling yourself,
      but I recommend this only in the case you can't call poll (because
      of the nature of your program) yourself at regular intervals.


   void almp3_stop_autopoll_mp3(ALMP3_MP3 *mp3);
      Destroys the allegro interrupt for that ALMP3_MP3.


   int almp3_get_pos_frames_mp3(ALMP3_MP3 *mp3);
   int almp3_get_pos_msecs_mp3(ALMP3_MP3 *mp3);
   int almp3_get_pos_secs_mp3(ALMP3_MP3 *mp3);
   int almp3_get_pos_bytes_mp3(ALMP3_MP3 *mp3);
      Returns the ALMP3_MP3 current position either in frames, msecs, secs
      or bytes.


   int almp3_get_length_frames_mp3(ALMP3_MP3 *mp3);
   int almp3_get_length_secs_mp3(ALMP3_MP3 *mp3);
   int almp3_get_length_msecs_mp3(ALMP3_MP3 *mp3);
   int almp3_get_length_bytes_mp3(ALMP3_MP3 *mp3);
      Returns the ALMP3_MP3 length either in frames, msecs, secs or bytes.


   int get_msecs_per_frame_mp3(ALMP3_MP3 *mp3);
      Returns the msecs per frame for the given ALMP3_MP3.


   int almp3_get_bitrate_mp3(ALMP3_MP3 *mp3);
      Returns the ALMP3_MP3 bitrate in bits per second, NOT in kbits. That's
      for example 128000, 64000, 96000, etc.


   int almp3_get_layer_mp3(ALMP3_MP3 *mp3);
      Returns 3 on MPEG-audio layer III (this is, mp3) or 2 on MPEG-audio
      layer II (mp2).


   int almp3_get_wave_bits_mp3(ALMP3_MP3 *mp3);
   int almp3_get_wave_is_stereo_mp3(ALMP3_MP3 *mp3);
   int almp3_get_wave_freq_mp3(ALMP3_MP3 *mp3);
      Returns info about the wave.


   SAMPLE *almp3_create_sample_from_mp3(ALMP3_MP3 *mp3);
      Decodes the given ALMP3_MP3 into an Allegro SAMPLE structure. Please
      note for big mp3s this function could generate a HUGE SAMPLE, so it
      is only recommended for very small mp3s like sound effects.

     return values:
      NULL on error.
      otherwise not NULL.


   void *almp3_get_output_wave_mp3(ALMP3_MP3 *mp3, int *buffer_size);
      Returns a pointer to the piece of wave decoded after each poll, and
      the size of this buffer as well in 'buffer_size' (in bytes). Note this
      function will NOT automatically convert from unsinged to signed 16 bit
      data using the Allegro format instead of the standard format, so this
      data cannot be saved directly into a WAV for example without
      modifications. Also note in order for this function to work, the
      ALMP3_MP3 needs to BE playing.

     return values:
      NULL if there is no wave being decoded.
      Else the buffer with the wave data.


   int almp3_is_playing_mp3(ALMP3_MP3 *mp3);
      Returns TRUE if the ALMP3_MP3 is currently being played or FALSE
      if it is not.


   int almp3_is_looping_mp3(ALMP3_MP3 *mp3);
   void almp3_set_loop_mp3(ALMP3_MP3 *mp3, int loop);
      Self explanatory. Note these functions only work when the ALMP3_MP3
      is playing.


   AUDIOSTREAM *almp3_get_audiostream_mp3(ALMP3_MP3 *mp3);
      Returns the allegro AUDIOSTREAM currently being used by the ALMP3_MP3.



   ALMP3_MP3STREAM *almp3_create_mp3stream(void *first_data_buffer, int data_buffer_len, int last_block);
      See almp3_create_mp3(). The only difference is that 'first_data_buffer'
      contains the very first buffer of len 'data_buffer_len' that you will
      have to give to the MP3STREAM periodically. If after this data, there
      won't be more (this is, this was the last buffer to be processed),
      pass TRUE to 'last_block'.


   void almp3_destroy_mp3stream(ALMP3_MP3STREAM *mp3);
      See almp3_destroy_mp3().


   int almp3_play_mp3stream(ALMP3_MP3STREAM *mp3, int buffer_len, int vol, int pan);
      See almp3_play_ex_mp3stream().


   int almp3_play_ex_mp3stream(ALMP3_MP3STREAM *mp3, int buffer_len, int vol, int pan, int speed);
      See almp3_play_ex_mp3(). The only difference is that here is no 'loop'
      parameter. To loop an ALMP3_MP3STREAM just destroy the ALMP3_MP3STREAM
      and recreate it (or pass data continuosly).


   void almp3_stop_mp3stream(ALMP3_MP3STREAM *mp3);
      See almp3_stop_mp3().


   void almp3_adjust_mp3stream(ALMP3_MP3STREAM *mp3, int vol, int pan, int speed);
      Adjust the ALMP3_MP3STREAM parameters when it is already playing.
      Note it doesn't include the parameter loop because ALMP3_MP3STREAMs are
      always looping (or better said, they don't have two points to loop
      from/to).


   int almp3_poll_mp3stream(ALMP3_MP3STREAM *mp3);
      See almp3_poll_mp3().

     return values:
      ALMP3_OK if there were no error.
      ALMP3_POLL_PLAYJUSTFINISHED (only once) when the file has JUST
        finished playing.
      ALMP3_POLL_NOTPLAYING if the file is not playing.
      ALMP3_POLL_FRAMECORRUPT if one of the frames is corrupt.
      ALMP3_POLL_BUFFERUNDERUN if the buffer was exhausted.
      ALMP3_POLL_INTERNALERROR if an internal error happened.


   void almp3_start_autopoll_mp3stream(ALMP3_MP3STREAM *mp3, int speed);
      See almp3_start_autopoll_mp3(). Note I discourage the use of this
      function with ALMP3_MP3STREAMs since in anyway you'll have to use
      almp3_get_mp3stream_buffer() to send data periodically.


   void almp3_stop_autopoll_mp3stream(ALMP3_MP3STREAM *mp3);
      See almp3_stop_autopoll_mp3().


   void *almp3_get_mp3stream_buffer(ALMP3_MP3STREAM *mp3);
      If the return value is not NULL, it will return a buffer that you'll
      have to fill with 'buffer_data_len' (from create_mp3stream) bytes MAX
      of new data. You will need to use free_mp3stream_buffer() when you
      are finished with it.

     return values:
      NULL if it doesn't need any data yet.
      Else the buffer to be filled.


   void almp3_free_mp3stream_buffer(ALMP3_MP3STREAM *mp3, int bytes_used);
      Use whenever you are finished with the buffer returned by
      almp3_get_mp3stream_buffer(). If 'bytes_used' is -1 it will use
      the full buffer and that will mean this is not the last block
      of data, else if 'bytes_used' is a number, it will indicate
      that this is the last buffer and the number of bytes to use from that
      last block. Once this buffer has been played and processed,
      almp3_poll_mp3_stream() will return ALMP3_POLL_JUSTFINISHED.


   int almp3_get_length_frames_mp3stream(ALMP3_MP3STREAM *mp3, int total_size);
   int almp3_get_length_secs_mp3stream(ALMP3_MP3STREAM *mp3, int total_size);
   int almp3_get_length_msecs_mp3stream(ALMP3_MP3STREAM *mp3, int total_size);
   int almp3_get_length_bytes_mp3stream(ALMP3_MP3STREAM *mp3, int total_size);
      Returns the ALMP3_MP3STREAM length either in frames, msecs or secs.
      You will have to pass in 'total_size' the total size (in
      bytes) of the mp3.

   int almp3_get_pos_frames_mp3stream(ALMP3_MP3STREAM *mp3);
   int almp3_get_pos_msecs_mp3stream(ALMP3_MP3STREAM *mp3);
   int almp3_get_pos_secs_mp3stream(ALMP3_MP3STREAM *mp3);
   int almp3_get_pos_bytes_mp3stream(ALMP3_MP3STREAM *mp3);
   int almp3_get_msecs_per_frame_mp3stream(ALMP3_MP3STREAM *mp3);
   int almp3_get_bitrate_mp3stream(ALMP3_MP3STREAM *mp3);
   int almp3_get_layer_mp3stream(ALMP3_MP3STREAM *mp3);
      See their ALMP3_MP3 equals.

   int almp3_get_wave_bits_mp3stream(ALMP3_MP3STREAM *mp3);
   int almp3_get_wave_is_stereo_mp3stream(ALMP3_MP3STREAM *mp3);
   int almp3_get_wave_freq_mp3stream(ALMP3_MP3STREAM *mp3);
      Returns info about the wave.


   void *almp3_get_output_wave_mp3stream(ALMP3_MP3STREAM *mp3, int *buffer_size);
      Returns a pointer to the piece of wave decoded after each poll, and
      the size of this buffer as well in 'buffer_size' (in bytes). Note this
      function will NOT automatically convert from unsinged to signed 16 bit
      data using the Allegro format instead of the standard format, so this
      data cannot be saved directly into a WAV for example without
      modifications. Also note in order for this function to work, the
      ALMP3_MP3STREAM needs to BE playing.

     return values:
      NULL if there is no wave being decoded.
      Else the buffer with the wave data.


   int almp3_is_playing_mp3stream(ALMP3_MP3STREAM *mp3);
      Returns TRUE if the ALMP3_MP3STREAM is currently being played or FALSE
      if it is not.


   AUDIOSTREAM *almp3_get_audiostream_mp3stream(ALMP3_MP3STREAM *mp3);
      Returns the allegro AUDIOSTREAM currently being used by the
      ALMP3_MP3STREAM.
      Note that when the ALMP3_MP3STREAM isn't being played most probably
      it will return NULL.


   int almp3_seek_abs_frames_mp3stream(ALMP3_MP3STREAM *mp3, int frame, int total_size);
   int almp3_seek_abs_msecs_mp3stream(ALMP3_MP3STREAM *mp3, int msecs, int total_size);
   int almp3_seek_abs_secs_mp3stream(ALMP3_MP3STREAM *mp3, int secs, int total_size);
   int almp3_seek_abs_bytes_mp3stream(ALMP3_MP3STREAM *mp3, int bytes, int total_size);
      Returns the position in bytes where you should position your stream
      (file, memory buffer, socket) to continue playing at that mp3 position
      using an absolute (from start position) seeking.
      You need to pass the total size (in bytes) of the stream.

     special note:
      This function doesn't perform any operation or change but informs you
      where to read your next chunk of data.
      

   int almp3_seek_rel_frames_mp3stream(ALMP3_MP3STREAM *mp3, int frame, int total_size);
   int almp3_seek_rel_msecs_mp3stream(ALMP3_MP3STREAM *mp3, int msec, int total_size);
   int almp3_seek_rel_secs_mp3stream(ALMP3_MP3STREAM *mp3, int sec, int total_size);
   int almp3_seek_rel_bytes_mp3stream(ALMP3_MP3STREAM *mp3, int bytes, int total_size);
      Returns the position in bytes where you should position your stream
      (file, memory buffer, socket) to continue playing at that mp3 position
      (using a relative, from current position, seeking).
      You need to pass the total size (in bytes) of the stream.

     special note:
      This function doesn't perform any operation or change but informs you
      where to read your next chunk of data.



   I hope these docs are useful to you.

