Dealing with recalls

Since AgsAudio is your entry point to do sound processing there are some useful functions to set it up, but later on them. Instances of AgsRecallAudio base object may be added or removed with void ags_audio_add_recall(AgsAudio*, GObject*, gboolean) and void ags_audio_remove_recall(AgsAudio*, GObject*, gboolean).

All audio processing is performed by one single function. Wheter you want to initialize, run or cancel playback. This is all done by void ags_channel_recursive_run_stage(AgsChannel*, gint, guint).

The following signals are triggered during playback ::play, ::tact and ::done - ::cancel and ::remove during termination.

Get port of recall

Ports are accessed as GList* from recall by accessing AgsRecall:port property.

Below an example shows howto instantiate an application context implementation, obtain it by its generic function ags_application_context_get_instance() and create an audio object with ags-fx recalls.

The recalls port "./volume[0]" is modified by ags_port_safe_write(AgsPort*, GValue*).

Example 5.4. Modify recall port

#include <glib.h>
#include <glib-object.h>

#include <ags/libags.h>
#include <ags/libags-audio.h>

AgsAudio *audio;
AgsRecallContainer *play_container, *recall_container;

AgsApplicationContext *application_context;

GObject *current_soundcard;

GList *start_soundcard;
GList *start_recall, *recall;
GList *start_port, *port;

guint audio_channels;
guint output_pads, input_pads;
gfloat volume;

ags_audio_application_context_new();

/* get application context and soundcard */
application_context = ags_application_context_get_instance();

start_soundcard = ags_sound_provider_get_soundcard(AGS_SOUND_PROVIDER(application_context));

current_soundcard = start_soundcard->data;

/* creat audio and resize channels */
audio_channels = 2;

output_pads = 1;
input_pads = 1;

audio = ags_audio_new(current_soundcard);
ags_audio_set_audio_channels(audio,
                             audio_channels);
ags_audio_set_pads(audio,
                   AGS_TYPE_OUTPUT,
                   output_pads);
ags_audio_set_pads(audio,
                   AGS_TYPE_INPUT,
                   input_pads);

/* add ags-fx-volume */
play_container = ags_recall_container_new();
recall_container = ags_recall_container_new();

start_recall = ags_fx_factory_create(audio,
				     play_container, recall_container,
				     "ags-fx-volume",
				     NULL,
				     NULL,
				     0, audio_channels,
				     0, input_pads,
				     0,
				     (AGS_FX_FACTORY_ADD | AGS_FX_FACTORY_INPUT),
				     0);

recall = start_recall;

volume = 0.75;

while(recall != NULL){
  start_port = NULL;
  g_object_get(recall->data,
	       "port", &start_port,
	       NULL);

  port = ags_port_find_specifier(start_port,
				 "./volume[0]");

  if(port != NULL){
    GValue value = G_VALUE_INIT;

    g_value_init(&value,
		 G_TYPE_FLOAT);

    g_value_set_float(&value,
		      volume);
    
    ags_port_safe_write(port->data,
			&value);
  }

  g_list_free_full(start_port,
		   (GDestroyNotify) g_object_unref);
  
  /* iterate */
  recall = recall->next;
}

g_list_free_full(start_recall,
		 (GDestroyNotify) g_object_unref);

g_list_free_full(start_soundcard,
		 (GDestroyNotify) g_object_unref);