static int sync_callback(jack_transport_state_t state, jack_position_t *position, void *notused) { assert(jack_client); g_debug("SYNC_CALLBACK"); if (!use_transport) return TRUE; int res = FALSE; if (pthread_mutex_trylock(&mutex) == 0) { if ((smf = smf_vol) != NULL) { if (!be_quiet) g_debug("Seeking to %f seconds.", nframes_to_seconds(position->frame)); res = loop_seek(smf, nframes_to_seconds(position->frame)); } else { res = TRUE; } pthread_mutex_unlock(&mutex); } ready_to_roll = res; return res; }
static int stream_callback (const void *input_buffer, void *output_buffer, unsigned long frames_per_buffer, const PaStreamCallbackTimeInfo * time_info, PaStreamCallbackFlags status_flags, void *user_data) { float **buffers = (float **) output_buffer; #ifdef _HAVE_RUBBERBAND_ static gboolean initialized = FALSE; if (!initialized) { rubberband_set_max_process_size(rubberband, frames_per_buffer); initialized = TRUE; } #endif size_t i; for (i = 0; i < 2; ++i) { memset (buffers[i], 0, frames_per_buffer * sizeof (float)); } if (!ready) return paContinue; #ifdef _HAVE_FLUIDSYNTH_ if (reset_audio) { fluidsynth_all_notes_off (); reset_synth_channels (); reset_audio = FALSE; return paContinue; } unsigned char event_data[MAX_MESSAGE_LENGTH]; //needs to be long enough for variable length messages... size_t event_length = MAX_MESSAGE_LENGTH; double event_time; double until_time = nframes_to_seconds (playback_frame + frames_per_buffer); #ifdef _HAVE_RUBBERBAND_ gint available = rubberband_available(rubberband); if((!rubberband_active) || (available < (gint)frames_per_buffer)) { #endif while (read_event_from_queue (AUDIO_BACKEND, event_data, &event_length, &event_time, until_time/slowdown)) {//g_print("%x %x %x\n", event_data[0], event_data[1], event_data[2] ); fluidsynth_feed_midi (event_data, event_length); //in fluid.c note fluidsynth api ues fluid_synth_xxx these naming conventions are a bit too similar } fluidsynth_render_audio (frames_per_buffer, buffers[0], buffers[1]); //in fluid.c calls fluid_synth_write_float() // Now get any audio to mix - dump it in the left hand channel for now event_length = frames_per_buffer; read_event_from_mixer_queue (AUDIO_BACKEND, (void *) buffers[1], &event_length); #ifdef _HAVE_RUBBERBAND_ } //if there is stuff available use it and give buffers[] to rubber band to process if(rubberband_active) { if(available < (gint)frames_per_buffer) rubberband_process(rubberband, (const float * const*)buffers, frames_per_buffer, 0); available = rubberband_available(rubberband); if(available >= (gint)frames_per_buffer) { rubberband_retrieve(rubberband, buffers, frames_per_buffer);//re-use buffers[] as they are available... write_samples_to_rubberband_queue (AUDIO_BACKEND, buffers[0], frames_per_buffer); write_samples_to_rubberband_queue (AUDIO_BACKEND, buffers[1], frames_per_buffer); available -= frames_per_buffer; } event_length = frames_per_buffer; read_event_from_rubberband_queue (AUDIO_BACKEND, (unsigned char *) buffers[0], &event_length); event_length = frames_per_buffer; read_event_from_rubberband_queue (AUDIO_BACKEND, (unsigned char *) buffers[1], &event_length); } #endif //_HAVE_RUBBERBAND_ if (until_time < get_playuntil ()) { #endif //_HAVE_FLUIDSYNTH_ playback_frame += frames_per_buffer; update_playback_time (TIMEBASE_PRIO_AUDIO, nframes_to_seconds (playback_frame)); #ifdef _HAVE_FLUIDSYNTH_ } #endif //_HAVE_FLUIDSYNTH_ // This is probably a bad idea to do heavy work in an audio callback record_audio(buffers, frames_per_buffer); return paContinue; }
void process_midi_input (jack_nframes_t nframes) { static int time_of_first_event = -1; int /*read,*/ events, i, channel; jack_midi_event_t event; int last_frame_time = jack_last_frame_time(jack_client); void * port_buffer = jack_port_get_buffer(input_port, nframes); if (port_buffer == NULL) { warn_from_jack_thread_context ( "jack_port_get_buffer failed, cannot receive anything." ); return; } #ifdef JACK_MIDI_NEEDS_NFRAMES events = jack_midi_get_event_count(port_buffer, nframes); #else events = jack_midi_get_event_count(port_buffer); #endif for (i = 0; i < events; ++i) { smf_event_t * smf_event; #ifdef JACK_MIDI_NEEDS_NFRAMES int read = jack_midi_event_get(&event, port_buffer, i, nframes); #else int read = jack_midi_event_get(&event, port_buffer, i); #endif if (read) { warn_from_jack_thread_context("jack_midi_event_get failed, RECEIVED NOTE LOST."); continue; } if (event.buffer[0] >= 0xF8) /* Ignore realtime messages. */ continue; if (time_of_first_event == -1) /* First event received? */ time_of_first_event = last_frame_time + event.time; smf_event = smf_event_new_from_pointer(event.buffer, event.size); if (smf_event == NULL) { warn_from_jack_thread_context ( "smf_event_from_pointer failed, RECEIVED NOTE LOST." ); continue; } // assert(smf_event->midi_buffer_length >= 1); channel = smf_event->midi_buffer[0] & 0x0F; smf_track_add_event_seconds ( tracks[channel], smf_event, nframes_to_seconds ( jack_last_frame_time(jack_client) + event.time - time_of_first_event ) ); } }