On this page you get some knowledge about ags
internals. Here you get an overview of the audio layer. All code related to it is located in subdirectory <ags/audio>. Linking AgsChannel is a quiet complex thing but If you wish to do so you can just call ags_channel_link() and this will the especially covered here.
Tree structure is formed by:
AgsAudio, AgsChannel and AgsRecycling are involved in linking. When talking about linking we should view AgsChannel objects as networked and therefore exists an additional nested network of AgsRecycling objects.
The AgsAudio object gives clarification about how AgsChannel has to be accessed either synchronously or asynchronously. Further it tells us whether AgsOutput or AgsInput has a new audio stream which causes in conjunction a dedicated AgsRecycling associated with the appropriate AgsChannel.
The picture above shows you a sample network layer of ags
.
object: | flags: |
---|---|
Audio#0 | AGS_AUDIO_SYNC | AGS_AUDIO_OUTPUT_HAS_RECYCLING |
Audio#1 | AGS_AUDIO_ASYNC |
Audio#2 | AGS_AUDIO_SYNC | AGS_AUDIO_OUTPUT_HAS_RECYCLING |
Audio#3 | AGS_AUDIO_SYNC | AGS_AUDIO_OUTPUT_HAS_RECYCLING |
Audio#4 | AGS_AUDIO_SYNC | AGS_AUDIO_OUTPUT_HAS_RECYCLING |
There may be two ways how you can link AgsChannel objects.
Prerequisites:
<pre>
AgsTaskThread \*task_thread;
AgsDevout \*devout;
AgsAudio \*master_audio, \*slave_audio;
AgsLinkChannel \*linkChannel;
GError \*error;
/\* some pseudo code \*/
devout = AGS_WINDOW(gtk_widget_get_toplevel(widget))->devout;
task_thread = AGS_AUDIO_LOOP(AGS_MAIN(devout->ags_main)->main_loop)->task_thread;
/\* create AgsAudio objects \*/
master_audio = (AgsAudio \*) g_object_new(AGS_TYPE_AUDIO,
"devout\\0", devout,
NULL);
slave_audio = (AgsAudio \*) g_object_new(AGS_TYPE_AUDIO,
"devout\\0", devout,
NULL);
/\* assign AgsAudioSignal objects to master_audio and slave_audio \*/
ags_audio_set_flags(master_audio,
AGS_AUDIO_OUTPUT_HAS_RECYCLING);
ags_audio_set_flags(slave_audio,
(AGS_AUDIO_ASYNC | AGS_AUDIO_OUTPUT_HAS_RECYCLING | AGS_AUDIO_INPUT_HAS_RECYCLING));
/\* create AgsChannel objects within master_audio and slave_audio \*/
ags_audio_set_audio_channels(master_audio, 2);
ags_audio_set_pads(master_audio, AGS_TYPE_OUTPUT, 1);
ags_audio_set_pads(master_audio, AGS_TYPE_INPUT, 1);
ags_audio_set_audio_channels(slave_audio, 2);
ags_audio_set_pads(slave_audio, AGS_TYPE_OUTPUT, 1);
ags_audio_set_pads(slave_audio, AGS_TYPE_INPUT, 8);
</pre>
Assumed you know really what you do, you may be interested in following code.
Thread unsafe way:
<pre>
/\* link master_audio's input with slave_audio's output \*/
ags_channel_set_link(ags_channel_nth(master_audio->input, 0),
ags_channel_nth(slave_audio->output, 0),
&error);
ags_channel_set_link(ags_channel_nth(master_audio->input, 1),
ags_channel_nth(slave_audio->output, 1),
&error);
</pre>
But generally you wish to create an AgsTask object and let it to link the AgsChannel for you.
Multithreading-Safe:
<pre>
/\* creating AgsLink task and add it to AgsDevout \*/
link_channel = ags_link_channel_new(ags_channel_nth(master_audio->input, 0),
ags_channel_nth(slave_audio->output, 0));
ags_task_thread_append_task(task_thread, link_channel);
link_channel = ags_link_channel_new(ags_channel_nth(master_audio->input, 1),
ags_channel_nth(slave_audio->output, 1));
ags_task_thread_append_task(task_thread, link_channel);
</pre>