📄 org_tritonus_lowlevel_alsa_asequencer0.c
字号:
/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: sendNoteEvent * Signature: (IIJIIIIIIIIIII)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_sendNoteEvent(JNIEnv *env, jobject obj, jint nType, jint nFlags, jint nTag, jint nQueue, jlong lTime, jint nSourcePort, jint nDestClient, jint nDestPort, jint nChannel, jint nNote, jint nVelocity, jint nOffVelocity, jint nDuration){ snd_seq_t* seq = getNativeSeq(env, obj); snd_seq_event_t event; memset(&event, 0, sizeof(event)); event.type = nType; //printf("event.type: %d\n", event.type); //printf(": %d\n", ); event.flags = nFlags; //printf("event.flags: %d\n", event.flags); event.tag = nTag; //printf("event.tag: %d\n", event.tag); event.queue = nQueue; //printf("event.queue: %d\n", event.queue); if ((event.flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_TICK) { event.time.tick = lTime; //printf("event.time.tick: %d\n", event.time.tick); } 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; //printf("event.source.port: %d\n", event.source.port); event.dest.client = nDestClient; //printf("event.dest.client: %d\n", event.dest.client); event.dest.port = nDestPort; //printf("event.dest.port: %d\n", event.dest.port); event.data.note.channel = nChannel; event.data.note.note = nNote; event.data.note.velocity = nVelocity; event.data.note.off_velocity = nOffVelocity; event.data.note.duration = nDuration; sendEvent(env, seq, &event);}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: sendObjectEvent * Signature: (IIIIJIIILjava/lang/Object;)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_sendObjectEvent(JNIEnv *env, jobject obj, jint nType, jint nFlags, jint nTag, jint nQueue, jlong lTime, jint nSourcePort, jint nDestClient, jint nDestPort, jobject objectRef){ snd_seq_t* seq = getNativeSeq(env, obj); snd_seq_event_t event; jobject globalRef; memset(&event, 0, sizeof(event)); event.type = nType; event.flags = nFlags; event.tag = nTag; event.queue = nQueue; // TODO: put setting of time into a subprogram 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; /* * Normally, object references passed to native code are only * valid until the native function returns (local reference). * Here, we need a global reference, since we want to pass * the reference through the ALSA sequencer. That's the reason * why we aquire a global reference (its lifetime lasts until * it is released explicitely). This reference is deleted in * getEvent(). There must be only one getEvent() that deletes * the reference (not trivial if a port has multiple subscribers). */ globalRef = (*env)->NewGlobalRef(env, objectRef); if (globalRef == NULL) { throwRuntimeException(env, "NewGlobalRef failed"); } /* * 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. */ *((jobject*) (event.data.raw32.d)) = globalRef; sendEvent(env, seq, &event);}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: sendQueueControlEvent * Signature: (IIIIJIIIIIIJ)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_sendQueueControlEvent(JNIEnv *env, jobject obj, jint nType, jint nFlags, jint nTag, jint nQueue, jlong lTime, jint nSourcePort, jint nDestClient, jint nDestPort, jint nControlQueue, jint nControlValue, jlong lControlTime){ 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.queue.queue = nControlQueue; if (nType == SND_SEQ_EVENT_TEMPO) { event.data.queue.param.value = nControlValue; } else if (nType == SND_SEQ_EVENT_SETPOS_TICK) { event.data.queue.param.time.tick = lTime; } else if (nType == SND_SEQ_EVENT_SETPOS_TIME) { event.data.queue.param.time.time.tv_sec = lTime / 1000000000; event.data.queue.param.time.time.tv_nsec = lTime % 1000000000; } sendEvent(env, seq, &event);}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: sendVarEvent * Signature: (IIIIJIII[BII)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_sendVarEvent(JNIEnv *env, jobject obj, jint nType, jint nFlags, jint nTag, jint nQueue, jlong lTime, jint nSourcePort, jint nDestClient, jint nDestPort, jbyteArray abData, jint nOffset, jint nLength){ snd_seq_t* seq = getNativeSeq(env, obj); snd_seq_event_t event; jbyte* data; 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; data = (*env)->GetByteArrayElements(env, abData, NULL); if (data == NULL) { throwRuntimeException(env, "GetByteArrayElements failed"); } event.data.ext.ptr = data + nOffset; event.data.ext.len = nLength; sendEvent(env, seq, &event); // some sort of release of the array elements necessary?}static voidsendEvent(JNIEnv *env, snd_seq_t* seq, snd_seq_event_t* pEvent){ int nReturn = 0; nReturn = snd_seq_event_output(seq, pEvent); // IDEA: execute flush only if event wants to circumvent queues? if (nReturn < 0) { throwRuntimeException(env, "snd_seq_event_output failed"); } // we have to restart this call in case it is interrupted by a signal. do { errno = 0; // printf("before flushing output\n"); nReturn = snd_seq_flush_output(seq); // printf("after flushing output\n"); } while ((nReturn == -1 && errno == EINTR) || nReturn == -EINTR); if (nReturn < 0) { printf("return: %d\n", nReturn); printf("errno: %d\n", errno); perror("abc"); throwRuntimeException(env, "snd_seq_flush_output failed"); }}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: setClientName * Signature: (Ljava/lang/String;)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_setClientName(JNIEnv *env, jobject obj, jstring strName){ snd_seq_t* seq = getNativeSeq(env, obj); snd_seq_client_info_t clientInfo; const char* name; int nReturn; memset(&clientInfo, 0, sizeof(clientInfo)); nReturn = snd_seq_get_client_info(seq, &clientInfo); if (nReturn < 0) { throwRuntimeException(env, "snd_seq_get_client_info failed"); } name = (*env)->GetStringUTFChars(env, strName, NULL); if (name == NULL) { throwRuntimeException(env, "GetStringUTFChars failed"); } strncpy(clientInfo.name, name, 63); clientInfo.name[64] = 0; nReturn = snd_seq_set_client_info(seq, &clientInfo); if (nReturn < 0) { throwRuntimeException(env, "snd_seq_set_client_info failed"); }}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: setQueueLocked * Signature: (IZ)V */JNIEXPORT void JNICALL Java_org_tritonus_lowlevel_alsa_ASequencer0_setQueueLocked(JNIEnv *env, jobject obj, jint nQueue, jboolean bLocked){ snd_seq_t* seq = getNativeSeq(env, obj); snd_seq_queue_owner_t owner; int nReturn; memset(&owner, 0, sizeof(owner)); // owner.queue = nQueue; nReturn = snd_seq_get_queue_owner(seq, nQueue, &owner); if (nReturn < 0) { // perror("abc"); throwRuntimeException(env, "snd_seq_get_queue_owner failed"); } owner.locked = bLocked; nReturn = snd_seq_set_queue_owner(seq, nQueue, &owner); if (nReturn < 0) { // perror("abc"); throwRuntimeException(env, "snd_seq_set_queue_owner failed"); }}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: setQueueTempo * Signature: (III)V */JNIEXPORT void JNICALLJava_org_tritonus_lowlevel_alsa_ASequencer0_setQueueTempo(JNIEnv *env, jobject obj, jint nQueue, jint nResolution, jint nTempo){ snd_seq_t* seq = getNativeSeq(env, obj); snd_seq_queue_tempo_t tempo; int nReturn; memset(&tempo, 0, sizeof(tempo)); tempo.queue = nQueue; tempo.ppq = nResolution; tempo.tempo = nTempo; // tempo.tempo = 60*1000000/nTempo; nReturn = snd_seq_set_queue_tempo(seq, nQueue, &tempo); if (nReturn < 0) { perror("abc"); throwRuntimeException(env, "snd_seq_set_queue_tempo failed"); }}/* * Class: org_tritonus_lowlevel_alsa_ASequencer0 * Method: subscribePort * Signature: (IIIIIZZZIII)V */JNIEXPORT void JNICALL Java_org_tritonus_lowlevel_alsa_ASequencer0_subscribePort(JNIEnv *env, jobject obj, jint nSenderClient, jint nSenderPort, jint nDestClient, jint nDestPort, jint nQueue, jboolean bExclusive, jboolean bRealtime, jboolean bConvertTime, jint nMidiChannels, jint nMidiVoices, jint nSynthVoices){ snd_seq_t* seq = getNativeSeq(env, obj); snd_seq_port_subscribe_t subs; int nReturn; memset(&subs, 0, sizeof(subs)); subs.sender.client = nSenderClient; subs.sender.port = nSenderPort; subs.dest.client = nDestClient; subs.dest.port = nDestPort; subs.queue = nQueue; subs.exclusive = bExclusive; subs.realtime = bRealtime; subs.convert_time = bConvertTime; subs.midi_channels = nMidiChannels; subs.midi_voices = nMidiVoices; subs.synth_voices = nSynthVoices; nReturn = snd_seq_subscribe_port(seq, &subs); if (nReturn < 0) { throwRuntimeException(env, "snd_seq_subscribe_port failed"); }}/*** org_tritonus_lowlevel_alsa_ASequencer0.c ***/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -