⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 player.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

        while (m_sigspmo) 
            usleep(50);

        browserInfo = " ";
        AcceptEvent(new BrowserMessageEvent(browserInfo));
        items->erase(url);
    }

    AcceptEvent(new Event(INFO_SignaturingStopped));

    delete items;
    m_bKillSignature = false;
}

void 
Player::
CreatePMO(const PlaylistItem * pc, Event * pC)
{
   Error     error = kError_NoErr;
   Event    *e;
   PhysicalMediaOutput *pmo = NULL;
   PhysicalMediaInput *pmi = NULL;
   LogicalMediaConverter *lmc = NULL;
   RegistryItem *pmi_item = NULL;
   RegistryItem *lmc_item = NULL;
   RegistryItem *item = NULL;

   if (!pc)
   {
      m_plm->SetCurrentIndex(0);
      if (m_pmo)
      {
         m_pmo->Pause();
         delete m_pmo;
         m_pmo = NULL;

         m_lmc = NULL;
      }
      if (SetState(PlayerState_Stopped))
      {
         SEND_NORMAL_EVENT(INFO_Stopped);
      }
      GetUIManipLock();

      e = new Event(INFO_PlaylistDonePlay);
      SendToUI(e);

      ReleaseUIManipLock();

      delete e;
   }

   if (m_pmo)
   {
      m_pmo->Pause();
      delete    m_pmo;
      m_pmo = NULL;
      m_lmc = NULL;
   }

   pmi_item = ChoosePMI(pc->URL().c_str());
   if (!pmi_item)
   {
      char szErr[1024];

      sprintf(szErr, "Cannot determine what pmi to use for %s\n", pc->URL().c_str());
      m_context->log->Error(szErr);
      AcceptEvent(new ErrorMessageEvent(szErr));

      return;
   }

   lmc_item = ChooseLMC(pc->URL().c_str());
   if (!lmc_item) 
   {
   // FIXME: Should probably have a user definable default LMC
      lmc_item = ChooseLMC("blah.mp3");
   }

   if (pmi_item)
   {
      pmi = (PhysicalMediaInput *) pmi_item->InitFunction()(m_context);
      pmi->SetPropManager((Properties *) this);
   }

   char *extension = GetExtension(pc->URL().c_str());
   if (extension) {
       if (!strncasecmp("CDA", extension, 3)) {
           int32 i = 0;

           while (NULL != (item = m_pmoRegistry->GetItem(i++)))
           {
               if (!strcmp("cd.pmo", item->Name()))
               {
                   break;
               }
           }
       }
       delete [] extension;
   }

   if (!item) {
       char defaultPMO[256];
       uint32 size = sizeof(defaultPMO);

       m_context->prefs->GetPrefString(kPMOPref, defaultPMO, &size);

       int32 i = 0;

       while (NULL != (item = m_pmoRegistry->GetItem(i++)))
       {
            if(!strcmp(defaultPMO, item->Name()))
            {
                break;
            }
       }

	   // if the default isn't around then just use first one 
	   // is there a better way?
	   if(!item)
		  item = m_pmoRegistry->GetItem(0);

	   if (item)
	   {
		  pmo = (PhysicalMediaOutput *) item->InitFunction()(m_context);
		  pmo->SetPropManager((Properties *) this);
	   }

	   error = kError_NoErr;
	   if (lmc_item)
	   {
		  lmc = (LogicalMediaConverter *) lmc_item->InitFunction()(m_context);

		  lmc->SetPropManager((Properties *) this);
	   }

	   lmc->SetPMI(pmi);
	   lmc->SetPMO(pmo);

	   pmo->SetPMI(pmi);
	   pmo->SetLMC(lmc);

	   lmc->SetEQData(m_eqValues, m_eqPreamp);
	   lmc->SetEQData(m_eqEnabled);
   }
   else
   {
	   // We're using the CD PMO, do no need to set up an LMC or PMI
	   pmo = (PhysicalMediaOutput *) item->InitFunction()(m_context);
	   pmo->SetPropManager((Properties *) this);
   }

   pmi = NULL;
   m_lmc = lmc;
   lmc = NULL;

   error = pmo->SetTo(pc->URL().c_str());
   // If this is a missing file, then just bail out -- the 
   // pmo that was created will have sent a missing file event
   // that will notify the user
   if (error == kError_FileNotFound)
   {
      AcceptEvent(new MissingFileEvent((PlaylistItem *)
                                       m_plm->GetCurrentItem()));
      //m_plm->GotoNextItem();
      AcceptEvent(new Event(CMD_Play));
      goto epilogue;
   }

   if (IsError(error))
   {
      char szErr[1024];

      sprintf(szErr, "Cannot setup the audio decode process: %d\n", error);
      m_context->log->Error(szErr);

      goto epilogue;
   }

   m_pmo = pmo;
   pmo = NULL;

   epilogue:

   if (pmo)
   {
       m_pmo = NULL;
       delete pmo;
   }

   if (pmi)
   {
       delete pmi;
   }

   if (lmc)
   {
       m_lmc = NULL;
       delete lmc;
   }
}

void 
Player::
DoneOutputting(Event *pEvent)
{
   // LMC or PMO sends this when its done
   // outputting whatever.  Now, go on to next
   // piece in playlist

   if (m_pmo)
   {
      delete m_pmo;
      m_pmo = NULL;
      m_lmc = NULL;
   }

   PlaylistItem *item = m_plm->GetCurrentItem();
   if (item)
   {
      MetaData mdata = (MetaData)item->GetMetaData();
      if (mdata.GUID().size() == 16) {
          mdata.AddPlayCount();
          item->SetMetaData(&mdata);
          m_musicCatalog->UpdateSong(item);
          m_APSInterface->WriteToLog(mdata.GUID());   
      }
   }

   if (SetState(PlayerState_Stopped))
   {
       SEND_NORMAL_EVENT(INFO_Stopped);
   }

   SEND_NORMAL_EVENT(INFO_DoneOutputting);

   if (pEvent->Type() == INFO_DoneOutputtingDueToError &&
       (m_plm->GetRepeatMode() == kPlaylistMode_RepeatOne || 
        (m_plm->GetRepeatMode() == kPlaylistMode_RepeatAll && 
         m_plm->CountItems() == 1))) 
   {
      m_plm->SetCurrentIndex(0);
      SEND_NORMAL_EVENT(INFO_PlaylistDonePlay);
      delete pEvent;
      
      return;
   }

   if (m_plm->HasAnotherItem()) 
   {
      //AcceptEvent(new Event(CMD_NextMediaPiece));
      m_plm->GotoNextItem(false);

      if (m_playerState == PlayerState_Paused)
      {
         AcceptEvent(new Event(CMD_PlayPaused));
      }
      else
      {
         AcceptEvent(new Event(CMD_Play));
      }
   }
   else
   {
      m_plm->SetCurrentIndex(0);
      SEND_NORMAL_EVENT(INFO_PlaylistDonePlay);
   }
   delete pEvent;
}


void 
Player::
Stop(Event *pEvent)
{
    if (m_pmo)
    {
       m_pmo->Pause();
       delete m_pmo;
       m_pmo = NULL;
       m_lmc = NULL;
    }

    if (SetState(PlayerState_Stopped))
    {
       SEND_NORMAL_EVENT(INFO_Stopped);
    }

    delete pEvent;
}

void
Player::
GetVolume(Event *pEvent)
{
    int32 left = -1, right = -1;

    delete pEvent;
    if (m_pmo) 
    {
       m_pmo->GetVolume(left, right);
       Event *e = new VolumeEvent(INFO_VolumeInfo, left, right);
       SendToUI(e);
       delete e;
    }   
}

void
Player::
SetVolume(Event *pEvent)
{
    int32 left=((VolumeEvent *) pEvent)->GetLeftVolume();
    int32 right=((VolumeEvent *) pEvent)->GetRightVolume();
    if (m_pmo) 
        m_pmo->SetVolume(left, right);
    delete pEvent;
}

void 
Player::
ChangePosition(Event *pEvent)
{
    if (m_pmo)
       m_pmo->ChangePosition(((ChangePositionEvent *) pEvent)->GetPosition());

    delete pEvent;
}

void 
Player::
HandleQueryState()
{
    if (m_playerState == PlayerState_Playing)
    {
        SEND_NORMAL_EVENT(INFO_Playing);
    }
    else if (m_playerState == PlayerState_Stopped)
    {
        SEND_NORMAL_EVENT(INFO_Stopped);
    }
    else if (m_playerState == PlayerState_Paused)
    {
        SEND_NORMAL_EVENT(INFO_Paused);
    }
}

void 
Player::
Play(Event *pEvent)
{
    const PlaylistItem               *pItem;
	
	if ((m_playerState == PlayerState_Playing) && (pEvent->Type() == PlayerState_Playing)) 
	{	// ignore double Playing event
		delete pEvent;
		return;
	}
    
	if (m_playerState == PlayerState_Playing)
    {
       delete m_pmo;
       m_pmo = NULL;
       m_lmc = NULL;

       if (SetState(PlayerState_Stopped))
       {
           SEND_NORMAL_EVENT(INFO_Stopped);
       }
    }

    if (!m_pmo)
    {
       pItem = m_plm->GetCurrentItem();
       if (pItem)
       {
            CreatePMO(pItem, pEvent);
       }   

       if (!m_pmo)  {
          delete pEvent;
          return;
       }
    }

    if (pEvent->Type() == CMD_PlayPaused)
    {
        if (SetState(PlayerState_Paused))
        {
           SEND_NORMAL_EVENT(INFO_Playing); 
           SEND_NORMAL_EVENT(INFO_Paused);
        }
    }
    else
    {
        m_pmo->Resume();
        if (SetState(PlayerState_Playing))
        {
           SEND_NORMAL_EVENT(INFO_Playing);
        }
    }

    delete pEvent;
}

void 
Player::
Next(Event *pEvent)
{
   if (m_playerState != PlayerState_Stopped)
   {
       PlaylistItem *item = m_plm->GetCurrentItem();
       if (item)
       {
          MetaData mdata = (MetaData)item->GetMetaData();
          m_APSInterface->WriteToLog(mdata.GUID(), APSInterface::SongSkip);
       }

      AcceptEvent(new Event(CMD_Stop));
   }

   m_plm->GotoNextItem(true);

   if (m_playerState != PlayerState_Stopped)
   {
       if (m_playerState == PlayerState_Paused)
       {
          AcceptEvent(new Event(CMD_PlayPaused));
       }   
       else
       { 
          AcceptEvent(new Event(CMD_Play));
       }   
   }

   delete pEvent;
}

void 
Player::
Previous(Event *pEvent)
{
   if (m_playerState != PlayerState_Stopped)
   {
       PlaylistItem *item = m_plm->GetCurrentItem();
       if (item)
       {
          MetaData mdata = (MetaData)item->GetMetaData();
          m_APSInterface->WriteToLog(mdata.GUID(), APSInterface::SongSkip);
       }

      AcceptEvent(new Event(CMD_Stop));
   }

   m_plm->GotoPreviousItem(true);

   if (m_playerState != PlayerState_Stopped)
   {
       if (m_playerState == PlayerState_Paused)
          AcceptEvent(new Event(CMD_PlayPaused));
       else
          AcceptEvent(new Event(CMD_Play));
   }

   delete pEvent;
}

void 
Player::
Pause(Event *pEvent)
{
   if (m_pmo)
   {
      m_pmo->Pause();
      if (SetState(PlayerState_Paused))
         SEND_NORMAL_EVENT(INFO_Paused);
   }
   delete pEvent;
}

void 
Player::
UnPause(Event *pEvent)
{
   if (m_pmo)
   {
      m_pmo->Resume();
      if (SetState(PlayerState_Playing))
         SEND_NORMAL_EVENT(INFO_Playing);
   }
   delete pEvent;
}

void 
Player::
TogglePause(Event *pEvent)
{
    if (m_pmo)
    {
       if (m_playerState == PlayerState_Playing)
           Pause(NULL);
       else
       if (m_playerState == PlayerState_Paused)
           UnPause(NULL);
    }

    delete pEvent;
}

int 
Player::
Quit(Event *pEvent)
{
   Event *pe;

   Stop(NULL);
   // 1) Set "I'm already quitting flag" (or exit if its already Set)
   m_imQuitting = 1;
   // 2) Get CIO/COO manipulation lock

   GetUIManipLock();
   // 3) Count CIO/COO, put into m_quitWaitingFor.
   m_quitWaitingFor = m_uiList->size();
   // 4) Send CMD_Cleanup event to all CIO/COOs

   pe = new Event(CMD_Cleanup);

   SendToUI(pe);
   delete    pe;

   delete  pEvent;

   if (m_quitWaitingFor == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -