/* * Copyright (C) 2014-2017 Eitan Isaacson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see: . */ #include #include #include #include "speak_lib.h" static int gSamplerate = 0; class eSpeakNGWorker { public: eSpeakNGWorker() : rate(espeakRATE_NORMAL), pitch(50), current_voice(NULL) { if (!gSamplerate) { gSamplerate = espeak_Initialize( AUDIO_OUTPUT_SYNCHRONOUS, 100, NULL, espeakINITIALIZE_DONT_EXIT); } samplerate = gSamplerate; voices = espeak_ListVoices(NULL); } void synth_(const char* aText, void* aCallback) { t_espeak_callback* cb = reinterpret_cast(aCallback); espeak_SetSynthCallback(cb); espeak_SetParameter(espeakPITCH, pitch, 0); espeak_SetParameter(espeakRATE, rate, 0); if (current_voice) espeak_SetVoiceByProperties(current_voice); else espeak_SetVoiceByName("default"); espeak_Synth(aText, 0, 0, POS_CHARACTER, 0, 0, NULL, NULL); // Reset callback so other instances will work too. espeak_SetSynthCallback(NULL); } int synth_ipa_(const char* aText, const char* virtualFileName) { /* phoneme_mode bit 1: 0=eSpeak's ascii phoneme names, 1= International Phonetic Alphabet (as UTF-8 characters). bit 7: use (bits 8-23) as a tie within multi-letter phonemes names bits 8-23: separator character, between phoneme names */ espeak_SetSynthCallback(NULL); int phoneme_options = (1 << 1); // Use IPA int use_custom_phoneme_separator = (0 << 7); int phonemes_separator = ' '; // Use a default value int phoneme_conf = phoneme_options | (phonemes_separator << 8); FILE* f_phonemes_out = fopen(virtualFileName,"wb"); if(!f_phonemes_out) return -1; //espeak_ng_InitializeOutput(ENOUTPUT_MODE_SYNCHRONOUS, 0, NULL); espeak_SetPhonemeTrace(phoneme_conf, f_phonemes_out); espeak_Synth(aText, 0, 0, POS_CHARACTER, 0, 0, NULL, NULL); espeak_SetPhonemeTrace(0, NULL); fclose(f_phonemes_out); return 0; } long set_voice( const char* aName, const char* aLang=NULL, unsigned char aGender=0, unsigned char aAge=0, unsigned char aVariant = 0 ) { long result = 0; if (aLang || aGender || aAge || aVariant) { espeak_VOICE props = { 0 }; props.name = aName; props.languages = aLang; props.gender = aGender; props.age = aAge; props.variant = aVariant; result = espeak_SetVoiceByProperties(&props); } else { result = espeak_SetVoiceByName(aName); } // This way we don't need to allocate the name/lang strings to the heap. // Instead, we store the actual global voice. current_voice = espeak_GetCurrentVoice(); return result; } int getSizeOfEventStruct_() { return sizeof(espeak_EVENT); } const espeak_VOICE** voices; int samplerate; int rate; int pitch; private: espeak_VOICE* current_voice; }; #include