static espeak_ERROR set_punctuation(struct synth_t *s, int punct, enum adjust_t adj) { espeak_ERROR rc; if (adj == ADJ_DEC) punct = -punct; if (adj != ADJ_SET) punct += s->punct; rc = espeak_SetParameter(espeakPUNCTUATION, punct, 0); if (rc == EE_OK) s->punct = punct; return rc; }
void tts_capitalize(int capitalize) { /* indicate capital by pitch */ espeak_ERROR erc; //debug_log(logfd, "Called tts_capitalize: %d\n", capitalize); tts_state.capitalize = capitalize; if (capitalize) { tts_allcaps_beep(0); tts_split_caps(0); } erc = espeak_SetParameter(espeakCAPITALS, (capitalize ? 3 : 0), 0); //debug_log(logfd, "In tts_capitalize espeak_SetParameter returned: %d\n", erc); return; } /* end tts_capitalize */
static espeak_ERROR set_pitch(struct synth_t *s, int pitch, enum adjust_t adj) { espeak_ERROR rc; if (adj == ADJ_DEC) pitch = -pitch; if (adj != ADJ_SET) pitch += s->pitch; rc = espeak_SetParameter(espeakPITCH, pitch * pitchMultiplier, 0); if (rc == EE_OK) s->pitch = pitch; return rc; }
static espeak_ERROR set_frequency(struct synth_t *s, int freq, enum adjust_t adj) { espeak_ERROR rc; if (adj == ADJ_DEC) freq = -freq; if (adj != ADJ_SET) freq += s->frequency; rc = espeak_SetParameter(espeakRANGE, freq * frequencyMultiplier, 0); if (rc == EE_OK) s->frequency = freq; return rc; }
void PlatformSpeechSynthesisProviderEfl::speak(PassRefPtr<PlatformSpeechSynthesisUtterance> utterance) { if (!engineInit() || !utterance) { fireSpeechEvent(SpeechError); return; } m_utterance = utterance; String voice = voiceName(m_utterance); espeak_SetVoiceByName(voice.utf8().data()); espeak_SetParameter(espeakRATE, convertRateToEspeakValue(m_utterance->rate()), 0); espeak_SetParameter(espeakVOLUME, convertVolumeToEspeakValue(m_utterance->volume()), 0); espeak_SetParameter(espeakPITCH, convertPitchToEspeakValue(m_utterance->pitch()), 0); String textToRead = m_utterance->text(); espeak_ERROR err = espeak_Synth(textToRead.utf8().data(), textToRead.length(), 0, POS_CHARACTER, 0, espeakCHARS_AUTO, 0, nullptr); if (err == EE_INTERNAL_ERROR) { fireSpeechEvent(SpeechError); m_utterance = nullptr; return; } fireSpeechEvent(SpeechStart); }
void tts_split_caps(int split_caps) { /* speak camel-case, IOW say 'capital' for every capital letter */ espeak_ERROR erc; //debug_log(logfd, "Called tts_split_caps: %d\n", split_caps); tts_state.split_caps = split_caps; if (split_caps) { tts_capitalize(0); tts_allcaps_beep(0); } erc = espeak_SetParameter(espeakCAPITALS, (split_caps ? 2 : 0), 0); //debug_log(logfd, "In tts_split_caps espeak_SetParameter returned: %d\n", erc); return; } /* end tts_split_caps */
int setRange(int range) { espeak_ERROR rc; if ( 100 < range ) { range = 100; } else if ( 0 > range ) { range = 0; } if ( 1 == initFlag ) { rc = espeak_SetParameter(espeakRANGE, range, 0); if ( EE_BUFFER_FULL == rc ) { sleep(3); rc = espeak_SetParameter(espeakRANGE, range, 0); if ( EE_OK != rc ) { return -1; } } if ( EE_INTERNAL_ERROR == rc ) { return -1; } } return 0; }
static espeak_ERROR set_rate(struct synth_t *s, int rate, enum adjust_t adj) { espeak_ERROR rc; if (adj == ADJ_DEC) rate = -rate; if (adj != ADJ_SET) rate += s->rate; rc = espeak_SetParameter(espeakRATE, rate * rateMultiplier + rateOffset, 0); if (rc == EE_OK) s->rate = rate; return rc; }
int setPunctuation(int punct) { espeak_ERROR rc; if ( 0 != punct || 1 != punct || 2 != punct ) { punct = 2; } if ( 1 == initFlag ) { rc = espeak_SetParameter(espeakPUNCTUATION, punct, 0); if ( EE_BUFFER_FULL == rc ) { sleep(3); rc = espeak_SetParameter(espeakPUNCTUATION, punct, 0); if ( EE_OK != rc ) { return -1; } } if ( EE_INTERNAL_ERROR == rc ) { return -1; } } return 0; }
int setPitch(int pitch) { espeak_ERROR rc; if ( 100 < pitch ) { pitch = 100; } else if ( 0 > pitch ) { pitch = 0; } if ( 1 == initFlag ) { rc = espeak_SetParameter(espeakPITCH, pitch, 0); if ( EE_BUFFER_FULL == rc ) { sleep(3); rc = espeak_SetParameter(espeakPITCH, pitch, 0); if ( EE_OK != rc ) { return -1; } } if ( EE_INTERNAL_ERROR == rc ) { return -1; } } return 0; }
static espeak_ERROR set_volume(struct synth_t *s, int vol, enum adjust_t adj) { espeak_ERROR rc; if (adj == ADJ_DEC) vol = -vol; if (adj != ADJ_SET) vol += s->volume; rc = espeak_SetParameter(espeakVOLUME, (vol + 1) * volumeMultiplier, 0); if (rc == EE_OK) s->volume = vol; return rc; }
static void espeak_set_rate(signed int rate) { assert(rate >= -100 && rate <= +100); int speed; int normal_rate = 170, max_rate = 390, min_rate = 80; if (rate < 0) speed = normal_rate + (normal_rate - min_rate) * rate / 100; else speed = normal_rate + (max_rate - normal_rate) * rate / 100; espeak_ERROR ret = espeak_SetParameter(espeakRATE, speed, 0); if (ret != EE_OK) { DBG("Espeak: Error setting rate %i.", speed); } else { DBG("Espeak: Rate set to %i.", speed); } }
static void espeak_set_pitch(signed int pitch) { assert(pitch >= -100 && pitch <= +100); int pitchBaseline; /* Possible range 0 to 100. */ if (pitch < 0) { pitchBaseline = ((float)(pitch + 100) * espeak_voice_pitch_baseline) / (float)100; } else { pitchBaseline = (((float)pitch * (100 - espeak_voice_pitch_baseline)) / (float)100) + espeak_voice_pitch_baseline; } assert (pitchBaseline >= 0 && pitchBaseline <= 100); espeak_ERROR ret = espeak_SetParameter(espeakPITCH, pitchBaseline, 0); if (ret != EE_OK) { DBG("Espeak: Error setting pitch %i.", pitchBaseline); } else { DBG("Espeak: Pitch set to %i.", pitchBaseline); } }
static void espeak_set_volume(signed int volume) { int vol; assert(volume >= OTTS_VOICE_VOLUME_MIN && volume <= OTTS_VOICE_VOLUME_MAX); /* Possible range 0 to 100. */ if (volume < OTTS_VOICE_VOLUME_DEFAULT) vol = (volume - OTTS_VOICE_VOLUME_MIN) * 100 / (OTTS_VOICE_VOLUME_MAX - OTTS_VOICE_VOLUME_MIN); else vol = 50 + ((volume - OTTS_VOICE_VOLUME_DEFAULT) * 100 / (OTTS_VOICE_VOLUME_MAX - OTTS_VOICE_VOLUME_MIN)); espeak_ERROR ret = espeak_SetParameter(espeakVOLUME, vol, 0); if (ret != EE_OK) { log_msg(OTTS_LOG_WARN, "Espeak: Error setting volume %i.", vol); } else { log_msg(OTTS_LOG_DEBUG, "Espeak: Volume set to %i.", vol); } }
static void espeak_set_cap_let_recogn(ECapLetRecogn cap_mode) { int espeak_cap_mode = 0; switch (cap_mode) { case RECOGN_NONE: espeak_cap_mode = EspeakCapitalPitchRise; break; case RECOGN_SPELL: espeak_cap_mode = 2; break; case RECOGN_ICON: espeak_cap_mode = 1; break; } espeak_ERROR ret = espeak_SetParameter(espeakCAPITALS, espeak_cap_mode, 1); if (ret != EE_OK) { DBG("Espeak: Failed to set capitals mode."); } else { DBG("Set capitals mode."); } }
static void espeak_set_punctuation_mode(EPunctMode punct_mode) { espeak_PUNCT_TYPE espeak_punct_mode = espeakPUNCT_SOME; switch (punct_mode) { case PUNCT_ALL: espeak_punct_mode = espeakPUNCT_ALL; break; case PUNCT_SOME: espeak_punct_mode = espeakPUNCT_SOME; break; case PUNCT_NONE: espeak_punct_mode = espeakPUNCT_NONE; break; } espeak_ERROR ret = espeak_SetParameter(espeakPUNCTUATION, espeak_punct_mode, 0); if (ret != EE_OK) { DBG("Espeak: Failed to set punctuation mode."); } else { DBG("Set punctuation mode."); } }
static void espeak_set_rate(signed int rate) { int speed; int normal_rate = 170, max_rate = 390, min_rate = 80; assert(rate >= OTTS_VOICE_RATE_MIN && rate <= OTTS_VOICE_RATE_MAX); if (rate < OTTS_VOICE_RATE_DEFAULT) speed = min_rate + ((normal_rate - min_rate) * (rate - OTTS_VOICE_RATE_MIN) / (OTTS_VOICE_RATE_DEFAULT - OTTS_VOICE_RATE_MIN)); else speed = normal_rate + ((max_rate - normal_rate) * (rate - OTTS_VOICE_RATE_DEFAULT) / (OTTS_VOICE_RATE_MAX - OTTS_VOICE_RATE_DEFAULT)); espeak_ERROR ret = espeak_SetParameter(espeakRATE, speed, 0); if (ret != EE_OK) { log_msg(OTTS_LOG_WARN, "Espeak: Error setting rate %i.", speed); } else { log_msg(OTTS_LOG_DEBUG, "Espeak: Rate set to %i.", speed); } }
ESpeak::ESpeak(QObject *parent) : QObject(parent), queueLength(0) { if (0 == refcount) { espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 100, 0, 0); espeak_VOICE voice; QString language = QLocale::system().languageToString(QLocale::system().language()); QByteArray languageData = language.toAscii(); languageData.prepend((char)0); languageData.append((char)0); QByteArray languages = QByteArray(1, (char)0); languageData += languages; voice.languages = languageData.data(); voice.name = 0; voice.gender = 2; voice.age = 20; espeak_SetVoiceByProperties(&voice); espeak_SetParameter(espeakRATE, 175, false); } ++refcount; }
// Sets the property with the specified value // // TODO: add pitch property here tts_result TtsEngine::setProperty(const char *property, const char *value, const size_t size) { int rate; int pitch; int volume; /* Set a specific property for the engine. Supported properties include: language (locale), rate, pitch, volume. */ /* Sanity check */ if (property == NULL) { LOGE("setProperty called with property NULL"); return TTS_PROPERTY_UNSUPPORTED; } if (value == NULL) { LOGE("setProperty called with value NULL"); return TTS_VALUE_INVALID; } if (strncmp(property, "language", 8) == 0) { // TODO: Fix this return TTS_SUCCESS; } else if (strncmp(property, "rate", 4) == 0) { rate = atoi(value); espeak_SetParameter(espeakRATE, rate, 0); // TODO: Fix this - use the return value here, don't just automatically return success! return TTS_SUCCESS; } else if (strncmp(property, "pitch", 5) == 0) { // TODO: Fix this return TTS_SUCCESS; } else if (strncmp(property, "volume", 6) == 0) { // TODO: Fix this return TTS_SUCCESS; } return TTS_PROPERTY_UNSUPPORTED; }
static void spk_setVolume(volatile SpeechSynthesizer *spk, unsigned char setting) { int volume = getIntegerSpeechVolume(setting, 50); espeak_SetParameter(espeakVOLUME, volume, 0); }
int main( int argc, char** argv ) { espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 0, NULL, 0); ros::init(argc, argv, "espeak_node"); ros::NodeHandle n; ros::NodeHandle priv_n("~"); // for list of voices, run "espeak --voices" // voices: "brazil", "default", "english", "lancashire", // "english-rp", "english-wmids", "english-us", "en-scottish" std::string voice_name; // dialects: "pt-br", "en", "en-uk", "en-uk-north", // "en-uk-rp", "en-uk-wmids", "en-us", "en-sc" std::string dialect; espeak_VOICE voice_select; // See speak_lib.h for details and range of the parameters below int rate, volume, pitch, range, punctuation; int voice_num, dialect_num, capitals, wordgap, age, gender; // Fetch default parameters rate = espeak_GetParameter(espeakRATE, 0); volume = espeak_GetParameter(espeakVOLUME, 0); pitch = espeak_GetParameter(espeakPITCH, 0); range = espeak_GetParameter(espeakRANGE, 0); punctuation = espeak_GetParameter(espeakPUNCTUATION, 0); capitals = espeak_GetParameter(espeakCAPITALS, 0); wordgap = espeak_GetParameter(espeakWORDGAP, 0); voice_num = 1; dialect_num = 1; // Fetch (and set if param could not be retrieved) ROS parameters if (priv_n.getParam("voice", voice_num) == false) { priv_n.setParam("voice", voice_num); } if (priv_n.getParam("dialect", dialect_num) == false) { priv_n.setParam("dialect", dialect_num); } if (priv_n.getParam("rate", rate) == false) { priv_n.setParam("rate", rate); } if (priv_n.getParam("volume", volume) == false) { priv_n.setParam("volume", volume); } if (priv_n.getParam("pitch", pitch) == false) { priv_n.setParam("pitch", pitch); } if (priv_n.getParam("punctuation", punctuation) == false) { priv_n.setParam("punctuation", punctuation); } if (priv_n.getParam("capitals", capitals) == false) { priv_n.setParam("capitals", capitals); } if (priv_n.getParam("wordgap", wordgap) == false) { priv_n.setParam("wordgap", wordgap); } priv_n.param("age", age, int(0)); priv_n.param("gender", gender, int(2)); if (age < 0 || age > 100) { age = 0; } if (gender < 0 || gender > 2) { gender = 2; } voice_name = getVoiceName(voice_num); dialect = getDialectName(dialect_num); std::memset(&voice_select,0,sizeof(voice_select)); voice_select.name = voice_name.c_str(); voice_select.languages = dialect.c_str(); voice_select.age = age; // 0=not specified, or age in years voice_select.gender = gender; // 0=none, 1=male, 2=female // set espeak parameters //if (espeak_SetVoiceByName(voice_name.c_str()) != EE_OK) { // ROS_ERROR("Could not set espeak voice. Aborting."); // return 1; //} if (espeak_SetVoiceByProperties(&voice_select) != EE_OK) { ROS_ERROR("Could not set espeak voice properties. Aborting."); return 1; } //ROS_INFO("Using voice %s", voice_name.c_str()); //ROS_INFO("Using dialect %s", dialect.c_str()); if (rate < 80 || rate > 450) { ROS_INFO("Parameter rate = %d out of range, using default value", rate); } else { if (espeak_SetParameter(espeakRATE, rate, 0) != EE_OK) { ROS_ERROR("Could not set espeak rate. Aborting."); return 1; } } if (volume < 0 || volume > 200) { ROS_INFO("Parameter volume = %d out of range, using default value", volume); } else { if (espeak_SetParameter(espeakVOLUME, volume, 0) != EE_OK) { ROS_ERROR("Could not set espeak volume. Aborting."); return 1; } } if (pitch < 0 || pitch > 100) { ROS_INFO("Parameter pitch = %d out of range, using default value", pitch); } else { if (espeak_SetParameter(espeakPITCH, pitch, 0) != EE_OK) { ROS_ERROR("Could not set espeak pitch. Aborting."); return 1; } } if (range < 0 || range > 100) { ROS_INFO("Parameter range = %d out of range, using default value", range); } else { if (espeak_SetParameter(espeakRANGE, range, 0) != EE_OK) { ROS_ERROR("Could not set espeak range. Aborting."); return 1; } } if (punctuation < 0 || punctuation > 2) { ROS_INFO("Parameter punctuation out of range, using default value"); } else { if (espeak_SetParameter(espeakPUNCTUATION, espeak_PUNCT_TYPE(punctuation), 0) != EE_OK) { ROS_ERROR("Could not set espeak punctuation. Aborting."); return 1; } } if (capitals < 0 || capitals > 3) { ROS_INFO("Parameter capitals out of range, using default value"); } else { if (espeak_SetParameter(espeakCAPITALS, capitals, 0) != EE_OK) { ROS_ERROR("Could not set espeak capitals. Aborting."); return 1; } } if (wordgap < 0 || wordgap > 1000 || wordgap % 10 != 0) { ROS_INFO("Parameter wordgap out of range, using default value"); } else { if (espeak_SetParameter(espeakWORDGAP, wordgap, 0) != EE_OK) { ROS_ERROR("Could not set espeak wordgap. Aborting."); return 1; } } dynamic_reconfigure::Server<espeak_ros::EspeakConfig> server; dynamic_reconfigure::Server<espeak_ros::EspeakConfig>::CallbackType f; f = boost::bind(&dyn_cfg_callback, _1, _2); server.setCallback(f); ros::Subscriber sub = n.subscribe("/espeak_node/speak_line", 20, espeak_callback); ros::spin(); while (n.ok()); return 0; }
int main (int argc, char **argv) //============================== { static struct option long_options[] = { /* These options set a flag. */ // {"verbose", no_argument, &verbose_flag, 1}, // {"brief", no_argument, &verbose_flag, 0}, /* These options don't set a flag. We distinguish them by their indices. */ {"help", no_argument, 0, 'h'}, {"stdin", no_argument, 0, 0x100}, {"compile-debug", optional_argument, 0, 0x101}, {"compile", optional_argument, 0, 0x102}, {"punct", optional_argument, 0, 0x103}, {"voices", optional_argument, 0, 0x104}, {"stdout", no_argument, 0, 0x105}, {"split", optional_argument, 0, 0x106}, {0, 0, 0, 0} }; static const char* err_load = "Failed to read "; FILE *f_text=NULL; char *p_text=NULL; int option_index = 0; int c; int ix; int flag_stdin = 0; int flag_compile = 0; int filesize = 0; int synth_flags = espeakCHARS_AUTO | espeakPHONEMES | espeakENDPAUSE; int volume = -1; int speed = -1; int pitch = -1; int wordgap = -1; int option_capitals = -1; int option_punctuation = -1; int option_phonemes = -1; int option_linelength = 0; int option_waveout = 0; char filename[120]; char voicename[40]; char voice_mbrola[20]; char dictname[40]; #define N_PUNCTLIST 100 wchar_t option_punctlist[N_PUNCTLIST]; voicename[0] = 0; voice_mbrola[0] = 0; dictname[0] = 0; wavefile[0] = 0; filename[0] = 0; option_punctlist[0] = 0; while(true) { c = getopt_long (argc, argv, "a:bf:g:hk:l:mp:qs:v:w:xXz", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 'b': synth_flags |= espeakCHARS_8BIT; break; case 'h': printf("\n"); printf("eSpeak text-to-speech: %s\n%s",espeak_Info(NULL),help_text); exit(0); break; case 'k': option_capitals = atoi(optarg); break; case 'x': option_phonemes = 1; break; case 'X': option_phonemes = 2; break; case 'm': synth_flags |= espeakSSML; break; case 'p': pitch = atoi(optarg); break; case 'q': quiet = 1; break; case 'f': strncpy0(filename,optarg,sizeof(filename)); break; case 'l': option_linelength = atoi(optarg); break; case 'a': volume = atoi(optarg); break; case 's': speed = atoi(optarg); break; case 'g': wordgap = atoi(optarg); break; case 'v': strncpy0(voicename,optarg,sizeof(voicename)); break; case 'w': option_waveout = 1; strncpy0(wavefile,optarg,sizeof(filename)); break; case 'z': // remove pause from the end of a sentence synth_flags &= ~espeakENDPAUSE; break; case 0x100: // --stdin flag_stdin = 1; break; case 0x105: // --stdout option_waveout = 1; strcpy(wavefile,"stdout"); break; case 0x101: // --compile-debug case 0x102: // --compile strncpy0(voicename,optarg,sizeof(voicename)); flag_compile = c; quiet = 1; break; case 0x103: // --punct option_punctuation = 1; if(optarg != NULL) { ix = 0; while((ix < N_PUNCTLIST) && ((option_punctlist[ix] = optarg[ix]) != 0)) ix++; option_punctlist[N_PUNCTLIST-1] = 0; option_punctuation = 2; } break; case 0x104: // --voices espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,0,NULL,0); DisplayVoices(stdout,optarg); exit(0); case 0x106: // -- split if(optarg == NULL) samples_split = 30; // default 30 minutes else samples_split = atoi(optarg); break; default: exit(0); } } if(option_waveout || quiet) { // writing to a file (or no output), we can use synchronous mode samplerate = espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,0,NULL,0); samples_split = (samplerate * samples_split) * 60; espeak_SetSynthCallback(SynthCallback); if(samples_split) { char *extn; extn = strrchr(wavefile,'.'); if((extn != NULL) && ((wavefile + strlen(wavefile) - extn) <= 4)) { strcpy(filetype,extn); *extn = 0; } } else if(option_waveout) { if(OpenWavFile(wavefile,samplerate) != 0) exit(4); } } else { // play the sound output samplerate = espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,0,NULL,0); } if(voicename[0] == 0) strcpy(voicename,"default"); if(espeak_SetVoiceByName(voicename) != EE_OK) { fprintf(stderr,"%svoice '%s'\n",err_load,voicename); exit(2); } if(flag_compile) { // This must be done after the voice is set espeak_CompileDictionary("", stderr, flag_compile & 0x1); exit(0); } // set any non-default values of parameters. This must be done after espeak_Initialize() if(speed > 0) espeak_SetParameter(espeakRATE,speed,0); if(volume >= 0) espeak_SetParameter(espeakVOLUME,volume,0); if(pitch >= 0) espeak_SetParameter(espeakPITCH,pitch,0); if(option_capitals >= 0) espeak_SetParameter(espeakCAPITALS,option_capitals,0); if(option_punctuation >= 0) espeak_SetParameter(espeakPUNCTUATION,option_punctuation,0); if(wordgap >= 0) espeak_SetParameter(espeakWORDGAP,wordgap,0); if(option_linelength > 0) espeak_SetParameter(espeakLINELENGTH,option_linelength,0); if(option_punctuation == 2) espeak_SetPunctuationList(option_punctlist); if(option_phonemes >= 0) espeak_SetPhonemeTrace(option_phonemes,stderr); if(filename[0]==0) { if((optind < argc) && (flag_stdin == 0)) { // there's a non-option parameter, and no -f or --stdin // use it as text p_text = argv[optind]; } else { f_text = stdin; if(flag_stdin == 0) { flag_stdin = 2; } } } else { filesize = GetFileLength(filename); f_text = fopen(filename,"r"); } if((f_text == NULL) && (p_text == NULL)) { fprintf(stderr,"%sfile '%s'\n",err_load,filename); exit(1); } if(p_text != NULL) { int size; size = strlen(p_text); espeak_Synth(p_text,size+1,0,POS_CHARACTER,0,synth_flags,NULL,NULL); } else if(flag_stdin) { int max = 1000; p_text = (char *)malloc(max); if(flag_stdin == 2) { // line by line input on stdin while(fgets(p_text,max,stdin) != NULL) { p_text[max-1] = 0; espeak_Synth(p_text,max,0,POS_CHARACTER,0,synth_flags,NULL,NULL); } } else { // bulk input on stdin ix = 0; while(!feof(stdin)) { p_text[ix++] = fgetc(stdin); if(ix >= (max-1)) { max += 1000; p_text = (char *)realloc(p_text,max); } } if(ix > 0) { p_text[ix-1] = 0; espeak_Synth(p_text,ix+1,0,POS_CHARACTER,0,synth_flags,NULL,NULL); } } } else if(f_text != NULL) { if((p_text = (char *)malloc(filesize+1)) == NULL) { fprintf(stderr,"Failed to allocate memory %d bytes",filesize); exit(3); } fread(p_text,1,filesize,f_text); p_text[filesize]=0; espeak_Synth(p_text,filesize+1,0,POS_CHARACTER,0,synth_flags,NULL,NULL); fclose(f_text); } espeak_Synchronize(); return(0); }
int main(int argc, char **argv) { static struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "stdin", no_argument, 0, 0x100 }, { "compile-debug", optional_argument, 0, 0x101 }, { "compile", optional_argument, 0, 0x102 }, { "punct", optional_argument, 0, 0x103 }, { "voices", optional_argument, 0, 0x104 }, { "stdout", no_argument, 0, 0x105 }, { "split", optional_argument, 0, 0x106 }, { "path", required_argument, 0, 0x107 }, { "phonout", required_argument, 0, 0x108 }, { "pho", no_argument, 0, 0x109 }, { "ipa", optional_argument, 0, 0x10a }, { "version", no_argument, 0, 0x10b }, { "sep", optional_argument, 0, 0x10c }, { "tie", optional_argument, 0, 0x10d }, { "compile-mbrola", optional_argument, 0, 0x10e }, { "compile-intonations", no_argument, 0, 0x10f }, { "compile-phonemes", optional_argument, 0, 0x110 }, { 0, 0, 0, 0 } }; FILE *f_text = NULL; char *p_text = NULL; FILE *f_phonemes_out = stdout; char *data_path = NULL; // use default path for espeak-ng-data int option_index = 0; int c; int ix; char *optarg2; int value; int flag_stdin = 0; int flag_compile = 0; int filesize = 0; int synth_flags = espeakCHARS_AUTO | espeakPHONEMES | espeakENDPAUSE; int volume = -1; int speed = -1; int pitch = -1; int wordgap = -1; int option_capitals = -1; int option_punctuation = -1; int phonemes_separator = 0; int phoneme_options = 0; int option_linelength = 0; int option_waveout = 0; espeak_VOICE voice_select; char filename[200]; char voicename[40]; char devicename[200]; #define N_PUNCTLIST 100 wchar_t option_punctlist[N_PUNCTLIST]; voicename[0] = 0; wavefile[0] = 0; filename[0] = 0; devicename[0] = 0; option_punctlist[0] = 0; while (true) { c = getopt_long(argc, argv, "a:b:d:f:g:hk:l:mp:qs:v:w:xXz", long_options, &option_index); // Detect the end of the options. if (c == -1) break; optarg2 = optarg; switch (c) { case 'b': // input character encoding, 8bit, 16bit, UTF8 if ((sscanf(optarg2, "%d", &value) == 1) && (value <= 4)) synth_flags |= value; else synth_flags |= espeakCHARS_8BIT; break; case 'd': strncpy0(devicename, optarg2, sizeof(devicename)); break; case 'h': printf("\n"); PrintVersion(); printf("%s", help_text); return 0; case 'k': option_capitals = atoi(optarg2); break; case 'x': phoneme_options |= espeakPHONEMES_SHOW; break; case 'X': phoneme_options |= espeakPHONEMES_TRACE; break; case 'm': synth_flags |= espeakSSML; break; case 'p': pitch = atoi(optarg2); break; case 'q': quiet = true; break; case 'f': strncpy0(filename, optarg2, sizeof(filename)); break; case 'l': option_linelength = atoi(optarg2); break; case 'a': volume = atoi(optarg2); break; case 's': speed = atoi(optarg2); break; case 'g': wordgap = atoi(optarg2); break; case 'v': strncpy0(voicename, optarg2, sizeof(voicename)); break; case 'w': option_waveout = 1; strncpy0(wavefile, optarg2, sizeof(filename)); break; case 'z': // remove pause from the end of a sentence synth_flags &= ~espeakENDPAUSE; break; case 0x100: // --stdin flag_stdin = 1; break; case 0x105: // --stdout option_waveout = 1; strcpy(wavefile, "stdout"); break; case 0x101: // --compile-debug case 0x102: // --compile if (optarg2 != NULL && *optarg2) { strncpy0(voicename, optarg2, sizeof(voicename)); flag_compile = c; quiet = true; break; } else { fprintf(stderr, "Voice name to '%s' not specified.\n", c == 0x101 ? "--compile-debug" : "--compile"); exit(EXIT_FAILURE); } case 0x103: // --punct option_punctuation = 1; if (optarg2 != NULL) { ix = 0; while ((ix < N_PUNCTLIST) && ((option_punctlist[ix] = optarg2[ix]) != 0)) ix++; option_punctlist[N_PUNCTLIST-1] = 0; option_punctuation = 2; } break; case 0x104: // --voices espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, 0, data_path, 0); DisplayVoices(stdout, optarg2); exit(0); case 0x106: // -- split if (optarg2 == NULL) samples_split_seconds = 30 * 60; // default 30 minutes else samples_split_seconds = atoi(optarg2) * 60; break; case 0x107: // --path data_path = optarg2; break; case 0x108: // --phonout if ((f_phonemes_out = fopen(optarg2, "w")) == NULL) fprintf(stderr, "Can't write to: %s\n", optarg2); break; case 0x109: // --pho phoneme_options |= espeakPHONEMES_MBROLA; break; case 0x10a: // --ipa phoneme_options |= espeakPHONEMES_IPA; if (optarg2 != NULL) { // deprecated and obsolete switch (atoi(optarg2)) { case 1: phonemes_separator = '_'; break; case 2: phonemes_separator = 0x0361; phoneme_options |= espeakPHONEMES_TIE; break; case 3: phonemes_separator = 0x200d; // ZWJ phoneme_options |= espeakPHONEMES_TIE; break; } } break; case 0x10b: // --version PrintVersion(); exit(0); case 0x10c: // --sep phoneme_options |= espeakPHONEMES_SHOW; if (optarg2 == 0) phonemes_separator = ' '; else utf8_in(&phonemes_separator, optarg2); if (phonemes_separator == 'z') phonemes_separator = 0x200c; // ZWNJ break; case 0x10d: // --tie phoneme_options |= (espeakPHONEMES_SHOW | espeakPHONEMES_TIE); if (optarg2 == 0) phonemes_separator = 0x0361; // default: combining-double-inverted-breve else utf8_in(&phonemes_separator, optarg2); if (phonemes_separator == 'z') phonemes_separator = 0x200d; // ZWJ break; case 0x10e: // --compile-mbrola { espeak_ng_InitializePath(data_path); espeak_ng_ERROR_CONTEXT context = NULL; espeak_ng_STATUS result = espeak_ng_CompileMbrolaVoice(optarg2, stdout, &context); if (result != ENS_OK) { espeak_ng_PrintStatusCodeMessage(result, stderr, context); espeak_ng_ClearErrorContext(&context); return EXIT_FAILURE; } return EXIT_SUCCESS; } case 0x10f: // --compile-intonations { espeak_ng_InitializePath(data_path); espeak_ng_ERROR_CONTEXT context = NULL; espeak_ng_STATUS result = espeak_ng_CompileIntonation(stdout, &context); if (result != ENS_OK) { espeak_ng_PrintStatusCodeMessage(result, stderr, context); espeak_ng_ClearErrorContext(&context); return EXIT_FAILURE; } return EXIT_SUCCESS; } case 0x110: // --compile-phonemes { espeak_ng_InitializePath(data_path); espeak_ng_ERROR_CONTEXT context = NULL; espeak_ng_STATUS result; if (optarg2) { result = espeak_ng_CompilePhonemeDataPath(22050, optarg2, NULL, stdout, &context); } else { result = espeak_ng_CompilePhonemeData(22050, stdout, &context); } if (result != ENS_OK) { espeak_ng_PrintStatusCodeMessage(result, stderr, context); espeak_ng_ClearErrorContext(&context); return EXIT_FAILURE; } return EXIT_SUCCESS; } default: exit(0); } } espeak_ng_InitializePath(data_path); espeak_ng_ERROR_CONTEXT context = NULL; espeak_ng_STATUS result = espeak_ng_Initialize(&context); if (result != ENS_OK) { espeak_ng_PrintStatusCodeMessage(result, stderr, context); espeak_ng_ClearErrorContext(&context); exit(1); } if (option_waveout || quiet) { // writing to a file (or no output), we can use synchronous mode result = espeak_ng_InitializeOutput(ENOUTPUT_MODE_SYNCHRONOUS, 0, devicename[0] ? devicename : NULL); samplerate = espeak_ng_GetSampleRate(); samples_split = samplerate * samples_split_seconds; espeak_SetSynthCallback(SynthCallback); if (samples_split) { char *extn; extn = strrchr(wavefile, '.'); if ((extn != NULL) && ((wavefile + strlen(wavefile) - extn) <= 4)) { strcpy(filetype, extn); *extn = 0; } } } else { // play the sound output result = espeak_ng_InitializeOutput(PLAYBACK_MODE, 0, devicename[0] ? devicename : NULL); samplerate = espeak_ng_GetSampleRate(); } if (result != ENS_OK) { espeak_ng_PrintStatusCodeMessage(result, stderr, NULL); exit(EXIT_FAILURE); } if (voicename[0] == 0) strcpy(voicename, ESPEAKNG_DEFAULT_VOICE); result = espeak_ng_SetVoiceByName(voicename); if (result != ENS_OK) { memset(&voice_select, 0, sizeof(voice_select)); voice_select.languages = voicename; result = espeak_ng_SetVoiceByProperties(&voice_select); if (result != ENS_OK) { espeak_ng_PrintStatusCodeMessage(result, stderr, NULL); exit(EXIT_FAILURE); } } if (flag_compile) { // This must be done after the voice is set espeak_ng_ERROR_CONTEXT context = NULL; espeak_ng_STATUS result = espeak_ng_CompileDictionary("", NULL, stderr, flag_compile & 0x1, &context); if (result != ENS_OK) { espeak_ng_PrintStatusCodeMessage(result, stderr, context); espeak_ng_ClearErrorContext(&context); return EXIT_FAILURE; } return EXIT_SUCCESS; } // set any non-default values of parameters. This must be done after espeak_Initialize() if (speed > 0) espeak_SetParameter(espeakRATE, speed, 0); if (volume >= 0) espeak_SetParameter(espeakVOLUME, volume, 0); if (pitch >= 0) espeak_SetParameter(espeakPITCH, pitch, 0); if (option_capitals >= 0) espeak_SetParameter(espeakCAPITALS, option_capitals, 0); if (option_punctuation >= 0) espeak_SetParameter(espeakPUNCTUATION, option_punctuation, 0); if (wordgap >= 0) espeak_SetParameter(espeakWORDGAP, wordgap, 0); if (option_linelength > 0) espeak_SetParameter(espeakLINELENGTH, option_linelength, 0); if (option_punctuation == 2) espeak_SetPunctuationList(option_punctlist); espeak_SetPhonemeTrace(phoneme_options | (phonemes_separator << 8), f_phonemes_out); if (filename[0] == 0) { if ((optind < argc) && (flag_stdin == 0)) { // there's a non-option parameter, and no -f or --stdin // use it as text p_text = argv[optind]; } else { f_text = stdin; if (flag_stdin == 0) flag_stdin = 2; } } else { struct stat st; if (stat(filename, &st) != 0) { fprintf(stderr, "Failed to stat() file '%s'\n", filename); exit(EXIT_FAILURE); } filesize = GetFileLength(filename); f_text = fopen(filename, "r"); if (f_text == NULL) { fprintf(stderr, "Failed to read file '%s'\n", filename); exit(EXIT_FAILURE); } if (S_ISFIFO(st.st_mode)) { flag_stdin = 2; } } if (p_text != NULL) { int size; size = strlen(p_text); espeak_Synth(p_text, size+1, 0, POS_CHARACTER, 0, synth_flags, NULL, NULL); } else if (flag_stdin) { size_t max = 1000; if ((p_text = (char *)malloc(max)) == NULL) { espeak_ng_PrintStatusCodeMessage(ENOMEM, stderr, NULL); exit(EXIT_FAILURE); } if (flag_stdin == 2) { // line by line input on stdin or from FIFO while (fgets(p_text, max, f_text) != NULL) { p_text[max-1] = 0; espeak_Synth(p_text, max, 0, POS_CHARACTER, 0, synth_flags, NULL, NULL); // Allow subprocesses to use the audio data through pipes. fflush(stdout); } if (f_text != stdin) { fclose(f_text); } } else { // bulk input on stdin ix = 0; while (true) { if ((c = fgetc(stdin)) == EOF) break; p_text[ix++] = (char)c; if (ix >= (max-1)) { char *new_text = NULL; if (max <= SIZE_MAX - 1000) { max += 1000; new_text = (char *)realloc(p_text, max); } if (new_text == NULL) { free(p_text); espeak_ng_PrintStatusCodeMessage(ENOMEM, stderr, NULL); exit(EXIT_FAILURE); } p_text = new_text; } } if (ix > 0) { p_text[ix-1] = 0; espeak_Synth(p_text, ix+1, 0, POS_CHARACTER, 0, synth_flags, NULL, NULL); } } free(p_text); } else if (f_text != NULL) { if ((p_text = (char *)malloc(filesize+1)) == NULL) { espeak_ng_PrintStatusCodeMessage(ENOMEM, stderr, NULL); exit(EXIT_FAILURE); } fread(p_text, 1, filesize, f_text); p_text[filesize] = 0; espeak_Synth(p_text, filesize+1, 0, POS_CHARACTER, 0, synth_flags, NULL, NULL); fclose(f_text); free(p_text); } result = espeak_ng_Synchronize(); if (result != ENS_OK) { espeak_ng_PrintStatusCodeMessage(result, stderr, NULL); exit(EXIT_FAILURE); } if (f_phonemes_out != stdout) fclose(f_phonemes_out); CloseWavFile(); espeak_ng_Terminate(); return 0; }
/* Functions internal to the eSpeak engine wrapper */ static void setSpeechRate(int speechRate) { espeak_ERROR err = espeak_SetParameter(espeakRATE, speechRate, 0); }
autoSound SpeechSynthesizer_to_Sound (SpeechSynthesizer me, const char32 *text, autoTextGrid *tg, autoTable *events) { try { int fsamp = espeak_Initialize (AUDIO_OUTPUT_SYNCHRONOUS, 0, nullptr, // 5000ms espeakINITIALIZE_PHONEME_EVENTS|espeakINITIALIZE_PHONEME_IPA); if (fsamp == -1) { Melder_throw (U"Internal espeak error."); } int synth_flags = espeakCHARS_WCHAR; if (my d_inputTextFormat == SpeechSynthesizer_INPUT_TAGGEDTEXT) { synth_flags |= espeakSSML; } if (my d_inputTextFormat != SpeechSynthesizer_INPUT_TEXTONLY) { synth_flags |= espeakPHONEMES; } option_phoneme_events = espeakINITIALIZE_PHONEME_EVENTS; // extern int option_phoneme_events; if (my d_outputPhonemeCoding == SpeechSynthesizer_PHONEMECODINGS_IPA) { option_phoneme_events |= espeakINITIALIZE_PHONEME_IPA; } espeak_SetParameter (espeakRATE, my d_wordsPerMinute, 0); espeak_SetParameter (espeakPITCH, my d_pitchAdjustment, 0); espeak_SetParameter (espeakRANGE, my d_pitchRange, 0); const char32 *voiceLanguageCode = SpeechSynthesizer_getVoiceLanguageCodeFromName (me, my d_voiceLanguageName); const char32 *voiceVariantCode = SpeechSynthesizer_getVoiceVariantCodeFromName (me, my d_voiceVariantName); espeakdata_SetVoiceByName ((const char *) Melder_peek32to8 (voiceLanguageCode), (const char *) Melder_peek32to8 (voiceVariantCode)); espeak_SetParameter (espeakWORDGAP, my d_wordgap * 100, 0); // espeak wordgap is in units of 10 ms espeak_SetParameter (espeakCAPITALS, 0, 0); espeak_SetParameter (espeakPUNCTUATION, espeakPUNCT_NONE, 0); espeak_SetSynthCallback (synthCallback); my d_events = Table_createWithColumnNames (0, U"time type type-t t-pos length a-pos sample id uniq"); #ifdef _WIN32 wchar_t *textW = Melder_peek32toW (text); espeak_Synth (textW, wcslen (textW) + 1, 0, POS_CHARACTER, 0, synth_flags, nullptr, me); #else espeak_Synth (text, str32len (text) + 1, 0, POS_CHARACTER, 0, synth_flags, nullptr, me); #endif espeak_Terminate (); autoSound thee = buffer_to_Sound (my d_wav, my d_numberOfSamples, my d_internalSamplingFrequency); if (my d_samplingFrequency != my d_internalSamplingFrequency) { thee = Sound_resample (thee.get(), my d_samplingFrequency, 50); } my d_numberOfSamples = 0; // re-use the wav-buffer if (tg) { double xmin = Table_getNumericValue_Assert (my d_events.get(), 1, 1); if (xmin > thy xmin) { xmin = thy xmin; } double xmax = Table_getNumericValue_Assert (my d_events.get(), my d_events -> rows.size, 1); if (xmax < thy xmax) { xmax = thy xmax; } autoTextGrid tg1 = Table_to_TextGrid (my d_events.get(), text, xmin, xmax); *tg = TextGrid_extractPart (tg1.get(), thy xmin, thy xmax, 0); } if (events) { Table_setEventTypeString (my d_events.get()); *events = my d_events.move(); } my d_events.reset(); return thee; } catch (MelderError) { espeak_Terminate (); Melder_throw (U"Text not played."); } }
/* Set the rate of TTS. * Hear in case of espeak the rate is ranging * from 80 to 450. So we multiply the given * rate with 3.7 and add 80 to get exact * rate for espeak */ void T4K_Tts_set_rate(int rate){ espeak_SetParameter(espeakRATE,(3.7*rate)+80,0); }
void T4K_Tts_set_pitch(int pitch){ espeak_SetParameter(espeakPITCH,pitch,0); }
//TTS Parameters void T4K_Tts_set_volume(int volume){ espeak_SetParameter(espeakVOLUME,2*volume,0); }
static void spk_setPitch(volatile SpeechSynthesizer *spk, unsigned char setting) { int pitch = getIntegerSpeechPitch(setting, 50); espeak_SetParameter(espeakPITCH, pitch, 0); }