// **** Audio card support // Aquire and enabled audio card // return 0 if ok, -1 if failed int HAE_AquireAudioCard(void *context, unsigned long sampleRate, unsigned long channels, unsigned long bits) { int flag; long bufferSize; short int bufferTime; flag = 0; g_activeDoubleBuffer = FALSE; g_shutDownDoubleBuffer = TRUE; g_audioFramesToGenerate = HAE_GetMaxSamplePerSlice(); // get number of frames per sample rate slice g_synthFramesPerBlock = HAE_FRAMES_PER_BLOCK; bufferTime = (HAE_GetSliceTimeInMicroseconds() / 1000) * g_synthFramesPerBlock; if (bits == 8) { bufferSize = (sizeof(char) * g_audioFramesToGenerate); } else { bufferSize = (sizeof(short int) * g_audioFramesToGenerate); } bufferSize *= channels; g_audioByteBufferSize = bufferSize; // try and configure card to match our audio output g_waveDevice = R0CARD_AcquireSoundCard(sampleRate, channels, bits, bufferTime, &g_audioByteBufferSize, PV_AudioHardwareCallback); if (g_waveDevice) { g_shutDownDoubleBuffer = FALSE; g_activeDoubleBuffer = TRUE; // must enable process, before thread begins flag = 0; // ok } else { flag = -1; // failed; HAE_ReleaseAudioCard(context); } return flag; }
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"); }
/* can be used as time stamp for interactive MIDI events */ INT64 XGetRealTimeSyncCount() { INT64 ret = g_checkpointSyncCount + (XMicroseconds() - g_checkpointMicros) + (HAE_GetSliceTimeInMicroseconds() * HAE_GetAudioBufferCount()); return ret; }