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;