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 + -
显示快捷键?