Skip to main content

Add voice guidance

|

Voice guidance in the Maps SDK for TypeScript allows you to enhance navigation experiences with spoken instructions. This guide covers how to integrate custom playback using the onTextToSpeechInstruction callback with the browser's built-in Text-to-Speech capabilities.

The Maps SDK for TypeScript provides instruction playback through:

  • External integration - delivery of TTS strings for use with the browser's window.speechSynthesis API or other third-party solutions.
Browser Environment

In the browser environment, the Maps SDK delivers text instructions through callbacks. You can use the browser's built-in window.speechSynthesis API to convert these text instructions into speech, as demonstrated in the examples below.

Basic Voice Guidance

To enable voice guidance in a browser application, you need to:

  1. Get TTS instruction strings from the SDK via the onTextToSpeechInstruction callback
  2. Use the browser's speechSynthesis API to speak the instructions

Here's a complete example of setting up voice guidance:

import { NavigationService, NavigationInstruction, Route, GemError, AlarmService, AlarmListener } from '@magiclane/maps-sdk';

// TTS engine using browser's speechSynthesis
class TTSEngine {
private synth: SpeechSynthesis;
private utter: SpeechSynthesisUtterance | null = null;

constructor() {
this.synth = window.speechSynthesis;
}

speakText(text: string) {
if (this.synth.speaking) {
this.synth.cancel();
}
this.utter = new SpeechSynthesisUtterance(text);
this.utter.rate = 0.75;
this.utter.pitch = 1.0;
this.utter.volume = 0.8;
this.synth.speak(this.utter);
}

stop() {
if (this.synth.speaking) {
this.synth.cancel();
}
}
}

// Create TTS engine instance
const ttsEngine = new TTSEngine();

// Start simulation with voice guidance
const navigationHandler = NavigationService.startSimulation(
route,
undefined,
{
onNavigationInstruction: (instruction: NavigationInstruction) => {
// Handle navigation instruction updates
},
onTextToSpeechInstruction: (textInstruction: string) => {
// Speak the instruction using browser's TTS
ttsEngine.speakText(textInstruction);
},
onDestinationReached: (landmark: any) => {
// Handle destination reached
},
onError: (error: GemError) => {
// Handle errors
}
}
);
tip

You can customize the voice characteristics by modifying the SpeechSynthesisUtterance properties:

  • rate: Speed of speech (0.1 to 10, default 1)
  • pitch: Voice pitch (0 to 2, default 1)
  • volume: Volume level (0 to 1, default 1)
  • lang: Language code (e.g., 'en-US', 'de-DE')
  • voice: Select from available voices via window.speechSynthesis.getVoices()

Voice Language and Browser TTS

When using the browser's speechSynthesis API, you can control the language and voice selection:

// Get available voices
const voices = window.speechSynthesis.getVoices();

// Create TTS engine with custom language
class TTSEngine {
private synth: SpeechSynthesis;
private selectedVoice: SpeechSynthesisVoice | null = null;

constructor(languageCode?: string) {
this.synth = window.speechSynthesis;

if (languageCode) {
// Find voice matching the language code
const voices = this.synth.getVoices();
this.selectedVoice = voices.find(v => v.lang.startsWith(languageCode)) || null;
}
}

speakText(text: string) {
if (this.synth.speaking) {
this.synth.cancel();
}

const utterance = new SpeechSynthesisUtterance(text);
utterance.rate = 0.75;
utterance.pitch = 1.0;
utterance.volume = 0.8;

if (this.selectedVoice) {
utterance.voice = this.selectedVoice;
utterance.lang = this.selectedVoice.lang;
}

this.synth.speak(utterance);
}
}

// Create TTS engine for German
const germanTTS = new TTSEngine('de');
tip

To change the language of the instructions provided through the onTextToSpeechInstruction callback, you can use SdkSettings.setTTSVoiceByLanguage to set the SDK's instruction language. The text will be generated in that language, and then you can use the browser's TTS with a matching voice.

Using Voice Guidance with Speed Alarms

You can combine voice guidance with alarm notifications for a more comprehensive navigation experience:

import { AlarmService, AlarmListener, NavigationService } from '@magiclane/maps-sdk';

const ttsEngine = new TTSEngine();
let alarmListener: any = null;
let alarmService: any = null;

// Create alarm listener for speed limit warnings
alarmListener = AlarmListener.create({
onSpeedLimit: async (speed: number, limit: number, insideCityArea: boolean) => {
const speedLimitConverted = Math.round(limit * 3.6); // Convert m/s to km/h
const speedWarning = `Current speed limit: ${speedLimitConverted}`;
ttsEngine.speakText(speedWarning);
}
});

// Create alarm service
alarmService = AlarmService.create(alarmListener);

// Start navigation with TTS instructions
const navigationHandler = NavigationService.startSimulation(
route,
undefined,
{
onNavigationInstruction: (instruction: NavigationInstruction) => {
// Handle navigation updates
},
onTextToSpeechInstruction: (textInstruction: string) => {
ttsEngine.speakText(textInstruction);
},
onDestinationReached: (landmark: any) => {
// Clean up
alarmService = null;
},
onError: (error: GemError) => {
// Handle error
}
}
);

Changing SDK Language for Instructions

To change the language of text instructions provided by the SDK:

import { SdkSettings, Language, GemError } from '@magiclane/maps-sdk';

// Get the desired language
const lang: Language | null = SdkSettings.getBestLanguageMatch("de", { regionCode: "DEU" });

if (lang) {
// Set the SDK to use German for instructions
const error: GemError = SdkSettings.setTTSVoiceByLanguage(lang);

if (error === GemError.success) {
console.log("Instruction language set to German");

// Now create a matching German TTS voice
const germanTTS = new TTSEngine('de-DE');
}
}
Note

The SDK language (SdkSettings.language) controls UI text, while the TTS language controls spoken instructions. You can set them independently based on your needs.

Available Browser Voices

You can list and select from available voices in the browser:

// Wait for voices to load
window.speechSynthesis.onvoiceschanged = () => {
const voices = window.speechSynthesis.getVoices();

console.log('Available voices:');
voices.forEach((voice, index) => {
console.log(`${index}: ${voice.name} (${voice.lang})`);
});

// Filter for English voices
const englishVoices = voices.filter(v => v.lang.startsWith('en'));
console.log('English voices:', englishVoices.map(v => v.name));
};
warning

The SoundPlayingService class and its features (built-in voice playback, human voices, voice management) are not available in the browser environment. Voice guidance in browsers must be implemented using the onTextToSpeechInstruction callback with window.speechSynthesis or other web-based TTS solutions.