Using AVIRT
===================================

## Introduction

## Table of Contents

1. [Load/Unload AVIRT](#un-load-avirt)
2. [Configuring AVIRT](#configuring-avirt)
3. [Checking AVIRT](#checking-avirt)

<a name="un-load-avirt"/>

## 1. Loading and Unloading AVIRT

### Load Out of Tree

As root, load the required `avirt_core.ko` and subsequent audio path.
As an example, the Dummy Audiopath is being loaded here.

```sh
insmod snd-avirt-core.ko
insmod dummy/snd-avirt-ap-dummy.ko
insmod loopback/snd-avirt-ap-loopback.ko
```

### Note:

The loading and unloading of drivers can be performed using the helper scripts.
To run, we must load the kernel modules using the `scripts/load.sh` script:

```sh
$ ./scripts/load.sh
```

To unload the drivers use:

```sh
$ ./scripts/unload.sh
```

### Load In Tree

#### Note:

Either build the module in tree, or you can copy the modules manually and then run `depmod` to generate dependencies.
For example, in AGL:

```sh
mkdir -p /lib/modules/$(uname -r)/extra
cp snd-avirt-core.ko snd-avirt-ap-dummy.ko snd-avirt-ap-loopback.ko /lib/modules/$(uname -r)/extra
depmod
```

Once the modules are in place, we can load the modules using:

```sh
modprobe snd-avirt-core
modprobe snd-avirt-ap-dummy
modprobe snd-avirt-ap-loopback
```

<a name="configure-avirt" />

## 2. Configuring AVIRT

AVIRT is configured using configfs.

### Note:

A sample script for the following is supplied inside the `scripts` folder.

First, verify the kernel supports the use of configfs.

```sh
fgrep configfs /proc/filesystems
```

The expected output is:

```
nodev	configfs
```

Once confirmed, we can mount the `configfs` filesystem at the conventional point:

```sh
# Check configfs is mounted on the system
mkdir -p /config
mount -t configfs none /config
```

Finally, we can configure AVIRT, for example:

```sh
# Set up each of the cards channels
mkdir /config/snd-avirt/streams/playback_media
echo "2">/config/snd-avirt/streams/playback_media/channels
echo "ap_dummy">/config/snd-avirt/streams/playback_media/map

mkdir /config/snd-avirt/streams/playback_navigation
echo "1">/config/snd-avirt/streams/playback_navigation/channels
echo "ap_dummy">/config/snd-avirt/streams/playback_navigation/map

mkdir /config/snd-avirt/streams/playback_emergency
echo "1">/config/snd-avirt/streams/playback_emergency/channels
echo "ap_dummy">/config/snd-avirt/streams/playback_emergency/map

mkdir /config/snd-avirt/streams/capture_voice
echo "1">/config/snd-avirt/streams/capture_voice/channels
echo "ap_dummy">/config/snd-avirt/streams/capture_voice/map

# Finally, set the card to 'configured', and initiate Audio Path configuration
echo "1">/config/snd-avirt/streams/configured
```

Alternatively, the test script at `scripts/test_configfs.sh` can be used.

The user-space library, [libavirt](https://github.com/fiberdyne/libavirt) can be used to interact with the configfs interface. Please refer to the README in libavirt for further details.

<a name="checking-avirt" />

## 3. Checking AVIRT Loaded Correctly

We can see the newly created streams by using the `aplay` utility. For example, the device list might look a little like this:

```sh
aplay -l
...
card 2: avirt [avirt], device 0: multimedia [multimedia]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: avirt [avirt], device 1: navigation [navigation]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: avirt [avirt], device 2: emergency [emergency]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
...
```