Combining Sounds

Most of the music you hear on the radio, television, or your favorite music streaming service is a carefully orchestrated mix of voices and instruments, not recorded live in one take, but recorded in separate sessions. It’s not uncommon for the instrumentalists to record their tracks in the absence of each other and the vocalists. It’s not until those tracks are mixed during production that the final product is created.

With APL-A, you get to sit at the mixing board and combine multiple sounds effects, musical pieces, and/or speech to produce a polished and professional sounding response. How you arrange the sounds is up to you. But APL-A provides you with three components for mixing sounds and speech:

  • Sequencer—Plays one or more child components in the order specified

  • Selector—Plays a single component from a list of child components, chosen either randomly or based on some condition

  • Mixer—Plays one or more child components simultaneously

These components are commonly referred to as multi-child components, because while they do not make sounds themselves, they bring together one or more child components.

As we begin our exploration of APL-A’s multi-child components, let’s start with the most basic of the three: Sequencer.

Sequencing Audio

The Sequencer component’s job is to play one or more child components, one after the other, in the order specified. For example, consider the following APL-A template that uses Sequencer to play some spoken text, followed by a sound effect:

 {
 "type"​: ​"APLA"​,
 "version"​: ​"0.9"​,
 "mainTemplate"​: {
 "items"​: [
  {
 "type"​: ​"Sequencer"​,
 "items"​: [
  {
 "type"​: ​"Speech"​,
 "content"​: ​"To the guy who invented zero, thanks for nothing."
  },
  {
 "type"​: ​"Audio"​,
 "source"​:
 "soundbank://soundlibrary/musical/amzn_sfx_drum_comedy_01"
  }
  ]
  }
  ]
  }
 }

The items property of Sequencer is used to specify the children components that are played one after another. In this case, the children are Speech and Audio components. But any of APL-A’s components, including Silence, can be children of Sequencer. By placing Silence between two Audio or Speech components as children of Sequencer, you can get a brief pause, as shown in this sample APL-A template:

 {
 "type"​: ​"APLA"​,
 "version"​: ​"0.9"​,
 "mainTemplate"​: {
 "items"​: [
  {
 "type"​: ​"Sequencer"​,
 "items"​: [
  {
 "type"​: ​"Speech"​,
 "content"​: ​"I'll give you a moment to decide."
  },
  {
 "type"​: ​"Silence"​,
 "duration"​: 10000
  },
  {
 "type"​: ​"Speech"​,
 "content"​: ​"What is your decision?"
  }
  ]
  }
  ]
  }
 }

Another interesting way to use Sequencer is to loop through several entries in a data array. To illustrate how this works, consider the following APL-A template that lists the planets in our solar system:

 {
 "type"​: ​"APLA"​,
 "version"​: ​"0.9"​,
 "mainTemplate"​: {
 "parameters"​: [
 "payload"
  ],
 "item"​: {
 "type"​: ​"Sequencer"​,
 "items"​: [
  {
 "type"​: ​"Speech"​,
 "content"​: ​"The planets in our solar system are"
  },
  {
 "type"​: ​"Sequencer"​,
 "item"​: {
 "type"​: ​"Speech"​,
 "content"​: ​"${index+1}. ${data}"
  },
 "data"​: ​"${payload.solarSystem.planets}"
  },
  {
 "type"​: ​"Speech"​,
 "content"​: ​"Yes. I consider Pluto to be a planet."
  }
  ]
  }
  }
 }

In this example, there are two Sequencer components in play. The first and outermost Sequencer isn’t much different from other Sequencer examples we’ve seen. It plays its children, one after another. But one of those children is another Sequencer that has only one Speech component as a child. But its data property is set to “${payload.solarSystem.planets}”, which is expected to be an array of planet names.

When this template is rendered, the inner Sequencer will list off each of the entries in the data array, speaking its index (plus one, since the index is zero-based) and then the value of the entry.

To try this example template in the APL-A editor, open the data editor and add the following model data:

 {
 "solarSystem"​: {
 "planets"​: [
 "Mercury"​,
 "Venus"​,
 "Earth"​,
 "Mars"​,
 "Jupiter"​,
 "Saturn"​,
 "Uranus"​,
 "Neptune"​,
 "Pluto"
  ]
  }
 }

After refreshing the audio and clicking the play button, you should hear Alexa speak the following:

  • The planets in our solar system are
  • One. Mercury
  • Two. Venus
  • Three. Earth
  • Four. Mars
  • Five. Jupiter
  • Six. Saturn
  • Seven. Uranus
  • Eight. Neptune
  • Nine. Pluto
  • Yes. I consider Pluto to be a planet.

Playing sounds in a sequence is just one way to combine them in an audio response. You may want to selectively play certain sounds instead of playing them all. For that, let’s have a look at the Selector component.

Conditionally Selecting Sounds

The Selector component, like the Sequencer component, has one or more child components. But instead of playing them all one after another, the Selector component only plays one of its children, either randomly or based on some criteria.

This can be especially useful when you want Alexa to respond differently to a request so that it doesn’t seem like she has canned responses. For example, after a user has scheduled a trip, you want Alexa to tell them to have a great time, but you may want her to say it in different ways each time. The following APL-A document uses Selector to randomly pick one of a few possible responses:

 {
 "type"​: ​"APLA"​,
 "version"​: ​"0.9"​,
 "mainTemplate"​: {
 "parameters"​: [
 "payload"
  ],
 "items"​: [
  {
 "type"​: ​"Selector"​,
 "strategy"​: ​"randomItem"​,
 "items"​: [
  {
 "type"​: ​"Speech"​,
 "content"​: ​"Enjoy your trip to ${payload.trip.destination}!"
  },
  {
 "type"​: ​"Speech"​,
 "content"​: ​"Have a great time on ${payload.trip.destination}!"
  },
  {
 "type"​: ​"Speech"​,
 "content"​: ​"I think ${payload.trip.destination} will be amazing!"
  }
  ]
  }
  ]
  }
 }

The strategy property is set to “randomItem” to specify that you want APL-A to randomly select an item from the items array. If you try this template in the APL-A editor, be sure to create the necessary model data in the data editor. The child item is chosen randomly each time you click the refresh button.

The “randomItem” strategy is just one of a few strategies supported by Selector. The default strategy is “normal”, which picks the first child in the “items” array that matches some criteria. To illustrate how the “normal” strategy works, have a look at the following APL-A template:

 {
 "type"​: ​"APLA"​,
 "version"​: ​"0.9"​,
 "mainTemplate"​: {
 "parameters"​: [
 "payload"
  ],
 "items"​: [
  {
 "type"​: ​"Selector"​,
 "items"​: [
  {
 "type"​: ​"Speech"​,
 "content"​: ​"Enjoy your trip to ${payload.trip.destination}!"​,
 "when"​: ​"${payload.trip.destination == 'Jupiter'}"
  },
  {
 "type"​: ​"Speech"​,
 "content"​: ​"Have a great time on ${payload.trip.destination}!"​,
 "when"​: ​"${payload.trip.destination == 'Mars'}"
  },
  {
 "type"​: ​"Speech"​,
 "content"​: ​"I think ${payload.trip.destination} will be great!"
  }
  ]
  }
  ]
  }
 }

Here, the when property is applied to two of the three children. If the destination is Jupiter, then the first child will be chosen and Alexa will say, “Enjoy your trip to Jupiter!” She’ll say, “Have a great time on Mars” if Mars is the destination. The third child has no when property, effectively making it the fallback choice for any destination that isn’t Mars or Jupiter.

The when property can be used on any APL-A component, even when the component isn’t a child of Selector. No matter where the when property is used, the component is conditionally rendered, depending on whether the expression given evaluates to true or false.

Another strategy you might apply is “randomData”. The “randomData” strategy is similar to “randomItem”, except that instead of randomly selecting a child component, a random entry from a collection of data items is chosen and made available to be used in the child component.

For example, suppose that you want Alexa to respond randomly the same as we did with “randomItem”, but instead of having three distinct Speech components as children, you just want to swap out the adjective used to wish them a good trip. Here’s an APL-A template that uses “randomData” to do that:

 {
 "type"​: ​"APLA"​,
 "version"​: ​"0.9"​,
 "mainTemplate"​: {
 "parameters"​: [
 "payload"
  ],
 "items"​: [
  {
 "type"​: ​"Selector"​,
 "strategy"​: ​"randomData"​,
 "data"​: [
  {
 "article"​: ​"an"​,
 "adjective"​: ​"amazing"
  },
  {
 "article"​: ​"a"​,
 "adjective"​: ​"great"
  },
  {
 "article"​: ​"an"​,
 "adjective"​: ​"awesome"
  },
  {
 "article"​: ​"an"​,
 "adjective"​: ​"outstanding"
  },
  {
 "article"​: ​"a"​,
 "adjective"​: ​"stellar"
  }
  ],
 "items"​: [
  {
 "type"​: ​"Speech"​,
 "content"​: ​"Have ${data.article} ${data.adjective} time on
  ${payload.trip.destination}!"
  }
  ]
  }
  ]
  }
 }

The data property lists a handful of possible adjectives that can be used to describe a trip, along with an article (either “a” or “an”) to accompany the adjective. When the template is rendered, one of the data entries is chosen randomly and the article and adjective are inserted in place of “${data.article}” and “${data.adjective}” in the Speech element’s content property. As a consquence, Alexa could say any one of the following responses for a trip to Saturn:

  • Have an amazing trip to Saturn!
  • Have a great trip to Saturn!
  • Have an awesome trip to Saturn!
  • Have an outstanding trip to Saturn!
  • Have a stellar trip to Saturn!

Maybe you like how “randomData” works, but you still want the ability to have different sentence structures like what “randomItem” offers. In that case, you might want to use the “randomItemRandomData” strategy. The following APL-A template demonstrates how “randomItemRandomData” is used:

 {
 "type"​: ​"APLA"​,
 "version"​: ​"0.9"​,
 "mainTemplate"​: {
 "parameters"​: [
 "payload"
  ],
 "items"​: [
  {
 "type"​: ​"Selector"​,
 "strategy"​: ​"randomItemRandomData"​,
 "data"​: [
  {
 "article"​: ​"an"​,
 "adjective"​: ​"amazing"
  },
  {
 "article"​: ​"a"​,
 "adjective"​: ​"great"
  },
  {
 "article"​: ​"an"​,
 "adjective"​: ​"awesome"
  },
  {
 "article"​: ​"an"​,
 "adjective"​: ​"outstanding"
  },
  {
 "article"​: ​"a"​,
 "adjective"​: ​"stellar"
  }
  ],
 "items"​: [
  {
 "type"​: ​"Speech"​,
 "content"​: ​"Have ${data.article} ${data.adjective} time on
  ${payload.trip.destination}!"
  },
  {
 "type"​: ​"Speech"​,
 "content"​: ​"I hope your trip to ${payload.trip.destination}
  is ${data.adjective}!"
  }
  ]
  }
  ]
  }
 }

Here, the data property has the same array of article/adjective pairs as before. But the items property has two possible sentence structures that could be used. Because we’re using the “randomItemRandomData” strategy, both the data item and the child Speech component will be randomly chosen. Consequently, Alexa could speak any combination of sentence structure and adjective:

  • Have an amazing trip to Saturn!
  • Have a great trip to Saturn!
  • Have an awesome trip to Saturn!
  • Have an outstanding trip to Saturn!
  • Have a stellar trip to Saturn!
  • I hope your trip to Saturn is amazing!
  • I hope your trip to Saturn is great!
  • I hope your trip to Saturn is awesome!
  • I hope your trip to Saturn is outstanding!
  • I hope your trip to Saturn is stellar!

The Selector component is arguably one of the most useful of APL-A’s multi-child components. Even if you don’t need some of the power that other APL-A components offer, Selector will no doubt prove useful anytime you just want to make Alexa seem more human by having her speak a different random response.

But where Selector is perhaps the most useful multi-child component, the Mixer component may just be the most awesome. Let’s have a look at how to use Mixer.

Mixing Sounds

The Mixer component does something that no other APL-A component or SSML markup can do: it plays two or more sounds simultaneously.

As an example of the Mixer component’s power, imagine that you want Alexa to speak a welcome message while some sound effect plays in the background. The following APL-A template uses Mixer to do exactly that:

 {
 "type"​: ​"APLA"​,
 "version"​: ​"0.9"​,
 "mainTemplate"​: {
 "items"​: [
  {
 "type"​: ​"Mixer"​,
 "items"​: [
  {
 "type"​: ​"Audio"​,
 "source"​:
 "soundbank://soundlibrary/musical/amzn_sfx_musical_drone_intro_02"
  },
  {
 "type"​: ​"Speech"​,
 "content"​: ​"Welcome to Star Port 75 Travel"
  }]
  }
  ]
  }
 }

Just like other multi-child components, the child components are specified in the items property. But where Sequencer plays the children one at a time and Selector plays only one child component, Mixer plays all of the children all together.

If you try this template in the APL-A editor, you’ll hear Alexa welcoming you to Star Port 75 Travel along with a musical sound in the background. At least that’s the intent. But the audio is a bit loud and at times drowns out the greeting being spoken. Fortunately, there’s a way to adjust the volume of any component by using filters. Let’s see how to use filters, including the Volume filter to make this example APL-A template sound a little better.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset