Example #1
0
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;
}
Example #2
0
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
         )
      );
   }
}