Examples
========
This page provides practical examples of using SSMD in real-world scenarios.
Basic TTS Integration
----------------------
pyttsx3 (Offline TTS)
~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
import pyttsx3
from ssmd import Document
# Initialize TTS engine
engine = pyttsx3.init()
# Create content with SSMD
text = """
# Welcome Message
*Hello* and welcome!
Please ...500ms listen carefully.
This is [very fast]{rate="x-fast"}.
"""
# Create document with pyttsx3 capabilities
doc = Document(text, capabilities='pyttsx3')
# Convert to SSML
ssml = doc.to_ssml()
# Speak (pyttsx3 handles SSML natively)
engine.say(ssml)
engine.runAndWait()
Google Text-to-Speech
~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
from google.cloud import texttospeech
from ssmd import Document
# Initialize Google TTS client
client = texttospeech.TextToSpeechClient()
# Create content
text = """
*Welcome* to our service.
[Bonjour]{lang="fr"} to our French users!
Please wait ...1s for the next message.
"""
# Create document with Google capabilities
doc = Document(text, capabilities='google')
# Convert to SSML
ssml = doc.to_ssml()
# Prepare TTS request
synthesis_input = texttospeech.SynthesisInput(ssml=ssml)
voice = texttospeech.VoiceSelectionParams(
language_code="en-US",
name="en-US-Neural2-J"
)
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.MP3
)
# Generate speech
response = client.synthesize_speech(
input=synthesis_input,
voice=voice,
audio_config=audio_config
)
# Save to file
with open("output.mp3", "wb") as f:
f.write(response.audio_content)
Google TTS with Speaking Styles
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Google Cloud TTS supports speaking styles for Neural2 and Studio voices:
.. code-block:: python
from google.cloud import texttospeech
from ssmd import Document
# Configure Google TTS styles as extensions
doc = Document(config={
'extensions': {
'cheerful': lambda text: f'{text}',
'calm': lambda text: f'{text}',
'empathetic': lambda text: f'{text}',
'apologetic': lambda text: f'{text}',
}
})
# Build content with speaking styles
doc.add_sentence("[Welcome to our customer service!]{ext=\"cheerful\"}")
doc.add_sentence("[We understand this must be frustrating.]{ext=\"empathetic\"}")
doc.add_sentence("[We sincerely apologize for the inconvenience.]{ext=\"apologetic\"}")
doc.add_sentence("[Please take a moment to breathe.]{ext=\"calm\"}")
# Generate SSML
ssml = doc.to_ssml()
# Initialize Google TTS client
client = texttospeech.TextToSpeechClient()
# Use a voice that supports styles (Neural2 or Studio)
synthesis_input = texttospeech.SynthesisInput(ssml=ssml)
voice = texttospeech.VoiceSelectionParams(
language_code="en-US",
name="en-US-Neural2-F" # Neural2 voices support styles
)
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.MP3
)
response = client.synthesize_speech(
input=synthesis_input,
voice=voice,
audio_config=audio_config
)
with open("styled_output.mp3", "wb") as f:
f.write(response.audio_content)
.. note::
Speaking styles are only supported by specific Google Cloud TTS voices
(Neural2 and Studio voices). See the complete example in
``examples/google_tts_styles.py``.
Amazon Polly
~~~~~~~~~~~~
.. code-block:: python
import boto3
from ssmd import Document
# Initialize Polly client
polly = boto3.client('polly')
# Create content with Amazon extensions
text = """
*Welcome* to our podcast.
Now for the [secret message]{ext="whisper"}.
Back to normal voice.
"""
# Create document with Polly capabilities
doc = Document(text, capabilities='polly')
# Convert to SSML
ssml = doc.to_ssml()
# Generate speech
response = polly.synthesize_speech(
Text=ssml,
TextType='ssml',
OutputFormat='mp3',
VoiceId='Joanna'
)
# Save audio
with open('output.mp3', 'wb') as f:
f.write(response['AudioStream'].read())
Streaming TTS
-------------
Sentence-by-Sentence Processing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
from ssmd import Document
import time
# Mock TTS engine for demonstration
class TTSEngine:
def speak(self, ssml):
print(f"Speaking: {ssml}")
time.sleep(0.5) # Simulate speech duration
engine = TTSEngine()
# Long document
document_text = """
# Chapter 1: The Beginning
It was a dark and stormy night.
The rain fell in torrents.
Lightning flashed across the sky.
# Chapter 2: The Discovery
Suddenly, a sound echoed through the halls.
What could it be?
"""
# Create document with automatic sentence splitting
doc = Document(document_text, auto_sentence_tags=True)
sentence_count = len(list(doc.sentences()))
print(f"Total sentences: {sentence_count}")
# Stream sentences
for i, sentence_doc in enumerate(doc.sentences(as_documents=True), 1):
print(f"\n[{i}/{sentence_count}]")
engine.speak(sentence_doc.to_ssml())
print("\nPlayback complete!")
Async TTS Streaming
~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
import asyncio
from ssmd import Document
class AsyncTTSEngine:
async def speak(self, ssml):
print(f"Speaking: {ssml[:50]}...")
await asyncio.sleep(0.5)
print("Done")
async def stream_document(doc):
engine = AsyncTTSEngine()
sentence_count = len(list(doc.sentences()))
for i, sentence_doc in enumerate(doc.sentences(as_documents=True), 1):
print(f"\n[Sentence {i}/{sentence_count}]")
await engine.speak(sentence_doc.to_ssml())
async def main():
text = """
Welcome to async TTS.
Each sentence is processed independently.
This allows for smooth streaming.
"""
doc = Document(text, auto_sentence_tags=True)
await stream_document(doc)
# Run
asyncio.run(main())
Interactive Story Reader
------------------------
.. code-block:: python
from ssmd import Document
import pyttsx3
class StoryReader:
def __init__(self, tts_engine='pyttsx3'):
self.capabilities = tts_engine
self.engine = pyttsx3.init()
self.current_doc = None
self.current_index = 0
def load_story(self, ssmd_text):
"""Load a story from SSMD text."""
self.current_doc = Document(
ssmd_text,
capabilities=self.capabilities,
auto_sentence_tags=True
)
self.current_index = 0
def play(self):
"""Play from current position."""
if not self.current_doc:
print("No story loaded")
return
sentences = list(self.current_doc.sentences(as_documents=True))
while self.current_index < len(sentences):
sentence_doc = sentences[self.current_index]
print(f"\n[{self.current_index + 1}/{len(sentences)}]")
self.engine.say(sentence_doc.to_ssml())
self.engine.runAndWait()
self.current_index += 1
# Interactive control
cmd = input("(n)ext, (p)rev, (q)uit: ").lower()
if cmd == 'q':
break
elif cmd == 'p' and self.current_index > 0:
self.current_index -= 2 # Go back two, play one forward
def get_progress(self):
"""Get reading progress."""
if not self.current_doc:
return 0
total_sentences = len(list(self.current_doc.sentences()))
return (self.current_index / total_sentences) * 100 if total_sentences > 0 else 0
# Usage
story = """
# The Adventure Begins
[Once upon a time]{volume="2" rate="2"}, in a land far away.
There lived a brave *knight* named Sir Galahad.
He faced many challenges ...1s but never gave up.
# The Quest
One day, the king summoned him.
[Go forth]{volume="x-loud"} said the king, [and save our kingdom]{volume="x-loud"}!
"""
reader = StoryReader()
reader.load_story(story)
reader.play()
Content Management System
--------------------------
SSMD CMS with Database
~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
from ssmd import Document, to_ssml
import sqlite3
from datetime import datetime
class SSMDContentManager:
def __init__(self, db_path='content.db'):
self.db = sqlite3.connect(db_path)
self._setup_db()
def _setup_db(self):
self.db.execute('''
CREATE TABLE IF NOT EXISTS content (
id INTEGER PRIMARY KEY,
title TEXT,
ssmd_text TEXT,
ssml_cache TEXT,
created_at TIMESTAMP,
updated_at TIMESTAMP
)
''')
self.db.commit()
def create(self, title, ssmd_text):
"""Create new content."""
ssml = to_ssml(ssmd_text)
now = datetime.now()
self.db.execute('''
INSERT INTO content (title, ssmd_text, ssml_cache, created_at, updated_at)
VALUES (?, ?, ?, ?, ?)
''', (title, ssmd_text, ssml, now, now))
self.db.commit()
def update(self, content_id, ssmd_text):
"""Update existing content."""
ssml = to_ssml(ssmd_text)
now = datetime.now()
self.db.execute('''
UPDATE content
SET ssmd_text = ?, ssml_cache = ?, updated_at = ?
WHERE id = ?
''', (ssmd_text, ssml, now, content_id))
self.db.commit()
def get_ssml(self, content_id):
"""Get cached SSML for content."""
cursor = self.db.execute(
'SELECT ssml_cache FROM content WHERE id = ?',
(content_id,)
)
row = cursor.fetchone()
return row[0] if row else None
def get_ssmd(self, content_id):
"""Get SSMD source."""
cursor = self.db.execute(
'SELECT ssmd_text FROM content WHERE id = ?',
(content_id,)
)
row = cursor.fetchone()
return row[0] if row else None
# Usage
cms = SSMDContentManager()
# Create content
cms.create("Welcome Message", """
# Welcome to Our Service
*Thank you* for joining us today!
""")
# Get SSML for TTS
ssml = cms.get_ssml(1)
print(ssml)
Multi-Language Support
----------------------
Language-Aware TTS
~~~~~~~~~~~~~~~~~~
.. code-block:: python
from ssmd import Document, to_ssml
class MultilingualTTS:
def __init__(self):
self.capabilities = 'google'
def create_multilingual_content(self, messages):
"""Create content with multiple languages."""
parts = []
for lang, text in messages:
if lang == 'en':
parts.append(text)
else:
parts.append(f"[{text}]{{lang=\"{lang}\"}}")
return " ".join(parts)
def speak_multilingual(self, messages):
ssmd_text = self.create_multilingual_content(messages)
ssml = to_ssml(ssmd_text, capabilities=self.capabilities)
return ssml
# Usage
tts = MultilingualTTS()
messages = [
('en', '*Welcome* to our global service.'),
('fr', 'Bienvenue à notre service mondial.'),
('de', 'Willkommen zu unserem globalen Service.'),
('es', 'Bienvenido a nuestro servicio global.'),
]
ssml = tts.speak_multilingual(messages)
print(ssml)
Podcast Generator
-----------------
.. code-block:: python
from ssmd import Document
from pathlib import Path
class PodcastGenerator:
def __init__(self, output_dir='podcasts'):
self.output_dir = Path(output_dir)
self.output_dir.mkdir(exist_ok=True)
def generate_episode(self, episode_number, script):
"""Generate podcast episode."""
# Add production elements
enhanced_script = f"""
# Episode {episode_number}
[Podcast intro music]{src="@intro_music.mp3"}
...1s
{script}
...2s
[Outro music]{src="@outro_music.mp3"}
"""
# Create document with Polly capabilities
doc = Document(
enhanced_script,
capabilities='polly',
auto_sentence_tags=True,
pretty_print=True
)
# Convert to SSML
ssml = doc.to_ssml()
# Save SSML
output_file = self.output_dir / f"episode_{episode_number}.ssml"
output_file.write_text(ssml)
return output_file
# Usage
podcast = PodcastGenerator()
script = """
*Welcome* to Tech Talks!
Today we're discussing artificial intelligence.
Our guest is Dr. Smith, an expert in machine learning.
[Welcome to the show]{volume="4"}, Doctor Smith!
...500ms
Thank you for having me.
"""
ssml_file = podcast.generate_episode(42, script)
print(f"Generated: {ssml_file}")
Testing and Validation
-----------------------
SSMD Linter
~~~~~~~~~~~
.. code-block:: python
from ssmd import to_ssml
class SSMDLinter:
def lint(self, ssmd_text):
"""Validate SSMD and provide feedback."""
issues = []
# Try to convert
try:
ssml = to_ssml(ssmd_text)
except Exception as e:
issues.append(f"Conversion error: {e}")
return issues
# Check for common issues
if '*' in ssmd_text and '**' not in ssmd_text:
if ssmd_text.count('*') % 2 != 0:
issues.append("Unmatched asterisks for emphasis")
# Check for very long pauses
if '...10s' in ssmd_text or '...10000ms' in ssmd_text:
issues.append("Warning: Very long pause detected")
# Success
if not issues:
issues.append("✓ No issues found")
return issues
# Usage
linter = SSMDLinter()
text = """
*Hello world
This has an unclosed emphasis tag.
"""
issues = linter.lint(text)
for issue in issues:
print(issue)
Complete Application Example
-----------------------------
Voice Assistant with SSMD
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
from ssmd import to_ssml
import random
class VoiceAssistant:
def __init__(self, name="Assistant", tts_engine='google'):
self.name = name
self.capabilities = tts_engine
def greet(self, user_name=None):
greetings = [
"*Hello*!",
"Good day!",
"*Welcome* back!",
]
greeting = random.choice(greetings)
if user_name:
message = f"{greeting} {user_name}."
else:
message = greeting
return to_ssml(message, capabilities=self.capabilities)
def error(self, message):
return to_ssml(f"--Sorry-- ...300ms {message}", capabilities=self.capabilities)
def success(self, message):
return to_ssml(f"*Great*! {message}", capabilities=self.capabilities)
def thinking(self):
return to_ssml("...500ms Let me think ...500ms", capabilities=self.capabilities)
def announce(self, title, message):
ssmd = f"""
# {title}
...300ms
{message}
"""
return to_ssml(ssmd, capabilities=self.capabilities)
# Usage
assistant = VoiceAssistant(name="Jarvis")
print(assistant.greet("John"))
print(assistant.thinking())
print(assistant.success("Task completed successfully"))
print(assistant.error("I couldn't find that file"))
print(assistant.announce("Weather Update", "It's sunny with a high of 72 degrees"))
Parser API Examples
-------------------
The Parser API extracts structured data from SSMD instead of generating SSML.
This is useful for building custom TTS pipelines.
Basic Segment Extraction
~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
from ssmd import parse_segments
text = "Hello *world*! This is ...500ms great."
segments = parse_segments(text)
for seg in segments:
print(f"Text: {seg.text!r}")
if seg.emphasis:
print(" - Has emphasis")
for brk in seg.breaks_after:
print(f" - Break: {brk.time}")
Multi-Voice Dialogue Processing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
from ssmd import parse_sentences
script = """
Welcome to the show!
Thanks Sarah! Great to be here.
Let's get started!
"""
for sentence in parse_sentences(script):
voice_name = sentence.voice.name if sentence.voice else "default"
text = "".join(seg.text for seg in sentence.segments)
print(f"[{voice_name}] {text}")
Custom TTS Pipeline
~~~~~~~~~~~~~~~~~~~
.. code-block:: python
from ssmd import parse_sentences
class CustomTTS:
def process_script(self, script):
"""Process SSMD script with custom handling."""
sentences = parse_sentences(script)
for sentence in sentences:
# Configure voice
voice = sentence.voice.name if sentence.voice else "default"
# Build text with transformations
full_text = ""
for seg in sentence.segments:
# Handle say-as
if seg.say_as:
if seg.say_as.interpret_as == "telephone":
text = self.format_phone(seg.text)
elif seg.say_as.interpret_as == "date":
text = self.format_date(seg.text)
else:
text = seg.text
# Handle substitution
elif seg.substitution:
text = seg.substitution
# Handle phoneme
elif seg.phoneme:
text = seg.text # Use phoneme data
else:
text = seg.text
full_text += text
# Speak with custom TTS
self.speak(full_text, voice=voice)
def format_phone(self, number):
"""Custom phone number formatting."""
# Remove non-digits and format
digits = ''.join(c for c in number if c.isdigit())
return f"{digits[:3]}-{digits[3:6]}-{digits[6:]}"
def format_date(self, date_str):
"""Custom date formatting."""
return date_str # Add custom date parsing
def speak(self, text, voice="default"):
"""Mock TTS speak method."""
print(f"[{voice}] {text}")
# Usage
tts = CustomTTS()
tts.process_script("""
Call [+1-555-0123]{as="telephone"} today!
""")
Text Transformation Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
from ssmd import parse_segments
text = """
Call [+1-555-0123]{as="telephone"} for info.
[H2O]{sub="water"} is important.
Say [tomato]{ipa="təˈmeɪtoʊ"} correctly.
"""
segments = parse_segments(text)
for seg in segments:
if seg.say_as:
print(f"Say-as: {seg.text!r} as {seg.say_as.interpret_as}")
elif seg.substitution:
print(f"Substitute: '{seg.text}' → '{seg.substitution}'")
elif seg.phoneme:
print(f"Phoneme: '{seg.text}' → /{seg.phoneme.ph}/")
For a complete parser demonstration, see ``examples/parser_demo.py``.
See Also
--------
* Check the `examples/` directory in the repository for more runnable examples:
* ``examples/parser_demo.py`` - Complete parser API demonstration
* ``examples/story_reader_demo.py`` - Interactive story reader
* ``examples/tts_with_capabilities.py`` - TTS engine capability filtering
* ``examples/tts_container_demo.py`` - Container-based TTS demo
* ``examples/google_tts_styles.py`` - Google Cloud TTS speaking styles
* Visit :doc:`api` for complete API documentation
* See :doc:`parser` for the Parser API guide
* See :doc:`capabilities` for TTS engine integration details