static jint CallToJavaStreamGetData(JNIEnv* e, jobject sourceLine, jbyteArray array, jint dataLength) { jint length; VTRACE2("CallToJavaStreamGetData, sourceLine: %lx, dataLength: %d\n", sourceLine, dataLength); length = (*e)->CallIntMethod(e, sourceLine, g_getDataMethodID, array, dataLength); VTRACE1("CallToJavaStreamGetData, sourceLine: %lx completed.\n", sourceLine); return length; }
JNIEXPORT jboolean JNICALL Java_com_sun_media_sound_MixerMidiChannel_nSetSolo(JNIEnv* e, jobject thisObj, jlong id, jint channelNumber, jboolean soloState) { char channels[16]; TRACE0("Java_com_sun_media_sound_MixerMidiChannel_nSetSolo.\n"); VTRACE1("-> id: %lu\n", id); VTRACE2("-> channelNumber: %d, soloState: %d\n", channelNumber, soloState); if (soloState) { GM_SoloChannel((GM_Song *) (INT_PTR) id, (INT16)channelNumber); } else { GM_UnsoloChannel((GM_Song *) (INT_PTR) id, (INT16)channelNumber); } GM_GetChannelSoloStatus((GM_Song *) (INT_PTR) id, channels); TRACE0("Java_com_sun_media_sound_MixerMidiChannel_nSetSolo completed.\n"); return ((jboolean)(channels[channelNumber])); }
static OPErr MixerSourceLineCallbackProc(void* context, GM_StreamMessage message, GM_StreamData* pAS) { JNIEnv* e = (JNIEnv*)context; VTRACE2("MixerSourceLineCallbackProc, context: %lx, message: %d\n", context, message); // for STREAM_CREATE, we just need to allocate the buffer. // we need to convert from gmData->dataLength (number of frames) to number of bytes. // $$kk: 03.15.98: this is the same calculation done by PV_GetSampleSizeInBytes. however, this // method is not available outside GenAudioStreams.c right now. if (message == STREAM_CREATE) { jint const byteCount = pAS->dataLength * pAS->channelSize * (pAS->dataBitSize / 8); VTRACE1("STREAM_CREATE: %lx\n", pAS->userReference); VTRACE3("STREAM_CREATE: byteCount = %d, dataLength = %lu, frameSize = %d.\n", byteCount, pAS->dataLength, (pAS->channelSize * (pAS->dataBitSize / 8)) ); pAS->pData = XNewPtr(byteCount); if (!pAS->pData) { ERROR1("MixerSourceLineCallbackProc: STREAM_CREATE: Failed to allocate %d bytes\n", byteCount); return MEMORY_ERR; } VTRACE1("STREAM_CREATE: %lx completed\n", pAS->userReference); } else if (message == STREAM_DESTROY) { VTRACE1("STREAM_DESTROY: %lx\n", pAS->userReference); CallToJavaStreamDestroy(e, (jobject)pAS->userReference); // $$kk: 12.21.98: for some reason, this causes the vm to crash some // random time later. so we have a memory leak here. i don't know // why we can't release the memory here.... // $$kk: 03.22.00: i am putting this code back in. the memory leak is // causing problems, and so far i have not been able to reproduce the // crash. the memory leak is reported in bug #4319431: "Memory leaks // on opening and closing source DataLines." if (pAS->pData) { XDisposePtr(pAS->pData); } VTRACE1("STREAM_DESTROY: %lx completed\n", pAS->userReference); } else if (message == STREAM_GET_DATA) { int length; int frameLengthInBytes = pAS->channelSize * (pAS->dataBitSize / 8); jbyteArray array = (jbyteArray)(*e)->GetObjectField(e, (jobject)pAS->userReference, g_dataArrayFieldID); if (array == NULL) { ERROR0("STREAM_GET_DATA: failed to get array\n"); return GENERAL_BAD; } // make the callback. // pAS->dataLength is the length in FRAMES. // length returned is length in FRAMES. length = (int)CallToJavaStreamGetData(e, (jobject)pAS->userReference, array, (jint)pAS->dataLength); // length will be -1 when the stream finishes if (length < 0) { VTRACE0("STREAM_GET_DATA: got negative length; stopping stream\n"); return STREAM_STOP_PLAY; } // get the relevant array elements // $$kk: 03.15.98: can we avoid this copy?? (*e)->GetByteArrayRegion(e, array, (jint)0, (jint)(length * frameLengthInBytes), (jbyte*)(pAS->pData)); // $$kk: 04.21.00: fix for bug #4332327: "JNI leaks local references on // keeping a SourceLine open for long." (*e)->DeleteLocalRef(e, array); // set dataLength to the number of frames read pAS->dataLength = length; VTRACE2("STREAM_GET_DATA: length: %d, pAS->dataLength: %lu\n", length, pAS->dataLength); VTRACE1("STREAM_GET_DATA: %lx completed\n", pAS->userReference); } else if (message == STREAM_START) { TRACE2("STREAM_START: stream: %lx, framePosition: %lu\n", pAS->userReference, pAS->startSample); CallToJavaStreamStart(e, (jobject)pAS->userReference); TRACE1("STREAM_START: %lx completed\n", pAS->userReference); } else if (message == STREAM_STOP) { TRACE2("STREAM_STOP: %lx, framePosition: %lu\n", pAS->userReference, pAS->startSample); CallToJavaStreamStop(e, (jobject)pAS->userReference); TRACE1("STREAM_STOP: %lx completed\n", pAS->userReference); } else if (message == STREAM_EOM) { TRACE2("STREAM_EOM: %lx, framePosition: %lu\n", pAS->userReference, pAS->startSample); CallToJavaStreamEOM(e, (jobject)pAS->userReference); TRACE1("STREAM_EOM: %lx completed\n", pAS->userReference); } else if (message == STREAM_ACTIVE) { TRACE2("STREAM_ACTIVE: %lx, framePosition: %lu\n", pAS->userReference, pAS->startSample); CallToJavaStreamActive(e, (jobject)pAS->userReference); TRACE1("STREAM_ACTIVE: %lx completed\n", pAS->userReference); } else if (message == STREAM_INACTIVE) { TRACE2("STREAM_INACTIVE: %lx, framePosition: %lu\n", pAS->userReference, pAS->startSample); CallToJavaStreamInactive(e, (jobject)pAS->userReference); TRACE1("STREAM_INACTIVE: %lx completed\n", pAS->userReference); } else { ERROR1("Bad message code in MixerSourceLineCallbackProc() : %d\n", message); return GENERAL_BAD; } return NO_ERR; }