bool CMusicChannelFMod::playStream() { if (FSOUND_Stream_GetOpenState(_MusicStream) == -3) { nlwarning("NLSOUND FMod Driver: stream failed to open. (file not found, out of memory or other error)"); FSOUND_Stream_Close(_MusicStream); _MusicStream = NULL; return false; } // Start playing if ((_MusicChannel = FSOUND_Stream_PlayEx(FSOUND_FREE, _MusicStream, NULL, true)) == -1) return false; // stereo pan (as reccomended) FSOUND_SetPan(_MusicChannel, FSOUND_STEREOPAN); // update volume int vol255 = (int)(_Gain * 255.0f); FSOUND_SetVolumeAbsolute(_MusicChannel, vol255); // Set a callback to know if stream has ended _CallBackEnded = false; FSOUND_Stream_SetEndCallback(_MusicStream, streamEndCallBack, static_cast<void *>(this)); // unpause FSOUND_SetPaused(_MusicChannel, false); return true; }
MUSIKEngine::Error FMODStreamOut::GetOpenStatus(MUSIKEngine::OpenStatus *pStatus) { if(!StreamPointer) { return MUSIKEngine::errUnknown; } int status = FSOUND_Stream_GetOpenState(StreamPointer); switch(status) { case 0: *pStatus = MUSIKEngine::OPENSTATUS_READY; break; case -1: return MUSIKEngine::errUnknown; break; case -3: *pStatus = MUSIKEngine::OPENSTATUS_OPENFAILED; break; case -2: case -4: case -5: *pStatus = MUSIKEngine::OPENSTATUS_OPENINPROGRESS; } return MUSIKEngine::errSuccess; }
/* [ [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; }
int CMusikPlayer::GetTime( int nType ) { if(_CurrentSongIsNetStream()) { MUSIKStream * p_NETSTREAM = NULL; if(m_ActiveStreams.GetCount() && m_ActiveStreams.Item( m_ActiveStreams.GetCount()-1 )) { p_NETSTREAM = m_ActiveStreams.Item( m_ActiveStreams.GetCount()-1 ); } else if (m_p_NETSTREAM_Connecting) { return m_NETSTREAM_read_percent; } int status = 0; if(p_NETSTREAM ) { m_NETSTREAM_last_read_percent = m_NETSTREAM_read_percent; status = _NetStreamStatusUpdate(p_NETSTREAM); int openstate = FSOUND_Stream_GetOpenState((FSOUND_STREAM*)p_NETSTREAM->GetStreamOut()->STREAM()); if( openstate == 0) { int off = p_NETSTREAM->GetTime(); int len = p_NETSTREAM->GetLengthMs(); if((status == FSOUND_STREAM_NET_ERROR) || (off >= len)) {// something is wrong, we try to restart the stream _PostPlayRestart(); } else m_bStreamIsWorkingStopWatchIsRunning = false;// everything is okay } else { // openstate is not okay if(m_bStreamIsWorkingStopWatchIsRunning && m_NETSTREAM_last_read_percent == m_NETSTREAM_read_percent && m_StreamIsWorkingStopWatch.Time() > 10 * 1000) // 10 sec { // stream is not working ( read percent did not change and FSOUND_Stream_GetOpenState failed)for 10 secs now m_bStreamIsWorkingStopWatchIsRunning = false; _PostPlayRestart(); } else { // stream is disturbed ,start watch ( if not already running) if(!m_bStreamIsWorkingStopWatchIsRunning) { m_NETSTREAM_last_read_percent = m_NETSTREAM_read_percent; m_StreamIsWorkingStopWatch.Start(); m_bStreamIsWorkingStopWatchIsRunning = true; } } } } return m_NETSTREAM_read_percent; } // no critical section here, because crossfader thread is stopped before m_ActiveStreams array is changed(add/remove) if(m_ActiveStreams.GetCount() == 0) m_nLastSongTime = 0; else m_nLastSongTime = m_ActiveStreams.Item( m_ActiveStreams.GetCount()-1 )->GetTime() ; if ( nType == FMOD_SEC ) m_nLastSongTime /= 1000; return m_nLastSongTime; }
int LLAudioStreamFMOD::getOpenState() { int open_state = FSOUND_Stream_GetOpenState(mInternetStream); return open_state; }