Liaison à des bibliothèques externes

Modules

L'exemple Summator dans Modules personnalisées en C++ est géniale pour les modules personnalisés de petite taille, mais si vous souhaitez utiliser une bibliothèque externe plus grande ? Regardons un exemple en utilisant Festival, une bibliothèque de synthétisation de parole (text-to-speech) écrite en C++.

Pour lier une bibliothèque externe, configurez un module similaire à l'exemple Summator :

godot/modules/tts/

Ensuite, vous allez créer un fichier d'en-tête avec une simple classe TTS :

/* tts.h */

#ifndef GODOT_TTS_H
#define GODOT_TTS_H

#include "core/reference.h"

class TTS : public Reference {
    GDCLASS(TTS, Reference);

protected:
    static void _bind_methods();

public:
    bool say_text(String p_txt);

    TTS();
};

#endif // GODOT_TTS_H

Et puis vous ajouterez le fichier cpp.

/* tts.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.
}

Tout comme avant, la nouvelle classe doit être enregistrée d'une manière ou d'une autre, deux fichiers supplémentaires doivent être créés :

register_types.h
register_types.cpp

Important

Ces fichiers doivent se trouver dans le dossier de haut niveau de votre module (à côté de vos fichiers SCsub et config.py) pour que le module soit correctement enregistré.

Ces fichiers doivent contenir les éléments suivants :

/* register_types.h */

void register_tts_types();
void unregister_tts_types();
/* yes, the word in the middle must be the same as the module folder name */
/* register_types.cpp */

#include "register_types.h"

#include "core/class_db.h"
#include "tts.h"

void register_tts_types() {
    ClassDB::register_class<TTS>();
}

void unregister_tts_types() {
    // Nothing to do here in this example.
}

Ensuite, vous devez créer un fichier SCsub pour que le système de compilation compile ce module :

# SCsub

Import('env')

env_tts = env.Clone()
env_tts.add_source_files(env.modules_sources, "*.cpp") # Add all cpp files to the build

Vous devrez installer la bibliothèque externe sur votre ordinateur pour obtenir les fichiers bibliothèques .a. Regardez la documentation officielle de la bibliothèque pour des instructions spécifiques sur la façon de procéder pour votre système d'exploitation. Nous avons inclus les commandes d'installation pour Linux ci-dessous, pour référence.

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

Important

Les voix utilisées par Festival (et toute autre ressource potentielle externe ou tierce partie) ont toutes des licences et des conditions d'utilisation variées ; certaines (si ce n'est la plupart) d'entre elles peuvent être problématiques avec Godot, même si la bibliothèque Festival elle-même est sous Licence compatible MIT. Veuillez lire les licences et les conditions d'utilisation.

La bibliothèque externe devra également être installée à l'intérieur de votre module pour rendre les fichiers source accessibles au compilateur, en gardant également le code du module autonome. Les bibliothèques festival et speech_tools peuvent être installés depuis le répertoire modules/tts/ via git en utilisant les commandes suivantes :

git clone https://github.com/festvox/festival
git clone https://github.com/festvox/speech_tools

Si vous ne voulez pas les fichiers source des répertoires externes committés dans votre répertoire, vous pouvez, à la place, les lier en les ajoutant comme sous-modules (depuis les répertoires modules/tts/), comme montré ci-dessous :

git submodule add https://github.com/festvox/festival
git submodule add https://github.com/festvox/speech_tools

Important

Veuillez noter que les sous-modules Git ne sont pas utilisés dans le dépôt Godot. Si vous développez un module à merge dans le dépôt principal de Godot, vous ne devez pas utiliser de sous-modules. Si votre module n'est pas merged, vous pouvez toujours essayer d'implémenter la bibliothèque externe comme un plugin GDNative C++.

Pour ajouter des répertoires d'include à consulter par le compilateur, vous pouvez l'ajouter aux chemins de l'environnement :

# 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 a path relative to /modules/tts/ where your .a libraries reside.
# If you are compiling the module externally (not in the godot source tree),
# these will need to be full paths.
env.Append(LIBPATH=['libpath'])

# 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 vous voulez ajouter des drapeaux de compilation personnalisés lors de la construction de votre module, vous devez d'abord cloner env, afin qu'il n'ajoute pas ces drapeaux à la construction de Godot (ce qui peut causer des erreurs). Exemple SCsub avec des drapeaux personnalisés :

# SCsub

Import('env')

env_tts = env.Clone()
env_tts.add_source_files(env.modules_sources, "*.cpp")
env_tts.Append(CCFLAGS=['-O2']) # Flags for C and C++ code
env_tts.Append(CXXFLAGS=['-std=c++11']) # Flags for C++ code only

Le module final devrait ressembler à cela :

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

Utilisation du module

Vous pouvez maintenant utiliser votre module nouvellement créé à partir de n'importe quel 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)

Et la sortie sera is_spoken: True si le texte est prononcé.