private void Initialize(IRecognizerInternal recognizer, ISpRecoResult recoResult, byte[] sapiResultBlob, int maxAlternates) { _recognizer = recognizer; _maxAlternates = maxAlternates; try { _sapiRecoResult = (recoResult as ISpRecoResult2); } catch (COMException) { _sapiRecoResult = null; } GCHandle gCHandle = GCHandle.Alloc(sapiResultBlob, GCHandleType.Pinned); try { IntPtr intPtr = gCHandle.AddrOfPinnedObject(); int num = Marshal.ReadInt32(intPtr, 4); if (num == Marshal.SizeOf(typeof(SPRESULTHEADER_Sapi51))) { SPRESULTHEADER_Sapi51 source = (SPRESULTHEADER_Sapi51)Marshal.PtrToStructure(intPtr, typeof(SPRESULTHEADER_Sapi51)); _header = new SPRESULTHEADER(source); _isSapi53Header = false; } else { _header = (SPRESULTHEADER)Marshal.PtrToStructure(intPtr, typeof(SPRESULTHEADER)); _isSapi53Header = true; } _header.Validate(); IntPtr phraseBuffer = new IntPtr((long)intPtr + (int)_header.ulPhraseOffset); SPSERIALIZEDPHRASE phraseHeader = RecognizedPhrase.GetPhraseHeader(phraseBuffer, _header.ulPhraseDataSize, _isSapi53Header); bool hasIPAPronunciation = (_header.fAlphabet & 1) != 0; InitializeFromSerializedBuffer(this, phraseHeader, phraseBuffer, (int)_header.ulPhraseDataSize, _isSapi53Header, hasIPAPronunciation); if (recoResult != null) { ExtractDictationAlternates(recoResult, maxAlternates); recoResult.Discard(255u); } } finally { gCHandle.Free(); } _sapiAudioBlob = new byte[_header.ulRetainedDataSize]; Array.Copy(sapiResultBlob, (int)_header.ulRetainedOffset, _sapiAudioBlob, 0, (int)_header.ulRetainedDataSize); _sapiAlternatesBlob = new byte[_header.ulPhraseAltDataSize]; Array.Copy(sapiResultBlob, (int)_header.ulPhraseAltOffset, _sapiAlternatesBlob, 0, (int)_header.ulPhraseAltDataSize); }
private void Initialize(IRecognizerInternal recognizer, ISpRecoResult recoResult, byte[] sapiResultBlob, int maxAlternates) { // record parameters _recognizer = recognizer; _maxAlternates = maxAlternates; try { _sapiRecoResult = recoResult as ISpRecoResult2; } catch (COMException) { _sapiRecoResult = null; } GCHandle gc = GCHandle.Alloc(sapiResultBlob, GCHandleType.Pinned); try { IntPtr buffer = gc.AddrOfPinnedObject(); int headerSize = Marshal.ReadInt32(buffer, 4); // Read header size directly from buffer - 4 is the offset of cbHeaderSize. if (headerSize == Marshal.SizeOf <SPRESULTHEADER_Sapi51>()) // SAPI 5.1 size { SPRESULTHEADER_Sapi51 legacyHeader = Marshal.PtrToStructure <SPRESULTHEADER_Sapi51>(buffer); _header = new SPRESULTHEADER(legacyHeader); _isSapi53Header = false; } else { _header = Marshal.PtrToStructure <SPRESULTHEADER>(buffer); _isSapi53Header = true; } // Validate the header fields _header.Validate(); // initialize the parent to be this result - this is needed for the homophones IntPtr phraseBuffer = new((long)buffer + (int)_header.ulPhraseOffset); SPSERIALIZEDPHRASE serializedPhrase = RecognizedPhrase.GetPhraseHeader(phraseBuffer, _header.ulPhraseDataSize, _isSapi53Header); // Get the alphabet of the main phrase, which should be the same as the current alphabet selected by us (applications). bool hasIPAPronunciation = (_header.fAlphabet & (uint)SPRESULTALPHABET.SPRA_APP_UPS) != 0; InitializeFromSerializedBuffer(this, serializedPhrase, phraseBuffer, (int)_header.ulPhraseDataSize, _isSapi53Header, hasIPAPronunciation); if (recoResult != null) { ExtractDictationAlternates(recoResult, maxAlternates); // Since we took ownership of this unmanaged object we can discard information that don't need. recoResult.Discard(SapiConstants.SPDF_ALL); } } finally { gc.Free(); } // save the sapi blobs splitting it in the relevant bits // audio _sapiAudioBlob = new byte[(int)_header.ulRetainedDataSize]; Array.Copy(sapiResultBlob, (int)_header.ulRetainedOffset, _sapiAudioBlob, 0, (int)_header.ulRetainedDataSize); // alternates _sapiAlternatesBlob = new byte[(int)_header.ulPhraseAltDataSize]; Array.Copy(sapiResultBlob, (int)_header.ulPhraseAltOffset, _sapiAlternatesBlob, 0, (int)_header.ulPhraseAltDataSize); }