void
ags_stream_audio_signal_finalize(GObject *gobject)
{
  if(AGS_RECALL_AUDIO_SIGNAL(gobject)->source != NULL &&
     AGS_RECALL(gobject)->parent != NULL){
    ags_recycling_remove_audio_signal(AGS_RECALL_RECYCLING(AGS_RECALL(gobject)->parent)->source,
				      AGS_RECALL_AUDIO_SIGNAL(gobject)->source);
  }
  //  g_object_unref(AGS_RECALL_AUDIO_SIGNAL(gobject)->source);	
  //  g_object_unref(AGS_RECALL_AUDIO_SIGNAL(gobject)->source);	

  /* call parent */
  G_OBJECT_CLASS(ags_stream_audio_signal_parent_class)->finalize(gobject); 
}
void
ags_recall_audio_signal_run_init_inter(AgsRecall *recall){
  AgsAudioSignal *source, *destination;

  source = AGS_RECALL_AUDIO_SIGNAL(recall)->source;
  destination = AGS_RECALL_AUDIO_SIGNAL(recall)->destination;

  AGS_RECALL_CLASS(ags_recall_audio_signal_parent_class)->run_init_inter(recall);

  if(source != NULL && (AGS_AUDIO_SIGNAL_TEMPLATE & (source->flags)) != 0)
    g_warning("AgsRecallAudioSignal@source - AGS_AUDIO_SIGNAL_TEMPLATE: run_init_inter\n\0");

  if(destination != NULL && (AGS_AUDIO_SIGNAL_TEMPLATE & (destination->flags)) != 0)
    g_warning("AgsRecallAudioSignal@destination - AGS_AUDIO_SIGNAL_TEMPLATE: run_init_inter\n\0");
}
void
ags_recall_audio_signal_get_property(GObject *gobject,
				   guint prop_id,
				   GValue *value,
				   GParamSpec *param_spec)
{
  AgsRecallAudioSignal *recall_audio_signal;

  recall_audio_signal = AGS_RECALL_AUDIO_SIGNAL(gobject);

  switch(prop_id){
  case PROP_AUDIO_CHANNEL:
    {
      g_value_set_uint(value, recall_audio_signal->audio_channel);
    }
    break;
  case PROP_DESTINATION:
    {
      g_value_set_object(value, recall_audio_signal->destination);
    }
    break;
  case PROP_SOURCE:
    {
      g_value_set_object(value, recall_audio_signal->source);
    }
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
    break;
  }
}
Exemple #4
0
/**
 * ags_recall_find_type:
 * @recall_i a #GList containing recalls
 * @provider a #GObject
 * Returns: a #GList containing recalls, or #NULL if not found
 * 
 * Finds next matching recall for type which has @provider. The @provider may be either an #AgsChannel
 * or an #AgsAudio object. This function tries to find the corresponding #AgsRecallChannel and #AgsRecallAudio
 * objects of a #AgsRecall to find. If these recalls contains the @provider, the function will return.
 */
GList*
ags_recall_find_provider(GList *recall_i, GObject *provider)
{
  AgsRecall *recall;

  while(recall_i != NULL){
    recall = AGS_RECALL(recall_i->data);

    if(AGS_IS_AUDIO(provider)){
      if(AGS_IS_RECALL_AUDIO(recall)){
	if(((GObject *) AGS_RECALL_AUDIO(recall)->audio) == provider)
	  return(recall_i);
      }else if(AGS_IS_RECALL_AUDIO_RUN(recall)){
	AgsRecallAudio *recall_audio;

	recall_audio = AGS_RECALL_AUDIO_RUN(recall)->recall_audio;

	if(recall_audio != NULL &&
	   ((GObject *) recall_audio->audio) == provider){
	  return(recall_i);
	}
      }
    }else if(AGS_IS_CHANNEL(provider)){
      if(AGS_IS_RECALL_CHANNEL(recall)){
	if(((GObject *) AGS_RECALL_CHANNEL(recall)->source) == provider)
	  return(recall_i);
      }else if(AGS_IS_RECALL_CHANNEL_RUN(recall)){
	if(((GObject *) AGS_RECALL_CHANNEL_RUN(recall)->source) == provider){
	  return(recall_i);
	}
      }
    }else if(AGS_IS_RECYCLING(provider)){
      if(AGS_IS_RECALL_RECYCLING(recall)){
	if(((GObject *) AGS_RECALL_RECYCLING(recall)->source) == provider){
	  return(recall_i);
	}
      }
    }else if(AGS_IS_AUDIO_SIGNAL(provider)){
      if(AGS_IS_RECALL_AUDIO_SIGNAL(recall)){
	if(((GObject *) AGS_RECALL_AUDIO_SIGNAL(recall)->source) == provider){
	  return(recall_i);
	}
      }
    }

    recall_i = recall_i->next;
  }

  return(NULL);
}
void
ags_stream_audio_signal_run_init_pre(AgsRecall *recall)
{
  void (*parent_class_run_init_pre)(AgsRecall *recall);

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

  parent_class_run_init_pre = AGS_RECALL_CLASS(ags_stream_audio_signal_parent_class)->run_init_pre;

  pthread_mutex_unlock(ags_recall_get_class_mutex());

  /* call parent */
  parent_class_run_init_pre(recall);
  
  AGS_STREAM_AUDIO_SIGNAL(recall)->dispose_source = (GObject *) AGS_RECALL_AUDIO_SIGNAL(recall)->source;
}
void
ags_recall_audio_signal_finalize(GObject *gobject)
{
  AgsRecallAudioSignal *recall_audio_signal;

  recall_audio_signal = AGS_RECALL_AUDIO_SIGNAL(gobject);

  if(recall_audio_signal->destination != NULL){
    g_object_unref(recall_audio_signal->destination);
  }

  if(recall_audio_signal->source != NULL){
    g_object_unref(recall_audio_signal->source);
  }

  /* call parent */
  G_OBJECT_CLASS(ags_recall_audio_signal_parent_class)->finalize(gobject);
}
AgsRecall*
ags_recall_audio_signal_duplicate(AgsRecall *recall,
				  AgsRecallID *recall_id,
				  guint *n_params, GParameter *parameter)
{
  AgsRecallAudioSignal *recall_audio_signal, *copy;

  recall_audio_signal = AGS_RECALL_AUDIO_SIGNAL(recall);
  parameter = ags_parameter_grow(G_OBJECT_TYPE(recall),
				 parameter, n_params,
				 "devout\0", AGS_RECALL(recall_audio_signal)->devout,
				 "audio_channel\0", recall_audio_signal->audio_channel,
				 "destination\0", recall_audio_signal->destination,
				 "source\0", recall_audio_signal->source,
				 NULL);

  copy = (AgsRecallAudioSignal *) AGS_RECALL_CLASS(ags_recall_audio_signal_parent_class)->duplicate(recall,
												    recall_id,
												    n_params, parameter);

  return((AgsRecall *) copy);
}
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);
}
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_recall_audio_signal_set_property(GObject *gobject,
				   guint prop_id,
				   const GValue *value,
				   GParamSpec *param_spec)
{
  AgsRecallAudioSignal *recall_audio_signal;

  recall_audio_signal = AGS_RECALL_AUDIO_SIGNAL(gobject);

  switch(prop_id){
  case PROP_AUDIO_CHANNEL:
    {
      guint audio_channel;

      audio_channel = (guint) g_value_get_uint(value);

      recall_audio_signal->audio_channel = audio_channel;
    }
    break;
  case PROP_DESTINATION:
    {
      AgsAudioSignal *destination;

      destination = (AgsAudioSignal *) g_value_get_object(value);

      if(recall_audio_signal->destination == destination)
	return;

      if(recall_audio_signal->destination != NULL)
	g_object_unref(recall_audio_signal->destination);

      if(destination != NULL)
	g_object_ref(G_OBJECT(destination));

      recall_audio_signal->destination = destination;
    }
    break;
  case PROP_SOURCE:
    {
      AgsAudioSignal *source;

      source = (AgsAudioSignal *) g_value_get_object(value);

      if(recall_audio_signal->source == source)
	return;

      if(recall_audio_signal->source != NULL)
	g_object_unref(recall_audio_signal->source);

      if(source != NULL)
	g_object_ref(G_OBJECT(source));

      recall_audio_signal->source = source;
    }
    break;
  default:
    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
    break;
  }
}