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
parameter
and add it to the data-binding context. - Evaluate the
items
property 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
IvySpeech
andJoeySpeech
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, thewhen
property for the firstSpeech
component istrue
, so the composition chooses the first component in theitems
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 chosenitem
. In this example, the chosen item is aSpeech
component, and theSpeech
component has acontentType
property. Therefore, theSpeech
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>"
}
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