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.
{
"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.
{
"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."
}
]
}
The following example shows a full document that defines the joeyVoice composition and then uses the composition as a component.
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:
- Evaluate each
parameterand add it to the data-binding context. - Evaluate the
itemsproperty using the single child algorithm. - 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.
{
"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.
{
"type": "Greetings",
"IvySpeech": "Hello",
"JoeySpeech": "Hi",
"contentType": "SSML"
}
Alexa uses the following logic to inflate this composition:
- Adds
IvySpeechandJoeySpeechto the data-binding context. This lets the composition reference these values with a data-binding expression, such as${IvySpeech}. - Evaluate the
itemsproperty using the single child algorithm. Assuming the user's locale is en-US, thewhenproperty for the firstSpeechcomponent istrue, so the composition chooses the first component in theitemsarray. - Pass along any other parameters that don't match the defined parameters. In this example,
contentTypeisn't defined in the composition. Alexa passes this parameter to the chosenitem. In this example, the chosen item is aSpeechcomponent, and theSpeechcomponent has acontentTypeproperty. Therefore, theSpeechcomponent 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>"
}
Greeting composition uses SSML text in the Speech component, it would be better to explicitly set contentType in the composition and not rely on the document passing in the correct type.Composition example
The following example defines a composition for a knock-knock joke. The document then uses this composition multiple times with different punchlines. The example provides the content for the jokes in an array in the data source.
Related topics
- APL for Audio Reference
- Document
- Conditional Component Inflation
- Data-binding Evaluation (APL for Audio)
Last updated: Nov 28, 2023