mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 20:50:44 +00:00
* config.make.in: Change to include BUILD_SPEECH in output
* configure: Regenerated * configure.ac: Check for flite library and flite.h header. * Tools/GNUmakefile: Add ${BUILD_SPEECH} to subproject list. * Tools/say/GNUmakefile * Tools/say/say.m: Say utility * Tools/speech/FliteSpeechEngine.m: * Tools/speech/GNUmakefile * Tools/speech/GSSpeechEngine.[hm] * Tools/speech/GSSpeechServer.[hm] * Tools/speech/GSSpeechSynthesizer.[hm]: Speech synthesis engine implementation using flite. * Tools/speech/main.m: main for the server application. Speech code by David Chisnall <theraven@sucs.org> Changes to makefiles and config by Gregory Casamento. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@28430 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
d5cb6fc832
commit
0e43459d49
16 changed files with 830 additions and 3 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
|||
2009-08-01 20:28-EDT Gregory John Casamento <greg.casamento@gmail.com>
|
||||
|
||||
* config.make.in: Change to include BUILD_SPEECH in output
|
||||
* configure: Regenerated
|
||||
* configure.ac: Check for flite library and flite.h header.
|
||||
* Tools/GNUmakefile: Add ${BUILD_SPEECH} to subproject list.
|
||||
* Tools/say/GNUmakefile
|
||||
* Tools/say/say.m: Say utility
|
||||
* Tools/speech/FliteSpeechEngine.m:
|
||||
* Tools/speech/GNUmakefile
|
||||
* Tools/speech/GSSpeechEngine.[hm]
|
||||
* Tools/speech/GSSpeechServer.[hm]
|
||||
* Tools/speech/GSSpeechSynthesizer.[hm]: Speech synthesis engine
|
||||
implementation using flite.
|
||||
* Tools/speech/main.m: main for the server application.
|
||||
Speech code by David Chisnall <theraven@sucs.org>
|
||||
Changes to makefiles and config by Gregory Casamento.
|
||||
|
||||
2009-08-01 17:49-EDT Gregory John Casamento <greg.casamento@gmail.com>
|
||||
|
||||
* Sounds/GNUmakefile: Change makefile to copy wav files.
|
||||
|
|
|
@ -28,7 +28,7 @@ include ../config.make
|
|||
|
||||
include ../Version
|
||||
|
||||
SUBPROJECTS = $(BUILD_GSND)
|
||||
SUBPROJECTS = $(BUILD_GSND) $(BUILD_SPEECH)
|
||||
TOOL_NAME = make_services set_show_service gopen gclose gcloseall
|
||||
SERVICE_NAME = GSspell
|
||||
|
||||
|
|
18
Tools/say/GNUmakefile
Normal file
18
Tools/say/GNUmakefile
Normal file
|
@ -0,0 +1,18 @@
|
|||
ETOILE_CORE_MODULE = YES
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
GSSPEECHENGINE = Flite
|
||||
|
||||
VERSION = 0.1
|
||||
TOOL_NAME = say
|
||||
|
||||
say_LANGUAGES = English
|
||||
|
||||
say_OBJC_FILES = \
|
||||
say.m
|
||||
|
||||
say_OBJCFLAGS += -std=c99 -g -Werror
|
||||
say_LDFLAGS += -lgnustep-gui
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/tool.make
|
62
Tools/say/say.m
Normal file
62
Tools/say/say.m
Normal file
|
@ -0,0 +1,62 @@
|
|||
#import <AppKit/AppKit.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
@interface SpeechDelegate : NSObject @end
|
||||
@implementation SpeechDelegate
|
||||
- (void)speechSynthesizer: (NSSpeechSynthesizer*)sender
|
||||
didFinishSpeaking: (BOOL)success
|
||||
{
|
||||
exit((int)success);
|
||||
}
|
||||
@end
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
[NSAutoreleasePool new];
|
||||
NSMutableString *words = [NSMutableString string];
|
||||
NSString *outFile = nil;
|
||||
NSString *voice = nil;
|
||||
NSString *inFile = nil;
|
||||
|
||||
int ch;
|
||||
while ((ch = getopt(argc, argv, "o:v:f:")) != -1)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case 'o':
|
||||
outFile = [NSString stringWithUTF8String: optarg];
|
||||
break;
|
||||
case 'f':
|
||||
inFile = [NSString stringWithUTF8String: optarg];
|
||||
break;
|
||||
case 'v':
|
||||
voice = [NSString stringWithUTF8String: optarg];
|
||||
break;
|
||||
}
|
||||
}
|
||||
int i;
|
||||
for (i=optind ; i<argc ; i++)
|
||||
{
|
||||
[words appendString: [NSString stringWithUTF8String: argv[i]]];
|
||||
[words appendString: @" "];
|
||||
}
|
||||
|
||||
NSSpeechSynthesizer *say = [[NSSpeechSynthesizer alloc] initWithVoice: voice];
|
||||
if (nil != inFile)
|
||||
{
|
||||
[words release];
|
||||
NSData *file = [NSData dataWithContentsOfFile: inFile];
|
||||
words = [NSString stringWithCString: [file bytes]];
|
||||
}
|
||||
|
||||
// Don't interrupt other apps.
|
||||
while ([NSSpeechSynthesizer isAnyApplicationSpeaking])
|
||||
{
|
||||
[NSThread sleepForTimeInterval: 0.1];
|
||||
}
|
||||
[say setDelegate: [SpeechDelegate new]];
|
||||
[say startSpeakingString: words];
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
// Not reached.
|
||||
return 0;
|
||||
}
|
121
Tools/speech/FliteSpeechEngine.m
Normal file
121
Tools/speech/FliteSpeechEngine.m
Normal file
|
@ -0,0 +1,121 @@
|
|||
#import "GSSpeechEngine.h"
|
||||
#include <flite/flite.h>
|
||||
|
||||
cst_voice *register_cmu_us_kal();
|
||||
|
||||
/**
|
||||
* Implementation of a speech engine using flite. This should be the default
|
||||
* for resource-constrained platforms.
|
||||
*/
|
||||
@interface FliteSpeechEngine : GSSpeechEngine {
|
||||
/** The audio device used for sound output. */
|
||||
cst_audiodev *ad;
|
||||
/** The current voice. Only one supported at the moment. */
|
||||
cst_voice *v;
|
||||
/** Flag set to tell the playback thread to exit. */
|
||||
volatile BOOL shouldEndSpeaking;
|
||||
/** Flag indicating whether the engine is currently speaking. */
|
||||
volatile BOOL isSpeaking;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation FliteSpeechEngine
|
||||
+ (void)initialize
|
||||
{
|
||||
flite_init();
|
||||
|
||||
}
|
||||
- (id)init
|
||||
{
|
||||
if (nil == (self = [super init])) { return nil; }
|
||||
|
||||
// Only one voice supported by flite unless others are compiled in.
|
||||
v = register_cmu_us_kal();
|
||||
if (NULL == v)
|
||||
{
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Each wave should be the same format.
|
||||
cst_wave *w = flite_text_to_wave("test", v);
|
||||
ad = audio_open(w->sample_rate, w->num_channels, CST_AUDIO_LINEAR16);
|
||||
delete_wave(w);
|
||||
if (NULL == ad)
|
||||
{
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (void)sayString: (NSArray*)args
|
||||
{
|
||||
id pool = [NSAutoreleasePool new];
|
||||
NSString *aString = [args objectAtIndex: 0];
|
||||
int i,n,r;
|
||||
int num_shorts;
|
||||
BOOL didFinish = YES;
|
||||
cst_wave *w = flite_text_to_wave([aString UTF8String], v);
|
||||
|
||||
num_shorts = w->num_samples * w->num_channels;
|
||||
for (i=0; i < num_shorts; i += r/2)
|
||||
{
|
||||
if (num_shorts > i+CST_AUDIOBUFFSIZE)
|
||||
{
|
||||
n = CST_AUDIOBUFFSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = num_shorts-i;
|
||||
}
|
||||
r = audio_write(ad, &w->samples[i], n*2);
|
||||
if (shouldEndSpeaking)
|
||||
{
|
||||
didFinish = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
isSpeaking = NO;
|
||||
NS_DURING
|
||||
[[args objectAtIndex: 1] didFinishSpeaking: didFinish];
|
||||
NS_HANDLER
|
||||
NS_ENDHANDLER
|
||||
[args release];
|
||||
[pool release];
|
||||
delete_wave(w);
|
||||
}
|
||||
- (void)startSpeaking: (NSString*)aString notifyWhenDone: (id)aDelegate
|
||||
{
|
||||
[[[aDelegate delegate] connectionForProxy] enableMultipleThreads];
|
||||
NSArray *arg = [[NSArray alloc] initWithObjects: aString, aDelegate, nil];
|
||||
shouldEndSpeaking = NO;
|
||||
isSpeaking = YES;
|
||||
[NSThread detachNewThreadSelector: @selector(sayString:)
|
||||
toTarget: self
|
||||
withObject: arg];
|
||||
|
||||
}
|
||||
- (BOOL)isSpeaking
|
||||
{
|
||||
return isSpeaking;
|
||||
}
|
||||
- (void)stopSpeaking
|
||||
{
|
||||
shouldEndSpeaking = YES;
|
||||
// Spin until the other thread has died.
|
||||
while (isSpeaking) {}
|
||||
}
|
||||
- (void)dealloc
|
||||
{
|
||||
[self stopSpeaking];
|
||||
audio_close(ad);
|
||||
[super dealloc];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation GSSpeechEngine (Flite)
|
||||
+ (GSSpeechEngine*)defaultSpeechEngine
|
||||
{
|
||||
return [[[FliteSpeechEngine alloc] init] autorelease];
|
||||
}
|
||||
@end
|
30
Tools/speech/GNUmakefile
Normal file
30
Tools/speech/GNUmakefile
Normal file
|
@ -0,0 +1,30 @@
|
|||
ETOILE_CORE_MODULE = YES
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
# Set the default. Eventually this should be conditional.
|
||||
GSSPEECHENGINE = Flite
|
||||
|
||||
VERSION = 0.1
|
||||
|
||||
# This is an app not a tool because, eventually, it will present the user
|
||||
# interface for the GUI part of the speech engine.
|
||||
APP_NAME = GSSpeechServer
|
||||
|
||||
GSSpeechServer_LANGUAGES = English
|
||||
|
||||
GSSpeechServer_OBJC_FILES = \
|
||||
GSSpeechEngine.m\
|
||||
GSSpeechServer.m\
|
||||
GSSpeechSynthesizer.m\
|
||||
main.m
|
||||
|
||||
ifeq ($(GSSPEECHENGINE), Flite)
|
||||
GSSpeechServer_OBJC_FILES += FliteSpeechEngine.m
|
||||
GSSpeechServer_INCLUDE_DIRS += -I/usr/local/include/flite
|
||||
GSSpeechServer_LIB_DIRS += -L/usr/local/lib -lflite_cmu_us_kal -lflite_usenglish -lflite_cmulex -lflite
|
||||
endif
|
||||
|
||||
GSSpeechServer_OBJCFLAGS = -std=c99 -g -Werror
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/application.make
|
50
Tools/speech/GSSpeechEngine.h
Normal file
50
Tools/speech/GSSpeechEngine.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* GSSpeechEngine is an abstract speech server. One concrete subclass should
|
||||
* be implemented for each speech engine. Currently, only one may be compiled
|
||||
* in to the speech server at any given time. This limitation may be removed
|
||||
* in future if pluggable speech engines are considered beneficial.
|
||||
*/
|
||||
@interface GSSpeechEngine : NSObject
|
||||
/**
|
||||
* Returns a new instance of the default speech engine.
|
||||
*/
|
||||
+ (GSSpeechEngine*)defaultSpeechEngine;
|
||||
/**
|
||||
* Begin speaking the specified string.
|
||||
*/
|
||||
- (void)startSpeaking: (NSString*)aString notifyWhenDone: (id)aDelegate;
|
||||
/**
|
||||
* Stop speaking.
|
||||
*/
|
||||
- (void)stopSpeaking;
|
||||
/**
|
||||
* Returns YES if the engine is currently outputting speech.
|
||||
*/
|
||||
- (BOOL)isSpeaking;
|
||||
/**
|
||||
* Returns an array of voices supported by this speech synthesizer.
|
||||
*/
|
||||
- (NSArray*)voices;
|
||||
/**
|
||||
* Sets the voice.
|
||||
*/
|
||||
- (void)setVoice: (NSString*)aVoice;
|
||||
/**
|
||||
* Returns the current voice.
|
||||
*/
|
||||
- (NSString*)voice;
|
||||
/**
|
||||
* Returns the name of the default voice for this speech engine.
|
||||
*/
|
||||
- (NSString*)defaultVoice;
|
||||
@end
|
||||
|
||||
@interface NSObject (GSSpeechEngineDelegate)
|
||||
/**
|
||||
* Called when the speech engine has finished speaking a phrase. Should be
|
||||
* used to notify the original caller.
|
||||
*/
|
||||
- (void)didFinishSpeaking: (BOOL)didFinish;
|
||||
@end
|
15
Tools/speech/GSSpeechEngine.m
Normal file
15
Tools/speech/GSSpeechEngine.m
Normal file
|
@ -0,0 +1,15 @@
|
|||
#import "GSSpeechEngine.h"
|
||||
|
||||
/**
|
||||
* Dummy implementation of a speech engine. Doesn't do anything.
|
||||
*/
|
||||
@implementation GSSpeechEngine
|
||||
+ (GSSpeechEngine*)defaultSpeechEngine { return [[self new] autorelease]; }
|
||||
- (void)startSpeaking: (NSString*)aString notifyWhenDone: (id)anObject{}
|
||||
- (void)stopSpeaking {}
|
||||
- (BOOL)isSpeaking { return NO; }
|
||||
- (NSArray*)voices { return [NSArray arrayWithObject: @"default"]; }
|
||||
- (void)setVoice: (NSString*)aVoice {}
|
||||
- (NSString*)voice { return @"default"; }
|
||||
- (NSString*)defaultVoice { return @"default"; }
|
||||
@end
|
44
Tools/speech/GSSpeechServer.h
Normal file
44
Tools/speech/GSSpeechServer.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
@class GSSpeechEngine;
|
||||
/**
|
||||
* GSSpeechServer handles all of the engine-agnostic operations. Currently,
|
||||
* there aren't any, but when the on-screen text interface is added it should
|
||||
* go in here.
|
||||
*/
|
||||
@interface GSSpeechServer : NSObject {
|
||||
GSSpeechEngine *engine;
|
||||
}
|
||||
/**
|
||||
* Returns a shared instance of the speech server.
|
||||
*/
|
||||
+ (id)sharedServer;
|
||||
/**
|
||||
* Begins speaking the string specified by the first argument. Calls the
|
||||
* delegate method on the client when done.
|
||||
*/
|
||||
- (BOOL)startSpeakingString: (NSString*)aString notifyWhenDone: (id)client;
|
||||
/**
|
||||
* Stop speaking.
|
||||
*/
|
||||
- (void)stopSpeaking;
|
||||
/**
|
||||
* Returns YES if the engine is currently outputting speech.
|
||||
*/
|
||||
- (BOOL)isSpeaking;
|
||||
/**
|
||||
* Returns an array of voices supported by this speech synthesizer.
|
||||
*/
|
||||
- (NSArray*)voices;
|
||||
/**
|
||||
* Sets the voice.
|
||||
*/
|
||||
- (void)setVoice: (NSString*)aVoice;
|
||||
/**
|
||||
* Returns the current voice.
|
||||
*/
|
||||
- (NSString*)voice;
|
||||
/**
|
||||
* Returns the name of the default voice.
|
||||
*/
|
||||
- (NSString*)defaultVoice;
|
||||
@end
|
72
Tools/speech/GSSpeechServer.m
Normal file
72
Tools/speech/GSSpeechServer.m
Normal file
|
@ -0,0 +1,72 @@
|
|||
#import "GSSpeechServer.h"
|
||||
#import "GSSpeechEngine.h"
|
||||
#import "GSSpeechSynthesizer.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
static GSSpeechServer *sharedInstance;
|
||||
|
||||
@implementation GSSpeechServer
|
||||
+ (void)initialize
|
||||
{
|
||||
sharedInstance = [self new];
|
||||
}
|
||||
+ (void)start
|
||||
{
|
||||
NSConnection *connection = [NSConnection defaultConnection];
|
||||
[connection setRootObject: sharedInstance];
|
||||
if (NO == [connection registerName: @"GSSpeechServer"])
|
||||
{
|
||||
return;
|
||||
}
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
}
|
||||
+ (id)sharedServer
|
||||
{
|
||||
return sharedInstance;
|
||||
}
|
||||
- (id)init
|
||||
{
|
||||
if (nil == (self = [super init])) { return nil; }
|
||||
engine = [GSSpeechEngine defaultSpeechEngine];
|
||||
if (nil == engine)
|
||||
{
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (id)newSynthesizer
|
||||
{
|
||||
return [[GSSpeechSynthesizer new] autorelease];
|
||||
}
|
||||
- (BOOL)startSpeakingString: (NSString*)aString notifyWhenDone: (id)client
|
||||
{
|
||||
[engine stopSpeaking];
|
||||
[engine startSpeaking: aString notifyWhenDone: client];
|
||||
return YES;
|
||||
}
|
||||
- (void)stopSpeaking
|
||||
{
|
||||
[engine stopSpeaking];
|
||||
}
|
||||
- (BOOL)isSpeaking
|
||||
{
|
||||
return [engine isSpeaking];
|
||||
}
|
||||
- (NSArray*)voices
|
||||
{
|
||||
return [engine voices];
|
||||
}
|
||||
- (oneway void)setVoice: (NSString*)aVoice
|
||||
{
|
||||
[engine setVoice: aVoice];
|
||||
}
|
||||
- (NSString*)voice
|
||||
{
|
||||
return [engine voice];
|
||||
}
|
||||
- (NSString*)defaultVoice
|
||||
{
|
||||
return [engine defaultVoice];
|
||||
}
|
||||
@end
|
17
Tools/speech/GSSpeechSynthesizer.h
Normal file
17
Tools/speech/GSSpeechSynthesizer.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#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
|
121
Tools/speech/GSSpeechSynthesizer.m
Normal file
121
Tools/speech/GSSpeechSynthesizer.m
Normal file
|
@ -0,0 +1,121 @@
|
|||
#import "GSSpeechSynthesizer.h"
|
||||
|
||||
static GSSpeechServer *server;
|
||||
static int clients;
|
||||
|
||||
@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];
|
||||
for (NSObject *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: isa
|
||||
selector: @selector(exitIfUnneeded:)
|
||||
userInfo: nil
|
||||
repeats: NO];
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
@end
|
12
Tools/speech/main.m
Normal file
12
Tools/speech/main.m
Normal file
|
@ -0,0 +1,12 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface GSSpeechServer
|
||||
+ (void)start;
|
||||
@end
|
||||
|
||||
int main(void)
|
||||
{
|
||||
[NSAutoreleasePool new];
|
||||
[GSSpeechServer start];
|
||||
return 0;
|
||||
}
|
|
@ -7,6 +7,7 @@ ADDITIONAL_LIB_DIRS += @ADDITIONAL_LIB_DIRS@
|
|||
ADDITIONAL_DEPENDS = @LIBS@
|
||||
|
||||
BUILD_GSND=@BUILD_GSND@
|
||||
BUILD_SPEECH=@BUILD_SPEECH@
|
||||
|
||||
GSCUPS_CFLAGS = @GSCUPS_CFLAGS@
|
||||
GSCUPS_LDFLAGS = @GSCUPS_LDFLAGS@
|
||||
|
|
233
configure
vendored
233
configure
vendored
|
@ -674,6 +674,7 @@ CPP
|
|||
GREP
|
||||
EGREP
|
||||
BUILD_GSND
|
||||
BUILD_SPEECH
|
||||
have_cups
|
||||
GSCUPS_CFLAGS
|
||||
GSCUPS_LDFLAGS
|
||||
|
@ -1283,6 +1284,7 @@ Optional Features:
|
|||
--enable-libgif Enable libgif-based GIF support
|
||||
--disable-aspell Disable aspell for spellchecker
|
||||
--disable-gsnd Disable gsnd server
|
||||
--disable-speech Disable speech server
|
||||
--disable-cups Disable cups printing support
|
||||
|
||||
Optional Packages:
|
||||
|
@ -5404,7 +5406,7 @@ if test "$ac_res" != no; then
|
|||
ac_cv_func_getmntent=yes
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_GETMNTENT
|
||||
#define HAVE_GETMNTENT 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
|
@ -7279,6 +7281,232 @@ if test $have_portaudio19 = yes -a $have_portaudio = yes -a $enable_gsnd = yes;
|
|||
fi
|
||||
|
||||
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# NSSpeechSynthesizer
|
||||
#--------------------------------------------------------------------
|
||||
# Check whether --enable-speech was given.
|
||||
if test "${enable_speech+set}" = set; then
|
||||
enableval=$enable_speech;
|
||||
else
|
||||
enable_speech=yes
|
||||
fi
|
||||
|
||||
BUILD_SPEECH=
|
||||
|
||||
# has flite, for speech synthesis.
|
||||
{ echo "$as_me:$LINENO: checking for new_utterance in -lflite" >&5
|
||||
echo $ECHO_N "checking for new_utterance in -lflite... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_lib_flite_new_utterance+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lflite $LIBS"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char new_utterance ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return new_utterance ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
ac_cv_lib_flite_new_utterance=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_lib_flite_new_utterance=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_lib_flite_new_utterance" >&5
|
||||
echo "${ECHO_T}$ac_cv_lib_flite_new_utterance" >&6; }
|
||||
if test $ac_cv_lib_flite_new_utterance = yes; then
|
||||
have_speech=yes
|
||||
else
|
||||
have_speech=no
|
||||
fi
|
||||
|
||||
|
||||
for ac_header in flite/flite.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
|
||||
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_Header'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
else
|
||||
# Is the header compilable?
|
||||
{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
|
||||
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
#include <$ac_header>
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (ac_try="$ac_compile"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_compile") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest.$ac_objext; then
|
||||
ac_header_compiler=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_header_compiler=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
|
||||
echo "${ECHO_T}$ac_header_compiler" >&6; }
|
||||
|
||||
# Is the header present?
|
||||
{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
|
||||
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <$ac_header>
|
||||
_ACEOF
|
||||
if { (ac_try="$ac_cpp conftest.$ac_ext"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } >/dev/null && {
|
||||
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
}; then
|
||||
ac_header_preproc=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_header_preproc=no
|
||||
fi
|
||||
|
||||
rm -f conftest.err conftest.$ac_ext
|
||||
{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
|
||||
echo "${ECHO_T}$ac_header_preproc" >&6; }
|
||||
|
||||
# So? What about this header?
|
||||
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
|
||||
yes:no: )
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
|
||||
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
|
||||
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
|
||||
ac_header_preproc=yes
|
||||
;;
|
||||
no:yes:* )
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
|
||||
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
|
||||
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
|
||||
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
|
||||
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
|
||||
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
|
||||
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
|
||||
|
||||
;;
|
||||
esac
|
||||
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
|
||||
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
|
||||
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
eval "$as_ac_Header=\$ac_header_preproc"
|
||||
fi
|
||||
ac_res=`eval echo '${'$as_ac_Header'}'`
|
||||
{ echo "$as_me:$LINENO: result: $ac_res" >&5
|
||||
echo "${ECHO_T}$ac_res" >&6; }
|
||||
|
||||
fi
|
||||
if test `eval echo '${'$as_ac_Header'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
if test $have_speech = yes -a $enable_speech = yes; then
|
||||
BUILD_SPEECH="speech say"
|
||||
fi
|
||||
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Find CUPS
|
||||
#--------------------------------------------------------------------
|
||||
|
@ -8289,6 +8517,7 @@ CPP!$CPP$ac_delim
|
|||
GREP!$GREP$ac_delim
|
||||
EGREP!$EGREP$ac_delim
|
||||
BUILD_GSND!$BUILD_GSND$ac_delim
|
||||
BUILD_SPEECH!$BUILD_SPEECH$ac_delim
|
||||
have_cups!$have_cups$ac_delim
|
||||
GSCUPS_CFLAGS!$GSCUPS_CFLAGS$ac_delim
|
||||
GSCUPS_LDFLAGS!$GSCUPS_LDFLAGS$ac_delim
|
||||
|
@ -8306,7 +8535,7 @@ LIBOBJS!$LIBOBJS$ac_delim
|
|||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 76; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 77; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
|
17
configure.ac
17
configure.ac
|
@ -380,6 +380,23 @@ if test $have_portaudio19 = yes -a $have_portaudio = yes -a $enable_gsnd = yes;
|
|||
fi
|
||||
AC_SUBST(BUILD_GSND)
|
||||
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# NSSpeechSynthesizer
|
||||
#--------------------------------------------------------------------
|
||||
AC_ARG_ENABLE(speech,
|
||||
[ --disable-speech Disable speech server],,
|
||||
enable_speech=yes)
|
||||
BUILD_SPEECH=
|
||||
|
||||
# has flite, for speech synthesis.
|
||||
AC_CHECK_LIB(flite, new_utterance, have_speech=yes, have_speech=no)
|
||||
AC_CHECK_HEADERS(flite/flite.h)
|
||||
if test $have_speech = yes -a $enable_speech = yes; then
|
||||
BUILD_SPEECH="speech say"
|
||||
fi
|
||||
AC_SUBST(BUILD_SPEECH)
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Find CUPS
|
||||
#--------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue