void ja_cycle_end(jack_nframes_t frames) { int i, j; SAMPLE *output = lisp_output; for (i = 0; i < frames; i++) { for (j = 0; j < ja_out_channels; j++) { ja_outputs[j][i] = (jack_default_audio_sample_t) *output; *output++ = (SAMPLE) 0.0; } } jack_cycle_signal(client, 0); }
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; }
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; }