示例#1
0
// Given a song pointer, this will attempt to free all memory related to the song: midi
// data, instruments, samples, etc. It can fail and will return STILL_PLAYING if
// midi data is still being accessed, or samples, or instruments.
//
// If you pass NULL, then this function will be called recursively will all songs
// currently playing.
OPErr GM_FreeSong(void *threadContext, GM_Song *pSong)
{
    OPErr	err;
    XPTR	midiData;

    err = NO_ERR;
    GM_EndSong(threadContext, pSong);
    if (pSong)
	{
	    GM_KillSongNotes(pSong);		// we must kill the notes because we are about to free
	    // instrument memory
	    if (pSong->processingSlice == FALSE)
		{
		    GM_PauseSong(pSong);
		    midiData = (XPTR)pSong->midiData;		// save midi pointer now
		    pSong->midiData = NULL;					// and disable midi decoder now, just
		    // in case the decoder thread comes to life
		    GM_SetCacheSamples(pSong, FALSE);
		    err = GM_UnloadSongInstruments(pSong);
		    if (err == NO_ERR)
			{
			    if (pSong->disposeSongDataWhenDone)
				{
				    XDisposePtr(midiData);
				}
			    XDisposePtr((XPTR)pSong->controllerCallback);

#if 0 && USE_CREATION_API == TRUE
			    if (pSong->pPatchInfo)
				{
				    PV_FreePatchInfo(pSong);	// must free before killing pSong pointer
				}
#endif

			    XDisposePtr((XPTR)pSong);
			}
		    else
			{
				//DebugStr("\pGM_FreeSong::GM_UnloadSongInstruments::STILL_PLAYING");
			}
		}
	    else
		{
		    //DebugStr("\pGM_FreeSong::STILL_PLAYING");
		    err = STILL_PLAYING;
		}
	}
    return err;
}
示例#2
0
JNIEXPORT void JNICALL
    Java_com_sun_media_sound_AbstractPlayer_nClose(JNIEnv* e, jobject thisObj, jlong id) {

    GM_Song *pSong = (GM_Song *) (INT_PTR) id;
    OPErr err;
    int waitTime;

    TRACE3("Java_com_sun_media_sound_AbstractPlayer_nClose: e: %lu, thisObj: %lu, pSong: %lu.\n", 
           e, thisObj, (UINT32) id);

    if (pSong) {
	    GM_KillSongNotes(pSong);
	    pSong->disposeSongDataWhenDone = TRUE;   // free our midi pointer
	    GM_PauseSong(pSong);
	    /* remove song from list of playing songs */
	    GM_RemoveFromSongsToPlay(pSong);
	    /* set to impossible scan mode to disable processing */
	    pSong->AnalyzeMode = (ScanMode) -1;
	    /* fix for 4795377: closing sequencer sometimes crashes the VM */
	    QGM_ClearSongFromQueue(pSong);
	    
	    /* wait until there was at least one mixer slice 
	     * processed so that the song notes are really 
	     * not used anymore
	     */
	    waitTime = HAE_GetSliceTimeInMicroseconds()/1000 + 5;
	    TRACE1("nClose: waiting %d millis to process GM_KillSongNotes...\n", waitTime);
	    SleepMillisInJava(e, waitTime);
	    
	    do {
		/* this may fail - wait until it was able to kill the song */
		err = GM_FreeSong((void *)e, pSong);
		if (err == STILL_PLAYING) {
		    ERROR0("nClose: STILL_PLAYING! wait 5 millis...\n");
		    SleepMillisInJava(e, 5);
		} else if (err != NO_ERR) {
		    ERROR1("nClose: GM_FreeSong returned error code: %d\n", err);
		}
	    } while (err == STILL_PLAYING);

	} else {
		ERROR0("Java_com_sun_media_sound_AbstractPlayer_nClose: pSong is NULL\n");
	    }

    TRACE0("Java_com_sun_media_sound_AbstractPlayer_nClose completed.\n");
}
示例#3
0
JNIEXPORT void JNICALL
    Java_com_sun_media_sound_MixerSynth_nDestroySynthesizer(JNIEnv* e, jobject thisObj, jlong id) 
{

    GM_Song			*pSong = (GM_Song *) (INT_PTR) id;

    TRACE0("Java_com_sun_media_sound_MixerSynth_nDestroySynthesizer.\n");

    if (pSong) {

	GM_KillSongNotes(pSong);
	pSong->disposeSongDataWhenDone = TRUE;   // free our midi pointer
	GM_FreeSong((void *)e, pSong);

    } else {

	ERROR0("pSong is NULL\n");
    }

    TRACE0("Java_com_sun_media_sound_MixerSynth_nDestroySynthesizer completed.\n");
}