2006-08-24 23:15:44 Dialog - Interview-to-speech tool
Help me clean up any little issues with this, but perhaps the code is interesting to someone in its own right.

This program takes as input a text file in an interview format. Something like:
( objc )
  1  Interview Guy: Some kinda question?
2 Guest: Some kinda answer. No line breaks unless it is a real paragraph break.


The only massage that someone needs to make to the text file to prepare it for this program is to add two lines to the top which give the strings to look for to cue the program to switch voices, which in this example would be:
  1  Interview Guy: 
2 Guest:


And then the file is ready for use. Optionally one can tell it what voices to use, otherwise by default the interviewer is Victoria and the guest is Bruce.
  1  #import <Cocoa/Cocoa.h>
2 // compiled with: gcc -std=gnu99 -fobjc-exceptions -o dialog -framework Cocoa dialog.m
3
4 int main(int argc, const char *argv[]) {
5 if (argc<2) {
6 printf( "Usage: dialog [filename] (interviewer voice) (guest voice)\n" );
7 exit( 1 );
8 }
9
10 NSAutoreleasePool *pool = [NSAutoreleasePool new];
11 NSString *guestVoice, *interviewerVoice;
12 NSMutableString *currentVoice = [NSMutableString new];
13
14 interviewerVoice = ( argc > 2 ? [NSString stringWithUTF8String:argv[2]] : @"Victoria" );
15 guestVoice = ( argc > 3 ? [NSString stringWithUTF8String:argv[3]] : @"Bruce" );
16
17 NSSpeechSynthesizer *interviewer = [[NSSpeechSynthesizer alloc] initWithVoice:
18 [NSString stringWithFormat:@"com.apple.speech.synthesis.voice.%@", interviewerVoice]];
19 NSSpeechSynthesizer *guest = [[NSSpeechSynthesizer alloc] initWithVoice:
20 [NSString stringWithFormat:@"com.apple.speech.synthesis.voice.%@", guestVoice]];
21
22 NSError *error;
23 NSString *inputFile = [NSString stringWithUTF8String:argv[1]];
24 NSString *inputText = [NSString stringWithContentsOfFile:inputFile
25 encoding:NSUTF8StringEncoding error:&error];
26
27 if (!inputText)
28 NSLog(@"Error opening file: %@", [error localizedDescription]);
29 else {
30
31 NSArray *lines = [inputText componentsSeparatedByString:@"\n"];
32 NSString *interviewerCue = [lines objectAtIndex:0];
33 NSString *guestCue = [lines objectAtIndex:1];
34 [currentVoice setString:@"interviewer"];
35
36 for( int i=2; i<[lines count]; i++ ) {
37 NSString *line = [lines objectAtIndex:i];
38 if ([line hasPrefix:interviewerCue]) {
39 [interviewer startSpeakingString:[line substringFromIndex:[interviewerCue length]]];
40 [currentVoice setString:@"interviewer"];
41 } else if ([line hasPrefix:guestCue]) {
42 [guest startSpeakingString:[line substringFromIndex:[guestCue length]]];
43 [currentVoice setString:@"guest"];
44 } else if ([line length]) {
45 usleep( 250 ); // pause for paragraph breaks
46 if ([currentVoice isEqualToString:@"interviewer"])
47 [interviewer startSpeakingString:line];
48 else
49 [guest startSpeakingString:line];
50 }
51 while( [NSSpeechSynthesizer isAnyApplicationSpeaking] ) usleep( 250 );
52 sleep( 1 );
53 }
54 }
55 [currentVoice release];
56 [interviewer release];
57 [guest release];
58 [pool release];
59 return 0;
60 }


Thanks to Joe for helping me out clean up this code and chase down a bug detecting an error if the file name is bogus.

I added a link to the source code, a binary build of the code (as a universal app).
Leave a comment