Ejemplo n.º 1
0
void
ags_recall_real_remove(AgsRecall *recall)
{
  AgsRecall *parent;

  ags_dynamic_connectable_disconnect_dynamic(AGS_DYNAMIC_CONNECTABLE(recall));

  if(recall->parent == NULL){
    parent = NULL;
    g_object_unref(recall);
    return;
  }else{
    parent = AGS_RECALL(recall->parent);

    parent->children = g_list_remove(parent->children, recall);
  }

  if(parent != NULL &&
     (AGS_RECALL_PROPAGATE_DONE & (parent->flags)) != 0 &&
     parent->children == NULL){
    ags_recall_done(parent);
  }

  g_object_unref(recall);
}
Ejemplo n.º 2
0
void
ags_recall_real_cancel(AgsRecall *recall)
{
  GList *list;

  if((AGS_RECALL_TEMPLATE & (recall->flags)) != 0){
    return;
  }

  /* call cancel for children */
  list = recall->children;

  while(list != NULL){
    ags_recall_cancel(AGS_RECALL(list->data));

    list = list->next;
  }

  if((AGS_RECALL_PERSISTENT & (recall->flags)) != 0 ||
     (AGS_RECALL_PERSISTENT_PLAYBACK & (recall->flags)) != 0){
    ags_recall_stop_persistent(recall);
  }else{
    ags_recall_done(recall);
  }
}
Ejemplo n.º 3
0
/**
 * ags_recall_stop_persistent:
 * @recall an #AgsRecall
 *
 * Unsets the %AGS_RECALL_PERSISTENT flag set and invokes ags_recall_done().
 */
void
ags_recall_stop_persistent(AgsRecall *recall)
{
  recall->flags &= (~(AGS_RECALL_PERSISTENT |
		      AGS_RECALL_PERSISTENT_PLAYBACK |
		      AGS_RECALL_PERSISTENT_SEQUENCER |
		      AGS_RECALL_PERSISTENT_NOTATION));

  ags_recall_done(recall);
}
Ejemplo n.º 4
0
void
ags_recall_dssi_run_run_pre(AgsRecall *recall)
{
  AgsRecallDssi *recall_dssi;
  AgsRecallChannelRun *recall_channel_run;
  AgsRecallRecycling *recall_recycling;
  AgsRecallDssiRun *recall_dssi_run;
  AgsAudioSignal *audio_signal;
  AgsPort *current_port;
  AgsRecallID *recall_id;
  AgsRecyclingContext *parent_recycling_context, *recycling_context;
  
  AgsCountBeatsAudioRun *count_beats_audio_run;
  AgsRouteDssiAudioRun *route_dssi_audio_run;
    
  GList *list_start, *list;
  GList *port;
  
  GList *note_start, *note;

  snd_seq_event_t **event_buffer;
  unsigned long *event_count;
    
  gchar *specifier, *current_specifier;
  
  LADSPA_Data port_data;

  guint bank, program;
  guint output_lines, input_lines;
  guint notation_counter;
  guint x0, x1;
  guint port_count;
  
  guint copy_mode_in, copy_mode_out;
  guint buffer_size;
  guint i, i_stop;

  void (*parent_class_run_pre)(AgsRecall *recall);

  void (*select_program)(LADSPA_Handle Instance,
			 unsigned long Bank,
			 unsigned long Program);
  void (*run_synth)(LADSPA_Handle Instance,
		    unsigned long SampleCount,
		    snd_seq_event_t *Events,
		    unsigned long EventCount);
  void (*run)(LADSPA_Handle Instance,
	      unsigned long SampleCount);
  void (*deactivate)(LADSPA_Handle Instance);
  void (*cleanup)(LADSPA_Handle Instance);
  
  pthread_mutex_t *recall_dssi_mutex;
  pthread_mutex_t *port_mutex;

  /* get parent class */
  pthread_mutex_lock(ags_recall_get_class_mutex());

  parent_class_run_pre = AGS_RECALL_CLASS(ags_recall_dssi_run_parent_class)->run_pre;
  
  pthread_mutex_unlock(ags_recall_get_class_mutex());

  /* call parent */
  parent_class_run_pre(recall);

  g_object_get(recall,
	       "recall-id", &recall_id,
	       "source", &audio_signal,
	       NULL);

  g_object_get(recall_id,
	       "recycling-context", &recycling_context,
	       NULL);

  g_object_get(recycling_context,
	       "parent", &parent_recycling_context,
	       NULL);

  g_object_get(audio_signal,
	       "note", &note_start,
	       NULL);

  if(ags_recall_global_get_rt_safe() &&
     parent_recycling_context != NULL &&
     note_start == NULL){
    g_object_unref(recall_id);

    g_object_unref(audio_signal);
    
    g_object_unref(recycling_context);

    g_object_unref(parent_recycling_context);
    
    return;
  }

  g_list_free_full(note_start,
		   g_object_unref);
  
  g_object_get(recall,
	       "parent", &recall_recycling,
	       NULL);

  g_object_get(recall_recycling,
	       "parent", &recall_channel_run,
	       NULL);

  g_object_get(recall_channel_run,
	       "recall-channel", &recall_dssi,
	       NULL);

  recall_dssi_run = AGS_RECALL_DSSI_RUN(recall);

  g_object_get(recall_dssi_run,
	       "route-dssi-audio-run", &route_dssi_audio_run,
	       NULL);
  
  if(route_dssi_audio_run == NULL){
    g_object_unref(recall_id);

    g_object_unref(audio_signal);

    g_object_unref(recycling_context);

    g_object_unref(parent_recycling_context);

    g_object_unref(recall_recycling);
    
    g_object_unref(recall_channel_run);

    g_object_unref(recall_dssi);

    return;
  }

  /* get recall dssi mutex */
  pthread_mutex_lock(ags_recall_get_class_mutex());
  
  recall_dssi_mutex = AGS_RECALL(recall_dssi)->obj_mutex;
  
  pthread_mutex_unlock(ags_recall_get_class_mutex());

  g_object_get(route_dssi_audio_run,
	       "count-beats-audio-run", &count_beats_audio_run,
	       NULL);

  g_object_get(audio_signal,
	       "buffer-size", &buffer_size,
	       NULL);

  /* get some fields */
  pthread_mutex_lock(recall_dssi_mutex);

  output_lines = recall_dssi->output_lines;
  input_lines = recall_dssi->input_lines;

  pthread_mutex_unlock(recall_dssi_mutex);

  if(input_lines < output_lines){
    i_stop = output_lines;
  }else{
    i_stop = input_lines;
  }

  g_object_get(count_beats_audio_run,
	       "notation-counter", &notation_counter,
	       NULL);
  
  if(ags_recall_global_get_rt_safe()){  
    g_object_get(recall_dssi_run,
		 "note", &note_start,
		 NULL);
    
    note = note_start;
    
    while(note != NULL){
      g_object_get(note->data,
		   "x0", &x0,
		   "x1", &x1,
		   NULL);
	
      if((x1 + 1 <= notation_counter &&
	  !ags_note_test_flags(note->data, AGS_NOTE_FEED)) ||
	 x0 > notation_counter){
	recall_dssi_run->note = g_list_remove(recall_dssi_run->note,
					      note->data);
	g_object_unref(note->data);
      }
    
      note = note->next;
    }
    
    if(note_start == NULL){
      memset(recall_dssi_run->event_buffer[0], 0, sizeof(snd_seq_event_t));
    }

    g_list_free_full(note_start,
		     g_object_unref);
  }else{  
    g_object_get(recall_dssi_run,
		 "note", &note_start,
		 NULL);
    
    g_object_get(note_start->data,
		 "x0", &x0,
		 "x1", &x1,
		 NULL);
    
    if(audio_signal->stream_current == NULL ||
       (x1 + 1 <= notation_counter &&
	!ags_note_test_flags(note_start->data, AGS_NOTE_FEED)) ||
       x0 > notation_counter){
      //    g_message("done");

      pthread_mutex_lock(recall_dssi_mutex);

      deactivate = recall_dssi->plugin_descriptor->LADSPA_Plugin->deactivate;
      cleanup = recall_dssi->plugin_descriptor->LADSPA_Plugin->cleanup;
      
      pthread_mutex_unlock(recall_dssi_mutex);
      
      for(i = 0; i < i_stop; i++){
	/* deactivate */
	//TODO:JK: fix-me
	if(deactivate != NULL){
	  deactivate(recall_dssi_run->ladspa_handle[i]);
	}
      
	cleanup(recall_dssi_run->ladspa_handle[i]);
      }
      
      ags_recall_done(recall);

      g_list_free_full(note_start,
		       g_object_unref);

      goto ags_recall_dssi_run_run_pre_END;
    }
  }
  
  /* get copy mode and clear buffer */
  copy_mode_in = ags_audio_buffer_util_get_copy_mode(AGS_AUDIO_BUFFER_UTIL_FLOAT,
						     ags_audio_buffer_util_format_from_soundcard(audio_signal->format));

  copy_mode_out = ags_audio_buffer_util_get_copy_mode(ags_audio_buffer_util_format_from_soundcard(audio_signal->format),
						      AGS_AUDIO_BUFFER_UTIL_FLOAT);
  
  if(recall_dssi_run->output != NULL){
    ags_audio_buffer_util_clear_float(recall_dssi_run->output, output_lines,
				      buffer_size);
  }

  if(recall_dssi_run->input != NULL){
    ags_audio_buffer_util_clear_float(recall_dssi_run->input, input_lines,
				      buffer_size);
  }

  /* copy data  */
  if(recall_dssi_run->input != NULL){
    ags_audio_buffer_util_copy_buffer_to_buffer(recall_dssi_run->input, input_lines, 0,
						audio_signal->stream_current->data, 1, 0,
						buffer_size, copy_mode_in);
  }

  /* select program */
  pthread_mutex_lock(recall_dssi_mutex);

  port_count = recall_dssi->plugin_descriptor->LADSPA_Plugin->PortCount;

  select_program = recall_dssi->plugin_descriptor->select_program;
  
  pthread_mutex_unlock(recall_dssi_mutex);

  /* cache port data */
  g_object_get(recall_dssi,
	       "port", &list_start,
	       NULL);
  
  for(i = 0; i < port_count; i++){
    pthread_mutex_lock(recall_dssi_mutex);

    specifier = g_strdup(recall_dssi->plugin_descriptor->LADSPA_Plugin->PortNames[i]);

    pthread_mutex_unlock(recall_dssi_mutex);

    list = list_start;
    
    while(list != NULL){
      gboolean success;
      
      current_port = list->data;

      /* get port mutex */
      pthread_mutex_lock(ags_port_get_class_mutex());

      port_mutex = current_port->obj_mutex;
      
      pthread_mutex_unlock(ags_port_get_class_mutex());

      /* check specifier */
      pthread_mutex_lock(port_mutex);

      current_specifier = g_strdup(current_port->specifier);
      
      pthread_mutex_unlock(port_mutex);
      
      success = (!g_strcmp0(specifier,
			    current_specifier)) ? TRUE: FALSE;
      g_free(current_specifier);
	
      if(success){
	GValue value = {0,};
	  
	g_value_init(&value,
		     G_TYPE_FLOAT);
	ags_port_safe_read(current_port,
			   &value);
	
	recall_dssi_run->port_data[i] = g_value_get_float(&value);

	g_value_unset(&value);
	
	break;
      }

      list = list->next;
    }

    g_free(specifier);
  }

  g_object_get(recall_dssi,
	       "bank", &bank,
	       "program", &program,
	       NULL);
  
  if(select_program != NULL){    
    for(i = 0; i < i_stop; i++){
      select_program(recall_dssi_run->ladspa_handle[i],
		     (unsigned long) bank,
		     (unsigned long) program);

      //      g_message("b p %u %u", bank, program);
    }
  }

  /* reset port data */    
  for(i = 0; i < port_count; i++){
    pthread_mutex_lock(recall_dssi_mutex);

    specifier = g_strdup(recall_dssi->plugin_descriptor->LADSPA_Plugin->PortNames[i]);

    pthread_mutex_unlock(recall_dssi_mutex);

    list = list_start;
    current_port = NULL;
    
    while(list != NULL){
      gboolean success;
      
      current_port = list->data;

      /* get port mutex */
      pthread_mutex_lock(ags_port_get_class_mutex());

      port_mutex = current_port->obj_mutex;
      
      pthread_mutex_unlock(ags_port_get_class_mutex());

      /* check specifier */
      pthread_mutex_lock(port_mutex);

      current_specifier = g_strdup(current_port->specifier);
      
      pthread_mutex_unlock(port_mutex);
      
      success = (!g_strcmp0(specifier,
			    current_specifier)) ? TRUE: FALSE;
      g_free(current_specifier);

      if(success){
	break;
      }

      list = list->next;
    }

    g_free(specifier);

    if(list != NULL){
      GValue value = {0,};
      
      g_value_init(&value,
		   G_TYPE_FLOAT);
      port_data = recall_dssi_run->port_data[i];

      g_value_set_float(&value,
			port_data);
      ags_port_safe_write(current_port,
			  &value);

      g_value_unset(&value);
    }
  }

  g_list_free_full(list_start,
		   g_object_unref);
  
  /* process data */
  pthread_mutex_lock(recall_dssi_mutex);

  run_synth = recall_dssi->plugin_descriptor->run_synth;
  run = recall_dssi->plugin_descriptor->LADSPA_Plugin->run;
  
  pthread_mutex_unlock(recall_dssi_mutex);

  g_object_get(recall_dssi_run,
	       "note", &note_start,
	       NULL);
  
  note = note_start;

  while(note != NULL){    
    if(run_synth != NULL){
      if(recall_dssi_run->event_buffer != NULL){
	event_buffer = recall_dssi_run->event_buffer;
	event_count = recall_dssi_run->event_count;
      
	while(*event_buffer != NULL){
	  if(event_buffer[0]->type == SND_SEQ_EVENT_NOTEON){
	    run_synth(recall_dssi_run->ladspa_handle[0],
		      (unsigned long) (output_lines * buffer_size),
		      event_buffer[0],
		      event_count[0]);
	  }
	  
	  event_buffer++;
	  event_count++;
	}
      }
    }else if(run != NULL){
      run(recall_dssi_run->ladspa_handle[0],
	  (unsigned long) buffer_size);
    }

    note = note->next;
  }

  g_list_free_full(note_start,
		   g_object_unref);
  
  /* copy data */
  if(recall_dssi_run->output != NULL){
    ags_audio_buffer_util_clear_buffer(audio_signal->stream_current->data, 1,
				       buffer_size, ags_audio_buffer_util_format_from_soundcard(audio_signal->format));
    
    ags_audio_buffer_util_copy_buffer_to_buffer(audio_signal->stream_current->data, 1, 0,
						recall_dssi_run->output, output_lines, 0,
						buffer_size, copy_mode_out);
  }

ags_recall_dssi_run_run_pre_END:
  
  g_object_unref(recall_id);

  g_object_unref(recycling_context);

  g_object_unref(parent_recycling_context);

  g_object_unref(recall_recycling);
    
  g_object_unref(recall_channel_run);

  g_object_unref(recall_dssi);

  g_object_unref(count_beats_audio_run);
}
Ejemplo n.º 5
0
void
ags_play_audio_signal_run_inter(AgsRecall *recall)
{
  AgsDevout *devout;
  AgsRecycling *recycling;
  AgsAudioSignal *source;
  AgsPlayChannel *play_channel;
  AgsPlayAudioSignal *play_audio_signal;
  GList *stream;
  signed short *buffer0, *buffer1;
  guint audio_channel;
  gboolean muted;
  GValue muted_value = {0,};
  GValue audio_channel_value = {0,};

  play_audio_signal = AGS_PLAY_AUDIO_SIGNAL(recall);

  devout = AGS_DEVOUT(AGS_RECALL(play_audio_signal)->devout);
  source = AGS_AUDIO_SIGNAL(AGS_RECALL_AUDIO_SIGNAL(play_audio_signal)->source);
  stream = source->stream_current;

  if(devout == NULL){
    g_warning("no devout\0");
    return;
  }

  if(stream == NULL){
    ags_recall_done(recall);

    return;
  }

  if((AGS_DEVOUT_BUFFER0 & devout->flags) != 0){
    buffer0 = devout->buffer[1];
    buffer1 = devout->buffer[2];
  }else if((AGS_DEVOUT_BUFFER1 & devout->flags) != 0){
    buffer0 = devout->buffer[2];
    buffer1 = devout->buffer[3];
  }else if((AGS_DEVOUT_BUFFER2 & devout->flags) != 0){
    buffer0 = devout->buffer[3];
    buffer1 = devout->buffer[0];
  }else if((AGS_DEVOUT_BUFFER3 & devout->flags) != 0){
    buffer0 = devout->buffer[0];
    buffer1 = devout->buffer[1];
  }else{
    g_warning("no output buffer\0");
    return;
  }

  play_channel = AGS_PLAY_CHANNEL(AGS_RECALL_CHANNEL_RUN(recall->parent->parent)->recall_channel);

  g_value_init(&muted_value, G_TYPE_BOOLEAN);
  ags_port_safe_read(play_channel->muted,
		     &muted_value);

  muted = g_value_get_boolean(&muted_value);

  if(muted){
    return;
  }

  g_value_init(&audio_channel_value, G_TYPE_UINT);
  ags_port_safe_read(play_channel->audio_channel,
		     &audio_channel_value);

  audio_channel = g_value_get_uint(&audio_channel_value);

  if((AGS_RECALL_INITIAL_RUN & (AGS_RECALL_AUDIO_SIGNAL(recall)->flags)) != 0){
    AGS_RECALL_AUDIO_SIGNAL(recall)->flags &= (~AGS_RECALL_INITIAL_RUN);
    ags_audio_signal_copy_buffer_to_buffer(&(buffer0[audio_channel + source->attack * devout->pcm_channels]),
					   devout->pcm_channels,
					   (signed short *) stream->data, 1,
					   AGS_DEVOUT_DEFAULT_BUFFER_SIZE - source->attack);
  }else{
    ags_audio_signal_copy_buffer_to_buffer(&(buffer0[audio_channel]), devout->pcm_channels,
					   (signed short *) stream->data, 1,
					   devout->buffer_size);
  }

  /* call parent */
  AGS_RECALL_CLASS(ags_play_audio_signal_parent_class)->run_inter(recall);
}
Ejemplo n.º 6
0
void
ags_stream_audio_signal_run_post(AgsRecall *recall)
{
  AgsStreamChannel *stream_channel;
  AgsStreamChannelRun *stream_channel_run;
  AgsStreamAudioSignal *stream_audio_signal;

  stream_audio_signal = AGS_STREAM_AUDIO_SIGNAL(recall);
  
  if(recall->parent != NULL &&
     recall->parent->parent != NULL){
    stream_channel_run = recall->parent->parent;
    stream_channel = AGS_RECALL_CHANNEL_RUN(stream_channel_run)->recall_channel;
  }else{
    stream_channel_run = NULL;
    stream_channel = NULL;
  }
  
  if(AGS_RECALL_AUDIO_SIGNAL(recall)->source->stream_current != NULL){
    if(stream_channel != NULL &&
       AGS_RECALL_AUDIO_SIGNAL(recall)->source->stream_current->next == NULL){
      GValue value = {0,};
      
      g_value_init(&value, G_TYPE_BOOLEAN);
      ags_port_safe_read(stream_channel->auto_sense,
			 &value);

      if(g_value_get_boolean(&value)){
	signed short *buffer;
	guint buffer_size;
	guint i;
	gboolean add_stream;

	buffer = AGS_RECALL_AUDIO_SIGNAL(recall)->source->stream_current->data;
	
	buffer_size = AGS_RECALL_AUDIO_SIGNAL(recall)->source->buffer_size;
	add_stream = FALSE;
	
	for(i = buffer_size - 1; i > buffer_size / 2; i--){
	  if(buffer[i] != 0){
	    add_stream = TRUE;
	    break;
	  }
	}
	
	if(add_stream){
	  ags_audio_signal_add_stream(AGS_RECALL_AUDIO_SIGNAL(recall)->source);
	}
      }
    }
    
    AGS_RECALL_AUDIO_SIGNAL(recall)->source->stream_current = AGS_RECALL_AUDIO_SIGNAL(recall)->source->stream_current->next;

    /* call parent */
    AGS_RECALL_CLASS(ags_stream_audio_signal_parent_class)->run_post(recall);
  }else{
    /* call parent */
    AGS_RECALL_CLASS(ags_stream_audio_signal_parent_class)->run_post(recall);

    if(recall->parent != NULL){
      ags_recycling_remove_audio_signal(AGS_RECALL_RECYCLING(recall->parent)->source,
					AGS_RECALL_AUDIO_SIGNAL(recall)->source);
    }

    ags_recall_done(recall);
  }
}
void
ags_stream_audio_signal_run_post(AgsRecall *recall)
{
  AgsAudioSignal *source;
  AgsStreamChannel *stream_channel;
  AgsStreamChannelRun *stream_channel_run;
  AgsStreamRecycling *stream_recycling;
  AgsStreamAudioSignal *stream_audio_signal;
  
  void (*parent_class_run_post)(AgsRecall *recall);

  stream_audio_signal = (AgsStreamAudioSignal *) recall;

  /* get parent class */
  pthread_mutex_lock(ags_recall_get_class_mutex());

  parent_class_run_post = AGS_RECALL_CLASS(ags_stream_audio_signal_parent_class)->run_post;

  pthread_mutex_unlock(ags_recall_get_class_mutex());

  g_object_get(stream_audio_signal,
	       "parent", &stream_recycling,
	       "source", &source,
	       NULL);
  
  g_object_get(stream_recycling,
	       "parent", &stream_channel_run,
	       NULL);

  g_object_get(stream_channel_run,
	       "recall-channel", &stream_channel,
	       NULL);

#ifdef AGS_DEBUG
  g_message("stream[%d] %x %d: %d", AGS_RECALL_CHANNEL(stream_channel)->source->line, source, g_list_length(source->stream), g_list_length(source->stream_current));
#endif
  
  if(source->stream_current != NULL){
    if(source->stream_current->next == NULL){
      AgsPort *port;

      gboolean auto_sense;
      
      GValue value = {0,};

      g_object_get(stream_channel,
		   "auto-sense", &port,
		   NULL);
      
      g_value_init(&value,
		   G_TYPE_BOOLEAN);
      
      ags_port_safe_read(port,
			 &value);

      auto_sense = g_value_get_boolean(&value);

      g_value_unset(&value);

      g_object_unref(port);
      
      if(auto_sense){
	void *buffer;
	guint buffer_size;
	guint format;
	guint i;
	gboolean add_stream;

	buffer = source->stream_current->data;

	g_object_get(source,
		     "buffer-size", &buffer_size,
		     "format", &format,
		     NULL);
	
	add_stream = FALSE;
	
	for(i = buffer_size - 1; i > buffer_size / 2 && !add_stream; i--){
	  switch(format){
	  case AGS_SOUNDCARD_SIGNED_8_BIT:
	    {
	      if(((gint8 *) buffer)[i] != 0){
		add_stream = TRUE;
	      }
	    }
	    break;
	  case AGS_SOUNDCARD_SIGNED_16_BIT:
	    {
	      if(((gint16 *) buffer)[i] != 0){
		add_stream = TRUE;
	      }
	    }
	    break;
	  case AGS_SOUNDCARD_SIGNED_24_BIT:
	    {
	      if(((gint32 *) buffer)[i] != 0){
		add_stream = TRUE;
	      }
	    }
	    break;
	  case AGS_SOUNDCARD_SIGNED_32_BIT:
	    {
	      if(((gint32 *) buffer)[i] != 0){
		add_stream = TRUE;
	      }
	    }
	    break;
	  case AGS_SOUNDCARD_SIGNED_64_BIT:
	    {
	      if(((gint64 *) buffer)[i] != 0){
		add_stream = TRUE;
	      }
	    }
	    break;
	  case AGS_SOUNDCARD_FLOAT:
	    {
	      if(((gfloat *) buffer)[i] != 0.0){
		add_stream = TRUE;
	      }
	    }
	    break;
	  case AGS_SOUNDCARD_DOUBLE:
	    {
	      if(((gdouble *) buffer)[i] != 0.0){
		add_stream = TRUE;
	      }
	    }
	    break;
	  default:
	    g_critical("unsupported soundcard format");
	  }
	}
	
	if(add_stream){
	  ags_audio_signal_add_stream(source);
	}
      }

      g_value_unset(&value);
    }

    source->stream_current = source->stream_current->next;
      
    /* call parent */
    parent_class_run_post(recall);
  }else{
    /* call parent */
    parent_class_run_post(recall);

    ags_recall_done(recall);
  }

  g_object_unref(stream_recycling);

  g_object_unref(source);

  g_object_unref(stream_channel_run);

  g_object_unref(stream_channel);
}
Ejemplo n.º 8
0
void
ags_recall_lv2_run_run_pre(AgsRecall *recall)
{
  AgsRecallLv2 *recall_lv2;
  AgsRecallChannelRun *recall_channel_run;
  AgsRecallRecycling *recall_recycling;
  AgsRecallLv2Run *recall_lv2_run;
  AgsAudioSignal *audio_signal;
  AgsPort *current_port;
  AgsRecallID *recall_id;
  AgsRecyclingContext *parent_recycling_context, *recycling_context;

  AgsCountBeatsAudioRun *count_beats_audio_run;
  AgsRouteLv2AudioRun *route_lv2_audio_run;

  GList *list_start, *list;
  GList *port;
  
  GList *note_start, *note;
  
  guint output_lines, input_lines;
  guint notation_counter;
  guint x0, x1;
  guint port_count;

  guint copy_mode_in, copy_mode_out;
  guint buffer_size;
  guint i;

  void (*parent_class_run_pre)(AgsRecall *recall);

  void (*run)(LV2_Handle instance,
	      uint32_t sample_count);
  void (*deactivate)(LV2_Handle instance);
  void (*cleanup)(LV2_Handle instance);
  
  pthread_mutex_t *recall_lv2_mutex;
  pthread_mutex_t *port_mutex;
  
  /* get parent class */
  pthread_mutex_lock(ags_recall_get_class_mutex());

  parent_class_run_pre = AGS_RECALL_CLASS(ags_recall_lv2_run_parent_class)->run_pre;
  
  pthread_mutex_unlock(ags_recall_get_class_mutex());

  /* call parent */
  parent_class_run_pre(recall);

  g_object_get(recall,
	       "recall-id", &recall_id,
	       "source", &audio_signal,
	       NULL);

  g_object_get(recall_id,
	       "recycling-context", &recycling_context,
	       NULL);

  g_object_get(recycling_context,
	       "parent", &parent_recycling_context,
	       NULL);

  g_object_get(audio_signal,
	       "note", &note_start,
	       NULL);

  if(ags_recall_global_get_rt_safe() &&
     parent_recycling_context != NULL &&
     note_start == NULL){
    g_object_unref(recall_id);

    g_object_unref(audio_signal);

    g_object_unref(recycling_context);

    g_object_unref(parent_recycling_context);

    return;
  }

  g_list_free_full(note_start,
		   g_object_unref);

  g_object_get(recall,
	       "parent", &recall_recycling,
	       NULL);

  g_object_get(recall_recycling,
	       "parent", &recall_channel_run,
	       NULL);

  g_object_get(recall_channel_run,
	       "recall-channel", &recall_lv2,
	       NULL);

  recall_lv2_run = AGS_RECALL_LV2_RUN(recall);

  g_object_get(recall_lv2_run,
	       "route-lv2-audio-run", &route_lv2_audio_run,
	       NULL);
  
  if(route_lv2_audio_run == NULL){
    g_object_unref(recall_id);

    g_object_unref(audio_signal);

    g_object_unref(recycling_context);

    if(parent_recycling_context != NULL){
      g_object_unref(parent_recycling_context);
    }
    
    g_object_unref(recall_recycling);
    
    g_object_unref(recall_channel_run);

    g_object_unref(recall_lv2);

    return;
  }

  /* get recall lv2 mutex */
  pthread_mutex_lock(ags_recall_get_class_mutex());
  
  recall_lv2_mutex = AGS_RECALL(recall_lv2)->obj_mutex;
  
  pthread_mutex_unlock(ags_recall_get_class_mutex());

  g_object_get(route_lv2_audio_run,
	       "count-beats-audio-run", &count_beats_audio_run,
	       NULL);

  g_object_get(audio_signal,
	       "buffer-size", &buffer_size,
	       NULL);

  /* get some fields */
  pthread_mutex_lock(recall_lv2_mutex);

  output_lines = recall_lv2->output_lines;
  input_lines = recall_lv2->input_lines;

  pthread_mutex_unlock(recall_lv2_mutex);

  g_object_get(count_beats_audio_run,
	       "notation-counter", &notation_counter,
	       NULL);
  
  g_object_get(recall_lv2_run,
	       "note", &note_start,
	       NULL);

  if(ags_recall_global_get_rt_safe()){
    note = note_start;

    while(note != NULL){
      g_object_get(note->data,
		   "x0", &x0,
		   "x1", &x1,
		   NULL);
       	
      if((x1 + 1 <= notation_counter &&
	  !ags_note_test_flags(note->data, AGS_NOTE_FEED)) ||
	 x0 > notation_counter){
	recall_lv2_run->note = g_list_remove(recall_lv2_run->note,
					     note->data);
	g_object_unref(note->data);
      }
    
      note = note->next;
    }

    g_list_free(note_start);
  }else{
    g_object_get(note_start->data,
		 "x0", &x0,
		 "x1", &x1,
		 NULL);
    
    if(audio_signal->stream_current == NULL ||
       (x1 + 1 <= notation_counter &&
	!ags_note_test_flags(note_start->data, AGS_NOTE_FEED)) ||
       x0 > notation_counter){
      //    g_message("done");
      pthread_mutex_lock(recall_lv2_mutex);

      deactivate = recall_lv2->plugin_descriptor->deactivate;
      cleanup = recall_lv2->plugin_descriptor->cleanup;
      
      pthread_mutex_unlock(recall_lv2_mutex);

      /* deactivate */
      if(deactivate != NULL){
	deactivate(recall_lv2_run->lv2_handle[0]);
      }

      /* cleanup */
      if(cleanup != NULL){
	cleanup(recall_lv2_run->lv2_handle[0]);
      }

      ags_recall_done(recall);
      g_list_free(note_start);
      
      goto ags_recall_lv2_run_run_pre_END;
    }
  }

  /* get copy mode and clear buffer */
  copy_mode_in = ags_audio_buffer_util_get_copy_mode(AGS_AUDIO_BUFFER_UTIL_FLOAT,
						     ags_audio_buffer_util_format_from_soundcard(audio_signal->format));

  copy_mode_out = ags_audio_buffer_util_get_copy_mode(ags_audio_buffer_util_format_from_soundcard(audio_signal->format),
						      AGS_AUDIO_BUFFER_UTIL_FLOAT);
  
  if(recall_lv2_run->output != NULL){
    ags_audio_buffer_util_clear_float(recall_lv2_run->output, 1,
				      output_lines * buffer_size);
  }

  if(recall_lv2_run->input != NULL){
    ags_audio_buffer_util_clear_float(recall_lv2_run->input, 1,
				      input_lines * buffer_size);
  }

  /* copy data  */
  if(recall_lv2_run->input != NULL){
    ags_audio_buffer_util_copy_buffer_to_buffer(recall_lv2_run->input, 1, 0,
						audio_signal->stream_current->data, 1, 0,
						(guint) buffer_size, copy_mode_in);
  }
  
  /* process data */
  pthread_mutex_lock(recall_lv2_mutex);

  run = recall_lv2->plugin_descriptor->run;
    
  pthread_mutex_unlock(recall_lv2_mutex);
  
  g_object_get(recall_lv2_run,
	       "note", &note_start,
	       NULL);
  
  note = note_start;

  while(note != NULL){
    run(recall_lv2_run->lv2_handle[0],
	(uint32_t) buffer_size);

    note = note->next;
  }

  g_list_free(note_start);

  /* copy data */
  if(recall_lv2_run->output != NULL){
    ags_audio_buffer_util_clear_buffer(audio_signal->stream_current->data, 1,
				       buffer_size, ags_audio_buffer_util_format_from_soundcard(audio_signal->format));
    
    ags_audio_buffer_util_copy_buffer_to_buffer(audio_signal->stream_current->data, 1, 0,
						recall_lv2_run->output, 1, 0,
						(guint) buffer_size, copy_mode_out);
  }

ags_recall_lv2_run_run_pre_END:
  
  g_object_unref(recall_id);

  g_object_unref(recycling_context);

  if(parent_recycling_context != NULL){
    g_object_unref(parent_recycling_context);
  }
  
  g_object_unref(recall_recycling);
    
  g_object_unref(recall_channel_run);

  g_object_unref(recall_lv2);

  g_object_unref(count_beats_audio_run);
}
Ejemplo n.º 9
0
void
ags_recall_lv2_run_run_inter(AgsRecall *recall)
{
  AgsRecallLv2 *recall_lv2;
  AgsRecallChannelRun *recall_channel_run;
  AgsRecallRecycling *recall_recycling;
  AgsRecallLv2Run *recall_lv2_run;
  AgsAudioSignal *audio_signal;

  AgsRecallID *recall_id;
  AgsRecyclingContext *parent_recycling_context, *recycling_context;

  AgsLv2Plugin *lv2_plugin;

  GList *note_start, *note;

  guint output_lines, input_lines;
  guint copy_mode_in, copy_mode_out;
  guint buffer_size;
  guint i;

  void (*parent_class_run_inter)(AgsRecall *recall);

  void (*run)(LV2_Handle instance,
	      uint32_t sample_count);
  void (*deactivate)(LV2_Handle instance);
  void (*cleanup)(LV2_Handle instance);
  
  pthread_mutex_t *recall_lv2_mutex;

  /* get recall mutex */
  pthread_mutex_lock(ags_recall_get_class_mutex());

  parent_class_run_inter = AGS_RECALL_CLASS(ags_recall_lv2_run_parent_class)->run_inter;
  
  pthread_mutex_unlock(ags_recall_get_class_mutex());

  /* call parent */
  parent_class_run_inter(recall);

  g_object_get(recall,
	       "source", &audio_signal,
	       "recall-id", &recall_id,
	       NULL);

  g_object_get(recall_id,
	       "recycling-context", &recycling_context,
	       NULL);

  g_object_get(recycling_context,
	       "parent", &parent_recycling_context,
	       NULL);

  g_object_get(audio_signal,
	       "note", &note_start,
	       NULL);

  if(ags_recall_global_get_rt_safe() &&
     parent_recycling_context != NULL &&
     note_start == NULL){
    g_object_unref(audio_signal);

    g_object_unref(recall_id);

    g_object_unref(recycling_context);

    g_object_unref(parent_recycling_context);
    
    return;
  }

  g_list_free_full(note_start,
		   g_object_unref);

  g_object_get(recall,
	       "parent", &recall_recycling,
	       NULL);

  g_object_get(recall_recycling,
	       "parent", &recall_channel_run,
	       NULL);

  g_object_get(recall_channel_run,
	       "recall-channel", &recall_lv2,
	       NULL);

  g_object_get(recall_lv2,
	       "plugin", &lv2_plugin,
	       NULL);
  
  recall_lv2_run = AGS_RECALL_LV2_RUN(recall);
  
  if(ags_lv2_plugin_test_flags(lv2_plugin,
			       AGS_LV2_PLUGIN_IS_SYNTHESIZER)){
    g_object_unref(audio_signal);

    g_object_unref(recall_id);

    g_object_unref(recycling_context);

    if(parent_recycling_context != NULL){
      g_object_unref(parent_recycling_context);
    }
    
    g_object_unref(recall_recycling);

    g_object_unref(recall_channel_run);

    g_object_unref(recall_lv2);

    g_object_unref(lv2_plugin);
    
    return;
  }

  /* get recall lv2 mutex */
  pthread_mutex_lock(ags_recall_get_class_mutex());
  
  recall_lv2_mutex = AGS_RECALL(recall_lv2)->obj_mutex;
  
  pthread_mutex_unlock(ags_recall_get_class_mutex());

  g_object_get(audio_signal,
	       "buffer-size", &buffer_size,
	       NULL);

  /* get some fields */
  pthread_mutex_lock(recall_lv2_mutex);

  output_lines = recall_lv2->output_lines;
  input_lines = recall_lv2->input_lines;

  run = recall_lv2->plugin_descriptor->run;

  deactivate = recall_lv2->plugin_descriptor->deactivate;
  cleanup = recall_lv2->plugin_descriptor->cleanup;
  
  pthread_mutex_unlock(recall_lv2_mutex);
  
  /* set up buffer */
  if(audio_signal->stream_current == NULL){
    //    g_message("done");
    /* deactivate */
    if(deactivate != NULL){
      deactivate(recall_lv2_run->lv2_handle[0]);
    }

    /* cleanup */
    if(cleanup != NULL){
      cleanup(recall_lv2_run->lv2_handle[0]);
    }

    ags_recall_done(recall);

    goto ags_recall_lv2_run_run_inter_END;
  }
  
  copy_mode_in = ags_audio_buffer_util_get_copy_mode(AGS_AUDIO_BUFFER_UTIL_FLOAT,
						     ags_audio_buffer_util_format_from_soundcard(audio_signal->format));

  copy_mode_out = ags_audio_buffer_util_get_copy_mode(ags_audio_buffer_util_format_from_soundcard(audio_signal->format),
						      AGS_AUDIO_BUFFER_UTIL_FLOAT);
  
  if(recall_lv2_run->output != NULL){
    ags_audio_buffer_util_clear_float(recall_lv2_run->output, output_lines,
				      buffer_size);
  }

  if(recall_lv2_run->input != NULL){
    ags_audio_buffer_util_clear_float(recall_lv2_run->input, input_lines,
				      buffer_size);
  }

  if(recall_lv2_run->input != NULL){
    ags_audio_buffer_util_copy_buffer_to_buffer(recall_lv2_run->input, (guint) input_lines, 0,
						audio_signal->stream_current->data, 1, 0,
						(guint) buffer_size, copy_mode_in);
  }
  
  /* process data */
  run(recall_lv2_run->lv2_handle[0],
      (uint32_t) buffer_size);
  
  /* copy data */
  if(recall_lv2_run->output != NULL){
    ags_audio_buffer_util_clear_buffer(audio_signal->stream_current->data, 1,
				       buffer_size, ags_audio_buffer_util_format_from_soundcard(audio_signal->format));
    
    ags_audio_buffer_util_copy_buffer_to_buffer(audio_signal->stream_current->data, 1, 0,
						recall_lv2_run->output, (guint) output_lines, 0,
						(guint) buffer_size, copy_mode_out);
  }

ags_recall_lv2_run_run_inter_END:
  
  g_object_unref(recall_id);

  g_object_unref(recycling_context);

  if(parent_recycling_context != NULL){
    g_object_unref(parent_recycling_context);
  }
  
  g_object_unref(recall_recycling);

  g_object_unref(recall_channel_run);

  g_object_unref(recall_lv2);

  g_object_unref(audio_signal);

  g_object_unref(lv2_plugin);
}