Logo Search packages:      
Sourcecode: zinf version File versions  Download package

Mpg123UI.cpp

/*____________________________________________________________________________
    
    Zinf - Zinf Is Not FreeA*p (The Free MP3 Player)

    Portions Copyright (C) 1998-2000 EMusic.com

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    
    $Id: Mpg123UI.cpp,v 1.7 2003/09/16 17:35:28 kgk Exp $
____________________________________________________________________________*/

#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <signal.h>

using namespace std;
#include "Mpg123UI.h"
#include "event.h"
#include "eventdata.h"
#include "playlist.h"
#include "i18n.h"

void      mysigterm(int);
void      mysigint(int);

extern    "C"
{
   UserInterface *Initialize(FAContext * context)
   {
      return new Mpg123UI(context);
   }
}

EventQueue *Mpg123UI::m_playerEQ = NULL;

Mpg123UI::Mpg123UI(FAContext * context)
{
   m_context = context;
   m_mediaInfo_set = false;
   m_mediaInfo = NULL;
   m_mpegInfo_set = false;

   verboseMode = false;
   m_totalFrames = 0;
   m_totalMilliSeconds = 0;
   m_lastCurrentMilliSeconds = 0;
   fileName[0] = '\0';

   m_plm = NULL;

   m_displaystuff = true;
}

Error     Mpg123UI::
Init(int32_t startup_level)
{
   if ((m_startupType = startup_level) == PRIMARY_UI)
   {

      m_plm = m_context->plm;
      m_playerEQ = m_context->target;
      m_propManager = m_context->props;

      m_argc = m_context->argc;
      m_argv = m_context->argv;

      ProcessArgs();
      // cout << endl << "mpg123 0.59k command line compatability mode" << endl 
      // << endl;
      cerr << 
        "High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2 and 3\n"
        "Version 2.1.0 (2000/Feb/04).  \n"
        "Copyrights EMusic, XingTech. See 'README' for more!\n"
        "This software is distributed under the GNU GPL.\n";
      signal(SIGTERM, mysigterm);
      signal(SIGINT, mysigint);

   }
   return kError_NoErr;
}

void 
mysigterm(int f)
{
   Event    *e = new Event(CMD_Stop);

 Mpg123UI::m_playerEQ->AcceptEvent(e);
   e = new Event(CMD_QuitPlayer);
 Mpg123UI::m_playerEQ->AcceptEvent(e);
}

void 
mysigint(int f)
{
   mysigterm(f);
}
Mpg123UI::~Mpg123UI()
{
   // cout << "deleting Mpg123UI" << endl;
   // NOTE: we don't call cleanup on this EventQueueRef because it is pointing
   // to the player here...
   if (m_playerEQ)
   {
      delete    m_playerEQ;

      m_playerEQ = NULL;
      delete    m_mediaInfo;
   }
}

Error     Mpg123UI::
AcceptEvent(Event * e)
{
   if (e)
   {
      //cerr << "Mpg123COO: processing event " << e->Type() << endl;
      switch (e->Type())
      {
      case INFO_ErrorMessage:
         {
           ErrorMessageEvent *eme = (ErrorMessageEvent *)e;
           string ErrMessage(eme->GetErrorMessage());
 
           cout << ErrMessage << endl;
           break;
         }
      case INFO_PlaylistDonePlay:
         {
            Event    *ev = new Event(CMD_QuitPlayer);

            m_playerEQ->AcceptEvent(ev);
            break;
         }
      case INFO_MPEGInfo:
         {
            if (e)
            {
               m_mpegInfo     = *((MpegInfoEvent *) e);
               m_mpegInfo_set = true;
               m_totalFrames  = m_mpegInfo.GetTotalFrames();
               DisplayMPEGStuff();
            }
            break;
         }
      case INFO_VorbisInfo:
         {
            VorbisInfoEvent *info = (VorbisInfoEvent *) e;
            DisplayVorbisStuff(info);
            break;
         }  
      case INFO_MediaInfo:
         {
            if ( e )
            {
               m_mediaInfo = new MediaInfoEvent(*((MediaInfoEvent *) e));
               m_mediaInfo_set = true;
               m_totalMilliSeconds = m_mediaInfo->m_totalMilliSeconds;
               DisplayMPEGStuff();
            }
            break;
         }
      case INFO_MediaTimeInfo:
         {
            MediaTimeInfoEvent *pmtp = (MediaTimeInfoEvent *) e;

            if (verboseMode == true)
            {
               fprintf(stderr, "\rFrame# %5d [%5d], ", pmtp->m_currentFrame, m_totalFrames - pmtp->m_currentFrame);
               fprintf(stderr, "Time: %3.2f [%3.2f], ", pmtp->m_currentMilliSeconds/1000.0, (m_totalMilliSeconds - pmtp->m_currentMilliSeconds)/1000.0);
            }
            m_lastCurrentMilliSeconds = pmtp->m_currentMilliSeconds;
            break;
         }
      case INFO_Stopped:
         {
            if (m_lastCurrentMilliSeconds <= 0 || fileName[0] == '\0')
               break;

            int32_t m = m_lastCurrentMilliSeconds/1000 / 60;
            int32_t s = m_lastCurrentMilliSeconds/1000 % 60;

            m_displaystuff = true;
            fprintf(stderr, _("\n[%d:%02d] Decoding of %s finished.\n"), m, s, fileName.c_str());
            break;
         }
      case CMD_Cleanup:
         {
            Event    *e = new Event(INFO_ReadyToDieUI);

            // cout << "I'm gonna ACTUALLY kill myself" << endl;
            m_playerEQ->AcceptEvent(e);
            break;
         }
      default:
         break;
      }
   }
//cerr << "Done cmdlinecoo: accpet event" << endl;
   return kError_NoErr;
}

void      Mpg123UI::
DisplayMPEGStuff()
{
   if (!m_mediaInfo_set)
      return;

   if (!m_mpegInfo_set)
      return;

   if (!m_displaystuff)
       return;

   m_displaystuff = false;

   string path = m_mediaInfo->m_filename;
   string fname = path;
   string::size_type pos;
   string dir;

   pos = path.rfind('/');
   if (pos != string::npos) {
       dir = path.substr(0, pos);
       fname = path.substr(pos+1);
   }
   fileName = fname;
   
/*    if (m_id3Tag.m_containsInfo) {
   fprintf(stderr,"Title  : %30s  Artist: %s\n",m_id3Tag.m_songName,m_id3Tag.m_artist);
   fprintf(stderr,"Album  : %30s  Year: %4s, Genre: %d\n",m_id3Tag.m_album,m_id3Tag.m_year,(int)m_id3Tag.m_genre);
   fprintf(stderr,"Comment: %30s \n",m_id3Tag.m_comment);
   } */
   cerr << endl;

   static const char *mpeg_string[4] =
   {"1.0", "1.0", "2.0", "2.5"};
   static const char *mpeg_layer[4] =
   {"Unknown", "I", "II", "III"};
   static const char *mpeg_stereo[4] =
   {"Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel"};
   static const char *mpeg_short_stereo[4] =
   {"stereo", "joint-stereo", "dual-channel", "mono"};

   if (verboseMode == false)
   {
      // NORMAL MODE
       if (dir.size())
           cerr << "Directory: " << dir << "/" << endl;
       cerr << _("Playing MPEG stream from ") << fileName << " ..." << endl;
       cerr << "MPEG " << mpeg_string[m_mpegInfo.GetMpegVersion()] << " layer " << mpeg_layer[m_mpegInfo.GetLayer()] << ", " << m_mpegInfo.GetBitRate() / 1000 << " KBit/s" << ", " << m_mpegInfo.GetSampleRate() << " Hz" << " " << mpeg_short_stereo[m_mpegInfo.GetStereo()] << endl;
   }
   else
   {
      // VERBOSE MODE
      if (dir.size())
      {
         cerr << "Directory: " << dir << "/" << endl;
      }
      cerr << _("Playing MPEG stream from ") << fileName << " ..." << endl;
      cerr << "MPEG " << mpeg_string[m_mpegInfo.GetMpegVersion()];
      cerr << ", Layer: " << mpeg_layer[m_mpegInfo.GetLayer()];
      cerr << ", Freq: " << m_mpegInfo.GetSampleRate();
      cerr << ", mode: " << mpeg_stereo[m_mpegInfo.GetStereo()] << ", modext: " << m_mpegInfo.GetModeExt() << ", BPF : " << m_mpegInfo.GetBytesPerFrame() << endl;
      cerr << "Channels: " << m_mpegInfo.GetChannels() << ", copyright: " << (m_mpegInfo.GetCopyright()? "Yes" : "No") << ", original: ";
      cerr << (m_mpegInfo.GetOriginal()? "Yes" : "No") << ", CRC: " << (m_mpegInfo.GetCRC()? "Yes" : "No") << ", emphasis: " << m_mpegInfo.GetEmphasis() << "." << endl;
      cerr << "Bitrate: " << m_mpegInfo.GetBitRate() / 1000 << " KBits/s, Extension value: 0" << endl;
      cerr << "Audio: 1:1 conversion, rate: " << m_mpegInfo.GetSampleRate() << ", encoding: signed 16 bit, channels: " << m_mpegInfo.GetChannels() << endl;
   }
}

void      Mpg123UI::
DisplayVorbisStuff(VorbisInfoEvent *info)
{
   if (!m_mediaInfo_set)
      return;

   if (!m_displaystuff)
       return;

   m_displaystuff = false;

   string path = m_mediaInfo->m_filename;
   string fname = path;
   string::size_type pos;
   string dir;

   pos = path.rfind('/');
   if (pos != string::npos) {
       dir = path.substr(0, pos);
       fname = path.substr(pos+1);
   }
   fileName = fname;
   
   if (verboseMode == false)
   {
      cerr << "\n";
      // NORMAL MODE
      if (dir.size()) {
          cerr << "Directory: " << dir << "/" << endl;
      }
      cerr << _("Playing Vorbis stream from ") << fileName << " ..." << endl;
      fprintf(stderr, "%ldkbps %ldkHz %s Vorbis\n\n",
               (long int)(info->GetBitRate() / 1000),
               (long int)(info->GetSampleRate() / 1000),
               info->GetChannels() ? "Stereo" : "Mono");  
   }
}

void      Mpg123UI::
ProcessArgs()
{
   char     *pc = NULL;
   int       addedStuff = 0;

   for (int i = 1; i < m_argc; i++)
   {
      pc = m_argv[i];
      if (pc[0] == '-')
      {
         switch (pc[1])
         {
         case 't':
            cout << "test mode" << endl;
            break;
         case 'v':
            verboseMode = true;
            // cout << "verbose mode" << endl;
            break;
         case 'k':
            i++;
            pc = m_argv[i];
            skipFirst = atoi(pc);
            // cout << "skiping first " << skipFirst << " frames" << endl;
            break;
         case 'c':
            cout << "check range violations" << endl;
            break;
         case 'b':
            i++;
            pc = m_argv[i];
            cout << "output buffer: " << pc << "Kbytes" << endl;
            break;
         case 'r':
            i++;
            pc = m_argv[i];
            cout << "override samplerate: " << pc << endl;
            break;
         case 'o':
            {
               switch (pc[2])
               {
               case 's':
                  cout << "output to builtin speaker" << endl;
                  break;
               case 'l':
                  cout << "output to line connector" << endl;
                  break;
               case 'h':
                  cout << "output to headphones" << endl;
                  break;
               }
            }
         case '2':
            cout << "downsample 1:2 (22 kHz)" << endl;
            break;
         case 'd':
            i++;
            pc = m_argv[i];
            cout << "play only every nth frame" << endl;
            break;
         case '0':
            cout << "decode channel 0 (left) only" << endl;
            break;
         case 'm':
            cout << "mix both channels (mono)" << endl;
            break;
         case '@':
            i++;
            pc = m_argv[i];
            cout << "read filenames/URLs from " << pc << endl;
            break;
         case 'q':
            cout << "quiet" << endl;
            break;
         case 's':
            cout << "write to standard out" << endl;
            break;
         case 'n':
            i++;
            pc = m_argv[i];
            cout << "decode only " << pc << " frames" << endl;
            break;
         case 'y':
            cout << "disable resync on errors" << endl;
            break;
         case 'f':
            i++;
            pc = m_argv[i];
            cout << "change scalefactor to " << pc << endl;
            break;
         case 'g':
            i++;
            pc = m_argv[i];
            cout << "set audio output hardware gain to " << pc << endl;
            break;
         case 'a':
            i++;
            pc = m_argv[i];
            cout << "set audio device " << pc << endl;
            break;
         case '4':
            cout << "downsample 1:4 (11 kHz)" << endl;
            break;
         case 'h':
            i++;
            pc = m_argv[i];
            cout << " play every frame " << pc << " times" << endl;
            break;
         case '1':
            cout << "decode channel 1 only (right) " << endl;
            break;
         case 'p':
            i++;
            pc = m_argv[i];
            cout << "use HTTP proxy " << pc << endl;
            break;
         case 'z':
            m_plm->SetShuffleMode(true);
            // cout << "shuffle play (with wildcards) " << endl;
            break;
         case 'Z':
            // random play has been temporarily disabled.
            // m_plm->SetShuffle(PlaylistManager::ORDER_RANDOM);
            // cout << "Random Play" << endl;
            break;
         case 'u':
         case 'U':
            i++;
            // the -ui to select the UI
            break;
         default:
            // cout << "Unknown option:  " << pc << endl;
            break;
         }
      }
      else
      {
         // ut << "Adding: " <<m_argv[i] << endl;
         //m_plm->AddItem(m_argv[i], 0);
         addedStuff++;
      }
   }

   if (addedStuff)
   {

      m_plm->SetCurrentIndex(0);
      //RAK: This should not be necessary as the player auto plays
      //Event    *e = new Event(CMD_Play);
      //m_playerEQ->AcceptEvent(e);
   }
   else
   {
      // cout << "Gonna try and quit..." << endl;
      m_playerEQ->AcceptEvent(new Event(CMD_QuitPlayer));
   }
}

/* arch-tag: 07b86260-a417-4ad5-b37f-2ce516ac458d
   (do not change this comment) */

Generated by  Doxygen 1.6.0   Back to index