예제 #1
0
        private Collection <RecognizedPhrase> ExtractAlternates(int numberOfAlternates, bool isSapi53Header)
        {
            Collection <RecognizedPhrase> alternates = new();

            if (numberOfAlternates > 0)
            {
                GCHandle gc = GCHandle.Alloc(_sapiAlternatesBlob, GCHandleType.Pinned);
                try
                {
                    IntPtr buffer = gc.AddrOfPinnedObject();

                    int sizeOfSpSerializedPhraseAlt = Marshal.SizeOf <SPSERIALIZEDPHRASEALT>();
                    int offset = 0;
                    for (int i = 0; i < numberOfAlternates; i++)
                    {
                        IntPtr altBuffer          = new((long)buffer + offset);
                        SPSERIALIZEDPHRASEALT alt = Marshal.PtrToStructure <SPSERIALIZEDPHRASEALT>(altBuffer);

                        offset += sizeOfSpSerializedPhraseAlt; // advance over SPSERIALIZEDPHRASEALT
                        if (isSapi53Header)
                        {
                            offset += (int)((alt.cbAltExtra + 7) & ~7); // advance over extra data with alignment padding
                        }
                        else
                        {
                            offset += (int)alt.cbAltExtra; // no alignment padding
                        }

                        // we cannot use a constructor parameter because RecognitionResult also derives from RecognizedPhrase
                        IntPtr             phraseBuffer     = new((long)buffer + offset);
                        SPSERIALIZEDPHRASE serializedPhrase = RecognizedPhrase.GetPhraseHeader(phraseBuffer, _header.ulPhraseAltDataSize - (uint)offset, _isSapi53Header);
                        int serializedPhraseSize            = (int)serializedPhrase.ulSerializedSize;

                        RecognizedPhrase phrase = new();

                        // Get the alphabet of the raw phrase alternate, which should be the same as the engine
                        bool hasIPAPronunciation = (_header.fAlphabet & (uint)SPRESULTALPHABET.SPRA_ENGINE_UPS) != 0;

                        phrase.InitializeFromSerializedBuffer(this, serializedPhrase, phraseBuffer, serializedPhraseSize, isSapi53Header, hasIPAPronunciation);
                        if (isSapi53Header)
                        {
                            offset += ((serializedPhraseSize + 7) & ~7); // advance over phrase with alignment padding
                        }
                        else
                        {
                            offset += serializedPhraseSize; // advance over phrase
                        }

                        alternates.Add(phrase);
                    }
                }
                finally
                {
                    gc.Free();
                }
            }

            return(alternates);
        }
예제 #2
0
        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);
        }
예제 #3
0
 private void ExtractDictationAlternates(ISpRecoResult recoResult, int maxAlternates)
 {
     if (recoResult != null && base.Grammar is DictationGrammar)
     {
         _alternates = new Collection <RecognizedPhrase>();
         IntPtr[] array = new IntPtr[maxAlternates];
         try
         {
             recoResult.GetAlternates(0, -1, maxAlternates, array, out maxAlternates);
         }
         catch (COMException)
         {
             maxAlternates = 0;
         }
         for (uint num = 0u; num < maxAlternates; num++)
         {
             ISpPhraseAlt spPhraseAlt = (ISpPhraseAlt)Marshal.GetObjectForIUnknown(array[num]);
             try
             {
                 IntPtr ppCoMemPhrase;
                 spPhraseAlt.GetSerializedPhrase(out ppCoMemPhrase);
                 try
                 {
                     RecognizedPhrase   recognizedPhrase = new RecognizedPhrase();
                     SPSERIALIZEDPHRASE phraseHeader     = RecognizedPhrase.GetPhraseHeader(ppCoMemPhrase, uint.MaxValue, _isSapi53Header);
                     bool hasIPAPronunciation            = (_header.fAlphabet & 1) != 0;
                     recognizedPhrase.InitializeFromSerializedBuffer(this, phraseHeader, ppCoMemPhrase, (int)phraseHeader.ulSerializedSize, _isSapi53Header, hasIPAPronunciation);
                     _alternates.Add(recognizedPhrase);
                 }
                 finally
                 {
                     Marshal.FreeCoTaskMem(ppCoMemPhrase);
                 }
             }
             finally
             {
                 Marshal.Release(array[num]);
             }
         }
     }
 }
예제 #4
0
        private Collection <RecognizedPhrase> ExtractAlternates(int numberOfAlternates, bool isSapi53Header)
        {
            Collection <RecognizedPhrase> collection = new Collection <RecognizedPhrase>();

            if (numberOfAlternates > 0)
            {
                GCHandle gCHandle = GCHandle.Alloc(_sapiAlternatesBlob, GCHandleType.Pinned);
                try
                {
                    IntPtr value = gCHandle.AddrOfPinnedObject();
                    int    num   = Marshal.SizeOf(typeof(SPSERIALIZEDPHRASEALT));
                    int    num2  = 0;
                    for (int i = 0; i < numberOfAlternates; i++)
                    {
                        IntPtr ptr = new IntPtr((long)value + num2);
                        SPSERIALIZEDPHRASEALT sPSERIALIZEDPHRASEALT = (SPSERIALIZEDPHRASEALT)Marshal.PtrToStructure(ptr, typeof(SPSERIALIZEDPHRASEALT));
                        num2 += num;
                        num2  = ((!isSapi53Header) ? (num2 + (int)sPSERIALIZEDPHRASEALT.cbAltExtra) : (num2 + (int)((sPSERIALIZEDPHRASEALT.cbAltExtra + 7) & -8)));
                        IntPtr             phraseBuffer      = new IntPtr((long)value + num2);
                        SPSERIALIZEDPHRASE phraseHeader      = RecognizedPhrase.GetPhraseHeader(phraseBuffer, (uint)((int)_header.ulPhraseAltDataSize - num2), _isSapi53Header);
                        int ulSerializedSize                 = (int)phraseHeader.ulSerializedSize;
                        RecognizedPhrase recognizedPhrase    = new RecognizedPhrase();
                        bool             hasIPAPronunciation = (_header.fAlphabet & 2) != 0;
                        recognizedPhrase.InitializeFromSerializedBuffer(this, phraseHeader, phraseBuffer, ulSerializedSize, isSapi53Header, hasIPAPronunciation);
                        num2 = ((!isSapi53Header) ? (num2 + ulSerializedSize) : (num2 + ((ulSerializedSize + 7) & -8)));
                        collection.Add(recognizedPhrase);
                    }
                    return(collection);
                }
                finally
                {
                    gCHandle.Free();
                }
            }
            return(collection);
        }
예제 #5
0
        private void ExtractDictationAlternates(ISpRecoResult recoResult, int maxAlternates)
        {
            // Get the alternates for dictation
            // alternates for dictation are not part of the recognition results and must be pulled out
            // from the recognition result bits.

            if (recoResult != null) // recoResult is null if we are in the case of our unit test.
            {
                if (Grammar is DictationGrammar)
                {
                    _alternates = new Collection <RecognizedPhrase>();
                    IntPtr[] sapiAlternates = new IntPtr[maxAlternates];
                    try
                    {
                        recoResult.GetAlternates(0, -1, maxAlternates, sapiAlternates, out maxAlternates);
                    }
                    catch (COMException)
                    {
                        // In some cases such as when the dictation grammar has been unloaded, the engine may not be able
                        // to provide the alternates. We set the alternate list to empty.
                        maxAlternates = 0;
                    }

                    //InnerList.Capacity = (int)numSapiAlternates;
                    for (uint i = 0; i < maxAlternates; i++)
                    {
                        ISpPhraseAlt phraseAlt = (ISpPhraseAlt)Marshal.GetObjectForIUnknown(sapiAlternates[i]);
                        try
                        {
                            IntPtr coMemSerializedPhrase;
                            phraseAlt.GetSerializedPhrase(out coMemSerializedPhrase);
                            try
                            {
                                // Build a recognition phrase result
                                RecognizedPhrase phrase = new();

                                // we cannot use a constructor parameter because RecognitionResult also derives from RecognizedPhrase
                                SPSERIALIZEDPHRASE serializedPhrase = RecognizedPhrase.GetPhraseHeader(coMemSerializedPhrase, uint.MaxValue, _isSapi53Header);

                                //
                                // If we are getting the alternates from SAPI, the alphabet should have already been converted
                                // to the alphabet we (applications) want.
                                //
                                bool hasIPAPronunciation = (_header.fAlphabet & (uint)SPRESULTALPHABET.SPRA_APP_UPS) != 0;

                                phrase.InitializeFromSerializedBuffer(this, serializedPhrase, coMemSerializedPhrase, (int)serializedPhrase.ulSerializedSize, _isSapi53Header, hasIPAPronunciation);
                                _alternates.Add(phrase);
                            }
                            finally
                            {
                                Marshal.FreeCoTaskMem(coMemSerializedPhrase);
                            }
                        }
                        finally
                        {
                            Marshal.Release(sapiAlternates[i]);
                        }
                    }
                }
            }
        }
예제 #6
0
        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);
        }