Compositions (APL for Audio)

A composition for APL for audio combines components into a new custom component that you can use and reuse within the main template of your document. You can use conditional logic within the composition to choose which components to render in the final audio clip. Using compositions helps simplify your APL code and ensure consistency.

About APL compositions

You define compositions in the compositions property in the APL document. This property takes a string/object map.

The following example shows the compositions property with one composition called JoeyVoice. The composition has one parameter called speechContent. This composition contains a single Speech component that uses content passed to the speechContent parameter to generate speech with SSML.

Copied to clipboard.

{
  "compositions": {
    "JoeyVoice": {
      "parameters": [
        {
          "name": "speechContent",
          "type": "string"
        }
      ],
      "items": [
        {
          "type": "Speech",
          "contentType": "SSML",
          "content": "<speak><voice name='Joey'><lang xml:lang='en-US'>${speechContent}</lang></voice></speak>"
        }
      ]
    }
  }
}

To use the composition in your document, provide the composition name as the component type and pass any parameters, similar to the way you add a primitive component. The following example shows a basic Sequencer component that uses the JoeyVoice composition twice, with different speechContent each time.

Copied to clipboard.

{
  "type": "Sequencer",
  "items": [
    {
      "type": "JoeyVoice",
      "speechContent": "I'm passing this text to the Joey Voice composition."
    },
    {
      "type": "JoeyVoice",
      "speechContent": "I can create a single composition and re-use it multiple times in my document. This simplifies my document."
    }
  ]
}

Composition properties

The following table shows the properties for a composition.

Property Type Required Description
description String No A description of this composition
item, items Array of Components Yes The item to inflate. When items contains an array, the first item where when evaluates to true is inflated.
parameters Parameter array No An array of parameters to pass to this composition.

item, items

Contains an array of components to inflate into an audio clip. When items contains an array, the first item where when evaluates to true is inflated. A composition is a type of component, so the items property can refer to other compositions, as long as they are also defined in the compositions property of the document.

For details about how data-binding works with arrays, see Data-binding with arrays.

parameters

Contains an array of parameters for the composition. Each parameter is an object with the properties shown in the following table.

Property Type Required Description
default Any No A default value to use if this parameter is not specified. Defaults to empty.
description String No A string describing the purpose of this parameter.
name String Yes The parameter name. Use this name to fill the parameter when you use the composition in your document. Set to a unique name that begins with an upper-case or lower-case letter and contains no white space.
type Type No A string that defines the type of the value the parameter expects. Set to one of the following types: any, array, boolean, component, integer, map, number, object, string. Defaults to "any".

When you define a parameter that doesn't require type coercion or default values, you can provide a simple parameter name instead of the parameter object. For example, provide just "title" instead of {"name": "title", ...}. This allows for more a compact composition definition.

Composition inflation

A composition works like a function that expands into a collection of other compositions and components. The algorithm to inflate a composition performs the following steps:

  1. Evaluate each parameter and add it to the data-binding context.
  2. Evaluate the items property using the single child algorithm.
  3. Pass any other properties that don't match the parameters defined for the composition to the composition item for evaluation.

The following example illustrates the inflation algorithm.

First, define a composition called Greetings with two parameters, JoeySpeech and IvySpeech. The items array contains two Speech components, each with a when clause. The final audio clip produced by this composition uses just one of these Speech components.

Copied to clipboard.

{
  "compositions": {
    "Greetings": {
      "parameters": [
        {
          "name": "JoeySpeech",
          "type": "string"
        },
        {
          "name": "IvySpeech",
          "type": "string"
        }
      ],
      "items": [
        {
          "type": "Speech",
          "when": "${environment.alexaLocale == 'en-US'}",
          "content": "<speak><voice name='Joey'><lang xml:lang='en-US'>${JoeySpeech}</lang></voice></speak>"
        },
        {
          "type": "Speech",
          "when": "${environment.alexaLocale != 'en-US'}",
          "content": "<speak><voice name='Ivy'><lang xml:lang='en-US'>${IvySpeech}</lang></voice></speak>"
        }
      ]
    }
  }
}

To inflate the composition and produce an audio clip, you add the composition to the mainTemplate in your APL document and pass values in the parameters. Note that this example passes three parameters to the composition – IvySpeech, JoeySpeech, and contentType.

Copied to clipboard.

{
  "type": "Greetings",
  "IvySpeech": "Hello",
  "JoeySpeech": "Hi",
  "contentType": "SSML"
}

Alexa uses the following logic to inflate this composition:

  • Adds IvySpeech and JoeySpeech to the data-binding context. This lets the composition reference these values with a data-binding expression, such as ${IvySpeech}.
  • Evaluate the items property using the single child algorithm. Assuming the user's locale is en-US, the when property for the first Speech component is true, so the composition chooses the first component in the items array.
  • Pass along any other parameters that don't match the defined parameters. In this example, contentType isn't defined in the composition. Alexa passes this parameter to the chosen item. In this example, the chosen item is a Speech component, and the Speech component has a contentType property. Therefore, the Speech component uses the provided "SSML" value.

The net result of this algorithm is a Speech component that looks like the following.

{
    "type": "Speech",
    "contentType": "SSML",
    "content": "<speak><voice name='Joey'><lang xml:lang='en-US'>Hi</lang></voice></speak>"
}