jack_nframes_t ja_cycle_begin(void) { int i; jack_nframes_t frames; if (ja_status != JA_RUNNING) return 0; /* * In JACK2, `sem_timedwait' is interrupted by SIGUSR2 during the gc. * We are within SB-SYS:WITHOUT-GCING but the inhibition of the gc is * not guaranteed, therefore it is not a good idea to block this signal * around `jack_cycle_wait', because it could cause the arrest of SBCL. */ frames = jack_cycle_wait(client); if (ja_status != JA_RUNNING) return 0; for (i = 0; i < ja_in_channels; i++) { int j; SAMPLE *tmp; ja_inputs[i] = jack_port_get_buffer(input_ports[i], frames); tmp = lisp_input + i; for (j = 0; j < frames; j++) { *tmp = (SAMPLE) ja_inputs[i][j]; tmp += ja_in_channels; } } for (i = 0; i < ja_out_channels; i++) ja_outputs[i] = jack_port_get_buffer(output_ports[i], frames); return frames; }
static void* ja_process_thread(void *arg) { (void) arg; while (ja_status == JA_RUNNING) { if (ja_lisp_busy) { int i; jack_nframes_t frames = jack_cycle_wait(client); if (ja_frames != frames) { /* Buffer size is changed */ ja_frames = frames; ja_buffer_bytes = frames * JA_SAMPLE_SIZE; } for (i = 0; i < ja_out_channels; i++) { ja_outputs[i] = jack_port_get_buffer(output_ports[i], ja_frames); /* Silence while lisp is busy */ memset(ja_outputs[i], 0, ja_buffer_bytes); } jack_cycle_signal(client, 0); } else { /* * Transfer the control of the client to lisp realtime * thread and block the current thread. * * Notice it is called ONLY ONE TIME after the first * cycle and ONLY ONE TIME after the gc in SBCL. The rt * lisp thread uses `jack_cycle_wait' and `jack_cycle_signal' * with the actual jack client. Practically, this thread * is an emergency exit when we use an implementation of * Common Lisp with a gc which stops the rt lisp thread. * If the implementation of CL has a realtime gc, there * aren't other transfers of the control from C to Lisp * and vice versa. */ __ja_condition_signal(&ja_lisp_cond, &ja_lisp_lock); __ja_condition_wait(&ja_c_cond, &ja_c_lock); } } return 0; }
void midiMainLoop(void) { fprintf (stderr, "midiMainLoop\n"); jack_midi_event_t input_event; int timeout = 10*1000*1000+time_us(); // 10 seconds in microseconds //int exitMainLoop = 0; while (!exitMainLoop) { jack_nframes_t nframes = jack_cycle_wait(jack_client); /* Get input and output buffer pointers. */ void* input_buf = jack_port_get_buffer (jack_midi_input_port, nframes); //void* output_buf = jack_port_get_buffer (jack_midi_output_port, nframes); jack_nframes_t input_event_count = jack_midi_get_event_count(input_buf); if (input_event_count>0) { unsigned int event_index = 0; for (;event_index<input_event_count;event_index++) { if (0==jack_midi_event_get(&input_event, input_buf, event_index)) { if (input_event.size > 0) { printhex("receive:", input_event.buffer,input_event.size); int i = 0; for (; i < input_event.size; i++) { midiReceive(input_event.buffer[i]); } } } } } if (time_us() > timeout) { fprintf(stderr, "timeout\n"); exit(1); } } jack_end(); fprintf (stderr, "midiMainLoop:end\n"); }
static void* jack_thread(void *arg) { jack_client_t* client = (jack_client_t*) arg; while (1) { jack_nframes_t frames = jack_cycle_wait (client); int status = _process(frames); jack_cycle_signal (client, status); /* Possibly do something else after signaling next clients in the graph */ /* End condition */ if (status != 0) return 0; } /* not reached*/ return 0; }