/************************************/
/* MP3 driver for SFA               */
/* Copyright (c) Florian Xaver 2000 */
/* Copyright (c) Owen Rudge 2001    */
/*                                  */
/* Uses code from GEMP3. Please see */
/* http://www.owenrudge.co.uk/GEM/  */
/* for more information.            */
/************************************/

/* OCR (16/9/2001): Added MP2 file extension support and updated new_soundformat_item
                    call. Also added ID3 support. */

/* OCR (4/10/2001): Added about box */

#include<seal.h>
#include<sound.h>
#include<dialogs.h>
#include<libamp.h>


#define TXT_STEREO      INI_TEXT("Stereo")
#define TXT_MONO        INI_TEXT("Mono")
#define TXT_MP3INFO     INI_TEXT("MPEG %d Layer %d, %s, %dHz, %dkbps, %s")
#define TXT_SURROUND    INI_TEXT("Surround")
#define TXT_NOSURROUND  INI_TEXT("No Surround")

#define TXT_ID3INFO     INI_TEXT("MPEG %d Layer %d, %s, %dHz, %dkbps, %s\n\nTitle: %s\nAuthor: %s\nAlbum: %s\nComment: %s\nGenre: %s")
#define TXT_UNSPECIFIED INI_TEXT("Unspecified")

static
const char *GenreStr[]={
"Blues","Classic Rock","Country","Dance","Disco","Funk","Grunge","Hip-Hop", // 0-7
"Jazz","Metal","New Age","Oldies","Other","Pop","R&B","Rap","Reggae","Rock",// 8-17
"Techno","Industrial","Alternative","Ska","Death Metal","Pranks",           // 18-23
"Soundtrack","Euro-Techno","Ambient","Trip-Hop","Vocal","Jazz+Funk",        // 24-29
"Fusion","Trance","Classical","Instrumental","Acid","House","Game",         // 30-36
"Sound Clip","Gospel","Noise","Alt. Rock","Bass","Soul","Punk","Space",     // 37-44
"Meditative","Instrumental Pop","Instrumental Rock","Ethnic","Gothic",      // 45-49
"Darkwave","Techno-Industrial","Electronic","Pop-Folk","Eurodance","Dream", // 50-55
"Southern Rock","Comedy","Cult","Gangsta Rap","Top 40","Christian Rap",     // 56-61
"Pop/Funk","Jungle","Native American","Cabaret","New Wave","Psychedelic",   // 62-67
"Rave","Showtunes","Trailer","Lo-Fi","Tribal","Acid Punk","Acid Jazz",      // 63-74
"Polka","Retro","Musical","Rock & Roll","Hard Rock","Folk","Folk/Rock",     // 75-81
"National Folk","Swing","Fast-Fusion","Bebob","Latin","Revival","Celtic",   // 82-88
"Bluegrass","Avantgarde","Gothic Rock","Progressive Rock",                  // 89-92
"Psychedelic Rock","Symphonic Rock","Slow Rock","Big Band","Chorus",        // 93-97
"Easy Listening","Acoustic","Humour","Speech","Chanson","Opera",            // 98-103
"Chamber Music","Sonata","Symphony","Booty Bass","Primus","Porn Groove",    // 104-109
"Satire","Slow Jam","Club","Tango","Samba","Folklore","Ballad",             // 110-116
"Power Ballad","Rhythmic Soul","Freestyle","Duet","Punk Rock","Drum Solo",  // 117-122
"Acapella","Euro-House","Dance Hall","Goa","Drum & Bass","Club-House",      // 123-128
"Hardcore","Terror","Indie","BritPop","Negerpunk","Polsk punk","Beat",      // 129-135
"Christian Gangsta Rap","Heavy Metal","Black Metal","Crossover",            // 136-139
"Contemporary Christian","Christian Rock"                                   // 140-141
};

const int maxKnownGenre=sizeof(GenreStr)/sizeof(char *);

   signed int mp3_pause = false;
   signed int PausedPos = 0;
   l_text filename;





   //play file funktion
   l_int mp3_init_file (p_soundformat_item o, l_text file)
         {


         if (filename)
          {
          _free(filename);
          }

         filename = _strdup(file);

//         seal_error(ERR_INFO, "filename: %s, file: %s", filename, file);

         if (install_amp() == FALSE)
               {
                     seal_error(ERR_INFO, INI_TEXT("Cannot init mp3 library!"));
                     return 0;
               };



         return 1;
         };

   //play file funktion
   l_int mp3_play_file (p_soundformat_item o)
         {
            if (load_amp(filename,FALSE) == FALSE)
                  {
                  seal_error(ERR_INFO, INI_TEXT("Cannot load file"));
                  return 0;
                  };

//         seal_error(ERR_INFO, "play %s", filename);
         return 1;
         };


   //poll file
   l_int mp3_poll_file(p_soundformat_item o)
         {
//         seal_error(ERR_INFO, "poll");
         if ( run_amp() == -1) return 0;
         return 1;
         };

   //stop file
   l_int mp3_stop_file(p_soundformat_item o)
         {
//         seal_error(ERR_INFO, "Stop");
         unload_amp();
         return 1;
         };

   //pause file
   l_int mp3_pause_file(p_soundformat_item o)
         {

   switch (mp3_pause)
   {

   case false:                            // pause
     {
     mp3_pause = true;
     stop_amp();
     PausedPos=amp_frame;
     break;
     }
   case true:                             //plays after pause
     {
     seek_amp_abs(PausedPos);
     mp3_pause = false;
     break;
     }

     }


         return 1;
         };

   //forward
   l_int mp3_forward_file(p_soundformat_item o, l_int relpos)
         {
         seek_amp_rel(relpos*amp_samprat/amp_pollsize);
         return 1;
         };

   //rewind
   l_int mp3_rewind_file(p_soundformat_item o, l_int relpos)
         {
         seek_amp_rel(-relpos*amp_samprat/amp_pollsize);
         return 1;
         };

   //set pos
   l_int mp3_set_pos(p_soundformat_item o, l_int pos)
         {
         seek_amp_abs(pos);
         return 1;
         };

   //get current pos
   l_int mp3_get_pos(p_soundformat_item o)
         {
         return amp_frame;

         };

   //lenght of file
   l_int mp3_get_len_file(p_soundformat_item o)
         {

         return 0;
         };

   // get current time
   l_int mp3_get_time(p_soundformat_item o)
         {
         return amp_time;
         };

   l_int mp3_is_stereo(p_soundformat_item o)
         {

         return amp_stereo;
         };

l_text mp3_get_additional_info(p_soundformat_item o)
{
   char title[31], author[31], album[35];
   unsigned char comment[31];
   char *genre = 0;
   char *buf;

   FILE *f;
   char buffer[128];
   long ret;

   f = fopen(filename,"rb");

   if (!f)
   {
      title[0]=0;
      author[0]=0;
      album[0]=0;
      comment[0]=0;
      genre=0;

      return set_format_text(NULL, TXT_MP3INFO, amp_mpg_ver, amp_layer, amp_stereo == 1 ? TXT_STEREO : TXT_MONO, amp_samprat, amp_bitrate, amp_reverse_phase == 1 ? TXT_SURROUND : TXT_NOSURROUND);
   }

   fseek(f,-128,SEEK_END);
   fread(buffer,128,1,f);
   ret=ftell(f);

   if (buffer[0] =='T' && buffer[1] =='A' && buffer[2] =='G')
   {
      unsigned char genre_id = buffer[127];

      memcpy(title,buffer+3,30);
      title[30]=0;

      memcpy(author,buffer+33,30);
      author[30]=0;

      memcpy(album,buffer+63,34); // Plus year
      album[34]=0;

      memcpy(comment,buffer+97,30);
      comment[30]=0;

      if ( genre_id >= maxKnownGenre)
         genre=TXT_UNSPECIFIED;
      else
         genre=GenreStr[ genre_id ];

      buf = set_format_text(NULL, TXT_ID3INFO, amp_mpg_ver, amp_layer, amp_stereo == 1 ? TXT_STEREO : TXT_MONO, amp_samprat, amp_bitrate, amp_reverse_phase == 1 ? TXT_SURROUND : TXT_NOSURROUND, title, author, album, comment, genre);
   }
   else
      buf = set_format_text(NULL, TXT_MP3INFO, amp_mpg_ver, amp_layer, amp_stereo == 1 ? TXT_STEREO : TXT_MONO, amp_samprat, amp_bitrate, amp_reverse_phase == 1 ? TXT_SURROUND : TXT_NOSURROUND);

   fclose(f);

   return buf;

}

l_int mp3_display_about(p_soundformat_item o)
{
   msgbox(MW_INFO, MB_OK, "MP3 Driver for SFA\n\nCopyright (c) Florian Xaver 2000\nCopyright (c) Owen Rudge 2001\n\nUses LibAmp plus some code from GEMP3\n(www.owenrudge.co.uk/GEM/)");
   return(0);
}

//lib_exportable;
#include "sfamp3.exp"

SetInfoAppName("MP3 Codec");
SetInfoDesciption("MP3 Codec for SFA");
SetInfoCopyright("Copyright (c) Florian Xaver 2000, Owen Rudge 2001");
SetInfoManufacturer("Florian Xaver, Owen Rudge");

lib_begin ( void ) {

  if ( ap_process == AP_ALLOC )
     {
     AP_EXPORTLIB();
     }


  if ( ap_process == AP_INIT ) {



      p_soundformat_item k, k2;

      AP_EXPORTLIB();

//      AP_SETNUMOFCALLS(1);




      //init sound format list!!

      k = new_soundformat_item(                      ("mp3"),
                                                     ("MP3 files"),
                                                     ("(c) Florian Xaver GNU GPL - virtual sound file"),
                                                     &mp3_init_file,
                                                     &mp3_play_file,
                                                     &mp3_poll_file,
                                                     &mp3_stop_file,
                                                     &mp3_pause_file,
                                                     &mp3_forward_file,
                                                     &mp3_rewind_file,
                                                     &mp3_set_pos,
                                                     &mp3_get_pos,
                                                     &mp3_get_len_file,
                                                     &mp3_get_time,
                                                     &mp3_is_stereo,
                                                     &mp3_get_additional_info,
                                                     &mp3_display_about
                                                     );

      k2 = new_soundformat_item(                     ("mp2"),
                                                     ("MP2 files"),
                                                     ("(c) Florian Xaver GNU GPL - virtual sound file"),
                                                     &mp3_init_file,
                                                     &mp3_play_file,
                                                     &mp3_poll_file,
                                                     &mp3_stop_file,
                                                     &mp3_pause_file,
                                                     &mp3_forward_file,
                                                     &mp3_rewind_file,
                                                     &mp3_set_pos,
                                                     &mp3_get_pos,
                                                     &mp3_get_len_file,
                                                     &mp3_get_time,
                                                     &mp3_is_stereo,
                                                     &mp3_get_additional_info,
                                                     &mp3_display_about
                                                     );



     sound_format_list->insert(sound_format_list, k);
     sound_format_list->insert(sound_format_list, k2);


//     seal_error(ERR_INFO, "Now extension \"mp3\" is supported!");

  }



  if ( ap_process == AP_DONE ) {




  }


  if ( ap_process == AP_FREE ) {



  };

} lib_end;
