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