Engage Audio Devices - rallytac/pub GitHub Wiki

Engage Audio Devices

Audio devices (microphones & speakers) in Engage used for audio capture and playout come in two flavors - (a) hardware-based devices provided by the OS platform and (b), application-defined audio devices (ADADs) which are managed entirely by the application using the Engage Engine. Both types of devices reside in the Engage Engine in the form of a registry which tracks unique identifiers for the various input and output devices.

During initialization, the Engage Engine queries the OS interfaces for audio hardware, building the registry as it goes. Subsequent to that, the application may register its own devices to add to that master registry. Once the registry is complete, groups (channels) are created - each potentially with their own input and output numeric identifiers for audio. These numeric identifiers are assigned automatically when the registry is built and/or ADADs are registered by the application.

Overriding Automatic Registry Creation

Now, sometimes, you may want to specifically include or exclude particular OS-provided hardware devices - forcing Engage to only use the registry you provide instead of what is reported by the platform. This may be done in the Engine's policy JSON used during initialization.

Below is an example where we've told Engage to operate at an 8Khz sampling rate in mono (i.e. not stereo) mode (the internalRate and internalChannels) settings.

What we've also done is provided a registry for Engage to use - overriding its normal procedure of hardware discovery. This is done in the registry object.

.
.
"audio": {
            "internalRate": 8000,
            "internalChannels": 1,
            "allowOutputOnTransmit": false,
            "muteTxOnTx": true,

            "registry": {
                    "inputs": [
                            {
                                    "hardwareId": "default",
                                    "isDefault": true,
                                    "name": "The default microphone"
                            },
                            {
                                    "hardwareId": "engage_audio_in_port01",
                                    "name": "A virtual microphone defined for Engage"
                            }
                    ],
                    "outputs": [
                            {
                                    "hardwareId": "default",
                                    "isDefault": true,
                                    "name": "The default speaker"
                            },
                            {
                                    "hardwareId": "engage_audio_out_port01",
                                    "isDefault": false,
                                    "name": "A virtual speaker defined for Engage"
                            }
                    ]
            }
}
.
.

In the example - which is tailored for Linux using ALSA - we've defined a registry with two inputs and two outputs. The first input has a hardware ID of default and is marked as the default with the isDefault setting. We've also defined a second input named engage_audio_in_port01. This is a virtual recording device which (again this is for Linux) which we've defined in the ALSA configuration as follows:

pcm.engage_audio_in_port01 {
    type plug
    slave.pcm "hw:0,0"
}

Similarly, we've done the same for our outputs - with a default and a engage_audio_out_port01 virtual device.

In fact, our ALSA configuration looks as follows:

# Engage Audio Input Ports
pcm.engage_audio_in_port01 {
    type plug
    slave.pcm "hw:0,0"
}

pcm.engage_audio_in_port02 {
    type plug
    slave.pcm "hw:0,0"
}

# Engage Audio Output Ports
pcm.engage_audio_out_port01 {
    type plug
    slave.pcm "hw:0,0"
}

pcm.engage_audio_out_port02 {
    type plug
    slave.pcm "hw:0,0"
}

Notice how the slave.pcm value is the same for all devices as the Linux machine only has one physical hardware audio card. This value would obviously be different on your machine where you may have multiple audio hardware cards.

Using Device Names Instead Of IDs

OK, cool; we've managed to (narrowly!) define Engage's audio device registry, using the audio.registry subobject in the Engage policy. But what is the numeric ID !? It hasn't (and cannot) be defined in our JSON-based registry. And therefore we cannot specify a group's audio.inputId or audio.outputId numeric values. Wouldn't it be nice if we could just use the names we defined in our registry?

Good news - we can!

Instead of using audio.inputId and/or audio.outputId, we'll use audio.inputHardwareId and audio.outputHardwareId as shown below. When the AirSupport group is created in Engage, it will use the name provided - say engage_audio_in_port01 to search the registry for the device that has a hardware ID of engage_audio_in_port01 to determine the numeric ID which will then be used automagically in the configuration.

{
  "id": "c0fda052-e0a0-47ec-88ab-e34a61ce5b1a",
  "name": "My Mission Name",
  "description": "Just a little mission to play with",
  "groups": [
    {
      "id": "AirSupport",
      "type": 1,
      "name": "AirSupport",
      "audio": {
        "inputHardwareId": "engage_audio_in_port01",
        "outputHardwareId": "engage_audio_out_port01"
      },
      "txAudio": {
        "encoder": 25
      },
      "tx": {
        "address": "234.5.6.7",
        "port": 17000
      },
      "rx": {
        "address": "234.5.6.7",
        "port": 17000
      }
    }
  ]
}

In a Linux environment - as we've seen - that name is defined in the ALSA configuration, and that's all that Engage needs to use that device.

Easy huh!?