Skip to content

Audio

Here you can find more information about the Audio settings and features.

AudioManager

Audio Manage is a class responsible for playing audio sounds on demand, redirecting output streams, setting of audio route, stopping playing sounds, etc. Here are all available operations in more detail.

Playing sounds

The most intuitive function of AudioManager is to play sounds. There are three types of supported sounds - Text-To-Speech, PCM data or audio file in a supported format. Playing any type of sound is straightforward:

val ttsSound = AudioTTSOutput("Hello TTS!")
audioManager.playOutput(ttsSound)

val pcmData = AudioPCMOutput(listOf(/*fill with PCM data*/))
audioManager.playOutput(pcmData)

val audioFile = AudioFileOutput(listOf("/sdcard/sounds/sound1.wav"))
audioManager.playOutput(audioFile)

Audio files are considered PCM data and are played in the same way.

Redirecting output

If the integrator does not want to play sounds through the SDK audio engine, it is possible to redirect this output to the integrator and they can decide if and how to play the sound. Everytime SDK is goind to play a sound, the redirected callback will be called instead. Example of redirecting sound playback:

audioManager.redirectTTSOutput { ttsString ->
    // do whatever you want with ttsString
    Log.d("AudioRedirection", "We are about to play $ttsString")
    // wait for any additional event
    // play ttsString through our own audio engine
    // or simply play it through SDK again
    audioManager.playOutput(AudioTTSOutput(ttsString))
}

// the same with PCM data
audioManager.redirectPCMDataOutput { pcmData ->
    // do something with PCM Data
}

Audio queue

Complex audio instructions are composed together from many shorter instructions and then queued together into a queue which is played one by one in a FIFO order. The udioManager class allows to control this queue with a few simple methods:

// skip current sound and continue playing remaining sounds from the audio queue
audioManager.skipCurrentOutput()

// let currently playing sound finish but clear remaining audio queue
audioManager.clearQueue()

// combination of above methods - stop the current sound and clear whole queue
audioManager.stopOutputAndClearQueue()

Play status

It is possible to listen for a playback status of the playing sound, for example if you need to wait for the playback to finish. To do this, it is possible to register a play status listener:

// add play status listener to audio manager
audioManager.addPlayStatusListener { playStatus ->
    when (playStatus) {
        AudioManager.PlayStatus.Playing -> { /* sound is playing right now */ }
        AudioManager.PlayStatus.Stopped -> { /* playback finished successfully and/or nothing is playing right now */ }
        AudioManager.PlayStatus.Error -> { /* last playback finished with error */ }
    }          
}
// for example, play any sound and get the above callbacks about its playback status
audioManager.playOutput(AudioTTSOutput("Check my playback status!"))

...

// remove the play status listener when you no longer need it
audioManager.removePlayStatusListener(listener)

Audio route

The audio manager allows to choose the output audio device for playing sounds. There are three options:

  • Default - let the operating system decide the output device. It might be any device including headphones bluetooth audio devices, phone speaker or anything that is set as default audio device in the operating system.
  • BluetoothHFP - play sound through bluetooth HFP device (handsfree sets, incar audio systems, etc). More info about HFP here
  • ForceSpeaker - try to force audio output through phone's integrated speaker. This functionality is not documented or allowed by Google, but similar behavior may be achieved with little tricks. Use at your own risk.

Example of changing the audio route:

// use HFP device
audioManager.audioRoute = AudioManager.AudioRoute.BluetoothHFP
// use system default device
audioManager.audioRoute = AudioManager.AudioRoute.Default

// get current audio route
val audioRoute = audioManager.audioRoute

Note

Since HFP devices "make a call" to the output device, play the sound and then end the call. We are not able to know when the call was "answered" by the audio device. Therefore it might be necessary to manually insert a delay between dialing and playing the sound. Note that this delay is different on different devices and it is necessary to let the user adjust this delay on their own (create an interface for them, for example a slider).

// use the HFP device
audioManager.audioRoute = AudioManager.AudioRoute.BluetoothHFP
// set 1 second delay in between dialing and playing sound
audioManager.setHfpDelay(1000)
// all navigation instructions will be shifted by 1 second to accomodate the desired HFP delay

AudioSettings

This class is offering interface for setting custom sounds for all navigation events/alerts/warnings which may occur while navigating or just driving. This includes warnigns for: Speed Cameras, Danger Turns, Speed Limit, Near Rail, Traffic, Last Mile, Scout Route, Vehicle Zones etc.

For example if you want to set your custom sound for Railway crossing warning:

// use TTS sound
audioSettings.ttsWarnNearRailText = "Railway crossing ahead!"

// use Audio file
audioSettings.warnNearRailSound = "/sdcard/sounds/railway.wav"

VoiceManager

Allows to get all installed voices (both TTS and standard voice files) and get/set voice for navigation.

// set first installed voice for navigation
voiceManager.getInstalledVoices { voiceList, operationStatus ->
    if (operationStatus.result == OperationStatus.Result.Success) {
        voiceManager.voice = voiceList.first()
    }
}

// get current voice set for navigation
val currentVoice = voiceManager.voice

Default TTS

Another feature of VoiceManager is to find out default TTS voice for current device based on system language, regional settings etc:

voiceManager.getDefaultTtsLocale { defaultTTS ->
    Log.d("VoiceManager", "Default TTS is $defaultTTS")
}

VoiceDownload

Class responsible for installing and uninstalling standard voice files downloaded from Sygic servers. Standard voices are pre-recorded voices that sound more human, but are not capable of reading street names.

To get the list of all available voices:

voiceDownload.getAvailableVoiceList { availableVoices, operationStatus ->
    if (operationStatus.result == OperationStatus.Result.Success) {
        // install the first available voice
        voiceDownload.installVoice(availableVoices.first())
        // cancel download
        voiceDownload.cancelDownload(availableVoices.first())
        // or uninstall it
        voiceDownload.uninstallVoice(availableVoices.first())
    }
}

Voice Install listener

It is also possible to watch for install/uninstall progress and finished callbacks

voiceDownload.addVoiceInstallationListener(object : VoiceInstallListener {
    override fun onVoiceInstallProgress(entry: VoiceEntry, bytesDownloaded: Long, totalBytes: Long) {
        // voice installation in progress
    }

    override fun onVoiceInstallFinished(entry: VoiceEntry, result: OperationStatus) {
        // voice installation finished with result
    }

    override fun onVoiceUninstallFinished(entry: VoiceEntry, result: OperationStatus) {
        // voice uninstallation finished with result
    }
})

...

// remove installation listener when no longer needed
voiceDownload.removeVoiceInstallationListener(listener)

NavigationManager offers interface for enabling/disabling specific audio notifications while driving or navigating. These notifications may be enabled or disabled by adding audio listener for specific notification types and return true or false from its callback method. For example to enable better route audio notification and disable railway crossing audio notification:

// enable/disable audio notifications
navigationManager.apply {
    // audio for better route notification will be played by the SDK engine
    setAudioBetterRouteListener { false }

    // audio for railway crossing notification will not be played by SDK engine, but you get the information
    // so that you can do anything with it, for example play it however you want, enhance it, etc.
    setAudioRailwayCrossingListener { true }
}

These types of audio notifications are available: Railway Crossing, Sharp Curves, SpeedLimit, Traffic, Incidents, Better Route, Instructions, Vehicle Aid, Vehicle Zone and Traffic Sign.