# Your tree linked with AgsChannel

AgsChannel forms your audio processing tree and contains recalls, too. You might want to iterate the channels of your audio object or just call one of these functions:

- `AgsChannel* ags_channel_first(AgsChannel*)`
- `AgsChannel* ags_channel_last(AgsChannel*)`
- `AgsChannel* ags_channel_nth(AgsChannel*, guint)`
- `AgsChannel* ags_channel_pad_first(AgsChannel*)`
- `AgsChannel* ags_channel_pad_last(AgsChannel*)`
- `AgsChannel* ags_channel_pad_nth(AgsChannel*, guint)`

As you see there is a grained access to channels. You can lookup channels from with the same audio channel with the functions containing pad in its name. An other exciting feature is finding channels having an assigned recycling. These functions operate on the very same audio channel.

- `AgsChannel* ags_channel_first_with_recycling(AgsChannel*)`
- `AgsChannel* ags_channel_last_with_recycling(AgsChannel*)`
- `AgsChannel* ags_channel_prev_with_recycling(AgsChannel*)`
- `AgsChannel* ags_channel_next_with_recycling(AgsChannel*)`

Following object fields are changed during linking. Further a new AgsRecycling might be instantiated to be provided as `first_recycling` and `last_recycling` of specified AgsInput eg. if it is NULL. So this input has got its very own recycling as specified by `AGS_AUDIO_INPUT_HAS_RECYCLING`:

- `AgsChannel:link` `recursive AgsChannel:first-recycling and AgsChannel:last-recycling as needed` `AgsRecycling:parent` `AgsRecycling:prev or AgsRecycling:next`

## The pattern

There can AgsPattern being added to a channel by `void ags_channel_add_pattern(AgsChannel*, GObject*)`. Later if not used anymore likewise call `void ags_channel_remove_pattern(AgsChannel*, GObject*)`.

### Adding AgsPattern

## Linking overview

In this section you get some knowledge about AgsChannel 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 `void ags_channel_set_link(AgsChannel*, AgsChannel*, GError**)` and this will the especially covered here.

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.

## AGS network layer table

object | flags
Audio#0 | AGS_AUDIO_SYNC | AGS_AUDIO_OUTPUT_HAS_RECYCLING
Audio#1 | AGS_AUDIO_ASYNC
Audio#2 | AGS_AUDIO_ASYNC | AGS_AUDIO_OUTPUT_HAS_RECYCLING
Audio#3 | AGS_AUDIO_ASYNC | AGS_AUDIO_OUTPUT_HAS_RECYCLING
Audio#4 | AGS_AUDIO_ASYNC | AGS_AUDIO_OUTPUT_HAS_RECYCLING

- green:

  - Bidirectional linked AgsChannel to an other AgsChannel.
  - Generally you link an AgsOutput to an AgsInput.

- red:

  - Bidirectional linked AgsRecycling to an other AgsRecycling on the same level.
  - They are linked across AgsAudio objects.
  - Same level means the linked AgsRecycling are all child nodes of a parent AgsRecycling.

- yellow:

  - Unidirectional linked AgsRecycling to an AgsChannel.
  - First AgsRecycling of an AgsOutput and last AgsRecycling of an (other) AgsOutput are linked to an AgsChannel.

## Limitations

- You may not create any kind of loops.
- You may not set AGS_AUDIO_INPUT_HAS_RECYCLING without setting AGS_AUDIO_OUTPUT_HAS_RECYCLING flag.

## Hands-On

There may be two ways how you can link AgsChannel objects.

### Prerequisites

Assumed you know really what you do, you may be interested in following code.

### Thread-Unsafe way

But generally you wish to create an AgsTask object and let it to link the AgsChannel for you.

### Multithread-Safe way