MUSIKEngine::Error  FMODStreamOut::SetMetadataCallback(IMUSIKStreamOutDefault::IMetadataCallback *pCB)
{
    MUSIKEngine::Error err =IMUSIKStreamOutDefault::SetMetadataCallback(pCB);
    if(err != MUSIKEngine::errSuccess)
        return err;
    return StreamPointer && FSOUND_Stream_Net_SetMetadataCallback(StreamPointer, MetadataCallback, this) ? MUSIKEngine::errSuccess: MUSIKEngine::errUnknown;
}
int LLAudioStreamManagerFMOD::startStream()
{
	// We need a live and opened stream before we try and play it.
	if (!mInternetStream || getOpenState())
	{
		llwarns << "No internet stream to start playing!" << llendl;
		return -1;
	}

	// Make sure the stream is set to 2D mode.
	FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D);
	FSOUND_Stream_Net_SetMetadataCallback(mInternetStream, metadataCallback, this);
	return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true);
}
Exemple #3
0
/*
[
    [DESCRIPTION]

    [PARAMETERS]
 
    [RETURN_VALUE]

    [REMARKS]

    [SEE_ALSO]
]
*/
int main(int argc, char *argv[])
{
    FSOUND_STREAM *stream;
    int read_percent = 0, i, driver = 0, channel = -1, status = 0, openstate, bitrate;
    unsigned int flags;
    char s[256] = "";
    char key;


    if (FSOUND_GetVersion() < FMOD_VERSION)
    {
        printf("Error : You are using the wrong DLL version!  You should be using FMOD %.02f\n", FMOD_VERSION);
        return 1;
    }

    if ((argc < 2) || (strnicmp(argv[1], "http:", 5)))
    {
        printf("-------------------------------------------------------------\n");
        printf("FMOD netstream example.\n");
        printf("Copyright (c) Firelight Technologies Pty, Ltd, 1999-2004.\n");
        printf("-------------------------------------------------------------\n");
        printf("Syntax:  netstream <url>\n");
        printf("Example: netstream http://www.fmod.org/stream.mp3\n\n");
        return 1;
    }

#if defined(WIN32) || defined(_WIN64) || defined(__CYGWIN32__) || defined(__WATCOMC__)
    FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
#elif defined(__linux__)
    FSOUND_SetOutput(FSOUND_OUTPUT_OSS);
#endif

    // ==========================================================================================
    // SELECT DRIVER
    // ==========================================================================================
    printf("---------------------------------------------------------\n");    
    switch (FSOUND_GetOutput())
    {
        case FSOUND_OUTPUT_NOSOUND:    printf("NoSound");                    break;
        case FSOUND_OUTPUT_WINMM:      printf("Windows Multimedia Waveout"); break;
        case FSOUND_OUTPUT_DSOUND:     printf("Direct Sound");               break;
        case FSOUND_OUTPUT_A3D:        printf("A3D");                        break;
        case FSOUND_OUTPUT_OSS:        printf("Open Sound System");          break;
        case FSOUND_OUTPUT_ESD:        printf("Enlightenment Sound Daemon"); break;
        case FSOUND_OUTPUT_ALSA:       printf("ALSA");                       break;
    };
    printf(" Driver list\n");    
    printf("---------------------------------------------------------\n");    

    for (i=0; i < FSOUND_GetNumDrivers(); i++) 
    {
        printf("%d - %s\n", i+1, FSOUND_GetDriverName(i));
    }
    printf("---------------------------------------------------------\n");
    printf("Press a corresponding number or ESC to quit\n");

    do
    {
        key = getch();
        if (key == 27) exit(0);

        driver = key - '1';
    } while (driver < 0 || driver >= FSOUND_GetNumDrivers());

    FSOUND_SetDriver(driver);

    // ==========================================================================================
    // INITIALIZE
    // ==========================================================================================
    if (!FSOUND_Init(44100, 32, 0))
    {
        printf("Error!\n");
        printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
        FSOUND_Close();
        return 1;
    }

    /*
        Internet streams can work with a much smaller stream buffer than normal streams because they
        use another level of buffering on top of the stream buffer.
    */
    FSOUND_Stream_SetBufferSize(100);

    /*
        Here's where we set the size of the network buffer and some buffering parameters.
        In this case we want a network buffer of 64k, we want it to prebuffer 60% of that when we first
        connect, and we want it to rebuffer 80% of that whenever we encounter a buffer underrun.
    */
    FSOUND_Stream_Net_SetBufferProperties(64000, 60, 80);

    /*
        Open the stream using FSOUND_NONBLOCKING because the connect/buffer process might take a long time
    */
    stream = FSOUND_Stream_Open(argv[1], FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0);
    if (!stream)
    {
        printf("Error!\n");
        printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
        FSOUND_Close();
        return 1;
    }

    printf("\nPress ESC to quit...\n\n");
  
    key = 0;
    do
    {
        if (kbhit())
        {
            key = getch();
        }

        /*
            Play the stream if it's not already playing
        */
        if (channel < 0)
        {
            channel = FSOUND_Stream_PlayEx(FSOUND_FREE, stream, NULL, TRUE);
            FSOUND_SetPaused(channel, FALSE);

            if (channel != -1)
            {
                FSOUND_Stream_Net_SetMetadataCallback(stream, metacallback, 0);
            }
        }

        openstate = FSOUND_Stream_GetOpenState(stream);
        if ((openstate == -1) || (openstate == -3))
        {
            printf("\nERROR: failed to open stream!\n");
            printf("SERVER: %s\n", FSOUND_Stream_Net_GetLastServerStatus());
            break;
        }

        FSOUND_Stream_Net_GetStatus(stream, &status, &read_percent, &bitrate, &flags);

        /*
            Show how much of the net buffer is used and what the status is
        */
        if (metanum)
        {
            printf("%s - %s\n", artist, title);
            metanum = 0;
        }
        s[0] = 0;
        strncat(s, bar, (read_percent >> 1) + (read_percent & 1));
        strncat(s, nobar, (100 - read_percent) >> 1);
        printf("|%s| %d%%  %s\r", s, read_percent, status_str[status]);

        Sleep(16);
    
    } while (key != 27);

    printf("\n");

    FSOUND_Stream_Close(stream);
    FSOUND_Close();

    return 0;
}
bool CMusikPlayer::Play( size_t nItem, int nStartPos, int nFadeType )
{
	if((m_bSuppressAutomaticSongPicking == false) 
		&& (m_Playlist.GetCount() < (size_t)wxGetApp().Prefs.nAutoDJChooseSongsToPlayInAdvance) 
		&& ( MUSIK_PLAYMODE_AUTO_DJ == m_Playmode || MUSIK_PLAYMODE_AUTO_DJ_ALBUM == m_Playmode)
		)
	{
		if(m_Playlist.GetCount() == 0)
			nItem = 0;
		_AddRandomSongs();
		if(m_Playlist.GetCount() == 0)   // no songs could be chosen
		{
			m_Playing = false;
			return false;
		}
	}
	m_bSuppressAutomaticSongPicking = false;
	//--- check for an invalid playlist ---//
	if ( ( nItem >= m_Playlist.GetCount() ) || ( m_Playlist.GetCount() == 0 ) )
	{
		m_Playing = false;
		return false;
	}
	if (IsPlaying() && _CurrentSongIsNetStream())
	{	
		if(m_SongIndex ==  nItem )
		{
			return true; // already playing this stream
		}

//		_PostPlayRestart(); // will restart playing postponed
//		return true;
	}
	else if (_IsNETSTREAMConnecting())
	{
		return true;
	}

    CSongPath sFilename;
    std::auto_ptr<CMusikSong> pNewSong = m_Playlist.Item( nItem ).Song();
    sFilename = pNewSong->MetaData.Filename;

    if((pNewSong->MetaData.eFormat != MUSIK_FORMAT_NETSTREAM) && !sFilename.FileExists())
	{	// not a network stream
		// and
		// file does not exist
			wxMessageBox( _( "Cannot find file.\n Filename:" ) + sFilename.GetFullPath(), MUSIKAPPNAME_VERSION, wxICON_STOP );
			Stop();
			return false;
	}
	bool bNewSongStarted = (m_Playlist[nItem] != m_CurrentSong) && (nStartPos == 0);
	if(bNewSongStarted && IsPlaying())
	{
	  // player is currently playing, so we have to record history here, because Stop() is not 
	  // called between the playing of the songs of the playlist.
			wxGetApp().Library.RecordSongHistory(m_CurrentSong,GetTime(FMOD_MSEC));
	}
	//---------------------------------------------//
	//--- start with the basics					---//
	//---------------------------------------------//
	m_Stopping		= false;
	m_SongIndex		= nItem;
	m_CurrentSong	= m_Playlist.Item( m_SongIndex );
	//---------------------------------------------//
	//--- if there is already a fade in			---//
	//--- progress, then we need to abort it	---//
	//---------------------------------------------//
	SetCrossfadeType( nFadeType );

	//---------------------------------------------//
	//--- open a new stream and push it to the	---//
	//--- bottom of the m_ActiveStreams array	---//
	//---------------------------------------------//
	FSOUND_Stream_SetBufferSize( wxGetApp().Prefs.nSndBuffer );
	FMODEngine::eOpenMode om = _CurrentSongNeedsMPEGACCURATE() ? FMODEngine::OpenMode_MPEGACCURATE : FMODEngine::OpenMode_Default;
	m_SndEngine.SetOpenMode(om);

	MUSIKStream* pNewStream = m_SndEngine.OpenMedia( ( const char* )ConvFn2A( sFilename.GetFullPath() ));
	if(pNewStream == NULL)
	{
		wxMessageBox( _( "Playback will be stopped, because loading failed.\n Filename:" ) + sFilename.GetFullPath(), MUSIKAPPNAME_VERSION, wxICON_STOP );
		Stop(false);
		return false;
	}
	InitDSP();
	if(_CurrentSongIsNetStream()&& _IsNETSTREAMConnecting() == false)
	{
		ClearOldStreams(true);// clear all streams
		m_MetaDataSong = CMusikSong();
		m_MetaDataSong.MetaData.eFormat = MUSIK_FORMAT_NETSTREAM;
		m_p_NETSTREAM_Connecting = pNewStream;
		m_Playing = true;
		m_b_NETSTREAM_AbortConnect = false;
		bool bExit = false;
		do
		{
			int  openstate = FSOUND_Stream_GetOpenState((FSOUND_STREAM*)pNewStream->GetStreamOut()->STREAM());
			if ((openstate == -1) || (openstate == -3))
			{
				wxMessageBox(_("ERROR: failed to open stream:")+ ConvA2W(FSOUND_Stream_Net_GetLastServerStatus()));
				m_b_NETSTREAM_AbortConnect = true;
				break;
			}
			
		    switch(_NetStreamStatusUpdate(pNewStream))
			{
			case FSOUND_STREAM_NET_READY:
				if(openstate == 0)
					bExit = true;
				break;
			case FSOUND_STREAM_NET_ERROR:
				m_b_NETSTREAM_AbortConnect = true;
				break;
			}
			wxGetApp().Yield();

		} while (!bExit && !m_b_NETSTREAM_AbortConnect);
		m_p_NETSTREAM_Connecting = NULL;
		if( m_b_NETSTREAM_AbortConnect )
		{
			delete pNewStream;
			Stop(false);
			m_b_NETSTREAM_AbortConnect = false;
			return false;
		}
		
	}
	//---------------------------------------------//
	//--- start playback on the new stream on	---//
	//--- the designated channel.				---//
	//---------------------------------------------//
	int retries = 2;
	bool bPlaySucceeded = false;
	pNewStream->SetTime( nStartPos * 1000 );
	while( retries -- && (!bPlaySucceeded))
	{
		if(!pNewStream->Play())
		{
			wxCriticalSectionLocker lock(m_protectingStreamArrays);
			if(m_ActiveStreams.GetCount())
			{
				delete( m_ActiveStreams[0] );
				m_ActiveStreams.RemoveAt(0);
			}

		}
		else
			bPlaySucceeded = true;
	}
	if(!bPlaySucceeded)
	{
		wxMessageBox(_("Play failed, please try again."));
		wxLogDebug(wxT("play failed:%s"),(const wxChar *) ConvA2W(m_SndEngine.ErrorString()));
		delete pNewStream;
		Stop(false);
		return false;

	}
	if(_CurrentSongIsNetStream())
	{
		FSOUND_Stream_Net_SetMetadataCallback((FSOUND_STREAM*)pNewStream->GetStreamOut()->STREAM(), MetadataCallback, this);
	}
	pNewStream->SetVolume(  0.0 );
	m_Playing = true;
	m_Paused = false;
	if(g_FaderThread)
    	g_FaderThread->CrossfaderAbort();
	//---------------------------------------------//
	//--- update the global arrays containing	---//
	//--- active channels and streams			---//
	//---------------------------------------------//
	{
		wxCriticalSectionLocker lock(m_protectingStreamArrays);
		m_ActiveStreams.Add( pNewStream );
	}
	//---------------------------------------------//
	//--- playback has been started, update the	---//
	//--- user interface to reflect it			---//
	//---------------------------------------------//
    MusikPlayerEvent ev_start(this,wxEVT_MUSIKPLAYER_PLAY_START);
	ProcessEvent(ev_start);
    
	UpdateUI();//TODO: remove this. replace by event handling of playlistctrl etc.
	//---------------------------------------------//
	//--- record history in database			---//
	//---------------------------------------------//
	if(bNewSongStarted)
	{
        MusikPlayerEvent ev_songchange(this,wxEVT_MUSIKPLAYER_SONG_CHANGED);
        ProcessEvent(ev_songchange);
		wxGetApp().Library.UpdateItemLastPlayed	( m_CurrentSong );//TODO: replace by event handling of  wxEVT_MUSIKPLAYER_SONG_CHANGED in library
	}
	//---------------------------------------------//
	//--- if fading is not enabled, shut down	---//
	//--- all of the old channels, and set the	---//
	//--- active stream to full volume			---//
	//---------------------------------------------//
	if ( wxGetApp().Prefs.bFadeEnable == 0 || wxGetApp().Prefs.bGlobalFadeEnable == 0 )
	{
		if(pNewStream)
			pNewStream->SetVolume(1.0);
		ClearOldStreams();
	}

	//---------------------------------------------//
	//--- tell the listening thread its time to	---//
	//--- start fading							---//
	//---------------------------------------------//
	else if ( wxGetApp().Prefs.bFadeEnable && wxGetApp().Prefs.bGlobalFadeEnable )
		SetFadeStart();		
	return true;
}