Trim Audio to Items of Variable Length Using New Features in APL for Audio (beta)

Austin Vach Feb 09, 2021
Share:
Multimodal
Blog_Header_Post_Img

Ever wish you could add background audio to an Alexa response and have it dynamically trimmed to the appropriate length? Ever wish you could repeat an audio clip over and over again? If you answered yes to either of those questions: 1) we should be friends and 2) today is your lucky day!

Today we’re excited to announce APL for Audio 0.91 (beta) which includes a new duration property and a repeat filter. These new features allow you to match background audio to the exact length of another component, repeat a section of your response a fixed number or times, or infinitely repeat an audio clip up to the maximum response length (currently 240 seconds).

 

The Duration Property:

The duration property is available on all components and has two values: auto and trimToParent. When set to auto , rendered audio will not be trimmed. When set to trimToParent, the rendered audio is trimmed to match the duration of it’s parent.

For example, let’s say I’m creating a weather skill (*cough* No Look Weather *cough*) and I want to play weather sounds behind a spoken forecast. Because weather changes, my text-to-speech forecasts will also vary in duration. Normally, it would be difficult to fit an audio asset to the exact length of the response (sometimes the audio will be too long and other times too short) but with the duration property, this becomes pretty simple.

trimToParent when the audio is LONGER than the weather forecast.

In the sample below, the 7s Audio component will be trimmed to match the length of the 6s Speech component.

Copied to clipboard
{
    "type": "APLA",
    "version": "0.91",
    "mainTemplate": {
        "parameters": [
            "payload"
        ],
        "item": {
            "type": "Mixer",
            "items": [
                {
                    "type": "Speech",
                    "description": "This text-to-speech (TTS) lasts for 6 seconds.",
                    "content": "In Seattle, it's 48 degrees and rainy. If you're headed outside, I suggest a rain jacket!"
                },
                {
                    "type": "Audio",
                    "description": "This audio lasts for 7 seconds.",
                    "source": "soundbank://soundlibrary/weather/rain/rain_06",
                    "duration": "trimToParent",
                    "filter": [
                        {
                            "type": "Volume",
                            "amount": "10%"
                        }
                    ]
                }
            ]
        }
    }
}

(.mp3 audio-file of  result)

 

“But wait, why is it called trimToParent if it’s actually trimming to its peer?” Good question! Let me take a moment to explain.

The duration of any parent component matches the duration of its longest child component. In the example above, the longest child component WOULD have been the 7 second audio component but since we had set its duration to trimToParent, its intrinsic value was ignored and the Mixer component adjusted to match the length of its next longest child component (the 6s Speech component).

Make sense? Now that we’ve got that cleared up, let’s keep moving forward.

trimToParent when the audio is SHORTER than the weather forecast.

In the sample below, the 4s Audio component is not trimmed because it is shorter than its 6s parent.

Copied to clipboard
{
    "type": "APLA",
    "version": "0.91",
    "mainTemplate": {
        "parameters": [
            "payload"
        ],
        "item": {
            "type": "Mixer",
            "items": [
                {
                    "type": "Speech",
                    "description": "This text-to-speech (TTS) lasts for 6 seconds.",
                    "content": "In Seattle, it's 48 degrees and rainy. If you're headed outside, I suggest a rain jacket!"
                },
                {
                    "type": "Audio",
                    "description": "This audio lasts for 4 seconds.",
                    "source": "soundbank://soundlibrary/nature/amzn_sfx_rain_03",
                    "duration": "trimToParent",
                    "filter": [
                        {
                            "type": "Volume",
                            "amount": "20%"
                        }
                    ]
                }
            ]
        }
    }
}

(.mp3 audio-file of  result)

 

“Ok cool. But is it possible to loop a shorter audio clip to ‘fill’ the duration of a longer parent component?” I like where your head’s at! Hold that thought, we’ll get to it in a moment :)

 

 

 

The Repeat Filter

 

 

 

The new Repeat filter repeats an audio sample for a specified number of times.

In the sample below, I use the repeat filter to repeat the rooster’s crow 1 ADDITIONAL time.

Copied to clipboard
{
    "type": "APLA",
    "version": "0.91",
    "mainTemplate": {
        "parameters": [
            "payload"
        ],
        "item": {
            "type": "Sequencer",
            "items": [
                {
                    "type": "Audio",
                    "source": "soundbank://soundlibrary/animals/amzn_sfx_rooster_crow_01",
                    "filter": [
                        {
                            "type": "Repeat",
                            "repeatCount": 1
                        }
                    ]
                },
                {
                    "type": "Speech",
                    "content": "Rise and shine!"
                }
            ]
        }
    }
}

(.mp3 audio file of result)

 

If repeatCount is set to -1, the audio will be repeated an infinite number of times (up to the maximum length of an APLA response). We’ll use this to our advantage when repeating the short background audio clip in our weather response.

 

WITH OUR POWERS COMBINED!

Using both “repeatCount”:-1 and “duration”:“trimToParent”, we can repeat a short audio clip to “fill” the length of a longer response. Let’s revise the second sample to see this in action.

In the sample below, the 4s Audio component is repeated indefinitely before being trimmed to the 6s duration of the parent component.

Copied to clipboard
{
    "type": "APLA",
    "version": "0.91",
    "mainTemplate": {
        "parameters": [
            "payload"
        ],
        "item": {
            "type": "Mixer",
            "items": [
                {
                    "type": "Speech",
                    "description": "This text-to-speech (TTS) lasts for 6 seconds.",
                    "content": "In Seattle, it's 48 degrees and rainy. If you're headed outside, I suggest a rain jacket!"
                },
                {
                    "type": "Audio",
                    "description": "This audio lasts for 4 seconds.",
                    "source": "soundbank://soundlibrary/nature/amzn_sfx_rain_03",
                    "duration": "trimToParent",
                    "filter": [
                        {
                            "type": "Volume",
                            "amount": "20%"
                        },
                        {
                            "type": "Repeat",
                            "repeatCount": -1
                        }
                    ]
                }
            ]
        }
    }
}

Get Started Today:

Learn more about these and other features in our technical documentation, check out the sample skill, and hit me up on Twitter if you have any questions!

Related Articles

Introducing APLA
Get started with APLA

Subscribe