How do I ensure synchronized ordered event callback processing in C++Builder and Delphi apps?

Last reviewed: 3/25/2025

HowTo Article ID: H032506

The information in this article applies to:

  • AudioSearch 6
  • GrammarKit 11
  • KinesicsKit 9
  • LexiconKit 11
  • ProfileKit 11
  • SpeechKit 14
  • SpeechManager 5
  • VoiceXMLKit 8

Summary

Chant library callback event handling processing for C++Builder and Delphi is enhanced to ensure that events are processed is the same ordered in which they were triggered.

More Information

With multicore processors, multi-threaded, and multi-platform application environments, it is imperative that callback events that are fired on separate threads are not only synchronized with the app thread but also managed to process serially in the order with which they were triggered.

Updates to C++Builder and Delphi callback thread management ensure this occurs for all event handling transparent to the application.

Event callbacks are the mechanism in which the class object sends information back to the application such as compilation is complete or there was an error.

With Chant libraries, events are completely optional for an application to process in most cases. They are required for handling speech recognition, Kinect sensor, and VoiceXML processing.

Applications register for the event types to receive. This allows the application to determine what and how much asynchronous activity it wants to process.

Event order is essential for accuracy and managing proper application state.

For example, with speech recognition, events return the text for the recognized utterances, processing states, and error notifications.

With speech synthesis, for example, events return processing progress, UI synchronization states, and error notification.


    ...
    if (_Recognizer != NULL)
    {
        // Register Event Handlers
        _Recognizer->SetRecognitionCommand(RecognitionCommand);
    }
    if (_Synthesizer != NULL)
    {
        // Register Event Handlers
        _Synthesizer->SetWordPosition(WordPosition);
    }
    ...

void CALLBACK RecognitionCommand(void* Sender, CRecognitionCommandEventArgs* Args)
{
    // Get the command
    if ((Args != NULL) && (Args->GetPhrase().Length() > 0))
    {
        ...
    }
}
void CALLBACK WordPosition(void* Sender, CWordPositionEventArgs* Args)
{
    if (Args != NULL) 
    {
        int startPosition = Args->GetPosition();
        int wordLength = Args->GetLength();
        ...
    }
}

    ...
    if (_Recognizer <> nil) then
    begin
        // Register Event Handlers
        _Recognizer.RecognitionCommand := RecognitionCommand;
    end;
    if (_Synthesizer <> nil) then
    begin
        // Register Event Handlers
        _Synthesizer.WordPosition := WordPosition;
    end;
    ...

procedure TForm1.RecognitionCommand(Sender: TObject; Args: TRecognitionCommandEventArgs);
begin
    // Get the command properties
    If ((Args <> nil) and (Length(Args.Phrase) > 0)) then
    begin
      ...
    end;
end;

procedure TForm1.WordPosition(Sender: TObject; Args: TWordPositionEventArgs);
var
  startPosition: Integer;
  wordLength: Integer;
begin
    If (Args <> nil) then
    begin
      startPosition := args.Position;
      wordLength := args.Length;
      ...
    end;
end;

The Chant Developer Workbench Events window provides insight into events when testing various application scenarios.