/** * Starts playing a new song. * * @param filename Path to a MIDI file. */ void MusicDriver_QtMidi::PlaySong(const MusicSongInfo &song) { if (!_quicktime_started) return; std::string filename = MidiFile::GetSMFFile(song); if (filename.empty()) return; DEBUG(driver, 2, "qtmidi: trying to play '%s'", filename.c_str()); switch (_quicktime_state) { case QT_STATE_PLAY: StopSong(); DEBUG(driver, 3, "qtmidi: previous tune stopped"); FALLTHROUGH; case QT_STATE_STOP: DisposeMovie(_quicktime_movie); DEBUG(driver, 3, "qtmidi: previous tune disposed"); _quicktime_state = QT_STATE_IDLE; FALLTHROUGH; case QT_STATE_IDLE: LoadMovieForMIDIFile(filename.c_str(), &_quicktime_movie); SetMovieVolume(_quicktime_movie, VOLUME); StartMovie(_quicktime_movie); _quicktime_state = QT_STATE_PLAY; } DEBUG(driver, 3, "qtmidi: playing '%s'", filename.c_str()); }
// // MusicEvents // Called in the event loop to keep track of MIDI music // void MIDI_Update (void) { if (midiTrack) { // pOx - adjust volume if changed if (old_volume != bgmvolume.value) MIDI_SetVolume (&bgmvolume); // Let QuickTime get some time MoviesTask (midiTrack, 0); // If this song is looping, restart it if (IsMovieDone (midiTrack)) { if (bLooped) { GoToBeginningOfMovie (midiTrack); StartMovie (midiTrack); } else { DisposeMovie (midiTrack); midiTrack = NULL; } } } }
void platformStartSound (long theSound) { #ifdef QuickTimeInstalled // start giving processing time to the sound player StartMovie((Movie)theSound); #endif // QuickTimeInstalled }
//------------------------------------------------------------ void ofQuicktimeSoundPlayer::setPaused(bool bP){ if (getIsPlaying() == true){ bPaused = bP; if (bP == true){ StopMovie(soundToPlay); } else { StartMovie(soundToPlay); } } }
// TODO: this is just a test at the moment... needs to be fixed up and work with memory checking... // void ofQuicktimeSoundPlayer::tryMultiPlay(){ //soundToPlay; //TODO: error checking here! TimeValue srcMovDuration; OSErr err = noErr; Handle audioFileDataRef; OSType audioFileDataRefType; short i, resID = 0; Movie tempMovie; // initialize our movie tempMovie = nil; // create a temporary movie -- we'll add // references to the audio file to this movie tempMovie = NewMovie(newMovieActive); assert(tempMovie != nil); srcMovDuration = GetMovieDuration(soundToPlay); // add multiple references to our audio file // Note: // by not calling BeginMediaEdits/EndMediaEdits // we are telling QuickTime to *not* copy the // actual data - this will give us only references // to the data which are small // add a reference to the source audio file to // our temporary movie err = InsertMovieSegment ( soundToPlay, // our audio file tempMovie, // temporary movie 0, srcMovDuration, GetMovieDuration(tempMovie) ); //printf("here \n"); // for completeness we'll copy the movie settings // from the source file err = CopyMovieSettings(soundToPlay, tempMovie); GoToBeginningOfMovie(tempMovie); StartMovie(tempMovie); soundsForMultiPlay.push_back(tempMovie); //TODO: copy speed, volume, pan settings to this movie? }
OSErr QTDR_PlayMovieFromRAM (Movie theMovie) { WindowPtr myWindow = NULL; Rect myBounds = {50, 50, 100, 100}; Rect myRect; StringPtr myTitle = QTUtils_ConvertCToPascalString(kWindowTitle); OSErr myErr = memFullErr; myWindow = NewCWindow(NULL, &myBounds, myTitle, false, 0, (WindowPtr)-1, false, 0); if (myWindow == NULL) goto bail; myErr = noErr; MacSetPort((GrafPtr)GetWindowPort(myWindow)); GetMovieBox(theMovie, &myRect); MacOffsetRect(&myRect, -myRect.left, -myRect.top); SetMovieBox(theMovie, &myRect); if (!EmptyRect(&myRect)) SizeWindow(myWindow, myRect.right, myRect.bottom, false); else SizeWindow(myWindow, 200, 0, false); MacShowWindow(myWindow); SetMovieGWorld(theMovie, GetWindowPort(myWindow), NULL); GoToBeginningOfMovie(theMovie); MoviesTask(theMovie, 0); StartMovie(theMovie); myErr = GetMoviesError(); if (myErr != noErr) goto bail; while (!IsMovieDone(theMovie)) MoviesTask(theMovie, 0); bail: free(myTitle); if (theMovie != NULL) DisposeMovie(theMovie); if (myWindow != NULL) DisposeWindow(myWindow); return(myErr); }
void wxOSXQuickTimeSoundData::SoundTask() { if(IsMovieDone(m_movie)) { if (m_flags & wxSOUND_LOOP) { StopMovie(m_movie); GoToBeginningOfMovie(m_movie); StartMovie(m_movie); } else Stop(); } else MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie }
void MIDI_Pause(int mode) { if (!midiTrack) return; if ((mode == MIDI_TOGGLE_PAUSE && bPaused) || mode == MIDI_ALWAYS_RESUME) { StartMovie (midiTrack); bPaused = false; } else { StopMovie (midiTrack); bPaused = true; } }
// ---------------------------------------------------------------------------- void ofQuicktimeSoundPlayer::play(){ // TODO: some logic in play needs work // if it's a looping sound, we should try to kill it, no? // or else people will have orphan channels that are looping if (bLoop == true){ //FMOD_Channel_Stop(channel); } // if the sound is not set to multiplay, then stop the current, // before we start another if (!bMultiPlay){ ////FMOD_Channel_Stop(channel); } GoToBeginningOfMovie(soundToPlay); StartMovie(soundToPlay); if (speed == 0){ bIWasPlayingAndMySpeedWasSetToZero = true; } else { bIWasPlayingAndMySpeedWasSetToZero = false; } ////FMOD_System_PlaySound(sys, ////FMOD_CHANNEL_FREE, sound, bPaused, &channel); ////FMOD_Channel_GetFrequency(channel, &internalFreq); //FMOD_Channel_SetVolume(channel,volume); //FMOD_Channel_SetPan(channel,pan); //FMOD_Channel_SetFrequency(channel, internalFreq * speed); //FMOD_Channel_SetMode(channel, (bLoop == true) ? //FMOD_LOOP_NORMAL : //FMOD_LOOP_OFF); //fmod update() should be called every frame - according to the docs. //we have been using fmod without calling it at all which resulted in channels not being able //to be reused. we should have some sort of global update function but putting it here //solves the channel bug //FMOD_System_Update(sys); }
void Notify() { if (m_pbPlaying && !*m_pbPlaying) { Shutdown(); } if(IsMovieDone(m_movie)) { if (!m_bLoop) Shutdown(); else { StopMovie(m_movie); GoToBeginningOfMovie(m_movie); StartMovie(m_movie); } } else MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie }
/* * PsychQTPlaybackRate() - Start- and stop movieplayback, set playback parameters. * * moviehandle = Movie to start-/stop. * playbackrate = zero == Stop playback, non-zero == Play movie with spec. rate, * e.g., 1 = forward, 2 = double speed forward, -1 = backward, ... * loop = 0 = Play once. 1 = Loop, aka rewind at end of movie and restart. * soundvolume = 0 == Mute sound playback, between 0.0 and 1.0 == Set volume to 0 - 100 %. * Returns Number of dropped frames to keep playback in sync. */ int PsychQTPlaybackRate(int moviehandle, double playbackrate, int loop, double soundvolume) { int dropped = 0; Movie theMovie; if (moviehandle < 0 || moviehandle >= PSYCH_MAX_MOVIES) { PsychErrorExitMsg(PsychError_user, "Invalid moviehandle provided!"); } // Fetch references to objects we need: theMovie = movieRecordBANK[moviehandle].theMovie; if (theMovie == NULL) { PsychErrorExitMsg(PsychError_user, "Invalid moviehandle provided. No movie associated with this handle !!!"); } if (playbackrate != 0) { // Start playback of movie: SetMovieAudioMute(theMovie, (soundvolume==0) ? TRUE : FALSE, 0); SetMovieVolume(theMovie, (short) (soundvolume * 255.0)); movieRecordBANK[moviehandle].loopflag = loop; movieRecordBANK[moviehandle].last_pts = -1.0; movieRecordBANK[moviehandle].nr_droppedframes = 0; SetMoviePreferredRate(theMovie, FloatToFixed(playbackrate)); StartMovie(theMovie); MoviesTask(theMovie, 10000); } else { // Stop playback of movie: StopMovie(theMovie); QTVisualContextTask(movieRecordBANK[moviehandle].QTMovieContext); // Output count of dropped frames: if ((dropped=movieRecordBANK[moviehandle].nr_droppedframes) > 0) { if (PsychPrefStateGet_Verbosity()>2) printf("PTB-INFO: Movie playback had to drop %i frames of movie %i to keep playback in sync.\n", movieRecordBANK[moviehandle].nr_droppedframes, moviehandle); } } return(dropped); }
bool wxSound::DoPlay(unsigned flags) const { Stop(); Movie movie; switch(m_type) { case wxSound_MEMORY: { if (!wxInitQT()) return false; Handle myHandle, dataRef = nil; MovieImportComponent miComponent; Track targetTrack = nil; TimeValue addedDuration = 0; long outFlags = 0; OSErr err; ComponentResult result; myHandle = NewHandleClear((Size)m_waveLength); BlockMove(m_hSnd, *myHandle, m_waveLength); err = PtrToHand(&myHandle, &dataRef, sizeof(Handle)); if (memcmp(&m_hSnd[8], "WAVE", 4) == 0) miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeWave); else if (memcmp(&m_hSnd[8], "AIFF", 4) == 0) miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFF); else if (memcmp(&m_hSnd[8], "AIFC", 4) == 0) miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFC); else { wxLogSysError(wxT("wxSound - Location in memory does not contain valid data")); return false; } movie = NewMovie(0); result = MovieImportDataRef(miComponent, dataRef, HandleDataHandlerSubType, movie, nil, &targetTrack, nil, &addedDuration, movieImportCreateTrack, &outFlags); if (result != noErr) { wxLogSysError(wxString::Format(wxT("Couldn't import movie data\nError:%i"), (int)result)); } SetMovieVolume(movie, kFullVolume); GoToBeginningOfMovie(movie); DisposeHandle(myHandle); } break; case wxSound_RESOURCE: { SoundComponentData data; unsigned long numframes, offset; ParseSndHeader((SndListHandle)m_hSnd, &data, &numframes, &offset); //m_waveLength = numFrames * data.numChannels; SndChannelPtr pSndChannel; SndNewChannel(&pSndChannel, sampledSynth, initNoInterp + (data.numChannels == 1 ? initMono : initStereo), NULL); if(SndPlay(pSndChannel, (SndListHandle) m_hSnd, flags & wxSOUND_ASYNC ? 1 : 0) != noErr) return false; if (flags & wxSOUND_ASYNC) { lastSoundTimer = ((wxSMTimer*&)m_pTimer) = new wxSMTimer(pSndChannel, m_hSnd, flags & wxSOUND_LOOP ? 1 : 0, &lastSoundIsPlaying); lastSoundIsPlaying = true; ((wxTimer*)m_pTimer)->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS); } else SndDisposeChannel(pSndChannel, TRUE); return true; } break; case wxSound_FILE: { if (!wxInitQT()) return false; OSErr err = noErr ; Handle dataRef = NULL; OSType dataRefType; err = QTNewDataReferenceFromFullPathCFString(wxMacCFStringHolder(m_sndname,wxLocale::GetSystemEncoding()), (UInt32)kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType); wxASSERT(err == noErr); if (NULL != dataRef || err != noErr) { err = NewMovieFromDataRef( &movie, newMovieDontAskUnresolvedDataRefs , NULL, dataRef, dataRefType ); wxASSERT(err == noErr); DisposeHandle(dataRef); } if (err != noErr) { wxLogSysError( wxString::Format(wxT("wxSound - Could not open file: %s\nError:%i"), m_sndname.c_str(), err ) ); return false; } } break; default: return false; }//end switch(m_type) //Start the movie! StartMovie(movie); if (flags & wxSOUND_ASYNC) { //Start timer and play movie asyncronously lastSoundTimer = ((wxQTTimer*&)m_pTimer) = new wxQTTimer(movie, flags & wxSOUND_LOOP ? 1 : 0, &lastSoundIsPlaying); lastSoundIsPlaying = true; ((wxQTTimer*)m_pTimer)->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS); } else { wxASSERT_MSG(!(flags & wxSOUND_LOOP), wxT("Can't loop and play syncronously at the same time")); //Play movie until it ends, then exit //Note that due to quicktime caching this may not always //work 100% correctly while (!IsMovieDone(movie)) MoviesTask(movie, 1); DisposeMovie(movie); } return true; }
bool wxOSXQuickTimeSoundData::Play(unsigned flags) { if ( m_movie ) Stop(); m_flags = flags; if (!wxInitQT()) return false; if( m_soundHandle ) { Handle dataRef = nil; MovieImportComponent miComponent; Track targetTrack = nil; TimeValue addedDuration = 0; long outFlags = 0; OSErr err; ComponentResult result; err = PtrToHand(&m_soundHandle, &dataRef, sizeof(Handle)); HLock(m_soundHandle); if (memcmp(&(*m_soundHandle)[8], "WAVE", 4) == 0) miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeWave); else if (memcmp(&(*m_soundHandle)[8], "AIFF", 4) == 0) miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFF); else if (memcmp(&(*m_soundHandle)[8], "AIFC", 4) == 0) miComponent = OpenDefaultComponent(MovieImportType, kQTFileTypeAIFC); else { HUnlock(m_soundHandle); wxLogSysError(wxT("wxSound - Location in memory does not contain valid data")); return false; } HUnlock(m_soundHandle); m_movie = NewMovie(0); result = MovieImportDataRef(miComponent, dataRef, HandleDataHandlerSubType, m_movie, nil, &targetTrack, nil, &addedDuration, movieImportCreateTrack, &outFlags); if (result != noErr) { wxLogSysError(wxString::Format(wxT("Couldn't import movie data\nError:%i"), (int)result)); } SetMovieVolume(m_movie, kFullVolume); GoToBeginningOfMovie(m_movie); } else { OSErr err = noErr ; Handle dataRef = NULL; OSType dataRefType; err = QTNewDataReferenceFromFullPathCFString(wxCFStringRef(m_sndname,wxLocale::GetSystemEncoding()), (UInt32)kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType); wxASSERT(err == noErr); if (NULL != dataRef || err != noErr) { err = NewMovieFromDataRef( &m_movie, newMovieDontAskUnresolvedDataRefs , NULL, dataRef, dataRefType ); wxASSERT(err == noErr); DisposeHandle(dataRef); } if (err != noErr) { wxLogSysError( wxString::Format(wxT("wxSound - Could not open file: %s\nError:%i"), m_sndname.c_str(), err ) ); return false; } } //Start the m_movie! StartMovie(m_movie); if (flags & wxSOUND_ASYNC) { CreateAndStartTimer(); } else { wxASSERT_MSG(!(flags & wxSOUND_LOOP), wxT("Can't loop and play syncronously at the same time")); //Play movie until it ends, then exit //Note that due to quicktime caching this may not always //work 100% correctly while (!IsMovieDone(m_movie)) MoviesTask(m_movie, 1); DoStop(); } return true; }
void PlaySound_QuickTime(const char *cSoundFilename) { int err; Str255 pSoundFilename; /* file pathname in Pascal-string format */ FSSpec fsSoundFile; /* movie file location descriptor */ short resRefNum; /* open movie file reference */ if (!fQTInitialised) { pthread_mutex_init(&mutexQTAccess, NULL); ListCreate(&movielist); fQTInitialised = TRUE; } /* QuickTime is NOT reentrant in Mac OS (it is in MS Windows!) */ pthread_mutex_lock(&mutexQTAccess); EnterMovies(); /* can be called multiple times */ err = NativePathNameToFSSpec(cSoundFilename, &fsSoundFile, 0); if (err != 0) { outputf(_("PlaySound_QuickTime: error #%d, can't find %s.\n"), err, cSoundFilename); } else { /* open movie (WAV or whatever) file */ err = OpenMovieFile(&fsSoundFile, &resRefNum, fsRdPerm); if (err != 0) { outputf(_("PlaySound_QuickTime: error #%d opening %s.\n"), err, cSoundFilename); } else { /* create movie from movie file */ Movie *movie = (Movie *) malloc(sizeof(Movie)); err = NewMovieFromFile(movie, resRefNum, NULL, NULL, 0, NULL); CloseMovieFile(resRefNum); if (err != 0) { outputf(_("PlaySound_QuickTime: error #%d reading %s.\n"), err, cSoundFilename); } else { /* reset movie timebase */ TimeRecord t = { 0 }; t.base = GetMovieTimeBase(*movie); SetMovieTime(*movie, &t); /* add movie to list of running movies */ ListInsert(&movielist, movie); /* run movie */ StartMovie(*movie); } } } pthread_mutex_unlock(&mutexQTAccess); if (!fQTPlaying) { /* launch playing thread if necessary */ int err; pthread_t qtthread; fQTPlaying = TRUE; err = pthread_create(&qtthread, 0L, Thread_PlaySound_QuickTime, NULL); if (err == 0) pthread_detach(qtthread); else fQTPlaying = FALSE; } }
void MIDI_Play (const char *Name) { FILE *midiFile; char midiName[MAX_OSPATH], tempName[MAX_QPATH]; OSErr err; FSSpec midiSpec; FSRef midiRef; short midiRefNum; if (!bMidiInited) //don't try to play if there is no midi return; MIDI_Stop(); if (!Name || !*Name) { Sys_Printf("no midi music to play\n"); return; } q_snprintf (tempName, sizeof(tempName), "%s.%s", Name, "mid"); FS_OpenFile (va("%s/%s", "midi", tempName), &midiFile, false); if (!midiFile) { Con_Printf("music file %s not found\n", tempName); return; } else { if (file_from_pak) { int ret; Con_Printf("Extracting %s from pakfile\n", tempName); q_snprintf (midiName, sizeof(midiName), "%s/%s.%s", host_parms->userdir, TEMP_MUSICNAME, "mid"); ret = FS_CopyFromFile (midiFile, midiName, fs_filesize); fclose (midiFile); if (ret != 0) { Con_Printf("Error while extracting from pak\n"); return; } } else /* use the file directly */ { fclose (midiFile); q_snprintf (midiName, sizeof(midiName), "%s/%s/%s", fs_filepath, "midi", tempName); } } // converting path to FSSpec. found in CarbonCocoaIntegration.pdf: // page 27, Obtaining an FSSpec Structure err = FSPathMakeRef ((UInt8*)midiName, &midiRef, NULL); if (err != noErr) { Con_Printf ("MIDI: FSPathMakeRef: error while opening %s\n", midiName); return; } err = FSGetCatalogInfo (&midiRef, kFSCatInfoNone, NULL, NULL, &midiSpec, NULL); if (err != noErr) { Con_Printf ("MIDI: FSGetCatalogInfo: error while opening %s\n", midiName); return; } err = OpenMovieFile (&midiSpec, &midiRefNum, fsRdPerm); if (err != noErr) { Con_Printf ("MIDI: OpenMovieStream: error opening midi file\n"); return; } err = NewMovieFromFile (&midiTrack, midiRefNum, NULL, NULL, newMovieActive, NULL); if (err != noErr || !midiTrack) { Con_Printf ("MIDI: QuickTime error in creating stream.\n"); return; } GoToBeginningOfMovie (midiTrack); PrerollMovie (midiTrack, 0, 0); // pOx - set initial volume MIDI_SetVolume (&bgmvolume); StartMovie (midiTrack); Con_Printf ("Started midi music %s\n", tempName); }
void quicktime_player::start() { if (m->playing == 0) StartMovie(m->movie); ++m->playing; }