Speech API
The car system has a cohesive Speech API, providing Text-To-Speech, Dictation, and Recording. A ui_description.xml file can have a set of <linkAction> elements with an actionType of readout, dictate, or record, and the linkModel points to a model with some parameters. There are some <actionEvent> elements that have a reference from an action parameter to these <linkAction> elements.
After setting up the model with the appropriate data, the related <actionEvent> should be triggered with rhmi_triggerHMIEvent() with args of {0:null}.
Readout
There are two <linkAction actionType="readout"> objects, and they point to two different raListModel objects. The event that points to the first linkAction is used to trigger general commands (let's call it Command Event), and the event that points to a second linkAction is used to start the actual readout (let's call it Start Event).
Basic TTS is very easy. The linkModel from the second linkAction[actionType=readout] is updated with a list with 2 columns and 1 row: The first column holds the text to read, and the second column is a name that will show up in progress report callbacks. Then, the actionEvent that refers to this second linkAction is triggered with rhmi_triggerHMIEvent() with args of {0:null}.
sequenceDiagram
participant App as Connected App
participant Car as BMW Car
App ->> Car: rhmi_setModel(startAction.model, ['words to read', 'application name'])
App ->> Car: rhmi_triggerHMIEvent(startEvent, {0:null})
Car ->> App: cds_onPropertyChangedEvent(cdsHandle, 113, "hmi.tts", {"TTSState": {}})
After the car has started reading out the text, the Command Event can be used to control the playback. Progress can be monitored through the CDS system, as the car updates the hmi.tts data..
sequenceDiagram
participant App as Connected App
participant Car as BMW Car
App ->> Car: rhmi_setModel(controlAction.model, ['STR_READOUT_PAUSE', 'application name'])
App ->> Car: rhmi_triggerHMIEvent(commandEvent, {0:null})
Car ->> App: cds_onPropertyChangedEvent(cdsHandle, 113, "hmi.tts", {"TTSState": {}})
The known commands are:
- STR_READOUT_PAUSE
- STR_READOUT_STOP
- STR_READOUT_PREV_BLOCK
- STR_READOUT_NEXT_BLOCK
- STR_READOUT_JUMP_TO_BEGIN
The TTSState object has some interesting data, which may be useful when controlling playback:
stateis a value from 0 to 4, representing the following values: UNDEFINED, IDLE, PAUSED, ACTIVE, BUSYcurrentblockshows the current playback progress. This is observed to be-2while it is parsing the text and the state isBUSY,-1when the state flips toACTIVEbut before it has started outputting audio, and then counts up from 0 to theblockscount.blocksis the number of total blocks to read outtypeis the name given by the app, as the second column of the RaListModel that was sent to be readlanguageavailableshows1for English