NSSpeechRecognizer skeleton

This commit is contained in:
Gregory John Casamento 2020-02-01 03:47:21 -05:00
parent 11ac26b58a
commit a880154841
4 changed files with 31 additions and 158 deletions

View file

@ -33,8 +33,38 @@
extern "C" {
#endif
@protocol NSSpeechRecognizerDelegate;
@interface NSSpeechRecognizer : NSObject
// Initialize
- (instancetype) init;
- (id<NSSpeechRecognizerDelegate>) delegate;
// Configuring...
- (NSArray *) commands;
- (void) setCommands: (NSArray *)commands;
- (NSString *) displayCommandsTitle;
- (void) setDisplayCommandsTitle: (NSString *)displayCommandsTitle;
- (BOOL) listensInForegroundOnly;
- (void) setListensInForgroundOnly: (BOOL)listensInForgroundOnly;
- (BOOL) blocksOtherRecognizers;
- (void) setBlocksOtherRecognizers: (BOOL)blocksOtherRecognizers;
// Listening
- (void) startListening;
- (void) stopListening;
@end
// Protocol
@protocol NSSpeechRecognizerDelegate
- (void) speechRecognizer: (NSSpeechRecognizer *)sender
didRecognizeCommand: (NSString *)command;
@end
#if defined(__cplusplus)

View file

@ -14,7 +14,7 @@ GSSpeechRecognitionServer_LANGUAGES = English
GSSpeechRecognitionServer_OBJC_FILES = \
GSSpeechRecognitionEngine.m \
GSSpeechRecognitionServer.m \
GSSpeechRecognitionSynthesizer.m \
GSSpeechRecognizer.m \
main.m

View file

@ -1,17 +0,0 @@
#import "GSSpeechServer.h"
#import <AppKit/NSSpeechSynthesizer.h>
@interface GSSpeechSynthesizer : NSSpeechSynthesizer {
NSString *currentVoice;
id delegate;
}
- (id)initWithVoice: (NSString*)aVoice;
- (id)init;
- (NSString*)voice;
- (id)delegate;
- (void)setDelegate: (id)aDelegate;
- (void)setVoice: (NSString*)aVoice;
- (BOOL)startSpeakingString: (NSString*)aString;
- (void)stopSpeaking;
@end

View file

@ -1,140 +0,0 @@
#import "GSSpeechSynthesizer.h"
static GSSpeechServer *server;
static int clients;
@interface GSSpeechSynthesizer (Private)
+ (void)connectionDied: (NSNotification*)aNotification;
@end
@implementation GSSpeechSynthesizer
+ (void)initialize
{
server = [[GSSpeechServer sharedServer] retain];
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(connectionDied:)
name: NSConnectionDidDieNotification
object: nil];
}
/**
* If the remote end exits before freeing the GSSpeechSynthesizer then we need
* to send it a -release message to make sure it dies.
*/
+ (void)connectionDied: (NSNotification*)aNotification
{
NSEnumerator *e = [[[aNotification object] localObjects] objectEnumerator];
NSObject *o = nil;
for (o = [e nextObject] ; nil != o ; o = [e nextObject])
{
if ([o isKindOfClass: self])
{
[o release];
}
}
}
/**
* If no clients have been active for some time, kill the speech server to
* conserve resources.
*/
+ (void)exitIfUnneeded: (NSTimer*)sender
{
if (clients == 0)
{
exit(0);
}
}
- (id)initWithVoice: (NSString*)aVoice
{
clients++;
if (nil == (self = [super init]))
{
return nil;
}
[self setVoice: currentVoice];
return self;
}
- (id)init
{
return [self initWithVoice: nil];
}
- (NSString*)voice
{
return currentVoice;
}
- (id)delegate
{
return delegate;
}
- (void)setDelegate: (id)aDelegate
{
// Either -retain or -release can throw an exception due to DO.
NS_DURING
aDelegate = [aDelegate retain];
NS_HANDLER
NS_ENDHANDLER
NS_DURING
[delegate release];
NS_HANDLER
NS_ENDHANDLER
delegate = aDelegate;
}
- (void)setVoice: (NSString*)aVoice
{
if (nil == aVoice)
{
aVoice = [server defaultVoice];
}
ASSIGN(currentVoice, aVoice);
}
- (BOOL)startSpeakingString: (NSString*)aString
{
[server setVoice: currentVoice];
return [server startSpeakingString: aString notifyWhenDone: self];
}
- (void)didFinishSpeaking: (BOOL)didFinish
{
// Throw the delegate away if it is throwing exceptions during
// notification.
NS_DURING
[delegate speechSynthesizer: self didFinishSpeaking: didFinish];
NS_HANDLER
NS_DURING
id d = delegate;
delegate = nil;
[d release];
NS_HANDLER
NS_ENDHANDLER
NS_ENDHANDLER
}
- (void)stopSpeaking
{
[server stopSpeaking];
}
- (void)dealloc
{
clients--;
[currentVoice release];
if (clients == 0)
{
[NSTimer scheduledTimerWithTimeInterval: 600
target: object_getClass(self)
selector: @selector(exitIfUnneeded:)
userInfo: nil
repeats: NO];
}
[super dealloc];
}
@end