5

How difficult would it be to implement something similar to AppleScript's say "words"?
That is to say, is it just a binary link and an import, or something as messy as a libxml implementation?

Edit: My answer solves this.


  • Acapela
    • A serious ripoff
    • €250 for the SDK, and that's not including updates
  • Ivona
    • Site does not present an iOS version with the others
    • Not interested
  • VoiceText
    • Site is ugly and difficult to navigate
    • Not interested
  • OpenEars
    • Open source, a definite plus
    • By far the best offline TTS I've heard of.
  • Flite
    • Super low quality, not worth using
    • Sucks as-is. OE improved on it a lot.
  • Google TTS
    • Good, but requires a network connection
    • Not ideal
Pops
  • 30,199
  • 37
  • 136
  • 151
Thromordyn
  • 1,581
  • 4
  • 17
  • 45

2 Answers2

7

I've looked into this and unfortunately the options are either very expensive or bad quality:

Related to this, here is how you can use Google's online TTS (code taken from iPhone SDK - Google TTS and encoding):

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"file.mp3"];

NSString *text = @"You are one chromosome away from being a potato.";
NSString *urlString = [NSString stringWithFormat:@"http://www.translate.google.com/translate_tts?tl=en&q=%@",text];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSMutableURLRequest* request = [[[NSMutableURLRequest alloc] initWithURL:url] autorelease];
[request setValue:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1" forHTTPHeaderField:@"User-Agent"];
NSURLResponse* response = nil;
NSError* error = nil;
NSData* data = [NSURLConnection sendSynchronousRequest:request
                                     returningResponse:&response
                                                 error:&error];
[data writeToFile:path atomically:YES];

AVAudioPlayer  *player;
NSError        *err;
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) 
{    
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:
              [NSURL fileURLWithPath:path] error:&err];
    player.volume = 0.4f;
    [player prepareToPlay];
    [player setNumberOfLoops:0];
    [player play];    
}

The voiceover framework from Apple is private and can only used on for accessibility. At least if you want your application approved. But if you want to use it while you decide on what system to use, here it is:

// Not App Store safe. Only available in real devices.
// See http://arstechnica.com/apple/2010/02/iphone-voiceservices-looking-under-the-hood/

#define RTLD_LAZY 0x1
#define RTLD_NOW 0x2
#define RTLD_LOCAL 0x4
#define RTLD_GLOBAL 0x8

NSObject *voiceSynthesizer;
void *voiceServices;

-(void) say:(NSString*)text {
    if (!voiceSynthesizer)
    {
        NSString *vsLocation = @"/System/Library/PrivateFrameworks/VoiceServices.framework/VoiceServices";
        voiceServices = dlopen(vsLocation.UTF8String, RTLD_LAZY);
        voiceSynthesizer = [NSClassFromString(@"VSSpeechSynthesizer") new];
    }
    [voiceSynthesizer performSelector:@selector(startSpeakingString:) withObject:text];
}
Community
  • 1
  • 1
Jano
  • 62,815
  • 21
  • 164
  • 192
  • Looks good. I'll see what I can do. (With the Google option, anyway.) – Thromordyn Jun 15 '11 at 01:32
  • I can't seem to get the online TTS to work... – Thromordyn Jun 15 '11 at 13:12
  • Lies! I added the mp3 player code, it should work. – Jano Jun 15 '11 at 13:38
  • I'm sure I broke something. That code looks a bit nicer than what I attempted. // How big are the higher quality TTS options? Price aside, how are they compared to Flite? My computer can't build over 200 files without locking up completely. (I ended up waiting two minutes for the Force Quit Applications window to open just so I could use Firefox.) It would take something like a Mac Pro to use Flite in Xcode 4. Horrendously inefficient, this version is, and way too happy to steal resources from everything else. – Thromordyn Jun 15 '11 at 13:50
  • Unfortunately, `![[NSFileManager defaultManager] fileExistsAtPath:@"/var/tmp/tts.mp3"]`. Can't figure out why. – Thromordyn Jun 15 '11 at 13:59
  • Taking a look at OpenEars now. Many, many warnings. (And 486 source files...) As soon as-- Hey, it's done. Switching to GoogleTTS. I know there's no way it'll be any good for the release, but for the sake of testing, placeholders are my friends. – Thromordyn Jun 15 '11 at 14:36
  • `Method '-applicationDocumentsDirectory' not found` // Is it safe to assume I'm not going to get away with an offline TTS that doesn't lock up the comp's UI while building? – Thromordyn Jun 15 '11 at 14:50
  • I forgot to mention, I've been building for my iPad. The iPhone Simulator does it right. (It's still a bit choppy, but certainly better than Flite. Isn't there a private API that would make all this so much easier and more convenient? I wonder if Apple might make that one public at some point...) – Thromordyn Jun 15 '11 at 15:28
1

From some question on SO (forget which one, can't find it again), I got a link to OpenEars.
For something so light, I can't really complain.

It's a bit confusing to plug in, but the documentation is all for Xcode 4. Barring user error, it won't explode a project. There are a few warnings (some of which look like they should cause a crash at runtime), but it's looking good so far.

Edit: Newest OE version is MUCH easier to install. Definitely recommended.

Thromordyn
  • 1,581
  • 4
  • 17
  • 45