static int process(jack_nframes_t nframes, void *arg) { int i,j; void* port_buf = jack_port_get_buffer(output_port, nframes); unsigned char* buffer; jack_midi_clear_buffer(port_buf); /*memset(buffer, 0, nframes*sizeof(jack_default_audio_sample_t));*/ for(i=0; i<nframes; i++) { for(j=0; j<num_notes; j++) { if(note_starts[j] == loop_index) { buffer = jack_midi_event_reserve(port_buf, i, 3); /* printf("wrote a note on, port buffer = 0x%x, event buffer = 0x%x\n", port_buf, buffer);*/ buffer[2] = 64; /* velocity */ buffer[1] = note_frqs[j]; buffer[0] = 0x90; /* note on */ } else if(note_starts[j] + note_lengths[j] == loop_index) { buffer = jack_midi_event_reserve(port_buf, i, 3); /* printf("wrote a note off, port buffer = 0x%x, event buffer = 0x%x\n", port_buf, buffer);*/ buffer[2] = 64; /* velocity */ buffer[1] = note_frqs[j]; buffer[0] = 0x80; /* note off */ } } loop_index = loop_index+1 >= loop_nsamp ? 0 : loop_index+1; } return 0; }
static void send_all_sound_off(void *port_buffers[MAX_NUMBER_OF_TRACKS], jack_nframes_t nframes) { int i, channel; unsigned char *buffer; for (i = 0; i <= smf->number_of_tracks; i++) { for (channel = 0; channel < 16; channel++) { #ifdef JACK_MIDI_NEEDS_NFRAMES buffer = jack_midi_event_reserve(port_buffers[i], 0, 3, nframes); #else buffer = jack_midi_event_reserve(port_buffers[i], 0, 3); #endif if (buffer == NULL) { warn_from_jack_thread_context("jack_midi_event_reserve failed, cannot send All Sound Off."); break; } buffer[0] = MIDI_CONTROLLER | channel; buffer[1] = MIDI_ALL_SOUND_OFF; buffer[2] = 0; } if (just_one_output) break; } }
static void _send(_t *dp, void *midi_out, jack_nframes_t t, unsigned char cmd, unsigned char note) { unsigned char midi[] = { cmd | (dp->opts.chan-1), note, 0 }; unsigned char* buffer = jack_midi_event_reserve(midi_out, t, 3); if (buffer == NULL) { fprintf(stderr, "jack won't buffer 3 midi bytes!\n"); } else { memcpy(buffer, midi, 3); } }
void note_on(struct note_t note, void* port_buf, int i) { unsigned char* buffer; buffer = jack_midi_event_reserve(port_buf, i, 3); buffer[2] = note.velocity; /* velocity */ buffer[1] = note.note_number; /* note number */ buffer[0] = MIDI_NOTE_ON + midi_channel; /* note on */ active_notes.note[active_notes.size] = note; active_notes.size++; }
MidiData* MidiBuffer::reserveEvent(int sample, size_t dataSize) { if(!isValid()) { return 0; } return jack_midi_event_reserve( _jackBuffer, (jack_nframes_t)sample, dataSize); }
void send_note(void *midi_out_buffer, jack_nframes_t ofs, float velocity) { jack_midi_data_t *midi_note = jack_midi_event_reserve(midi_out_buffer, 0, 3); midi_note[0] = 0x90; /* noteon */ midi_note[1] = note; /* freq */ midi_note[2] = MIN(127, (unsigned char) (velocity * 127)); /* velocity */ DEBUG("sending note with velocity = %u\n", midi_note[2]); }
static int _process(jack_nframes_t nframes, void *arg) { // process input events _t *data = (_t *)arg; framework_midi_event_init(&data->fw, NULL, nframes); /* for all frames in the buffer */ for(int i = 0; i < nframes; i++) { /* process all midi events at this sample time */ jack_midi_event_t event; int port; while (framework_midi_event_get(&data->fw, i, &event, &port)) { if (data->started && _writeable(data, event.size)) _write(data, sdrkit_last_frame_time(arg)+i, event.size, event.buffer); } } // process output events _t *dp = (_t *)arg; void* midi_out = jack_port_get_buffer(framework_midi_output(dp,0), nframes); jack_midi_event_t event; // find out what there is to do framework_midi_event_init(&dp->fw, &dp->midi, nframes); // clear the jack output buffer jack_midi_clear_buffer(midi_out); // for each frame in this callback for(int i = 0; i < nframes; i += 1) { // process all midi output events at this sample frame int port; while (framework_midi_event_get(&dp->fw, i, &event, &port)) { if (event.size != 0) { unsigned char* buffer = jack_midi_event_reserve(midi_out, i, event.size); if (buffer == NULL) { fprintf(stderr, "%s:%d: jack won't buffer %ld midi bytes!\n", __FILE__, __LINE__, (long)event.size); } else { memcpy(buffer, event.buffer, event.size); //fprintf(stderr, "midi_insert sent %x %x %x\n", buffer[0], buffer[1], buffer[2]); } } } } return 0; }
void mute(void *port_buf, int i) { unsigned char* buffer; int j; for(j=0; j < MAX_DELAYED_NOTES_COUNT; j++){ if (delayed_notes[j].note.velocity != 0) { timer_delete(delayed_notes[j].timer); } delayed_notes[j].note.velocity = 0; } queued_notes.size = 0; while(active_notes.size > 0) { buffer = jack_midi_event_reserve(port_buf, i, 3); buffer[2] = active_notes.note[active_notes.size - 1].velocity; /* velocity */ buffer[1] = active_notes.note[active_notes.size - 1].note_number; /* note number */ buffer[0] = MIDI_NOTE_OFF + midi_channel; /* note off */ active_notes.size--; } }
/* * ============================ Input ============================== */ static void do_jack_input(alsa_seqmidi_t *self, port_t *port, struct process_info *info) { // process port->early_events alsa_midi_event_t ev; while (jack_ringbuffer_read(port->early_events, (char*)&ev, sizeof(ev))) { jack_midi_data_t* buf; int64_t time = ev.time - info->period_start; if (time < 0) time = 0; else if (time >= info->nframes) time = info->nframes - 1; buf = jack_midi_event_reserve(port->jack_buf, (jack_nframes_t)time, ev.size); if (buf) jack_ringbuffer_read(port->early_events, (char*)buf, ev.size); else jack_ringbuffer_read_advance(port->early_events, ev.size); debug_log("input: it's time for %d bytes at %lld", ev.size, time); } }
// Jack process callback int jackProcessOut( jack_nframes_t nframes, void *arg ) { JackMidiData *data = (JackMidiData *) arg; jack_midi_data_t *midiData; int space; // Is port created? if ( data->port == NULL ) return 0; void *buff = jack_port_get_buffer( data->port, nframes ); jack_midi_clear_buffer( buff ); while ( jack_ringbuffer_read_space( data->buffSize ) > 0 ) { jack_ringbuffer_read( data->buffSize, (char *) &space, (size_t) sizeof(space) ); midiData = jack_midi_event_reserve( buff, 0, space ); jack_ringbuffer_read( data->buffMessage, (char *) midiData, (size_t) space ); } return 0; }
bool MidiJackDevice::queueEvent(const MidiPlayEvent& e) { if (!_out_client_jackport) // p3.3.55 return false; void* pb = jack_port_get_buffer(_out_client_jackport, segmentSize); // p3.3.55 int frameOffset = audio->getFrameOffset(); unsigned pos = audio->pos().frame(); int ft = e.time() - frameOffset - pos; if (ft < 0) ft = 0; if (ft >= (int) segmentSize) { if(debugMsg) printf("MidiJackDevice::queueEvent: Event time:%d out of range. offset:%d ft:%d (seg=%d)\n", e.time(), frameOffset, ft, segmentSize); if (ft > (int) segmentSize) ft = segmentSize - 1; } #ifdef JACK_MIDI_DEBUG printf("MidiJackDevice::queueEvent time:%d type:%d ch:%d A:%d B:%d\n", e.time(), e.type(), e.channel(), e.dataA(), e.dataB()); #endif switch (e.type()) { case ME_NOTEON: case ME_NOTEOFF: case ME_POLYAFTER: case ME_CONTROLLER: case ME_PITCHBEND: { #ifdef JACK_MIDI_DEBUG printf("MidiJackDevice::queueEvent note on/off polyafter controller or pitch\n"); #endif unsigned char* p = jack_midi_event_reserve(pb, ft, 3); if (p == 0) { #ifdef JACK_MIDI_DEBUG fprintf(stderr, "MidiJackDevice::queueEvent NOTE CONTROL PAT or PB: buffer overflow, stopping until next cycle\n"); #endif return false; } p[0] = e.type() | e.channel(); p[1] = e.dataA(); p[2] = e.dataB(); } break; case ME_PROGRAM: case ME_AFTERTOUCH: { #ifdef JACK_MIDI_DEBUG printf("MidiJackDevice::queueEvent program or aftertouch\n"); #endif unsigned char* p = jack_midi_event_reserve(pb, ft, 2); if (p == 0) { #ifdef JACK_MIDI_DEBUG fprintf(stderr, "MidiJackDevice::queueEvent PROG or AT: buffer overflow, stopping until next cycle\n"); #endif return false; } p[0] = e.type() | e.channel(); p[1] = e.dataA(); } break; case ME_SYSEX: { #ifdef JACK_MIDI_DEBUG printf("MidiJackDevice::queueEvent sysex\n"); #endif const unsigned char* data = e.data(); int len = e.len(); unsigned char* p = jack_midi_event_reserve(pb, ft, len + 2); if (p == 0) { fprintf(stderr, "MidiJackDevice::queueEvent ME_SYSEX: buffer overflow, sysex too big, event lost\n"); return true; } p[0] = 0xf0; p[len + 1] = 0xf7; memcpy(p + 1, data, len); } break; case ME_SONGPOS: case ME_CLOCK: case ME_START: case ME_CONTINUE: case ME_STOP: if(debugMsg) printf("MidiJackDevice::queueEvent: event type %x not supported\n", e.type()); return true; break; } return true; }
static void process_midi_output(jack_nframes_t nframes) { int i, t, bytes_remaining, track_number; unsigned char *buffer, tmp_status; void *port_buffers[MAX_NUMBER_OF_TRACKS]; jack_nframes_t last_frame_time; jack_transport_state_t transport_state; static jack_transport_state_t previous_transport_state = JackTransportStopped; static int previous_playback_started = -1; static int previous_playback_paused = 0; for (i = 0; i <= smf->number_of_tracks; i++) { port_buffers[i] = jack_port_get_buffer(output_ports[i], nframes); if (port_buffers[i] == NULL) { warn_from_jack_thread_context("jack_port_get_buffer failed, cannot send anything."); return; } #ifdef JACK_MIDI_NEEDS_NFRAMES jack_midi_clear_buffer(port_buffers[i], nframes); #else jack_midi_clear_buffer(port_buffers[i]); #endif if (just_one_output) break; } if (ctrl_c_pressed) { send_all_sound_off(port_buffers, nframes); /* The idea here is to exit at the second time process_midi_output gets called. Otherwise, All Sound Off won't be delivered. */ ctrl_c_pressed++; if (ctrl_c_pressed >= 3) exit(0); return; } // g_debug("PROCESS CALLBACK!!!"); if (playback_paused) { if (!previous_playback_paused) { send_all_sound_off(port_buffers, nframes); } previous_playback_paused = playback_paused; return; } previous_playback_paused = playback_paused; if (use_transport) { // if (!ready_to_roll) return; transport_state = jack_transport_query(jack_client, NULL); if (transport_state == JackTransportStopped) { if (previous_transport_state == JackTransportRolling) { send_all_sound_off(port_buffers, nframes); } playback_started = -1; } if (transport_state == JackTransportStarting) { playback_started = -1; } if (transport_state == JackTransportRolling) { if (previous_transport_state != JackTransportRolling) { jack_position_t position; jack_transport_query(jack_client, &position); song_position = position.frame; playback_started = jack_last_frame_time(jack_client); } } previous_transport_state = transport_state; } else { if (playback_started == -1) { if (previous_playback_started >= 0) { send_all_sound_off(port_buffers, nframes); send_sond_end(); } } previous_playback_started = playback_started; } /* End of song already? */ if (playback_started < 0) return; last_frame_time = jack_last_frame_time(jack_client); /* We may push at most one byte per 0.32ms to stay below 31.25 Kbaud limit. */ bytes_remaining = nframes_to_ms(nframes) * rate_limit; double loop_offset = loop_song(smf); for (;;) { smf_event_t *event = smf_peek_next_event(smf); int end_of_song = 0; int is_meta_event = 0; if (event == NULL) { end_of_song = 1; } else if (smf_event_is_metadata(event)) { is_meta_event = 1; char *decoded = smf_event_decode(event); if (decoded) { if (!be_quiet) g_debug("Metadata: %s", decoded); end_of_song = process_meta_event(decoded); free(decoded); } } if (end_of_song) { if (!be_quiet) g_debug("End of song."); playback_started = -1; if (!use_transport) ctrl_c_pressed = 1; break; } if (is_meta_event) { smf_event_t *ret = smf_get_next_event(smf); assert(ret != 0); continue; } bytes_remaining -= event->midi_buffer_length; if (rate_limit > 0.0 && bytes_remaining <= 0) { warn_from_jack_thread_context("Rate limiting in effect."); break; } // t = seconds_to_nframes(event->time_seconds) + playback_started - song_position + nframes - last_frame_time; t = seconds_to_nframes(event->time_seconds + loop_offset) + playback_started - song_position - last_frame_time; /* If computed time is too much into the future, we'll need to send it later. */ if (t >= (int)nframes) break; /* If computed time is < 0, we missed a cycle because of xrun. */ if (t < 0) t = 0; assert(event->track->track_number >= 0 && event->track->track_number <= MAX_NUMBER_OF_TRACKS); /* We will send this event; remove it from the queue. */ smf_event_t *ret = smf_get_next_event(smf); assert(ret != 0); /* First, send it via midi_out. */ track_number = 0; #ifdef JACK_MIDI_NEEDS_NFRAMES buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length, nframes); #else buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length); #endif if (buffer == NULL) { warn_from_jack_thread_context("jack_midi_event_reserve failed, NOTE LOST."); break; } memcpy(buffer, event->midi_buffer, event->midi_buffer_length); /* Ignore per-track outputs? */ if (just_one_output) continue; /* Send it via proper output port. */ track_number = event->track->track_number; #ifdef JACK_MIDI_NEEDS_NFRAMES buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length, nframes); #else buffer = jack_midi_event_reserve(port_buffers[track_number], t, event->midi_buffer_length); #endif if (buffer == NULL) { warn_from_jack_thread_context("jack_midi_event_reserve failed, NOTE LOST."); break; } /* Before sending, reset channel to 0. XXX: Not very pretty. */ assert(event->midi_buffer_length >= 1); tmp_status = event->midi_buffer[0]; if (event->midi_buffer[0] >= 0x80 && event->midi_buffer[0] <= 0xEF) event->midi_buffer[0] &= 0xF0; memcpy(buffer, event->midi_buffer, event->midi_buffer_length); event->midi_buffer[0] = tmp_status; } }
static int a2j_process (jack_nframes_t nframes, void * arg) { struct a2j* self = (struct a2j *) arg; struct a2j_stream * stream_ptr; int i; struct a2j_port ** port_ptr; struct a2j_port * port; if (g_freewheeling) { return 0; } self->cycle_start = jack_last_frame_time (self->jack_client); stream_ptr = &self->stream; a2j_add_ports (stream_ptr); // process ports for (i = 0 ; i < PORT_HASH_SIZE ; i++) { port_ptr = &stream_ptr->port_hash[i]; while (*port_ptr != NULL) { struct a2j_alsa_midi_event ev; jack_nframes_t now; jack_nframes_t one_period; char *ev_buf; port = *port_ptr; if (port->is_dead) { if (jack_ringbuffer_write_space (self->port_del) >= sizeof(port_ptr)) { a2j_debug("jack: removed port %s", port->name); *port_ptr = port->next; jack_ringbuffer_write (self->port_del, (char*)&port, sizeof(port)); } else { a2j_error ("port deletion lost - no space in event buffer!"); } port_ptr = &port->next; continue; } port->jack_buf = jack_port_get_buffer(port->jack_port, nframes); /* grab data queued by the ALSA input thread and write it into the JACK port buffer. it will delivered during the JACK period that this function is called from. */ /* first clear the JACK port buffer in preparation for new data */ // a2j_debug ("PORT: %s process input", jack_port_name (port->jack_port)); jack_midi_clear_buffer (port->jack_buf); now = jack_frame_time (self->jack_client); one_period = jack_get_buffer_size (self->jack_client); while (jack_ringbuffer_peek (port->inbound_events, (char*)&ev, sizeof(ev) ) == sizeof(ev) ) { jack_midi_data_t* buf; jack_nframes_t offset; if (ev.time >= self->cycle_start) { break; } //jack_ringbuffer_read_advance (port->inbound_events, sizeof (ev)); ev_buf = (char *) alloca( sizeof(ev) + ev.size ); if (jack_ringbuffer_peek (port->inbound_events, ev_buf, sizeof(ev) + ev.size ) != sizeof(ev) + ev.size) break; offset = self->cycle_start - ev.time; if (offset > one_period) { /* from a previous cycle, somehow. cram it in at the front */ offset = 0; } else { /* offset from start of the current cycle */ offset = one_period - offset; } a2j_debug ("event at %d offset %d", ev.time, offset); /* make sure there is space for it */ buf = jack_midi_event_reserve (port->jack_buf, offset, ev.size); if (buf) { /* grab the event */ memcpy( buf, ev_buf + sizeof(ev), ev.size ); } else { /* throw it away (no space) */ a2j_error ("threw away MIDI event - not reserved at time %d", ev.time); } jack_ringbuffer_read_advance (port->inbound_events, sizeof(ev) + ev.size); a2j_debug("input on %s: sucked %d bytes from inbound at %d", jack_port_name (port->jack_port), ev.size, ev.time); } port_ptr = &port->next; } } return 0; }
int process(jack_nframes_t nframes, void *arg) { struct guitarseq *guitarseq = arg; if(!guitarseq) { fprintf(stderr, "No guitarseq instance!\n"); return 1; } void* port_buf; jack_nframes_t now = jack_frame_time (guitarseq->jack_client); //Output port_buf = jack_port_get_buffer(guitarseq->out_port, nframes); jack_midi_clear_buffer(port_buf); while (1) { jack_nframes_t time; //TODO: Do a safer read, in case only part of the message is here if (!jack_ringbuffer_read (guitarseq->out_buffer, (char *)&time, sizeof(time))) { break; } // from the future? if (time >= now) { break; } // time it right jack_nframes_t offset = time - now + nframes - 1; // get the size of the event size_t size; jack_ringbuffer_read(guitarseq->out_buffer, (char *)&size, sizeof(size)); INFO("out event at %u%+d size %zu\n", now, offset, size); if (offset > nframes) // from the past, somehow. cram it in at the front offset = 0; // proceed to giving it to jack jack_midi_data_t *buffer = jack_midi_event_reserve (port_buf, offset, size); if(buffer) { jack_ringbuffer_read(guitarseq->out_buffer, (char *)buffer, size); } else { // throw it away :( TODO: find more jack_ringbuffer_read_advance (guitarseq->out_buffer, size); ERROR("threw away MIDI event - no space reserved at time %u offset %d\n",time,offset); } } // Input port_buf = jack_port_get_buffer(guitarseq->in_port, nframes); jack_nframes_t event_count = jack_midi_get_event_count(port_buf); for(jack_nframes_t i=0; i<event_count; i++) { jack_midi_event_t in_event; jack_midi_event_get(&in_event, port_buf, i); //adds a note to the ringbuffer if (jack_ringbuffer_write_space(guitarseq->in_buffer) >= sizeof(in_event.time)+sizeof(in_event.size)+in_event.size) { jack_ringbuffer_write(guitarseq->in_buffer, (char *)&in_event.time, sizeof(in_event.time)); jack_ringbuffer_write(guitarseq->in_buffer, (char *)&in_event.size, sizeof(in_event.size)); jack_ringbuffer_write(guitarseq->in_buffer, (char *)in_event.buffer, in_event.size); } else { ERROR("Couldn't write to ringbuffer at %u, %zu midi data bytes lost\n", in_event.time, in_event.size); } } return 0; }
// JACK specifics. int qmidinetJackMidiDevice::process ( jack_nframes_t nframes ) { jack_nframes_t buffer_size = jack_get_buffer_size(m_pJackClient); m_last_frame_time = jack_last_frame_time(m_pJackClient); // Enqueue/dequeue events // to/from ring-buffers... for (int i = 0; i < m_nports; ++i) { if (m_ppJackPortIn && m_ppJackPortIn[i] && m_pJackBufferIn) { void *pvBufferIn = jack_port_get_buffer(m_ppJackPortIn[i], nframes); const int nevents = jack_midi_get_event_count(pvBufferIn); const unsigned int nlimit = jack_ringbuffer_write_space(m_pJackBufferIn); unsigned char achBuffer[nlimit]; unsigned char *pchBuffer = &achBuffer[0]; unsigned int nwrite = 0; for (int n = 0; n < nevents; ++n) { if (nwrite + sizeof(qmidinetJackMidiEvent) >= nlimit) break; qmidinetJackMidiEvent *pJackEventIn = (struct qmidinetJackMidiEvent *) pchBuffer; jack_midi_event_get(&pJackEventIn->event, pvBufferIn, n); if (nwrite + sizeof(qmidinetJackMidiEvent) + pJackEventIn->event.size >= nlimit) break; pJackEventIn->port = i; pchBuffer += sizeof(qmidinetJackMidiEvent); nwrite += sizeof(qmidinetJackMidiEvent); ::memcpy(pchBuffer, pJackEventIn->event.buffer, pJackEventIn->event.size); pchBuffer += pJackEventIn->event.size; nwrite += pJackEventIn->event.size; } if (nwrite > 0) { jack_ringbuffer_write(m_pJackBufferIn, (const char *) achBuffer, nwrite); } } if (m_ppJackPortOut && m_ppJackPortOut[i] && m_pJackBufferOut) { void *pvBufferOut = jack_port_get_buffer(m_ppJackPortOut[i], nframes); jack_midi_clear_buffer(pvBufferOut); const unsigned int nlimit = jack_midi_max_event_size(pvBufferOut); unsigned int nread = 0; qmidinetJackMidiEvent ev; while (jack_ringbuffer_peek(m_pJackBufferOut, (char *) &ev, sizeof(ev)) == sizeof(ev) && nread < nlimit) { if (ev.port != i) break; if (ev.event.time > m_last_frame_time) break; jack_nframes_t offset = m_last_frame_time - ev.event.time; if (offset > buffer_size) offset = 0; else offset = buffer_size - offset; jack_ringbuffer_read_advance(m_pJackBufferOut, sizeof(ev)); jack_midi_data_t *pMidiData = jack_midi_event_reserve(pvBufferOut, offset, ev.event.size); if (pMidiData) jack_ringbuffer_read(m_pJackBufferOut, (char *) pMidiData, ev.event.size); else jack_ringbuffer_read_advance(m_pJackBufferOut, ev.event.size); nread += ev.event.size; } } } if (m_pJackBufferIn && jack_ringbuffer_read_space(m_pJackBufferIn) > 0) m_pRecvThread->sync(); return 0; }
void toggle_midi_event(void *out, int frame, midi_event_t *midi_event, float volume) { unsigned char* buffer = jack_midi_event_reserve(out, frame, 3); buffer[0] = 0x80 | ((midi_event->playing = !midi_event->playing) << 4) | (midi_event->channel & 0xF); // On this channel, set on or off this buffer[1] = midi_event->note; // note, buffer[2] = 0x7F * (analog ? volume : 1); // played at this velocity. }
static int handle_process(jack_nframes_t frames, void *arg) { jack_midi_data_t *buffer; jack_midi_event_t event; jack_nframes_t event_count; jack_nframes_t event_time; jack_nframes_t frame; size_t i; jack_nframes_t last_frame_time; jack_midi_data_t *message; jack_time_t microseconds; void *port_buffer; jack_time_t time; jack_midi_clear_buffer(jack_port_get_buffer(out_port, frames)); switch (process_state) { case 0: /* State: initializing */ switch (wait_semaphore(init_semaphore, 0)) { case -1: set_process_error(SOURCE_WAIT_SEMAPHORE, get_semaphore_error()); /* Fallthrough on purpose */ case 0: return 0; } highest_latency = 0; lowest_latency = 0; messages_received = 0; messages_sent = 0; process_state = 1; total_latency = 0; total_latency_time = 0; unexpected_messages = 0; xrun_count = 0; jack_port_get_latency_range(remote_in_port, JackCaptureLatency, &in_latency_range); jack_port_get_latency_range(remote_out_port, JackPlaybackLatency, &out_latency_range); goto send_message; case 1: /* State: processing */ port_buffer = jack_port_get_buffer(in_port, frames); event_count = jack_midi_get_event_count(port_buffer); last_frame_time = jack_last_frame_time(client); for (i = 0; i < event_count; i++) { jack_midi_event_get(&event, port_buffer, i); message = (messages_received % 2) ? message_2 : message_1; if ((event.size == message_size) && (! memcmp(message, event.buffer, message_size * sizeof(jack_midi_data_t)))) { goto found_message; } unexpected_messages++; } microseconds = jack_frames_to_time(client, last_frame_time) - last_activity_time; if ((microseconds / 1000000) >= timeout) { set_process_error(SOURCE_PROCESS, ERROR_MSG_TIMEOUT); } break; found_message: event_time = last_frame_time + event.time; frame = event_time - last_activity; time = jack_frames_to_time(client, event_time) - last_activity_time; if ((! highest_latency) || (frame > highest_latency)) { highest_latency = frame; highest_latency_time = time; } if ((! lowest_latency) || (frame < lowest_latency)) { lowest_latency = frame; lowest_latency_time = time; } latency_time_values[messages_received] = time; latency_values[messages_received] = frame; total_latency += frame; total_latency_time += time; messages_received++; if (messages_received == samples) { process_state = 2; if (! signal_semaphore(process_semaphore)) { /* Sigh ... */ die(SOURCE_SIGNAL_SEMAPHORE, get_semaphore_error()); } break; } send_message: frame = (jack_nframes_t) ((((double) rand()) / RAND_MAX) * frames); if (frame >= frames) { frame = frames - 1; } port_buffer = jack_port_get_buffer(out_port, frames); buffer = jack_midi_event_reserve(port_buffer, frame, message_size); if (buffer == NULL) { set_process_error(SOURCE_EVENT_RESERVE, ERROR_RESERVE); break; } message = (messages_sent % 2) ? message_2 : message_1; memcpy(buffer, message, message_size * sizeof(jack_midi_data_t)); last_activity = jack_last_frame_time(client) + frame; last_activity_time = jack_frames_to_time(client, last_activity); messages_sent++; case 2: /* State: finished - do nothing */ case -1: /* State: error - do nothing */ case -2: /* State: signalled - do nothing */ ; } return 0; }
static int process_callback(jack_nframes_t nframes, void *arg) { int i, ax, axis_note, axis_velocity; void* port_buffer = jack_port_get_buffer(output_port, nframes); unsigned char* buffer; unsigned char axis_playing[24]; jack_midi_clear_buffer(port_buffer); for (i=0; i<nframes; i++) { for (ax=0; ax<20; ax++) { if (!isPoly) { buffer = jack_midi_event_reserve(port_buffer, i, 3); buffer[2] = 0x00; //as much poly as the host can get buffer[1] = 0x7F; //enable poly buffer[0] = 0xB0; //control mode isPoly = 1; if (debug) printf("Polyphonic mode enabled\n"); } if (black_keys) { if (ax==0) axis_note = -2; //dummy else if (ax==1) axis_note = 0x02; //leftY (Modulation) else if (ax==2) axis_note = 0x0A; //rightH (Pan) else if (ax==3) axis_note = -2; //dummy else if (ax==4) axis_note = 0x10; //Acc X (Misc 1) 0x10 else if (ax==5) axis_note = 0x11; //Acc Y (Misc 2) 0x11 else if (ax==6) axis_note = 0x12; //Acc Z (Misc 3) 0x12 else if (ax==7) axis_note = -2; //gyro (doesn't work) else if (ax==8) axis_note = 61+(12*oct); //up else if (ax==9) axis_note = 62+(12*oct); //right else if (ax==10) axis_note = 63+(12*oct); //down else if (ax==11) axis_note = 60+(12*oct); //left else if (ax==12) axis_note = 65+(12*oct); //l2 else if (ax==13) axis_note = 66+(12*oct); //r2 else if (ax==14) axis_note = 64+(12*oct); //l1 else if (ax==15) axis_note = 67+(12*oct); //r1 else if (ax==16) axis_note = 69+(12*oct); //triangle else if (ax==17) axis_note = 70+(12*oct); //circle else if (ax==18) axis_note = 71+(12*oct); //cross else if (ax==19) axis_note = 68+(12*oct); //square } else { if (ax==0) axis_note = -2; //dummy else if (ax==1) axis_note = 0x02; //leftY (Modulation) else if (ax==2) axis_note = 0x0A; //rightH (Pan) else if (ax==3) axis_note = -2; //dummy else if (ax==4) axis_note = 0x10; //Acc X (Misc 1) 0x10 else if (ax==5) axis_note = 0x11; //Acc Y (Misc 2) 0x11 else if (ax==6) axis_note = 0x12; //Acc Z (Misc 3) 0x12 else if (ax==7) axis_note = -2; //gyro (doesn't work) else if (ax==8) axis_note = 62+(12*oct); //up else if (ax==9) axis_note = 64+(12*oct); //right else if (ax==10) axis_note = 65+(12*oct); //down else if (ax==11) axis_note = 60+(12*oct); //left else if (ax==12) axis_note = 69+(12*oct); //l2 else if (ax==13) axis_note = 71+(12*oct); //r2 else if (ax==14) axis_note = 67+(12*oct); //l1 else if (ax==15) axis_note = 72+(12*oct); //r1 else if (ax==16) axis_note = 76+(12*oct); //triangle else if (ax==17) axis_note = 77+(12*oct); //circle else if (ax==18) axis_note = 79+(12*oct); //cross else if (ax==19) axis_note = 74+(12*oct); //square } if (ax==1) axis_velocity = abs(axis[ax]/0xff) - 1; // modulation else if (ax==2) axis_velocity = ((axis[ax]/0xff)/2) + 63; // pan else if (ax<7) axis_velocity = ((axis[ax]/0xff)/2) + 63; // other controls else if (ax>=8 && ax<=19) { // keys axis_velocity = (axis[ax]/0xff) - 1; if (axis_velocity > 0) { axis_velocity = axis_velocity*(6.0-logf(axis_velocity)); if (axis_velocity < 0) axis_velocity = 0; else if (axis_velocity > 127) axis_velocity = 127; } } else axis_velocity = (axis[ax]/0xff) - 1; // all the others if (axis_velocity == -1) axis_velocity = 0; if (axis[ax]) axis_playing[ax] = 1; else axis_playing[ax] = 0; if (axis_prev_action[ax] != axis_playing[ax]) { axis_is_checked[ax] = 0; } if (!axis_is_checked[ax]) { if (axis_playing[ax]) { buffer = jack_midi_event_reserve(port_buffer, i, 3); buffer[2] = axis_velocity; buffer[1] = axis_note; if (ax>7) buffer[0] = 0x90; //note-on else buffer[0] = 0xB0; //control/mode axis_prev_action[ax] = 1; if (debug && (ax<4 || ax>7) && axis_note>0) printf("PLAY: axis %02i; velocity is %03i; playing ? %i\n", ax, axis_velocity, axis_playing[ax]); } else { buffer = jack_midi_event_reserve(port_buffer, i, 3); buffer[2] = axis_velocity; buffer[1] = axis_note; if (ax>7) buffer[0] = 0x80;//note-off else buffer[0] = 0xB0; //control/mode axis_prev_action[ax] = 0; if (debug && (ax<4 || ax>7) && axis_note>0) printf("STOP: axis %02i; velocity is %03i; playing ? %i\n", ax, axis_velocity, axis_playing[ax]); } axis_is_checked[ax] = 1; } else if (axis_prev_velocity[ax] != axis[ax]) { buffer = jack_midi_event_reserve(port_buffer, i, 3); buffer[2] = axis_velocity; buffer[1] = axis_note; if (ax>7) buffer[0] = 0xA0; //aftertouch else buffer[0] = 0xB0; //control/mode if (debug && (ax<4 || ax>7) && axis_note>0) printf("CTRL: axis %02i; velocity is %03i; playing ? %i\n", ax, axis_velocity, axis_playing[ax]); } axis_prev_velocity[ax] = axis[ax]; } } return 0; }
int process(jack_nframes_t nframes, void *arg) { int i,j; void* port_buf = jack_port_get_buffer(output_port, nframes); unsigned char* buffer; jack_midi_clear_buffer(port_buf); for(i = 0; i < nframes; i++) { while(queued_notes.size > 0) { note_on(queued_notes.note[queued_notes.size - 1], port_buf, i); queued_notes.size--; } if (strummer_action != STRUMMER_ACTION_NONE) { if (strummer_action == STRUMMER_ACTION_MID_DOWN || strummer_action == STRUMMER_ACTION_MID_UP) { strum_chord(chord[chord_state], port_buf, i); strummer_action = STRUMMER_ACTION_NONE; } else { if (strummer_state != STRUMMER_STATE_SUSTAINED) { mute(port_buf, i); strummer_action = STRUMMER_ACTION_NONE; } } } if (whammy_action != WHAMMY_ACTION_NONE) { buffer = jack_midi_event_reserve(port_buf, i, 3); unsigned int pitch_shift = (MIDI_PITCH_CENTER * whammy_state) / CWIID_GUITAR_WHAMMY_MAX ; unsigned int pitch_value = MIDI_PITCH_CENTER - pitch_shift; buffer[2] = (pitch_value & 0x3F80) >> 7; // most significant bits buffer[1] = pitch_value & 0x007f; // least significant bits buffer[0] = MIDI_PITCH_WHEEL + midi_channel; // pitch wheel change printf("whammy! %x, %x, %x, desimalt: %d\n", buffer[0], buffer[2], buffer[1], pitch_value); whammy_action = WHAMMY_ACTION_NONE; } if (touchbar_action != TOUCHBAR_ACTION_NONE) { buffer = jack_midi_event_reserve(port_buf, i, 3); // scale input to output values (5th represents maximum possible input value) unsigned int modulation = (MIDI_MODULATION_MAX * touchbar_state) / CWIID_GUITAR_TOUCHBAR_5TH ; printf("touchbar action! %d, %x, sent %x\n", touchbar_action, touchbar_state, modulation); buffer[2] = modulation; buffer[1] = 0x1; // modulation buffer[0] = MIDI_CONTROL_CHANGE + midi_channel; // control change touchbar_action = TOUCHBAR_ACTION_NONE; } if (stick_action != STICK_ACTION_NONE) { printf("stick_action!\n"); unsigned int volume = last_sent_volume_value; if (stick_action == STICK_ACTION_ROTATE_COUNTER_CLOCKWISE) { volume += stick_zone_average_value / 2 ; if (volume > 127) { volume = 127; } } else if (stick_action == STICK_ACTION_ROTATE_CLOCKWISE) { if (volume >= stick_zone_average_value / 2) { volume -= stick_zone_average_value / 2; } else { volume = 0; } } if (volume != last_sent_volume_value) { printf("volume: %d\n", volume); buffer = jack_midi_event_reserve(port_buf, i, 3); buffer[2] = volume; buffer[1] = 0x7; // volume buffer[0] = MIDI_CONTROL_CHANGE + midi_channel; // control change last_sent_volume_value = volume; } stick_action = STICK_ACTION_NONE; } while (drums_action != 0) { uint8_t send_note_off = 0; buffer = jack_midi_event_reserve(port_buf, i, 3); buffer[2] = 0x7F; /* velocity */ if ((drums_action & RED) == RED) { /* if ((drums_state & RED) == RED) { send_note_off = 1; } drums_state ^= RED; */ buffer[1] = 38; /* note number */ drums_action &= ~RED; } else if ((drums_action & YELLOW) == YELLOW) { /* if ((drums_state & YELLOW) == YELLOW) { send_note_off = 1; } drums_state ^= YELLOW; */ buffer[1] = 42; /* note number */ drums_action &= ~YELLOW; } else if ((drums_action & BLUE) == BLUE) { /* if ((drums_state & BLUE) == BLUE) { send_note_off = 1; } drums_state ^= BLUE; */ buffer[1] = 48; /* note number */ drums_action &= ~BLUE; } else if ((drums_action & ORANGE) == ORANGE) { /* if ((drums_state & ORANGE) == ORANGE) { send_note_off = 1; } drums_state ^= ORANGE; */ buffer[1] = 51; /* note number */ drums_action &= ~ORANGE; } else if ((drums_action & GREEN) == GREEN) { /* if ((drums_state & GREEN) == GREEN) { send_note_off = 1; } drums_state ^= GREEN; */ buffer[1] = 45; /* note number */ drums_action &= ~GREEN; } else if ((drums_action & PEDAL) == PEDAL) { /* if ((drums_state & PEDAL) == PEDAL) { send_note_off = 1; } drums_state ^= PEDAL; */ buffer[1] = 36; /* note number */ drums_action &= ~PEDAL; } if (send_note_off) { buffer[0] = MIDI_NOTE_OFF + 9; // note off } else { buffer[0] = MIDI_NOTE_ON + 9; // note on } } if (crossfader_action != CROSSFADER_ACTION_NONE) { buffer = jack_midi_event_reserve(port_buf, i, 3); uint8_t crossfader_midi_value = current_turntables_state.crossfader * 127 / CWIID_TURNTABLES_CROSSFADER_MAX; buffer[2] = crossfader_midi_value; buffer[1] = MIDI_BALANCE_MSB; buffer[0] = MIDI_CONTROL_CHANGE + midi_channel; // control change crossfader_action = CROSSFADER_ACTION_NONE; } if (effect_dial_action != EFFECT_DIAL_ACTION_NONE) { buffer = jack_midi_event_reserve(port_buf, i, 3); buffer[0] = MIDI_CONTROL_CHANGE + midi_channel; // control change buffer[1] = MIDI_EFFECT_CTL_1_MSB; int16_t signed_value; switch (effect_dial_action) { case EFFECT_DIAL_ACTION_ROTATE_CLOCKWISE: effect_dial_state.value += effect_dial_state.change; if (effect_dial_state.value > effect_dial_state.max_value) { effect_dial_state.value = effect_dial_state.max_value; } break; case EFFECT_DIAL_ACTION_ROTATE_COUNTER_CLOCKWISE: signed_value = effect_dial_state.value + effect_dial_state.change; effect_dial_state.value += effect_dial_state.change; if (signed_value < effect_dial_state.min_value) { effect_dial_state.value = effect_dial_state.min_value; } break; case EFFECT_DIAL_ACTION_INITIALIZE: printf("initialize\n"); current_turntables_state.effect_dial = effect_dial_state.initial_value; break; } buffer[2] = effect_dial_state.value; effect_dial_action = EFFECT_DIAL_ACTION_NONE; } }