Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Vinculación a bibliotecas externas
Módulos
The Summator example in Módulos personalizados en C++ is great for small, custom modules, but what if you want to use a larger, external library? Let's look at an example using Festival, a speech synthesis (text-to-speech) library written in C++.
Para vincular una biblioteca externa, configura un directorio de módulos similar al ejemplo del Summator:
godot/modules/tts/
Next, you will create a header file with a TTS class:
#pragma once
#include "core/object/ref_counted.h"
class TTS : public RefCounted {
GDCLASS(TTS, RefCounted);
protected:
static void _bind_methods();
public:
bool say_text(String p_txt);
TTS();
};
Y luego agregarás el archivo cpp.
#include "tts.h"
#include <festival.h>
bool TTS::say_text(String p_txt) {
//convert Godot String to Godot CharString to C string
return festival_say_text(p_txt.ascii().get_data());
}
void TTS::_bind_methods() {
ClassDB::bind_method(D_METHOD("say_text", "txt"), &TTS::say_text);
}
TTS::TTS() {
festival_initialize(true, 210000); //not the best way to do it as this should only ever be called once.
}
Al igual que antes, la nueva clase necesita ser registrada de alguna manera, por lo que se deben crear dos archivos más:
register_types.h
register_types.cpp
Importante
Los archivos anteriores deben estar en la carpeta de nivel superior de tu módulo (junto a tus archivos SCsub y config.py) para que el módulo se registre correctamente.
Estos archivos deberán contener lo siguiente:
void initialize_tts_module(ModuleInitializationLevel p_level);
void uninitialize_tts_module(ModuleInitializationLevel p_level);
/* yes, the word in the middle must be the same as the module folder name */
#include "register_types.h"
#include "core/object/class_db.h"
#include "tts.h"
void initialize_tts_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
ClassDB::register_class<TTS>();
}
void uninitialize_tts_module(ModuleInitializationLevel p_level) {
// Nothing to do here in this example.
}
Next, you need to create an SCsub file so the build system compiles
this module:
Import('env')
env_tts = env.Clone()
env_tts.add_source_files(env.modules_sources, "*.cpp") # Add all cpp files to the build
You'll need to install the external library on your machine to get the .a library files. See the library's official documentation for specific instructions on how to do this for your operating system. We've included the installation commands for Linux below, for reference.
sudo apt-get install festival festival-dev # Installs festival and speech_tools libraries
apt-cache search festvox-* # Displays list of voice packages
sudo apt-get install festvox-don festvox-rablpc16k festvox-kallpc16k festvox-kdlpc16k # Installs voices
Importante
Las voces que utiliza Festival (y cualquier otro recurso externo o de terceros potencial) tienen diferentes licencias y términos de uso; algunos (si no la mayoría) de ellos pueden ser problemáticos con Godot, incluso si la propia biblioteca de Festival es compatible con la Licencia MIT. Asegúrate de verificar las licencias y los términos de uso.
La biblioteca externa también deberá ser instalada dentro de tu módulo para que los archivos fuente sean accesibles al compilador, al mismo tiempo que mantienes el código del módulo autocontenido. Las bibliotecas festival y speech_tools se pueden instalar desde el directorio modules/tts/ a través de git utilizando los siguientes comandos:
git clone https://github.com/festvox/festival
git clone https://github.com/festvox/speech_tools
Si no deseas que los archivos fuente del repositorio externo se incluyan en tu propio repositorio, puedes enlazarlos agregándolos como submódulos (desde el directorio modules/tts/), como se muestra a continuación:
git submodule add https://github.com/festvox/festival
git submodule add https://github.com/festvox/speech_tools
Importante
Please note that Git submodules are not used in the Godot repository. If you are developing a module to be merged into the main Godot repository, you should not use submodules. If your module doesn't get merged in, you can always try to implement the external library as a GDExtension.
Puedes agregar directorios de inclusión a las rutas de entorno para que sean vistos por el compilador:
# These paths are relative to /modules/tts/
env_tts.Append(CPPPATH=["speech_tools/include", "festival/src/include"])
# LIBPATH and LIBS need to be set on the real "env" (not the clone)
# to link the specified libraries to the Godot executable.
# This is an absolute path where your .a libraries reside.
# If using a relative path, you must convert it to a
# full path using a utility function, such as `Dir('...').abspath`.
env.Append(LIBPATH=[Dir('libpath').abspath])
# Check with the documentation of the external library to see which library
# files should be included/linked.
env.Append(LIBS=['Festival', 'estools', 'estbase', 'eststring'])
Si deseas agregar banderas personalizadas del compilador al construir tu módulo, primero debes clonar env, para evitar que agregue esas banderas a toda la compilación de Godot (lo que puede causar errores). A continuación, te muestro un ejemplo de SCsub con banderas personalizadas:
Import('env')
env_tts = env.Clone()
env_tts.add_source_files(env.modules_sources, "*.cpp")
# Append CCFLAGS flags for both C and C++ code.
env_tts.Append(CCFLAGS=['-O2'])
# If you need to, you can:
# - Append CFLAGS for C code only.
# - Append CXXFLAGS for C++ code only.
El módulo debería verse así:
godot/modules/tts/festival/
godot/modules/tts/libpath/libestbase.a
godot/modules/tts/libpath/libestools.a
godot/modules/tts/libpath/libeststring.a
godot/modules/tts/libpath/libFestival.a
godot/modules/tts/speech_tools/
godot/modules/tts/config.py
godot/modules/tts/tts.h
godot/modules/tts/tts.cpp
godot/modules/tts/register_types.h
godot/modules/tts/register_types.cpp
godot/modules/tts/SCsub
Usar el módulo
Ahora puedes usar tu módulo recién creado desde cualquier script:
var t = TTS.new()
var script = "Hello world. This is a test!"
var is_spoken = t.say_text(script)
print('is_spoken: ', is_spoken)
Y la salida será is_spoken: True si el texto es hablado.