/* * Case-insensitive match on NAME. */ static int getVoiceSpec(char *name, VoiceSpec *vspec) { OSErr theErr = noErr; short nvoices; long vindex; VoiceDescription vdesc; DEBUG1("looking for voice %s", name); theErr = CountVoices(&nvoices); if (theErr != noErr) { errorMsg("CountVoices failed", theErr); } else { for (vindex = 1; vindex <= nvoices; vindex++) { theErr = GetIndVoice(vindex, vspec); if (theErr != noErr) { errorMsg("GetIndVoice failed", theErr); } else { theErr = GetVoiceDescription(vspec, &vdesc, sizeof(VoiceDescription)); if (theErr != noErr) { errorMsg("GetVoiceDescription failed", theErr); } else if (strncasecmp(name, vdesc.name+1, vdesc.name[0]) == 0) { DEBUG3("found voice %s: creator=%d, id=%d", name, vspec->creator, vspec->id); return 0; } } } } return -1; }
int main(int argc, char **argv) { OSErr rc; SpeechChannel channel; VoiceSpec vs; int voice; char *text = "What do you want to say?"; if (!argv[1]) { voice = 1; } else { voice = atoi(argv[1]); } if (argc == 3) { text = argv[2]; } // GetIndVoice gets the voice define by the (positive) index rc = GetIndVoice(voice, // SInt16 index, &vs); // VoiceSpec *voice // NewSpeechChannel basically makes the voice usable rc = NewSpeechChannel(&vs, // VoiceSpec *voice, &channel); // Can be NULL CFStringRef string = CFStringCreateWithCString(NULL, text, kCFStringEncodingUTF8); rc = SpeakCFString(channel, string, NULL); if (rc) { fprintf(stderr, "unable to speak!\n"); exit(1); } while (SpeechBusy()) sleep(1); exit(0); }
// ---------------------------------------------------------- bool ofxAudioUnitSpeechSynth::setVoice(int voiceIndex) // ---------------------------------------------------------- { VoiceSpec vSpec; OSErr err; err = GetIndVoice(voiceIndex, &vSpec); if(!err) { StopSpeech(_channel); err = SetSpeechInfo(_channel, soCurrentVoice, &vSpec); } return (err == 0); }
int prSetSpeechVoice(struct VMGlobals *g, int numArgsPushed){ OSErr theErr = noErr; //PyrSlot *a = g->sp-2; PyrSlot *b = g->sp-1; PyrSlot *c = g->sp; int val; int chan; VoiceSpec theVoiceSpec; slotIntVal(b, &chan); slotIntVal(c, &val); theErr = GetIndVoice (val, &theVoiceSpec); if (SetSpeechInfo (fCurSpeechChannel[chan], soCurrentVoice, &theVoiceSpec) == incompatibleVoice) return (!errNone); return errNone; }
/* * The constructor for the ofxSpeechSynthesizer sets the status of the synthesizer * as well as populates the list of voices available in the system. This way one * can call listVoices and then initialize the synthesizer with one of those * available voices. */ ofxSpeechSynthesizer::ofxSpeechSynthesizer() { isSpeaking = false; //-- Populate the list of available voices in the system. OSErr errorStatus = noErr; short numberOfVoices; VoiceSpec theVoiceSpec; errorStatus = CountVoices(&numberOfVoices); if(!errorStatus) { for(int voiceIndex = 1; voiceIndex <= numberOfVoices; voiceIndex++) { VoiceDescription theVoiceDescription; errorStatus = GetIndVoice(voiceIndex, &theVoiceSpec); if(!errorStatus) { errorStatus = GetVoiceDescription(&theVoiceSpec, &theVoiceDescription, sizeof(theVoiceDescription)); } //-- Get the voice's name and add it to the list of available voices //-- The voices available vary depending on the version of the OS. if(!errorStatus) { size_t voiceNameLength = theVoiceDescription.name[0]; char voiceName[voiceNameLength]; for(int i=0; i < voiceNameLength; i++) { voiceName[i] = theVoiceDescription.name[i+1]; } std::string aVoice = std::string(voiceName, voiceNameLength); voices[aVoice] = voiceIndex; } } } }
// ---------------------------------------------------------- std::vector<std::string> ofxAudioUnitSpeechSynth::getAvailableVoices() // ---------------------------------------------------------- { SInt16 numVoices = 0; CountVoices(&numVoices); std::vector<std::string> voiceNames; // voices seem to be 1-indexed instead of 0-indexed for(int i = 1; i <= numVoices; i++) { VoiceSpec vSpec; VoiceDescription vDesc; GetIndVoice(i, &vSpec); GetVoiceDescription(&vSpec, &vDesc, sizeof(VoiceDescription)); string name = string((const char *)vDesc.name); // the first "character" in vDesc.name is actually just the length // of the string. We're tossing it out here by making a substring. voiceNames.push_back(string(name, 1, name[0])); } return voiceNames; }
/* * The initSynthesizer method creates the speech channel to be used by the * synthesizer with the specified voice. If no voice is specified, then the * the synthesizer is initializeed with the default system voice. */ void ofxSpeechSynthesizer::initSynthesizer(std::string voice) { OSErr errorStatus; VoiceSpec theVoiceSpec; if(voice == "") { //-- Create a speech channel with a null voice spec, this returns the default system voice currentVoice = "Default"; errorStatus = NewSpeechChannel(NULL, &speechChannel); } else { //-- Create a speech channel with the voice spec that has the specified voice currentVoice = voice; short voiceIndex = voices[voice]; errorStatus = GetIndVoice(voiceIndex, &theVoiceSpec); if(!errorStatus) errorStatus = NewSpeechChannel(&theVoiceSpec, &speechChannel); } }