# Sounds & Text to Speech

It's possible to override the main aircraft sound.xml however this method isn't recommended as only one addon will "win" if there are multiple that attempt to do it. Additionally, addons may become stale as the main aircraft sound.xml changes. Where possible the Voice Server can be used to manage sounds.

# Built-in sounds

play_audio can play various built-in sounds.

# Voice Server

The Voice Server is a an external program which must be running while the user runs the mission. The voice server will accept commands and subsequently play sounds (outside of MSFS).

To use the voice server, it must first be connected. Call connect_voice_server with an on_connected COMMANDLIST. Note that you should gracefully handle the case where the voice server isn't available.

Example:

{"connect_voice_server": {
  "on_connected":[
    {"speak":"Speech activated."}
  ],
  "on_disconnected":[
    {"set_message":{"text":"No voice server available"}}
  ]
}}

When running the above, you'll either see No voice server available or hear Speech activated.

You can check if the voice server is connected at any time by the boolean result of {"fn":"is_voice_server_connected"}.

Once you are connected, you can send the speak command in several variations:

  1. {"speak":"hello world"} In this case we simply speak some text. speak returns instantly after sending the command.

  2. {"speak":{"text":"hello world: {0}", "params":[ 99 ]}} Here we use text/params to build up a string.

  3. {"speak":"hello world", "interrupt: 1}, Here we are using interrupt to abort any active speech/audio, and to immediately begin playing this new message.

  4. {"speak":"hello.wav", "is_audio_file":1} Here we are playing the sound hello.wav (from the audio folder), and the directive is_audio_file tells the server that the text which is normally speech is instead a file name.

# Implement a compatible voice server (Advanced)

Server must run on localhost:5997 and be of type websocket.

Messages:

  • {"Text":"","FileName":"test1.wav","Interrupt":false}
  • {"Text":"hello your name","FileName":"","Interrupt":false}
  • {"Text":"stop text","FileName":"","Interrupt":true}

# Voice Server Test Program

{
  "title": "Voice Server Test Program",
  "briefing": [
    {"title": "Voice Server Test Program"},
    
    {
      "buttonbar": [ {"title":"Connect to voice server",  "commands":[ {"call_macro":"connect_voice"}]} ],
      "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 0}
    },
    {
      "text":"Not connected to voice server.",
      "color":"red",
      "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 0}
    },
    {
      "text":"Connected to voice server.",
      "color":"green",
      "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}
    },
    {"text": "-------------------"},
    
    {"text":".wav file test1", "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}},
    {
      "buttonbar": [ {"title":"Play",  "commands":[
        {"speak":"test1.wav", "is_audio_file":1}
      ]}],
      "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}
    },
    
    
    {"text":"speech recognition test text", "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}},
    {
      "buttonbar": [ {"title":"Speak",  "commands":[ 
        {"speak":"speech recognition test text"}
      ]}],
      "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}
    },
    
    {"text":"INTERRUPT: stop text", "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}},
    {
      "buttonbar": [ {"title":"Speak",  "commands":[
        {"speak":"stop text", "interrupt":1}
      ]}],
      "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}
    },
    
    
    {"text":{"text":"Custom Message: {0}", "params":[ {"local":"message_textbox"} ]}, "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}},
    {"textbox": "message_textbox"},
    {
      "buttonbar": [ {"title":"Speak",  "commands":[
        {"speak": {"local":"message_textbox"}}
      ]}],
      "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}
    },
    
    {"text":{"text":"Format Message: hello {0}", "params":[ {"local":"message_textbox"} ]}, "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}},
    {
      "buttonbar": [ {"title":"Speak",  "commands":[ 
        {"speak": {"text":"hello {0}", "params": [ {"local":"message_textbox"} ]}}
      ]}],
      "show_condition": {"require":{"fn":"is_voice_server_connected"}, "eq": 1}
    }
  ],
  "macros": {
    "connect_voice": [
      {"connect_voice_server": {
      	"on_connected":[
      		{"speak":"Speech activated."}
      	],
      	"on_disconnected":[
      	  {"set_message":"No voice server available"}
      	]
      }}
    ]
  },
  "objectives": [
    {
      "title": "Done",
      "commands": [
        {"set":{"local":"message_textbox"},"value":"your name"},
        {"call_macro":"connect_voice"},
        {"sleep": "forever"}
      ]
    }
  ]
}