У меня все еще проблемы с FLite TTS. После встраивания его в свой проект (c ++ в Ubuntu 16.04) я не могу загрузить голос для преобразования TTS. Я пробовал три способа инициализировать нужный голос, но безуспешно.

Сначала я попробовал "register_cmu_us_kal" из примера документации, но он содержит много ошибок сборки и даже не компилируется, так как не может найти некоторые внутренние функции.

Позже попробовал "flite_voice_select" только для того, чтобы получить сбой во время выполнения (затем выяснилось, что голос не был возвращен, потому что список голосовых сообщений пуст, я должен его заполнить? Разве метод init не должен этого делать?)

Наконец-то я устал от "flite_voice_load" и получил какой-то намек на то, что идет не так, но он не работает.

Используя вызов flite_voice_load, я получаю следующий результат:

2020-09-08T12:54:55.099821  DEBUG   TTSFliteManager::TTSTranslate()
Error load voice: lang/lex eng not supported in this binary
2020-09-08T12:55:01.588762  DEBUG   TTSFliteManager::TTSTranslate() voice list = 0
2020-09-08T12:55:01.588814  ERROR   TTSFliteManager::TTSTranslate() NO VOICE SELECTED 0

Если я правильно понял, он находит файл voice.flitevox, но не хватает чего-то еще, языка? лексикон? Понятия не имею, тем более, что я использую только голоса, предоставленные самим FLtie, так что я думаю, что они молодцы. Глядя на сигнатуры функций, я понимаю, что я не могу использовать «flite_add_voice» или «flite_add_lang» до тех пор, пока у меня не будет загружен голос, так какой еще инструкции мне не хватает, чтобы фактически загрузить голосовой файл в мое приложение, чтобы выполнить преобразование?

extern "C" {
cst_voice *register_cmu_us_kal(const char*);
}     
...
bool
TTSFliteManager::TTSTranslate(std::string text, std::string destination)
{
    ADD_LOG_DEBUG << "TTSFliteManager::TTSTranslate()";
    cst_voice *voice;
    flite_init();
//    std::string voiceName = "file:///home/user/download/cmu_us_aew.flitevox";
    std::string voiceName = "http://festvox.org/flite/packed/flite-2.0/voices/cmu_us_rxr.flitevox";

    voice = flite_voice_load(voiceName.c_str());
//    voice = flite_voice_select(voiceName.c_str());
//    voice = register_cmu_us_kal(NULL);
    
    
    ADD_LOG_DEBUG << "TTSFliteManager::TTSTranslate() voice list = " << flite_voice_list ;
    
    if(voice == nullptr)
    {
        ADD_LOG_ERROR << "TTSFliteManager::TTSTranslate() NO VOICE SELECTED " << voice;
        return false;
    }
    ADD_LOG_DEBUG << "TTSFliteManager::TTSTranslate() ready to convert text '" << text.c_str() << "' to destination '" << destination.c_str() << "' with voice '" << voice << "'";
    float secs = flite_text_to_speech(text.c_str(),voice,destination.c_str());
    if (secs == 0)
    {
        ADD_LOG_ERROR << "TTSFliteManager::TTSTranslate() ERROR GENERATED AUDIO FILE IS EMPTY";
        return false;
    }
    return true;
    
}

Что меня особенно сбивает с толку и расстраивает, так это то, что из командной строки он работает отлично, поэтому на самом деле он просто не видит этого. Следующая команда произвела отлично слышимый файл:

flite -voice file:///home/user/download/cmu_us_aew.flitevox -f /home/user/download/flite-2.0.0-release/doc/intro.txt -o intro.wav
-1
progywannabe 8 Сен 2020 в 16:56

1 ответ

Лучший ответ

Вопреки ерунде ALX23z, вот решение (возможно, на самом деле чтение документации и попытка реализовать решение было бы более полезным вместо этого):

extern "C" {
cst_voice *register_cmu_us_rms(const char *voxdir);
void unregister_cmu_us_rms(cst_voice *v);
void usenglish_init(cst_voice *v);
cst_lexicon *cmulex_init(void);
}
    
bool
TTSFliteManager::TTSTranslate(std::string text, std::string destination)
{
    ADD_LOG_DEBUG << "TTSFliteManager::TTSTranslate()";
    cst_voice *voice;
    flite_init();
    std::string voiceName = "/home/user/download/cmu_us_rms.flitevox";
//    std::string voiceName = "http://festvox.org/flite/packed/flite-2.0/voices/cmu_us_rms.flitevox";
    flite_add_lang("eng",usenglish_init,cmulex_init);
    flite_add_lang("usenglish",usenglish_init,cmulex_init);

    voice = flite_voice_load(voiceName.c_str());    
    if(voice == nullptr)
    {
        ADD_LOG_ERROR << "TTSFliteManager::TTSTranslate() NO VOICE SELECTED " << voice;
        return false;
    }
    ADD_LOG_DEBUG << "TTSFliteManager::TTSTranslate() ready to convert text '" << text.c_str() << "' to destination '" << destination.c_str() << "' with voice '" << voice << "'";
    float secs = flite_text_to_speech(text.c_str(),voice,destination.c_str());
    if (secs == 0)
    {
        ADD_LOG_ERROR << "TTSFliteManager::TTSTranslate() ERROR GENERATED AUDIO FILE IS EMPTY";
        return false;
    }
    return true;
}

Обратите внимание, что он отлично работает с локальным файлом И удаленным файлом, просто раскомментируйте второе объявление "std :: string voiceName" (и удалите первое), чтобы библиотека загрузила голос из онлайн-репозитория, я выбрал локальный файл для очевидного причины производительности.

0
progywannabe 17 Сен 2020 в 10:23