📄 org_tritonus_lowlevel_alsa_asequencer0.c
字号:
panValues[5] = pEvent->source.port; panValues[6] = pEvent->dest.client; panValues[7] = pEvent->dest.port; if ((pEvent->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_TICK) { palValues[0] = pEvent->time.tick; } else // time { palValues[0] = (jlong) pEvent->time.time.tv_sec * (jlong) 1E9 + (jlong) pEvent->time.time.tv_nsec; } switch (pEvent->type) { case SND_SEQ_EVENT_NOTE: case SND_SEQ_EVENT_NOTEON: case SND_SEQ_EVENT_NOTEOFF: panValues[8] = pEvent->data.note.channel; panValues[9] = pEvent->data.note.note; panValues[10] = pEvent->data.note.velocity; panValues[11] = pEvent->data.note.off_velocity; panValues[12] = pEvent->data.note.duration; break; case SND_SEQ_EVENT_KEYPRESS: case SND_SEQ_EVENT_CONTROLLER: case SND_SEQ_EVENT_PGMCHANGE: case SND_SEQ_EVENT_CHANPRESS: case SND_SEQ_EVENT_PITCHBEND: case SND_SEQ_EVENT_CONTROL14: case SND_SEQ_EVENT_NONREGPARAM: case SND_SEQ_EVENT_REGPARAM: panValues[8] = pEvent->data.control.channel; panValues[9] = pEvent->data.control.param; panValues[10] = pEvent->data.control.value; break; case SND_SEQ_EVENT_USR9: /* * Processing this event includes deleting a global * object reference (see comments in sendObjectEvent()). * Since this must happen only one per reference and the * sender of this event only aquires one reference, there * must be only one receiver of this event deleting the * reference. * The programmer is responsible for this. Other receivers * than the dedicated one must pass null or an empty * array for the object array, so that processing of * these events does not happen for the other receivers. */ if (aObjValues != NULL) { break; } nLength = (*env)->GetArrayLength(env, aObjValues); if (nLength < 1) { break; // throwRuntimeException(env, "array does not have enough elements (1 required)"); } /* * There is a potential pitfal here. If on a 64-bit * machine jobject is a 64-bit pointer and the * architecture allows only 64-bit-aligned access, this * may result in an error since the data in raw32 events * is only 32-bit-aligned. */ objectRef = *((jobject*) pEvent->data.raw32.d); (*env)->SetObjectArrayElement(env, aObjValues, 0, objectRef); (*env)->DeleteGlobalRef(env, objectRef); break; case SND_SEQ_EVENT_SYSEX: case SND_SEQ_EVENT_BOUNCE: case SND_SEQ_EVENT_USR_VAR0: case SND_SEQ_EVENT_USR_VAR1: case SND_SEQ_EVENT_USR_VAR2: case SND_SEQ_EVENT_USR_VAR3: case SND_SEQ_EVENT_USR_VAR4: { jbyteArray abData; abData = (*env)->NewByteArray(env, pEvent->data.ext.len); if (abData == NULL) { throwRuntimeException(env, "NewByteArray failed"); } (*env)->SetByteArrayRegion(env, abData, 0, pEvent->data.ext.len, pEvent->data.ext.ptr); nLength = (*env)->GetArrayLength(env, aObjValues); if (nLength < 1) { throwRuntimeException(env, "array does not have enough elements (1 required)"); } (*env)->SetObjectArrayElement(env, aObjValues, 0, abData); } break; } if (bIsCopyI == JNI_TRUE) { (*env)->ReleaseIntArrayElements(env, anValues, panValues, 0); } if (bIsCopyL == JNI_TRUE) { (*env)->ReleaseLongArrayElements(env, alValues, palValues, 0); } if ((pEvent->flags & SND_SEQ_EVENT_LENGTH_MASK) == SND_SEQ_EVENT_LENGTH_VARUSR) { byteArray = (*env)->NewByteArray(env, pEvent->data.ext.len); if (byteArray == NULL) { throwRuntimeException(env, "NewByteArray failed"); } (*env)->SetByteArrayRegion(env, byteArray, 0, pEvent->data.ext.len, pEvent->data.ext.ptr); (*env)->SetObjectArrayElement(env, aObjValues, 0, byteArray); } // TODO: should events be freed with snd_seq_free_event()? return JNI_TRUE;}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: getNextClientInfo * Signature: (I[I[Ljava/lang/String;)I */JNIEXPORT jint JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_getNextClientInfo(JNIEnv *env, jobject obj, jint nClient, jintArray anValues, jobjectArray astrValues){ snd_seq_client_info_t clientInfo; snd_seq_t* seq = getNativeSeq(env, obj); int nReturn; memset(&clientInfo, 0, sizeof(clientInfo)); clientInfo.client = nClient; nReturn = snd_seq_query_next_client(seq, &clientInfo); // printf("return: %d\n", nReturn); // perror("abc"); // -2 (no such file or directory): returned when no more client is available if (nReturn < 0/* && nReturn != -2*/) { // throwRuntimeException(env, "snd_seq_query_next_client failed"); } else { fillClientInfoArrays(env, obj, &clientInfo, anValues, astrValues); } return (jint) nReturn;}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: getNextPortInfo * Signature: (II[I[Ljava/lang/String;)I */JNIEXPORT jint JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_getNextPortInfo(JNIEnv *env, jobject obj, jint nClient, jint nPort, jintArray anValues, jobjectArray astrValues){ snd_seq_port_info_t portInfo; snd_seq_t* seq = getNativeSeq(env, obj); int nReturn; // printf("1\n"); memset(&portInfo, 0, sizeof(portInfo)); portInfo.client = nClient; portInfo.port = nPort; // printf("2\n"); nReturn = snd_seq_query_next_port(seq, &portInfo); // printf("3\n"); if (nReturn < 0) { // throwRuntimeException(env, "snd_seq_query_next_port failed"); } else { // printf("4\n"); fillPortInfoArrays(env, obj, &portInfo, anValues, astrValues); // printf("5\n"); } return (jint) nReturn;}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: getQueueStatus * Signature: (I[I[J)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_getQueueStatus(JNIEnv *env, jobject obj, jint nQueue, jintArray anValues, jlongArray alValues){ jint* values = NULL; jlong* lvalues = NULL; int nLength; snd_seq_queue_status_t queueStatus; snd_seq_t* seq = getNativeSeq(env, obj); int nReturn = snd_seq_get_queue_status(seq, nQueue, &queueStatus); if (nReturn < 0) { throwRuntimeException(env, "snd_seq_get_queue_status failed"); } nLength = (*env)->GetArrayLength(env, anValues); if (nLength < 3) { throwRuntimeException(env, "array does not have enough elements (3 required)"); } values = (*env)->GetIntArrayElements(env, anValues, NULL); if (values == NULL) { throwRuntimeException(env, "GetIntArrayElements failed"); } values[0] = queueStatus.events; values[1] = queueStatus.running; values[2] = queueStatus.flags; (*env)->ReleaseIntArrayElements(env, anValues, values, 0); nLength = (*env)->GetArrayLength(env, alValues); if (nLength < 2) { throwRuntimeException(env, "array does not have enough elements (2 required)"); } lvalues = (*env)->GetLongArrayElements(env, alValues, NULL); if (lvalues == NULL) { throwRuntimeException(env, "GetLongArrayElements failed"); } lvalues[0] = queueStatus.tick; lvalues[1] = (jlong) queueStatus.time.tv_sec * 1000000000 + queueStatus.time.tv_nsec; (*env)->ReleaseLongArrayElements(env, alValues, lvalues, 0);}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: getQueueTempo * Signature: (I[I)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_getQueueTempo(JNIEnv *env, jobject obj, jint nQueue, jintArray anValues){ jint* values = NULL; int nLength; snd_seq_queue_tempo_t queueTempo; snd_seq_t* seq = getNativeSeq(env, obj); int nReturn = snd_seq_get_queue_tempo(seq, nQueue, &queueTempo); if (nReturn < 0) { throwRuntimeException(env, "snd_seq_get_queue_tempo failed"); } nLength = (*env)->GetArrayLength(env, anValues); if (nLength < 2) { throwRuntimeException(env, "array does not have enough elements (2 required)"); } values = (*env)->GetIntArrayElements(env, anValues, NULL); if (values == NULL) { throwRuntimeException(env, "GetIntArrayElements failed"); } values[0] = queueTempo.tempo; values[1] = queueTempo.ppq; (*env)->ReleaseIntArrayElements(env, anValues, values, 0);}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: getSystemInfo * Signature: ([I)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_getSystemInfo(JNIEnv *env, jobject obj, jintArray anValues){ jint* values = NULL; int nLength; snd_seq_system_info_t systemInfo; snd_seq_t* seq = getNativeSeq(env, obj); int nReturn = snd_seq_system_info(seq, &systemInfo); if (nReturn < 0) { throwRuntimeException(env, "snd_seq_system_info failed"); } nLength = (*env)->GetArrayLength(env, anValues); if (nLength < 4) { throwRuntimeException(env, "array does not have enough elements (4 required)"); } values = (*env)->GetIntArrayElements(env, anValues, NULL); if (values == NULL) { throwRuntimeException(env, "GetIntArrayElements failed"); } values[0] = systemInfo.queues; values[1] = systemInfo.clients; values[2] = systemInfo.ports; values[3] = systemInfo.channels; (*env)->ReleaseIntArrayElements(env, anValues, values, 0);}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: open * Signature: ()I */JNIEXPORT jint JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_open(JNIEnv *env, jobject obj){ snd_seq_t* seq; int nReturn; // errno = 0; nReturn = snd_seq_open(&seq, SND_SEQ_OPEN); // printf("2\n"); // printf("return: %d\n", nReturn); // perror("abc"); if (nReturn < 0) { throwRuntimeException(env, "snd_seq_open failed"); return (jint) nReturn; } // printf("3\n"); snd_seq_block_mode(seq, 1); // printf("4\n"); setNativeSeq(env, obj, seq); // printf("5\n"); nReturn = snd_seq_client_id(seq); // printf("6\n"); // printf("return: %d\n", nReturn); // perror("abc"); fflush(stdout); if (nReturn < 0) { throwRuntimeException(env, "snd_seq_client_id failed"); } // printf("7\n"); return (jint) nReturn;}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: sendControlEvent * Signature: (IIJIIIIIIIIII)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_sendControlEvent(JNIEnv *env, jobject obj, jint nType, jint nFlags, jint nTag, jint nQueue, jlong lTime, jint nSourcePort, jint nDestClient, jint nDestPort, jint nChannel, jint nParam, jint nValue){ snd_seq_t* seq = getNativeSeq(env, obj); snd_seq_event_t event; memset(&event, 0, sizeof(event)); event.type = nType; event.flags = nFlags; event.tag = nTag; event.queue = nQueue; if ((event.flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_TICK) { event.time.tick = lTime; } else { event.time.time.tv_sec = lTime / 1000000000; event.time.time.tv_nsec = lTime % 1000000000; } // is set by the sequencer to sending client //event.source.client = nSourceClient; event.source.port = nSourcePort; event.dest.client = nDestClient; event.dest.port = nDestPort; event.data.control.channel = nChannel; event.data.control.param = nParam; event.data.control.value = nValue; sendEvent(env, seq, &event);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -