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.

외부 라이브러리에 바인딩

모듈

:ref:`doc_custom_modules_in_cpp`의 Summator 예제는 소규모 사용자 정의 모듈에 적합하지만 더 큰 외부 라이브러리를 사용하려면 어떻게 해야 합니까? C++로 작성된 음성 합성(텍스트 음성 변환) 라이브러리인 `Festival <https://www.cstr.ed.ac.uk/projects/festival/>`_을 사용한 예를 살펴보겠습니다.

외부 라이브러리에 바인딩하려면 Summator 예제와 유사한 모듈 디렉터리를 설정합니다.

godot/modules/tts/

다음으로 TTS 클래스를 사용하여 헤더 파일을 만듭니다.

godot/modules/tts/tts.h
#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();
};

그런 다음 cpp 파일을 추가합니다.

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

이전과 마찬가지로 새 클래스를 어떻게든 등록해야 하므로 두 개의 파일을 더 생성해야 합니다.

register_types.h
register_types.cpp

중요

모듈이 제대로 등록되려면 이러한 파일이 모듈의 최상위 폴더(SCsubconfig.py 파일 옆)에 있어야 합니다.

적 씬은 다음 노드들을 사용할 것입니다:

godot/modules/tts/register_types.h
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 */
godot/modules/tts/register_types.cpp
#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.
}

다음으로, 빌드 시스템이 이 모듈을 컴파일할 수 있도록 SCsub 파일을 생성해야 합니다.

godot/modules/tts/SCsub
Import('env')

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

.a 라이브러리 파일을 얻으려면 컴퓨터에 외부 라이브러리를 설치해야 합니다. 운영 체제에서 이 작업을 수행하는 방법에 대한 구체적인 지침은 라이브러리의 공식 문서를 참조하세요. 참고용으로 아래에 Linux용 설치 명령을 포함시켰습니다.

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

중요

Festival에서 사용하는 보이스(및 기타 잠재적인 외부/제3자 리소스)에는 모두 다양한 라이선스와 사용 약관이 있습니다. 페스티벌 라이브러리 자체가 MIT 라이센스와 호환되더라도 그 중 일부(대부분은 아닐지라도)는 Godot에 문제가 있을 수 있습니다. 라이센스 및 이용약관을 반드시 확인하시기 바랍니다.

컴파일러가 소스 파일에 액세스할 수 있도록 하는 동시에 모듈 코드를 자체적으로 유지하려면 외부 라이브러리도 모듈 내부에 설치해야 합니다. Festival 및 speech_tools 라이브러리는 다음 명령을 사용하여 git을 통해 module/tts/ 디렉터리에서 설치할 수 있습니다.

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

외부 저장소 소스 파일을 저장소에 커밋하지 않으려면 아래와 같이 해당 파일을 (modules/tts/ 디렉터리 내에서) 하위 모듈로 추가하여 링크할 수 있습니다.

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

중요

Git 하위 모듈은 Godot 저장소에서 사용되지 않습니다. 기본 Godot 저장소에 병합할 모듈을 개발하는 경우 하위 모듈을 사용하면 안 됩니다. 모듈이 병합되지 않으면 언제든지 외부 라이브러리를 GDExtension으로 구현해 볼 수 있습니다.

컴파일러가 볼 수 있는 포함 디렉터리를 추가하려면 해당 디렉터리를 환경 경로에 추가하면 됩니다.

godot/modules/tts/SCsub
# 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'])

모듈을 빌드할 때 사용자 정의 컴파일러 플래그를 추가하려면 먼저 `env`를 복제해야 합니다. 그러면 해당 플래그가 전체 Godot 빌드에 추가되지 않습니다(이로 인해 오류가 발생할 수 있음). 사용자 정의 플래그가 있는 `SCsub`의 예:

godot/modules/tts/SCsub
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.

최종 스크립트는 다음과 같아야 합니다:

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

모듈 사용

이제 스크립트에서 새로 생성된 모듈을 사용할 수 있습니다.

var t = TTS.new()
var script = "Hello world. This is a test!"
var is_spoken = t.say_text(script)
print('is_spoken: ', is_spoken)

그리고 텍스트를 말하면 출력은 ``is_spoken: True``가 됩니다.