helix-sp.cpp

来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 2,109 行 · 第 1/4 页

CPP
2,109
字号
            print2stderr("Failed to open audio(%s)!!!!!!! Code is: %d  errno: %d\n",                   szDevName, m_nDevID, errno );            //Error opening device.         }      }      break;      case ALSA:      {#ifdef USE_HELIX_ALSA         int err;         print2stderr("Opening ALSA mixer device PCM\n");         err = snd_mixer_open(&m_pAlsaMixerHandle, 0);         if (err < 0)            print2stderr("snd_mixer_open: %s\n", snd_strerror (err));         if (err == 0)         {            err = snd_mixer_attach(m_pAlsaMixerHandle, m_alsaDevice);            if (err < 0)               print2stderr("snd_mixer_attach: %s\n", snd_strerror (err));         }         if (err == 0)         {            err = snd_mixer_selem_register(m_pAlsaMixerHandle, NULL, NULL);            if (err < 0)               print2stderr("snd_mixer_selem_register: %s\n", snd_strerror (err));         }         if (err == 0)         {            err = snd_mixer_load(m_pAlsaMixerHandle);            if(err < 0 )               print2stderr("snd_mixer_load: %s\n", snd_strerror (err));         }         if (err == 0)         {            /* Find the mixer element */            snd_mixer_elem_t* elem = snd_mixer_first_elem(m_pAlsaMixerHandle);            snd_mixer_elem_type_t type;            const char* elem_name = NULL;            snd_mixer_selem_id_t *sid = NULL;            snd_mixer_selem_id_alloca(&sid);            while (elem)            {               type = snd_mixer_elem_get_type(elem);               if (type == SND_MIXER_ELEM_SIMPLE)               {                  snd_mixer_selem_get_id(elem, sid);                  /* We're only interested in playback volume controls */                  if(snd_mixer_selem_has_playback_volume(elem) && !snd_mixer_selem_has_common_volume(elem) )                  {                     elem_name = snd_mixer_selem_id_get_name(sid);                     if (!m_pAlsaPCMMixerElem && strcmp(elem_name, "Master") == 0)                        m_pAlsaMasterMixerElem = elem;                     if (!m_pAlsaPCMMixerElem && strcmp(elem_name, "PCM") == 0)                        m_pAlsaPCMMixerElem = elem;                     if (m_pAlsaMasterMixerElem && m_pAlsaPCMMixerElem)                        break;                  }               }               elem = snd_mixer_elem_next(elem);            }            if (!elem)            {               print2stderr("Could not find a usable mixer element\n");               err = -1;            }         }         if (err != 0)         {            if(m_pAlsaMixerHandle)            {               snd_mixer_close(m_pAlsaMixerHandle);               m_pAlsaMixerHandle = NULL;            }         }#endif      }      break;      default:         print2stderr("Unknown audio interface in openAudioDevice()\n");   }}void HelixSimplePlayer::closeAudioDevice(){   switch (m_direct)   {      case OSS:      {         if( m_nDevID >= 0 )         {            ::close( m_nDevID );            m_nDevID = -1;         }      }      break;      case ALSA:      {#ifdef USE_HELIX_ALSA         int err = 0;         if (m_pAlsaMixerHandle && m_pAlsaMasterMixerElem)         {            err = snd_mixer_detach(m_pAlsaMixerHandle, "Master");            if (err < 0)               print2stderr("snd_mixer_detach: %s\n", snd_strerror(err));         }         if (m_pAlsaMixerHandle && m_pAlsaPCMMixerElem)         {            err = snd_mixer_detach(m_pAlsaMixerHandle, "PCM");            if (err < 0)               print2stderr("snd_mixer_detach: %s\n", snd_strerror(err));         }         if (m_pAlsaMixerHandle)         {            if(err == 0)            {               err = snd_mixer_close(m_pAlsaMixerHandle);               if(err < 0)                  print2stderr("snd_mixer_close: %s\n", snd_strerror (err));            }            if(err == 0)            {               m_pAlsaMixerHandle = NULL;               m_pAlsaPCMMixerElem = NULL;            }         }#endif      }      break;      default:         print2stderr("Unknown audio interface in closeAudioDevice()\n");   }}// it seems the master volume only gets reset on track change when using ALSA// sheez, I thought Amarok wasnt supposed to be a mixer??// all this code is so that you can actually *use* a mixer and have it work// the way you expect...#ifdef USE_HELIX_ALSAint HelixSimplePlayer::getDirectMasterVolume(){   int nRetVolume   = 0;   switch (m_direct)   {      case ALSA:      {         if (!m_pAlsaMasterMixerElem)            return nRetVolume;         snd_mixer_elem_type_t type;         int err = 0;         type = snd_mixer_elem_get_type(m_pAlsaMasterMixerElem);         if (type == SND_MIXER_ELEM_SIMPLE)         {            long volumeL, volumeR, min_volume, max_volume;            if(snd_mixer_selem_has_playback_volume(m_pAlsaMasterMixerElem) ||               snd_mixer_selem_has_playback_volume_joined(m_pAlsaMasterMixerElem))            {               err = snd_mixer_selem_get_playback_volume(m_pAlsaMasterMixerElem,                                                         SND_MIXER_SCHN_FRONT_LEFT,                                                         &volumeL);               if (err < 0)                  print2stderr("snd_mixer_selem_get_playback_volume (L): %s\n", snd_strerror (err));               else               {                  if ( snd_mixer_selem_is_playback_mono ( m_pAlsaMasterMixerElem ))                     volumeR = volumeL;                  else                  {                     err = snd_mixer_selem_get_playback_volume(m_pAlsaMasterMixerElem,                                                               SND_MIXER_SCHN_FRONT_RIGHT,                                                               &volumeR);                     if (err < 0)                        print2stderr("snd_mixer_selem_get_playback_volume (R): %s\n", snd_strerror (err));                  }               }               if (err == 0)               {                  snd_mixer_selem_get_playback_volume_range(m_pAlsaMasterMixerElem,                                                            &min_volume,                                                            &max_volume);                  if(max_volume > min_volume)                     nRetVolume = (UINT16) (0.5 + (100.0 * (double)(volumeL + volumeR) / (2.0 * (max_volume - min_volume))));               }            }         }      }      break;      default:         print2stderr("Unknown audio interface in getDirectMasterVolume()\n");   }   return nRetVolume;}void HelixSimplePlayer::setDirectMasterVolume(int vol){   switch (m_direct)   {      case ALSA:      {         if (!m_pAlsaMasterMixerElem)            return;         snd_mixer_elem_type_t type;         int err = 0;         type = snd_mixer_elem_get_type(m_pAlsaMasterMixerElem);         if (type == SND_MIXER_ELEM_SIMPLE)         {            long volume, min_volume, max_volume, range;            if(snd_mixer_selem_has_playback_volume(m_pAlsaMasterMixerElem) ||               snd_mixer_selem_has_playback_volume_joined(m_pAlsaMasterMixerElem))            {               snd_mixer_selem_get_playback_volume_range(m_pAlsaMasterMixerElem,                                                         &min_volume,                                                         &max_volume);               range = max_volume - min_volume;               volume = (long) (((double)vol / 100) * range + min_volume);               err = snd_mixer_selem_set_playback_volume( m_pAlsaMasterMixerElem,                                                          SND_MIXER_SCHN_FRONT_LEFT,                                                          volume);               if (err < 0)                  print2stderr("snd_mixer_selem_set_playback_volume: %s\n", snd_strerror (err));               if (!snd_mixer_selem_is_playback_mono (m_pAlsaMasterMixerElem))               {                  /* Set the right channel too */                  err = snd_mixer_selem_set_playback_volume( m_pAlsaMasterMixerElem,                                                             SND_MIXER_SCHN_FRONT_RIGHT,                                                             volume);                  if (err < 0)                     print2stderr("snd_mixer_selem_set_playback_volume: %s\n", snd_strerror (err));               }            }         }      }      break;      default:         print2stderr("Unknown audio interface in setDirectMasterVolume()\n");   }}#endifint HelixSimplePlayer::getDirectPCMVolume(){   int nRetVolume   = 0;   switch (m_direct)   {      case OSS:      {         int nVolume      = 0;         int nLeftVolume  = 0;         int nRightVolume = 0;         if (m_nDevID < 0 || (::ioctl( m_nDevID, MIXER_READ(HX_VOLUME), &nVolume) < 0))         {            print2stderr("ioctl fails when reading HW volume: mnDevID=%d, errno=%d\n", m_nDevID, errno);            nRetVolume = 50; // sensible default         }         else         {            nLeftVolume  = (nVolume & 0x000000ff);            nRightVolume = (nVolume & 0x0000ff00) >> 8;            //Which one to use? Average them?            nRetVolume = nLeftVolume ;         }      }      break;      case ALSA:      {#ifdef USE_HELIX_ALSA         if (!m_pAlsaPCMMixerElem)            return nRetVolume;         snd_mixer_elem_type_t type;         int err = 0;         type = snd_mixer_elem_get_type(m_pAlsaPCMMixerElem);         if (type == SND_MIXER_ELEM_SIMPLE)         {            long volumeL, volumeR, min_volume, max_volume;            if(snd_mixer_selem_has_playback_volume(m_pAlsaPCMMixerElem) ||               snd_mixer_selem_has_playback_volume_joined(m_pAlsaPCMMixerElem))            {               err = snd_mixer_selem_get_playback_volume(m_pAlsaPCMMixerElem,                                                         SND_MIXER_SCHN_FRONT_LEFT,                                                         &volumeL);               if (err < 0)                  print2stderr("snd_mixer_selem_get_playback_volume (L): %s\n", snd_strerror (err));               else               {                  if ( snd_mixer_selem_is_playback_mono ( m_pAlsaPCMMixerElem ))                     volumeR = volumeL;                  else                  {                     err = snd_mixer_selem_get_playback_volume(m_pAlsaPCMMixerElem,                                                               SND_MIXER_SCHN_FRONT_RIGHT,                                                               &volumeR);                     if (err < 0)                        print2stderr("snd_mixer_selem_get_playback_volume (R): %s\n", snd_strerror (err));                  }               }               if (err == 0)               {                  snd_mixer_selem_get_playback_volume_range(m_pAlsaPCMMixerElem,                                                            &min_volume,                                                            &max_volume);                  if(max_volume > min_volume)                     nRetVolume = (UINT16) (0.5 + (100.0 * (double)(volumeL + volumeR) / (2.0 * (max_volume - min_volume))));               }            }         }#endif      }      break;      default:         print2stderr("Unknown audio interface in getDirectPCMVolume()\n");   }   return nRetVolume;}void HelixSimplePlayer::setDirectPCMVolume(int vol){   switch (m_direct)   {      case OSS:      {         int nNewVolume=0;         //Set both left and right volumes.         nNewVolume = (vol & 0xff) | ((vol & 0xff) << 8);         if (::ioctl( m_nDevID, MIXER_WRITE(HX_VOLUME), &nNewVolume) < 0)            print2stderr("Unable to set direct HW volume\n");      }      break;      case ALSA:      {#ifdef USE_HELIX_ALSA         if (!m_pAlsaPCMMixerElem)            return;         snd_mixer_elem_type_t type;         int err = 0;         type = snd_mixer_elem_get_type(m_pAlsaPCMMixerElem);         if (type == SND_MIXER_ELEM_SIMPLE)         {            long volume, min_volume, max_volume, range;            if(snd_mixer_selem_has_playback_volume(m_pAlsaPCMMixerElem) ||               snd_mixer_selem_has_playback_volume_joined(m_pAlsaPCMMixerElem))            {               snd_mixer_selem_get_playback_volume_range(m_pAlsaPCMMixerElem,                                                         &min_volume,                                                         &max_volume);               range = max_volume - min_volume;               volume = (long) (((double)vol / 100) * range + min_volume);               err = snd_mixer_selem_set_playback_volume( m_pAlsaPCMMixerElem,                                                          SND_MIXER_SCHN_FRONT_LEFT,                                                          volume);               if (err < 0)                  print2stderr("snd_mixer_selem_set_playback_volume: %s\n", snd_strerror (err));               if (!snd_mixer_selem_is_playback_mono (m_pAlsaPCMMixerElem))               {                  /* Set the right channel too */                  err = snd_mixer_selem_set_playback_volume( m_pAlsaPCMMixerElem,                                                             SND_MIXER_SCHN_FRONT_RIGHT,                                                             volume);                  if (err < 0)                     print2stderr("snd_mixer_selem_set_playback_volume: %s\n", snd_strerror (err));               }            }         }#endif      }      break;      default:         print2stderr("Unknown audio interface in setDirectPCMVolume()\n");   }}int HelixSimplePlayer::setURL(const char *file, int playerIndex, bool islocal){   if (playerIndex == ALL_PLAYERS)   {      int i;      for (i=0; i<nNumPlayers; i++)         setURL(file, i);   }   else   {      int len = strlen(file);      if (len >= MAXPATHLEN)         return -1;;      print2stderr("SETURL MASTER VOL: %d\n",getDirectMasterVolume());      if (ppctrl[playerIndex]->pszURL)         delete [] ppctrl[playerIndex]->pszURL;      // see if the file is already in the form of a url      char *tmp = strstr(file, "://");      if (!tmp)      {         char pszURLOrig[MAXPATHLEN];         const char* pszAddOn;         strcpy(pszURLOrig, file);         RemoveWrappingQuotes(pszURLOrig);         pszAddOn = "file://";         ppctrl[playerIndex]->pszURL = new char[strlen(pszURLOrig)+strlen(pszAddOn)+1];         if ( (len + strlen(pszAddOn)) < MAXPATHLEN )         {            sprintf( ppctrl[playerIndex]->pszURL, "%s%s", pszAddOn, pszURLOrig );            islocal = true; // diesnt matter what we were told...         }         else            return -1;      }      else      {         ppctrl[playerIndex]->pszURL = new char[len + 1];         if (ppctrl[playerIndex]->pszURL)            strcpy(ppctrl[playerIndex]->pszURL, file);         else            return -1;      }      ppctrl[playerIndex]->isLocal = islocal;      print2stderr("opening %s on player %d, src cnt %d\n",             ppctrl[playerIndex]->pszURL, playerIndex, ppctrl[playerIndex]->pPlayer->GetSourceCount());#ifdef __NOCROSSFADER__      if (HXR_OK == ppctrl[playerIndex]->pPlayer->OpenURL(ppctrl[playerIndex]->pszURL))      {         print2stderr("opened player on %d src cnt %d\n", playerIndex, ppctrl[playerIndex]->pPlayer->GetSourceCount());         m_urlchanged = true;      }#else      /* try OpenRequest instead... */      IHXRequest *ireq = 0;      pthread_mutex_lock(&m_engine_m);      pCommonClassFactory->CreateInstance(CLSID_IHXRequest, (void **)&ireq);      if (ireq)      {         //print2stderr("GOT THE IHXRequest Interface!!\n");         ireq->SetURL(ppctrl[playerIndex]->pszURL);         ppctrl[playerIndex]->pPlayer2->OpenRequest(ireq);         m_urlchanged = true;         ireq->Release();      }      pthread_mutex_unlock(&m_engine_m);#endif   }   return 0;}int HelixSimplePlayer::numPlugins() const{   if (pPluginE)   {      return ((int)pPluginE->GetNumOfPlugins());   }   return 0;}int HelixSimplePlayer::getPluginInfo(int index,

⌨️ 快捷键说明

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