3
3
* This software is released under the provisions of the GPL version 2.
4
* see file "COPYING". If that file is not available, the full statement
4
* see file "COPYING". If that file is not available, the full statement
5
5
* of the license can be found at
7
7
* http://www.fsf.org/licensing/licenses/gpl.txt
70
70
class HelixSimplePlayerAudioStreamInfoResponse : public IHXAudioStreamInfoResponse
73
HelixSimplePlayerAudioStreamInfoResponse(HelixSimplePlayer *player, int playerIndex) :
73
HelixSimplePlayerAudioStreamInfoResponse(HelixSimplePlayer *player, int playerIndex) :
74
74
m_Player(player), m_index(playerIndex), m_lRefCount(0) {}
75
75
virtual ~HelixSimplePlayerAudioStreamInfoResponse() {}
139
139
STDMETHODIMP HelixSimplePlayerAudioStreamInfoResponse::OnStream(IHXAudioStream *pAudioStream)
141
m_Player->print2stderr("Stream Added on player %d, stream duration %ld, sources %d\n", m_index,
141
m_Player->print2stderr("Stream Added on player %d, stream duration %ld, sources %d\n", m_index,
142
142
m_Player->duration(m_index), m_Player->ppctrl[m_index]->pPlayer->GetSourceCount());
144
144
m_Player->ppctrl[m_index]->pStream = pAudioStream;
145
m_Player->ppctrl[m_index]->pPreMixHook = new HSPPreMixAudioHook(m_Player, m_index, pAudioStream,
146
m_Player->ppctrl[m_index]->bFadeIn,
145
m_Player->ppctrl[m_index]->pPreMixHook = new HSPPreMixAudioHook(m_Player, m_index, pAudioStream,
146
m_Player->ppctrl[m_index]->bFadeIn,
147
147
m_Player->ppctrl[m_index]->ulFadeLength);
149
149
// addpremixhook adds another ref
150
150
pAudioStream->AddPreMixHook(m_Player->ppctrl[m_index]->pPreMixHook, false);
151
m_Player->ppctrl[m_index]->pPreMixHook->Release(); // release the ref added in the premixhook constructor
151
m_Player->ppctrl[m_index]->pPreMixHook->Release(); // release the ref added in the premixhook constructor
153
153
m_Player->ppctrl[m_index]->bStarting = false;
168
168
// IUnknown::QueryInterface
170
// Implement this to export the interfaces supported by your
170
// Implement this to export the interfaces supported by your
173
173
STDMETHODIMP HelixSimplePlayerVolumeAdvice::QueryInterface(REFIID riid, void** ppvObj)
331
331
gettimeofday(&t, NULL);
334
// the fact that the result is bigger than a UINT32 is really irrelevant;
334
// the fact that the result is bigger than a UINT32 is really irrelevant;
335
335
// we can still play a stream for many many years...
336
336
return (UINT32)((t.tv_sec * 1000) + (t.tv_usec / 1000));
482
482
pPathNextPosition += ulBytesToCopy;
483
483
ulBytesLeft -= ulBytesToCopy;
486
486
SafeSprintf(pNextPath, 256, "DT_Codecs=%s", codecshome);
487
487
//print2stderr("Codec path %s\n", pNextPath );
488
488
ulBytesToCopy = strlen(pNextPath) + 1;
764
764
ppctrl[nNumPlayers]->pPlayer->QueryInterface(IID_IHXPreferences, (void**) &pPreferences);
765
765
ppctrl[nNumPlayers]->pHSPContext->Init(ppctrl[nNumPlayers]->pPlayer, pPreferences, pszGUID);
766
766
ppctrl[nNumPlayers]->pPlayer->SetClientContext(ppctrl[nNumPlayers]->pHSPContext);
767
767
HX_RELEASE(pPreferences);
769
769
ppctrl[nNumPlayers]->pPlayer->QueryInterface(IID_IHXErrorSinkControl, (void**) &pErrorSinkControl);
770
770
if (pErrorSinkControl)
774
774
pErrorSinkControl->AddErrorSink(pErrorSink, HXLOG_EMERG, HXLOG_INFO);
775
775
HX_RELEASE(pErrorSink);
778
778
HX_RELEASE(pErrorSinkControl);
780
780
// Get the Player2 interface
781
781
ppctrl[nNumPlayers]->pPlayer->QueryInterface(IID_IHXPlayer2, (void**) &ppctrl[nNumPlayers]->pPlayer2);
782
782
if (!ppctrl[nNumPlayers]->pPlayer2)
783
783
print2stderr("no player2 device\n");
785
785
// Get the Audio Player
786
786
ppctrl[nNumPlayers]->pPlayer->QueryInterface(IID_IHXAudioPlayer, (void**) &ppctrl[nNumPlayers]->pAudioPlayer);
787
787
if (ppctrl[nNumPlayers]->pAudioPlayer)
1007
HelixSimplePlayer::AUDIOAPI HelixSimplePlayer::getOutputSink()
1009
return m_outputsink;
1007
HelixSimplePlayer::AUDIOAPI HelixSimplePlayer::getOutputSink()
1009
return m_outputsink;
1012
void HelixSimplePlayer::setDevice( const char *dev )
1012
void HelixSimplePlayer::setDevice( const char *dev )
1014
1014
delete [] m_device;
1016
1016
int len = strlen(dev);
1017
1017
m_device = new char [len + 1];
1018
strcpy(m_device, dev);
1018
strcpy(m_device, dev);
1021
const char *HelixSimplePlayer::getDevice()
1021
const char *HelixSimplePlayer::getDevice()
1035
1035
//Check the environmental variable to let user overide default device.
1036
1036
char *pszOverrideName = getenv( "AUDIO" ); /* Flawfinder: ignore */
1037
1037
char szDevName[MAX_DEV_NAME]; /* Flawfinder: ignore */
1039
1039
// Use defaults if no environment variable is set.
1040
1040
if ( pszOverrideName && strlen(pszOverrideName)>0 )
1046
1046
SafeStrCpy( szDevName, "/dev/mixer", MAX_DEV_NAME );
1049
1049
// Open the audio device if it isn't already open
1050
1050
if ( m_nDevID < 0 )
1052
1052
m_nDevID = ::open( szDevName, O_WRONLY );
1055
1055
if ( m_nDevID < 0 )
1057
1057
print2stderr("Failed to open audio(%s)!!!!!!! Code is: %d errno: %d\n",
1058
1058
szDevName, m_nDevID, errno );
1060
1060
//Error opening device.
1067
1067
#ifdef USE_HELIX_ALSA
1070
1070
print2stderr("Opening ALSA mixer device PCM\n");
1072
1072
err = snd_mixer_open(&m_pAlsaMixerHandle, 0);
1074
1074
print2stderr("snd_mixer_open: %s\n", snd_strerror (err));
1078
1078
err = snd_mixer_attach(m_pAlsaMixerHandle, m_alsaDevice);
1080
1080
print2stderr("snd_mixer_attach: %s\n", snd_strerror (err));
1085
1085
err = snd_mixer_selem_register(m_pAlsaMixerHandle, NULL, NULL);
1087
1087
print2stderr("snd_mixer_selem_register: %s\n", snd_strerror (err));
1194
1194
err = snd_mixer_close(m_pAlsaMixerHandle);
1196
print2stderr("snd_mixer_close: %s\n", snd_strerror (err));
1196
print2stderr("snd_mixer_close: %s\n", snd_strerror (err));
1201
1201
m_pAlsaMixerHandle = NULL;
1214
1214
// it seems the master volume only gets reset on track change when using ALSA
1215
// sheez, I thought amaroK wasnt supposed to be a mixer??
1215
// sheez, I thought Amarok wasnt supposed to be a mixer??
1216
1216
// all this code is so that you can actually *use* a mixer and have it work
1217
1217
// the way you expect...
1218
1218
#ifdef USE_HELIX_ALSA
1227
1227
if (!m_pAlsaMasterMixerElem)
1228
1228
return nRetVolume;
1230
snd_mixer_elem_type_t type;
1230
snd_mixer_elem_type_t type;
1232
1232
type = snd_mixer_elem_get_type(m_pAlsaMasterMixerElem);
1234
1234
if (type == SND_MIXER_ELEM_SIMPLE)
1236
long volumeL, volumeR, min_volume, max_volume;
1236
long volumeL, volumeR, min_volume, max_volume;
1238
if(snd_mixer_selem_has_playback_volume(m_pAlsaMasterMixerElem) ||
1238
if(snd_mixer_selem_has_playback_volume(m_pAlsaMasterMixerElem) ||
1239
1239
snd_mixer_selem_has_playback_volume_joined(m_pAlsaMasterMixerElem))
1241
1241
err = snd_mixer_selem_get_playback_volume(m_pAlsaMasterMixerElem,
1242
SND_MIXER_SCHN_FRONT_LEFT,
1242
SND_MIXER_SCHN_FRONT_LEFT,
1245
1245
print2stderr("snd_mixer_selem_get_playback_volume (L): %s\n", snd_strerror (err));
1248
if ( snd_mixer_selem_is_playback_mono ( m_pAlsaMasterMixerElem ))
1248
if ( snd_mixer_selem_is_playback_mono ( m_pAlsaMasterMixerElem ))
1249
1249
volumeR = volumeL;
1252
1252
err = snd_mixer_selem_get_playback_volume(m_pAlsaMasterMixerElem,
1253
SND_MIXER_SCHN_FRONT_RIGHT,
1253
SND_MIXER_SCHN_FRONT_RIGHT,
1256
1256
print2stderr("snd_mixer_selem_get_playback_volume (R): %s\n", snd_strerror (err));
1262
1262
snd_mixer_selem_get_playback_volume_range(m_pAlsaMasterMixerElem,
1287
1287
if (!m_pAlsaMasterMixerElem)
1290
snd_mixer_elem_type_t type;
1290
snd_mixer_elem_type_t type;
1292
1292
type = snd_mixer_elem_get_type(m_pAlsaMasterMixerElem);
1295
1295
if (type == SND_MIXER_ELEM_SIMPLE)
1297
long volume, min_volume, max_volume, range;
1299
if(snd_mixer_selem_has_playback_volume(m_pAlsaMasterMixerElem) ||
1297
long volume, min_volume, max_volume, range;
1299
if(snd_mixer_selem_has_playback_volume(m_pAlsaMasterMixerElem) ||
1300
1300
snd_mixer_selem_has_playback_volume_joined(m_pAlsaMasterMixerElem))
1302
1302
snd_mixer_selem_get_playback_volume_range(m_pAlsaMasterMixerElem,
1306
1306
range = max_volume - min_volume;
1307
1307
volume = (long) (((double)vol / 100) * range + min_volume);
1310
1310
err = snd_mixer_selem_set_playback_volume( m_pAlsaMasterMixerElem,
1311
SND_MIXER_SCHN_FRONT_LEFT,
1311
SND_MIXER_SCHN_FRONT_LEFT,
1314
1314
print2stderr("snd_mixer_selem_set_playback_volume: %s\n", snd_strerror (err));
1318
1318
/* Set the right channel too */
1319
1319
err = snd_mixer_selem_set_playback_volume( m_pAlsaMasterMixerElem,
1320
SND_MIXER_SCHN_FRONT_RIGHT,
1320
SND_MIXER_SCHN_FRONT_RIGHT,
1323
1323
print2stderr("snd_mixer_selem_set_playback_volume: %s\n", snd_strerror (err));
1344
1344
int nVolume = 0;
1345
1345
int nLeftVolume = 0;
1346
1346
int nRightVolume = 0;
1348
1348
if (m_nDevID < 0 || (::ioctl( m_nDevID, MIXER_READ(HX_VOLUME), &nVolume) < 0))
1350
1350
print2stderr("ioctl fails when reading HW volume: mnDevID=%d, errno=%d\n", m_nDevID, errno);
1355
nLeftVolume = (nVolume & 0x000000ff);
1355
nLeftVolume = (nVolume & 0x000000ff);
1356
1356
nRightVolume = (nVolume & 0x0000ff00) >> 8;
1358
1358
//Which one to use? Average them?
1359
1359
nRetVolume = nLeftVolume ;
1367
1367
if (!m_pAlsaPCMMixerElem)
1368
1368
return nRetVolume;
1370
snd_mixer_elem_type_t type;
1370
snd_mixer_elem_type_t type;
1372
1372
type = snd_mixer_elem_get_type(m_pAlsaPCMMixerElem);
1374
1374
if (type == SND_MIXER_ELEM_SIMPLE)
1376
long volumeL, volumeR, min_volume, max_volume;
1376
long volumeL, volumeR, min_volume, max_volume;
1378
if(snd_mixer_selem_has_playback_volume(m_pAlsaPCMMixerElem) ||
1378
if(snd_mixer_selem_has_playback_volume(m_pAlsaPCMMixerElem) ||
1379
1379
snd_mixer_selem_has_playback_volume_joined(m_pAlsaPCMMixerElem))
1381
1381
err = snd_mixer_selem_get_playback_volume(m_pAlsaPCMMixerElem,
1382
SND_MIXER_SCHN_FRONT_LEFT,
1382
SND_MIXER_SCHN_FRONT_LEFT,
1385
1385
print2stderr("snd_mixer_selem_get_playback_volume (L): %s\n", snd_strerror (err));
1388
if ( snd_mixer_selem_is_playback_mono ( m_pAlsaPCMMixerElem ))
1388
if ( snd_mixer_selem_is_playback_mono ( m_pAlsaPCMMixerElem ))
1389
1389
volumeR = volumeL;
1392
1392
err = snd_mixer_selem_get_playback_volume(m_pAlsaPCMMixerElem,
1393
SND_MIXER_SCHN_FRONT_RIGHT,
1393
SND_MIXER_SCHN_FRONT_RIGHT,
1396
1396
print2stderr("snd_mixer_selem_get_playback_volume (R): %s\n", snd_strerror (err));
1402
1402
snd_mixer_selem_get_playback_volume_range(m_pAlsaPCMMixerElem,
1430
1430
//Set both left and right volumes.
1431
1431
nNewVolume = (vol & 0xff) | ((vol & 0xff) << 8);
1433
1433
if (::ioctl( m_nDevID, MIXER_WRITE(HX_VOLUME), &nNewVolume) < 0)
1434
1434
print2stderr("Unable to set direct HW volume\n");
1441
1441
if (!m_pAlsaPCMMixerElem)
1444
snd_mixer_elem_type_t type;
1444
snd_mixer_elem_type_t type;
1446
1446
type = snd_mixer_elem_get_type(m_pAlsaPCMMixerElem);
1449
1449
if (type == SND_MIXER_ELEM_SIMPLE)
1451
long volume, min_volume, max_volume, range;
1453
if(snd_mixer_selem_has_playback_volume(m_pAlsaPCMMixerElem) ||
1451
long volume, min_volume, max_volume, range;
1453
if(snd_mixer_selem_has_playback_volume(m_pAlsaPCMMixerElem) ||
1454
1454
snd_mixer_selem_has_playback_volume_joined(m_pAlsaPCMMixerElem))
1456
1456
snd_mixer_selem_get_playback_volume_range(m_pAlsaPCMMixerElem,
1460
1460
range = max_volume - min_volume;
1461
1461
volume = (long) (((double)vol / 100) * range + min_volume);
1464
1464
err = snd_mixer_selem_set_playback_volume( m_pAlsaPCMMixerElem,
1465
SND_MIXER_SCHN_FRONT_LEFT,
1465
SND_MIXER_SCHN_FRONT_LEFT,
1468
1468
print2stderr("snd_mixer_selem_set_playback_volume: %s\n", snd_strerror (err));
1472
1472
/* Set the right channel too */
1473
1473
err = snd_mixer_selem_set_playback_volume( m_pAlsaPCMMixerElem,
1474
SND_MIXER_SCHN_FRONT_RIGHT,
1474
SND_MIXER_SCHN_FRONT_RIGHT,
1477
1477
print2stderr("snd_mixer_selem_set_playback_volume: %s\n", snd_strerror (err));
1508
1508
if (ppctrl[playerIndex]->pszURL)
1509
1509
delete [] ppctrl[playerIndex]->pszURL;
1511
1511
// see if the file is already in the form of a url
1512
1512
char *tmp = strstr(file, "://");
1515
1515
char pszURLOrig[MAXPATHLEN];
1516
1516
const char* pszAddOn;
1518
1518
strcpy(pszURLOrig, file);
1519
1519
RemoveWrappingQuotes(pszURLOrig);
1520
1520
pszAddOn = "file://";
1522
1522
ppctrl[playerIndex]->pszURL = new char[strlen(pszURLOrig)+strlen(pszAddOn)+1];
1523
1523
if ( (len + strlen(pszAddOn)) < MAXPATHLEN )
1540
1540
ppctrl[playerIndex]->isLocal = islocal;
1542
print2stderr("opening %s on player %d, src cnt %d\n",
1542
print2stderr("opening %s on player %d, src cnt %d\n",
1543
1543
ppctrl[playerIndex]->pszURL, playerIndex, ppctrl[playerIndex]->pPlayer->GetSourceCount());
1545
1545
#ifdef __NOCROSSFADER__
1547
1547
if (HXR_OK == ppctrl[playerIndex]->pPlayer->OpenURL(ppctrl[playerIndex]->pszURL))
1549
print2stderr("opened player on %d src cnt %d\n", playerIndex, ppctrl[playerIndex]->pPlayer->GetSourceCount());
1549
print2stderr("opened player on %d src cnt %d\n", playerIndex, ppctrl[playerIndex]->pPlayer->GetSourceCount());
1550
1550
m_urlchanged = true;
1584
int HelixSimplePlayer::getPluginInfo(int index,
1585
const char *&description,
1586
const char *©right,
1584
int HelixSimplePlayer::getPluginInfo(int index,
1585
const char *&description,
1586
const char *©right,
1587
1587
const char *&moreinfourl) const
1589
1589
if (index < m_numPlugins)
2009
2009
// Read in the entire file
2010
2010
nNumRead = fread(pszBuffer, sizeof(char), readSize, pFile);
2011
2011
pszBuffer[nNumRead] = '\0';
2013
2013
// Store it for later parsing
2014
2014
m_pszGUIDList = new char[nNumRead + 1];
2015
2015
strcpy(m_pszGUIDList, pszBuffer); /* Flawfinder: ignore */
2027
2027
delete [] pszBuffer;
2029
2029
return bSuccess;
2033
void HelixSimplePlayer::addScopeBuf(struct DelayQueue *item, int playerIndex)
2033
void HelixSimplePlayer::addScopeBuf(struct DelayQueue *item, int playerIndex)
2035
2035
if (playerIndex >=0 && playerIndex < nNumPlayers)
2037
2037
pthread_mutex_lock(&ppctrl[playerIndex]->m_scope_m);
2039
2039
if (ppctrl[playerIndex]->scopebuftail)
2059
2059
if (playerIndex >=0 && playerIndex < nNumPlayers)
2061
2061
pthread_mutex_lock(&ppctrl[playerIndex]->m_scope_m);
2063
2063
struct DelayQueue *item = ppctrl[playerIndex]->scopebufhead;
2067
2067
ppctrl[playerIndex]->scopebufhead = item->fwd;
2069
2069
if (!ppctrl[playerIndex]->scopebufhead)
2070
2070
ppctrl[playerIndex]->scopebuftail = 0;
2073
2073
pthread_mutex_unlock(&ppctrl[playerIndex]->m_scope_m);
2081
int HelixSimplePlayer::peekScopeTime(unsigned long &t, int playerIndex)
2081
int HelixSimplePlayer::peekScopeTime(unsigned long &t, int playerIndex)
2083
2083
if (playerIndex >=0 && playerIndex < nNumPlayers)