<Say>

The <Say> verb reads the supplied text back to the caller. It is useful for text that is difficult to pre-record. The gender and language in which the text will be read is customizable.

Verb Attributes

Attribute
voice optionalThe attribute voice supports: man, woman, alice, Amazon Polly voices by prefixing them with Polly., Amazon Polly Neural voices by prefixing them with Polly. and ending them with -Neural, Google Cloud voices by prefixing them with gcloud.. Polly Neural and Google Wavenet voices are charged a premium price compared to Polly Standard and Google Standard voices. Default is woman for most languages. alice is deprecated and provided for backward compatibility. See below for language specifications on each of these voices.
loop optionalThe attribute loop specifies the number of times a text is to be repeated. If loop is set to 0, the text will be continuously repeated until the call is terminated. Default behavior is one repetition.
language optionalThe attribute language allows you to specify the dialect (language and locale) of voice. See below for all language specifications.

The available Amazon Polly voices are here

The available Google Cloud voices are here

The following languages are permitted:

Value
language default: enarb [Arabic, Modern Standard]
ar-AR [Arabic, Modern Standard]
ar-XA [Arabic] gcloud
bn-IN [Bengali, India] gcloud
yue-HK [Chinese, Hong Kong] gcloud
cmn-CN [Chinese, Mandarin] gcloud
cmn-TW [Chinese, Mandarin] gcloud
zh-CN [Chinese, Mandarin]
cs-CZ [Czech, Czech Republic] gcloud
cy-GB [Welsh, UK]
da-DK [Danish, Denmark]
de [German, Germany]
de-DE [German, Germany]
en [English, United States]
en-AU [English, Australia]
en-CA [English, Canada]
en-GB [English, UK]
en-GB-WLS [English, Wales]
en-IN [English, India]
en-US [English, United States]
es [Spanish, United States]
es-ES [Spanish, Spain]
es-MX [Spanish, Mexico]
es-US [Spanish, United States]
fil-PH [Filipino, Phillipines] gcloud
fi-FI [Finnish, Finland] gcloud
fr [French, France]
fr-CA [French, Canada]
fr-FR [French, France]
el-GR [Greek, Greece] gcloud
gu-IN [Gujarati, India] gcloud
hi-IN [Hindi, India]
hu-HU [Hungarian, Hungary] gcloud
is-IS [Icelandic, Iceland]
id-ID [Indonesian, Indonesia] gcloud
it [Italian, Italy]
it-IT [Italian, Italy]
ja-JP [Japanese, Japan]
kn-IN [Kannada, India] gcloud
ko-KR [Korean, Korea]
ml-IN [Malayalam, India] gcloud
morse [Morse Code, Dit Dah]
nb-NO [Norwegian, Norway]
nl-NL [Dutch, Netherlands]
pl-PL [Polish, Poland]
pt-BR [Portuguese, Brazil]
pt-PT [Portuguese, Portugal]
ro-RO [Romanian, Romania]
ru-RU [Russian, Russia]
sk-SK [Slovak, Slovakia] gcloud
sv-SE [Swedish, Sweden]
ta-IN [Tamil, India] gcloud
te-IN [Telugu, India] gcloud
th-TH [Thai, Thailand] gcloud
tr-TR [Turkish, Turkey]
uk-UA [Ukrainian, Ukraine] gcloud
vi-VN [Vietnamese, Vietnam] gcloud

Nouns

The noun of a LaML verb is nested within the verb upon which the verb acts. <Say> has the following noun:

Noun
plain text limit: 4,096 unicode charactersThe text that will be read to the caller.

Speech Synthesis Markup Language (SSML)

Speech Synthesis Markup Language (SSML) is an XML-based markup language that provides a standard way to mark up text for synthesized speech.

SSML is usually wrapped within <speak> tags. But, when using SSML with the <Say> verb, you can ignore those <speak> tags. The rest of the SSML tags will be placed inside the <Say> verb.

Below are the supported SSML tags.

Tag
<break> A pause in speech. Set the length of the pause with the time attribute. Maximum pause time is 10s. Include the unit s or ms when setting a time. The strength attribute can also be used for pauses. See below for possible values.
<emphasis> Emphasize words or phrases. This tag changes the rate and volume of speech. More emphasis generates louder and slower speech while less emphasis generates quieter and faster speech. Emphasis can be modified with the level attribute. See below for possible values.
<lang> Specify another language for specific words or phrases. Set the language with the xml:lang attribute. Possible languages are: en-US, en-GB, en-IN, en-AU, en-CA, de-DE, es-ES, it-IT, ja-JP, fr-FR (English, German, Spanish, Italian, Japanese, French).
<p> Add a pause between paragraphs.
<phoneme> Phonetic pronunciation for specified words or phrases. Set the phonetic alphabet to use with the alphabet attribute. See below for possible values. In addition, you can use the ph attribute to set the phonetic pronunciation to speak. See here for a list of supported symbols.
<prosody> Modify the volume, pitch, and rate of the tagged speech.
<s> Add a pause between sentences.
<say-as> Describe how text should be interpreted. See below for all the possible values of the interpret-as attribute of the <say-as> tag.
<sub> Pronounce the specified word or phrase as a different word or phrase. Specify the pronunciation to substitute with the alias attribute.

strength attribute

The strength attribute has the following values. Default is medium.

Value
none No pause. Can be used to remove a pause that would normally occur.
x-weak No pause.
weak Treat adjacent words as if separated by a single comma.
medium Treat adjacent words as if separated by a single comma.
strong Sentence break.
x-strong Paragraph break.

level attribute

The level attribute has the following values. Default is moderate.

Value
strong Increase the volume and slow down the speaking rate. Speech is louder and slower.
moderate Increase the volume and slow down the speaking rate, but not as much as strong.
moderate Decrease the volume and speed up the speaking rate. Speech is softer and faster.

alphabet attribute

The alphabet attribute has the following values.

Value
ipa The International Phonetic Alphabet (IPA).
x-sampa The Extended Speech Assessment Methods Phonetic Alphabet (X-SAMPA).

volume attribute

The volume attribute has the following values. Set the volume with one of the values below. Then, you can specify a percentage to increase or decrease the volume of the speech. See here for more information.

Value
silent No volume.
x-soft Lowest volume.
soft Lower volume.
medium Normal volume.
loud Louder volume.
x-loud Loudest volume.

pitch attribute

The pitch attribute has the following values. Set the pitch with one of the values below. Then, you can specify a percentage to increase or decrease the pitch of the speech. See here for more information.

Value
x-low Lowest pitch.
low Lower pitch.
medium Normal pitch.
high Higher pitch.
x-high Highest pitch.

rate attribute

The rate attribute has the following values. Set the rate with one of the values below. Then, you can specify a percentage to increase or decrease the speed of the speech. See here for more information.

Value
x-slow Slowest rate.
slow Slower rate.
medium Normal rate.
fast Faster rate.
x-fast Fastest rate.

interpret-as attribute

The interpret-as attribute has the following values.

Value
characters Spell out each letter.
spell-out Spell out each letter.
cardinal Interpret value as cardinal number.
number Interpret value as cardinal number.
ordinal Interpret value as ordinal number.
digits Spell each digit separately.
fraction Interpret value as fraction.
unit Interpret value as measurement.
date Interpret value as a date. Use format attribute to indicate format of date: mdy, dmy, ymd, md, dm, ym, my, d, m, y.
time Interpret as a duration of minutes and seconds.
telephone Interpret as telephone number.
address Interpret as part of a street address.
interjection Interpret as an interjection.
expletive "Bleep" out content in tag.

Example

<Response>
  <Say>
    Welcome to SignalWire
    <break strength="x-weak" time="100ms"/>
    <emphasis level="moderate">Emphasized words</emphasis>
    <p>Words in a paragraph</p>
    <phoneme alphabet="x-sampa" ph="pɪˈkɑːn">Phonetic pronunciation</phoneme>
    <prosody pitch="-10%" rate="85%" volume="-6dB">Words to speak</prosody>
    <s>Words in a sentence.</s>
    <say-as interpret-as="spell-out">Words</say-as>
    <sub alias="alias">Words to be substituted</sub>
  </Say>
</Response>

Here is an example of how to use some of the SSML tags within the Say verb.

Nesting

No other verbs can be nested within <Say>. However, <Say> can be nested within <Gather>.

Examples

A Simple Message to be Read

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say>Hello World.</Say>
</Response>
const { RestClient } = require('@signalwire/node')
const response = new RestClient.LaML.VoiceResponse()

response.say('Hello World.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Hello World.');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Hello World.");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say

response = VoiceResponse()
response.say('Hello World.')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(message: 'Hello World.')
end

puts response.to_s

'Hello World' will be read once in a male voice.

A Simple Message to be Read using Amazon Polly voice

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say voice="Polly.Joanna">Hello World.</Say>
</Response>
const { RestClient } = require('@signalwire/node')
const response = new RestClient.LaML.VoiceResponse()

response.say({voice:'Polly.Joanna'}, 'Hello World.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Hello World.', ['voice' => 'Polly.Joanna']);
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Hello World.", voice: "Polly.Joanna");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say

response = VoiceResponse()
response.say('Hello World.', voice='Polly.Joanna')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(voice: 'Polly.Joanna', message: 'Hello World.')
end

puts response.to_s

'Hello World' will be read once using the Amazon Polly "Joanna" voice.

A Simple Message to be Read using Amazon Polly Neural voice

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say voice="Polly.Joanna-Neural">Hello World.</Say>
</Response>
const { RestClient } = require('@signalwire/node')
const response = new RestClient.LaML.VoiceResponse()

response.say({voice:'Polly.Joanna-Neural'}, 'Hello World.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Hello World.', ['voice' => 'Polly.Joanna-Neural']);
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Hello World.", voice: "Polly.Joanna-Neural");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say

response = VoiceResponse()
response.say('Hello World.', voice='Polly.Joanna-Neural')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(voice: 'Polly.Joanna-Neural', message: 'Hello World.')
end

puts response.to_s

'Hello World' will be read once using the Amazon Polly "Joanna" Neural voice. Amazon Polly Neural voices are charged a premium price compared to Amazon Polly Standard voices.

A Simple Message to be Read using Google Cloud text-to-speech voice

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say voice="gcloud.en-US-Standard-A">Hello World.</Say>
</Response>
const { RestClient } = require('@signalwire/node')
const response = new RestClient.LaML.VoiceResponse()

response.say({voice:'gcloud.en-US-Standard-A'}, 'Hello World.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Hello World.', ['voice' => 'gcloud.en-US-Standard-A']);
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Hello World.", voice: "gcloud.en-US-Standard-A");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say

response = VoiceResponse()
response.say('Hello World.', voice='gcloud.en-US-Standard-A')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(voice: 'gcloud.en-US-Standard-A', message: 'Hello World.')
end

puts response.to_s

'Hello World' will be read once using the Google Cloud text-to-speech en-US-Standard-A voice.

Repetition of a Message in a Foreign Language

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say voice="alice" language="fr-CA" loop="5">Bonjour.</Say>
</Response>
const { RestClient } = require('@signalwire/node')
const response = new RestClient.LaML.VoiceResponse()

response.say({ voice: 'alice', language: 'fr-CA', loop: 5 }, 'Bonjour.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Bonjour', array(
    'voice' => 'alice',
    'language' => 'fr-CA',
    'loop' => 5
  ));
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Bonjour.", voice: "alice", language: "fr-CA", loop: 5);

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say

response = VoiceResponse()
response.say('Bonjour.', voice='alice', language='fr-CA', loop=5)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(message: 'Bonjour.', voice: 'alice', language: 'fr-CA', loop: 5)
end

puts response.to_s

'Hello' will be repeated 5 times in Canadian French.

Notes on Usage

  • There is a 4,096 Unicode character limit on the text
  • Numbers are spoken, or read, based on context. For example, '234' is read as "two hundred thirty-four", whereas '2 3 4' is read as "two three four".
  • Short pauses in spoken text are accomplished by inserting punctuations, i.e. commas and periods, in the written text. For longer pauses, place text in a separate <Say> verbs and place a <Pause> verb in between them.
  • Dates, times, money amounts, and abbreviations may not follow intuitive pronunciations. Test these situations to ensure they are pronounced to your liking.