private void BakeAndSaveTTS(string path, string utterance, double rate, int pitch) { var bake = _selectedVoice.BakeTTS(utterance, rate, pitch); if (bake == null) { return; } if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var hash = IntegratedAuthoringToolAsset.GenerateUtteranceId(utterance); var path2 = Path.Combine(path, hash.ToString()); using (var audioFile = File.Open(path2 + ".wav", FileMode.Create, FileAccess.Write)) { audioFile.Write(bake.waveStreamData, 0, bake.waveStreamData.Length); } using (var writer = new XmlTextWriter(path2 + ".xml", new UTF8Encoding(false))) { writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); writer.WriteStartElement("LipSyncVisemes"); writer.WriteAttributeString("wavFile", hash + ".wav"); double time = 0; foreach (var v in bake.visemes) { if (v.viseme > Viseme.Silence) { writer.WriteStartElement("viseme"); writer.WriteAttributeString("type", ((sbyte)v.viseme).ToString()); writer.WriteAttributeString("time", time.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("duration", v.duration.ToString(CultureInfo.InvariantCulture)); writer.WriteEndElement(); } time += v.duration; } writer.WriteEndElement(); writer.WriteEndDocument(); } }