internal static ISpPhrase CreatePhraseFromWordUnits(RecognizedWordUnit[] words, CultureInfo culture, out GCHandle[] memHandles, out IntPtr coMem) { SPPHRASEELEMENT[] array = new SPPHRASEELEMENT[words.Length]; int num = Marshal.SizeOf(typeof(SPPHRASEELEMENT)); List <GCHandle> list = new List <GCHandle>(); coMem = Marshal.AllocCoTaskMem(num * array.Length); try { for (int i = 0; i < words.Length; i++) { RecognizedWordUnit recognizedWordUnit = words[i]; array[i] = new SPPHRASEELEMENT(); array[i].bDisplayAttributes = RecognizedWordUnit.DisplayAttributesToSapiAttributes((recognizedWordUnit.DisplayAttributes == DisplayAttributes.None) ? DisplayAttributes.OneTrailingSpace : recognizedWordUnit.DisplayAttributes); array[i].SREngineConfidence = recognizedWordUnit.Confidence; array[i].ulAudioTimeOffset = (uint)(recognizedWordUnit._audioPosition.Ticks * 10000 / 10000); array[i].ulAudioSizeTime = (uint)(recognizedWordUnit._audioDuration.Ticks * 10000 / 10000); if (recognizedWordUnit.Text != null) { GCHandle item = GCHandle.Alloc(recognizedWordUnit.Text, GCHandleType.Pinned); list.Add(item); array[i].pszDisplayText = item.AddrOfPinnedObject(); } if (recognizedWordUnit.Text == null || recognizedWordUnit.LexicalForm != recognizedWordUnit.Text) { GCHandle item2 = GCHandle.Alloc(recognizedWordUnit.LexicalForm, GCHandleType.Pinned); list.Add(item2); array[i].pszLexicalForm = item2.AddrOfPinnedObject(); } else { array[i].pszLexicalForm = array[i].pszDisplayText; } if (!string.IsNullOrEmpty(recognizedWordUnit.Pronunciation)) { GCHandle item3 = GCHandle.Alloc(recognizedWordUnit.Pronunciation, GCHandleType.Pinned); list.Add(item3); array[i].pszPronunciation = item3.AddrOfPinnedObject(); } Marshal.StructureToPtr((object)array[i], new IntPtr((long)coMem + num * i), false); } } finally { memHandles = list.ToArray(); } SPPHRASE sPPHRASE = new SPPHRASE(); sPPHRASE.cbSize = (uint)Marshal.SizeOf(sPPHRASE.GetType()); sPPHRASE.LangID = (ushort)culture.LCID; sPPHRASE.Rule = new SPPHRASERULE(); sPPHRASE.Rule.ulCountOfElements = (uint)words.Length; sPPHRASE.pElements = coMem; SpPhraseBuilder spPhraseBuilder = new SpPhraseBuilder(); ((ISpPhraseBuilder)spPhraseBuilder).InitFromPhrase(sPPHRASE); return((ISpPhrase)spPhraseBuilder); }
/// <summary> /// Helper function used to create a new phrase object from a /// test string. Each word in the string is converted to a phrase element. /// This is useful to create a phrase to pass to the EmulateRecognition method. /// </summary> internal static ISpPhrase CreatePhraseFromWordUnits(RecognizedWordUnit[] words, CultureInfo culture, out GCHandle[] memHandles, out IntPtr coMem) { SPPHRASEELEMENT[] elements = new SPPHRASEELEMENT[words.Length]; // build the unmanaged interop layer int size = Marshal.SizeOf(typeof(SPPHRASEELEMENT)); List <GCHandle> handles = new(); coMem = Marshal.AllocCoTaskMem(size * elements.Length); try { for (int i = 0; i < words.Length; i++) { RecognizedWordUnit word = words[i]; elements[i] = new SPPHRASEELEMENT { // display + confidence bDisplayAttributes = RecognizedWordUnit.DisplayAttributesToSapiAttributes(word.DisplayAttributes == DisplayAttributes.None ? DisplayAttributes.OneTrailingSpace : word.DisplayAttributes), SREngineConfidence = word.Confidence, // Timing information ulAudioTimeOffset = unchecked ((uint)(word._audioPosition.Ticks * 10000 / TimeSpan.TicksPerMillisecond)), ulAudioSizeTime = unchecked ((uint)(word._audioDuration.Ticks * 10000 / TimeSpan.TicksPerMillisecond)) }; // DLP information if (word.Text != null) { GCHandle handle = GCHandle.Alloc(word.Text, GCHandleType.Pinned); handles.Add(handle); elements[i].pszDisplayText = handle.AddrOfPinnedObject(); } if (word.Text == null || word.LexicalForm != word.Text) { GCHandle handle = GCHandle.Alloc(word.LexicalForm, GCHandleType.Pinned); handles.Add(handle); elements[i].pszLexicalForm = handle.AddrOfPinnedObject(); } else { elements[i].pszLexicalForm = elements[i].pszDisplayText; } if (!string.IsNullOrEmpty(word.Pronunciation)) { GCHandle handle = GCHandle.Alloc(word.Pronunciation, GCHandleType.Pinned); handles.Add(handle); elements[i].pszPronunciation = handle.AddrOfPinnedObject(); } Marshal.StructureToPtr(elements[i], new IntPtr((long)coMem + size * i), false); } } finally { memHandles = handles.ToArray(); } SPPHRASE spPhrase = new(); spPhrase.cbSize = (uint)Marshal.SizeOf(spPhrase.GetType()); spPhrase.LangID = (ushort)culture.LCID; spPhrase.Rule = new SPPHRASERULE { ulCountOfElements = (uint)words.Length }; spPhrase.pElements = coMem; // Initialized the phrase SpPhraseBuilder phraseBuilder = new(); ((ISpPhraseBuilder)phraseBuilder).InitFromPhrase(spPhrase); return((ISpPhrase)phraseBuilder); }