How do I downcast event results to API-specific objects?

Last reviewed: 3/25/2023

HOW Article ID: H032305

The information in this article applies to:

  • SpeechKit 12

Summary

Access API-specific objects and properties by downcasting event result arguments.

More Information

Speech recognition and synthesis events in most cases provide result objects with properties associated with the event. Some of these properties are common across APIs but most are not.

To support a variety of APIs, the event objects are designed and classes factored to allow for shared common properties and downcasting for access to unique API-specific property values.

The SpeechKit developer guide enumerates the event arguments and identifies common and API-specific properties.

For example, review speech recognition event handling discussed in the Speech Recognition Applications Events section and speech synthesis event handling discussed in the Speech Synthesis Applications Events section.

Take a look at the RecognitionCommandEventArgs result class that has common property of Phrase that is the recognized command and subclasses for Android (AndroidRecognitionCommandEventArgs), iOS/macOS (SFRecognitionCommandEventArgs), Windows Microsoft SAPI and Dragon NaturallySpeaking (WindowsRecognitionCommandEventArgs), and Windows WindowsMedia (WindowsMediaRecognitionCommandEventArgs) for platform/API-specific properties.

An event callback signature uses the result argument parent class. To access platform/API-specific properties downcast the object to the applicable subclass.


private void Recognizer_RecognitionCommand(object sender, RecognitionCommandEventArgs e)
{
    if ((e != null) && (e.Phrase != null))
    {
        if (e is WindowsRecognitionCommandEventArgs)
        {
            WindowsRecognitionCommandEventArgs windowsArgs = e as WindowsRecognitionCommandEventArgs;
            if (windowsArgs.SAPIPhrases != null)
            {
                ...
            }
        }
        if (e is WindowsMediaRecognitionCommandEventArgs)
        {
            WindowsMediaRecognitionCommandEventArgs windowsMediaArgs = e as WindowsMediaRecognitionCommandEventArgs;
            if (windowsMediaArgs.Semantics != null)
            {
                ...
            }
        }
        ...
    }
}
        

void CALLBACK RecognitionCommand(void* Sender, CRecognitionCommandEventArgs* Args)
{
    // Since we may not know which API we're running, cast and use the applicable object
    CWindowsRecognitionCommandEventArgs* windowsArgs = dynamic_cast(Args);
    CWindowsMediaRecognitionCommandEventArgs* windowsMediaArgs = dynamic_cast(Args);
    // Get the command properties
    if (windowsArgs != NULL)
    {
        ...
    }
    if (windowsMediaArgs != NULL)
    {
        ...
    }
    ...
}
    

void RecognitionCommand(void* Sender, CRecognitionCommandEventArgs* Args)
{
    // Since we may not know which API we're running, cast and use the applicable object
    CWindowsRecognitionCommandEventArgs* windowsArgs = dynamic_cast(Args);
    CWindowsMediaRecognitionCommandEventArgs* windowsMediaArgs = dynamic_cast(Args);
    if (windowsArgs != NULL) 
    {
        ...
    }
    if (windowsMediaArgs != NULL)
    {
        ...
    }
    ...
}

procedure TForm1.RecognitionCommand(Sender: TObject; Args: TRecognitionCommandEventArgs);
var
...
windowsArgs : TWindowsRecognitionCommandEventArgs;
windowsMediaArgs : TWindowsMediaRecognitionCommandEventArgs;
begin
    if Args.ClassType = TWindowsRecognitionCommandEventArgs then
    begin
      windowsArgs := Args as TWindowsRecognitionCommandEventArgs;
      // Get the command properties
      If (windowsArgs <> nil) then
      begin
        ...
      end;
    end;
    if Args.ClassType = TWindowsMediaRecognitionCommandEventArgs then
    begin
      windowsMediaArgs := Args as TWindowsMediaRecognitionCommandEventArgs;
      // Get the command properties
      If (windowsMediaArgs <> nil) then
      begin
        ...
      end;
    end;
    ...
end;
    

public void recognitionCommand(Object sender, RecognitionCommandEventArgs args)
{
    if (args != null) 
    {
        if (args instanceof WindowsRecognitionCommandEventArgs)
        {
            WindowsRecognitionCommandEventArgs windowsArgs = (WindowsRecognitionCommandEventArgs)args;
            ...
        }
        if (args instanceof WindowsMediaRecognitionCommandEventArgs)
        {
            WindowsMediaRecognitionCommandEventArgs windowsMediaArgs = (WindowsMediaRecognitionCommandEventArgs)args;
            ...
        }
        ...
    }
}
    

Private Sub Recognizer_RecognitionCommand(ByVal sender As System.Object, ByVal e As RecognitionCommandEventArgs) Handles _Recognizer.RecognitionCommand
    ...
    Dim windowsArgs As WindowsRecognitionCommandEventArgs
    Dim windowsMediaArgs As WindowsMediaRecognitionCommandEventArgs
    If (e IsNot Nothing) Then
        If (e.GetType Is GetType(WindowsRecognitionCommandEventArgs)) Then
            windowsArgs = e
            ...
        End If
        If (e.GetType Is GetType(WindowsMediaRecognitionCommandEventArgs)) Then
            windowsMediaArgs = e
            ...
        End If
        ...
    End If
End Sub

Run the Command samples for the various platforms and programming languages to see downcasting event results in action.