Fixes: #1547 - Implement building and testing with cmake - Download libsonic from repository (when enabled and not available as system library), ref: #650 - Migrate android native build to cmake - Migrate CI to cmake - Add windows CI TODO (might be done in separate PR): - Building as [cmake external project](https://cmake.org/cmake/help/latest/module/ExternalProject.html) - Building for package managers (deb, rpm, ...) - Strip out `vcproj` - _to be discussed_ - Strip out `autotools` after next release - Update build documentation for `cmake`master
| config: [debug, release] | config: [debug, release] | ||||
| include: | include: | ||||
| - config: debug | - config: debug | ||||
| target: assembleDebug | |||||
| apkname: espeak-debug.apk | apkname: espeak-debug.apk | ||||
| - config: release | - config: release | ||||
| target: assembleRelease | |||||
| apkname: espeak-release-unsigned.apk | apkname: espeak-release-unsigned.apk | ||||
| name: Build ${{ matrix.config }} APK | name: Build ${{ matrix.config }} APK | ||||
| steps: | steps: | ||||
| - uses: actions/checkout@v3 | - uses: actions/checkout@v3 | ||||
| - name: autoconf | |||||
| run: ./autogen.sh ; chmod -x INSTALL m4/*.m4 | |||||
| - name: configure | |||||
| run: ./configure --with-gradle=$(pwd)/android/gradlew | |||||
| - name: make | - name: make | ||||
| run: make apk-${{ matrix.config }} | |||||
| run: cd android ; ./gradlew ${{ matrix.target }} | |||||
| - name: upload | - name: upload | ||||
| uses: actions/upload-artifact@v3 | uses: actions/upload-artifact@v3 | ||||
| with: | with: |
| - sanitizer: "memory" | - sanitizer: "memory" | ||||
| configenv: "CC=clang CXX=clang++" | configenv: "CC=clang CXX=clang++" | ||||
| sanitizer_cflags: "-fsanitize=memory -fsanitize-memory-track-origins=2" | sanitizer_cflags: "-fsanitize=memory -fsanitize-memory-track-origins=2" | ||||
| config: "--without-pcaudiolib --without-sonic" | |||||
| config: "-DUSE_LIBPCAUDIO:BOOL=OFF -DUSE_LIBSONIC:BOOL=OFF" | |||||
| sanitize_env: "MSAN_OPTIONS=exitcode=42" | sanitize_env: "MSAN_OPTIONS=exitcode=42" | ||||
| - sanitizer: "thread" | - sanitizer: "thread" | ||||
| sanitize_env: "UBSAN_OPTIONS=halt_on_error=1" | sanitize_env: "UBSAN_OPTIONS=halt_on_error=1" | ||||
| - sanitizer: "valgrind" | - sanitizer: "valgrind" | ||||
| sanitize_env: 'VALGRIND="libtool --mode=execute valgrind --track-origins=yes --leak-check=full --error-exitcode=1"' | |||||
| sanitize_env: 'VALGRIND="valgrind --track-origins=yes --leak-check=full --error-exitcode=1"' | |||||
| exclude: | exclude: | ||||
| - os: macos | - os: macos | ||||
| sudo apt-get install ronn kramdown python3 | sudo apt-get install ronn kramdown python3 | ||||
| - name: apt-arch-deps | - name: apt-arch-deps | ||||
| if: matrix.os == 'ubuntu' && matrix.cross == 'no' | if: matrix.os == 'ubuntu' && matrix.cross == 'no' | ||||
| run: "sudo apt-get install libtool-bin valgrind g++-12-multilib linux-libc-dev:${{ matrix.arch }} libpcaudio-dev:${{ matrix.arch }} libsonic-dev:${{ matrix.arch }} libstdc++-12-dev:${{ matrix.arch }} libc6-dbg:${{ matrix.arch }}" | |||||
| run: "sudo apt-get install cmake valgrind g++-12-multilib linux-libc-dev:${{ matrix.arch }} libpcaudio-dev:${{ matrix.arch }} libsonic-dev:${{ matrix.arch }} libstdc++-12-dev:${{ matrix.arch }} libc6-dbg:${{ matrix.arch }}" | |||||
| - name: apt-cross-deps | - name: apt-cross-deps | ||||
| if: matrix.cross == 'yes' | if: matrix.cross == 'yes' | ||||
| run: sudo apt-get install qemu-user g++-12-${{ matrix.arch }}-${{ matrix.sys }} | run: sudo apt-get install qemu-user g++-12-${{ matrix.arch }}-${{ matrix.sys }} | ||||
| # MacOS - dependencies | # MacOS - dependencies | ||||
| - name: brew-deps | - name: brew-deps | ||||
| if: matrix.os == 'macos' | if: matrix.os == 'macos' | ||||
| run: brew install libtool automake ronn OJFord/homebrew-formulae/kramdown && | |||||
| brew install --HEAD anarchivist/espeak-ng/waywardgeek-sonic | |||||
| run: brew install cmake ronn OJFord/homebrew-formulae/kramdown | |||||
| - name: brew-compile-deps | - name: brew-compile-deps | ||||
| if: matrix.os == 'macos' && matrix.compiler == 'gcc' | if: matrix.os == 'macos' && matrix.compiler == 'gcc' | ||||
| run: brew install gcc@12 | run: brew install gcc@12 | ||||
| - uses: actions/checkout@v3 | - uses: actions/checkout@v3 | ||||
| # Configure | # Configure | ||||
| - name: autoconf | |||||
| run: | | |||||
| ./autogen.sh | |||||
| chmod -x INSTALL m4/*.m4 | |||||
| - name: configure | - name: configure | ||||
| run: | | run: | | ||||
| [ 'x${{ matrix.compiler }}' = 'xgcc' ] && export CC="${{ matrix.ccarch }}-${{ matrix.sys }}-gcc-12" | [ 'x${{ matrix.compiler }}' = 'xgcc' ] && export CC="${{ matrix.ccarch }}-${{ matrix.sys }}-gcc-12" | ||||
| [ 'x${{ matrix.cross }}' = 'xyes' ] && export LD="${{ matrix.ccarch }}-${{ matrix.sys }}-ld" | [ 'x${{ matrix.cross }}' = 'xyes' ] && export LD="${{ matrix.ccarch }}-${{ matrix.sys }}-ld" | ||||
| export CFLAGS="-g -Og -fno-omit-frame-pointer ${{ matrix.compiler_flags }} ${{ matrix.sanitizer_cflags }} ${{ matrix.archcflags }}" | export CFLAGS="-g -Og -fno-omit-frame-pointer ${{ matrix.compiler_flags }} ${{ matrix.sanitizer_cflags }} ${{ matrix.archcflags }}" | ||||
| export CXXFLAGS="-g -Og -fno-omit-frame-pointer ${{ matrix.compiler_flags }} ${{ matrix.sanitizer_cflags }} ${{ matrix.archcflags }}" | export CXXFLAGS="-g -Og -fno-omit-frame-pointer ${{ matrix.compiler_flags }} ${{ matrix.sanitizer_cflags }} ${{ matrix.archcflags }}" | ||||
| ./configure --host=${{ matrix.arch }}-${{ matrix.sys }} ${{ matrix.config }} | |||||
| cmake -Bbuild ${{ matrix.config }} -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.arch }} -DUSE_ASYNC:BOOL=OFF | |||||
| - name: config-failed-upload | - name: config-failed-upload | ||||
| if: ${{ failure() }} | if: ${{ failure() }} | ||||
| uses: actions/upload-artifact@v3 | uses: actions/upload-artifact@v3 | ||||
| with: | with: | ||||
| name: config-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.compiler }}-${{ matrix.sanitizer }}.log | |||||
| path: config.log | |||||
| name: cmake-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.compiler }}-${{ matrix.sanitizer }}-builddir | |||||
| path: build | |||||
| # Build and test | # Build and test | ||||
| - name: make-binary | - name: make-binary | ||||
| run: make src/speak-ng src/espeak-ng | |||||
| run: cmake --build build --target espeak-ng | |||||
| - name: make-data | - name: make-data | ||||
| run: ${{ matrix.sanitize_env }} ${{ matrix.runenv }} make all-am | |||||
| run: ${{ matrix.sanitize_env }} ${{ matrix.runenv }} cmake --build build --target data | |||||
| - name: test | - name: test | ||||
| run: ${{ matrix.sanitize_env }} ${{ matrix.runenv }} make check | |||||
| run: | | |||||
| ${{ matrix.sanitize_env }} ${{ matrix.runenv }} cmake --build build --target tests | |||||
| ${{ matrix.sanitize_env }} ${{ matrix.runenv }} ctest --test-dir build -Ttest -j1 --output-on-failure |
| branches: [ master ] | branches: [ master ] | ||||
| env: | env: | ||||
| deps: libpcaudio-dev libsonic-dev ronn kramdown python3 | |||||
| deps: cmake libpcaudio-dev libsonic-dev ronn kramdown python3 | |||||
| jobs: | jobs: | ||||
| if: matrix.arch == 'x86-32' | if: matrix.arch == 'x86-32' | ||||
| - name: dependencies | - name: dependencies | ||||
| run: sudo apt-get update && sudo apt-get install ${{ env.deps }} reprotest ${{ matrix.archdeps }} | run: sudo apt-get update && sudo apt-get install ${{ env.deps }} reprotest ${{ matrix.archdeps }} | ||||
| - name: autoconf | |||||
| run: ./autogen.sh ; chmod -x INSTALL m4/*.m4 | |||||
| - name: run | - name: run | ||||
| run: reprotest 'CFLAGS="${{ matrix.archconfigflags }}" CXXFLAGS="${{ matrix.archconfigflags }}" ./configure --without-gradle && make clean && make && make check && touch success' success | |||||
| run: reprotest 'CFLAGS="${{ matrix.archconfigflags }}" CXXFLAGS="${{ matrix.archconfigflags }}" rm -rf build && cmake -Bbuild -DUSE_ASYNC:BOOL=OFF && cmake --build build && ctest --test-dir build -Ttest -j1 --output-on-failure && touch success' success | |||||
| distcheck: | distcheck: | ||||
| - uses: actions/checkout@v3 | - uses: actions/checkout@v3 | ||||
| - name: dependencies | - name: dependencies | ||||
| run: sudo apt-get update && sudo apt-get install ${{ env.deps }} | run: sudo apt-get update && sudo apt-get install ${{ env.deps }} | ||||
| - name: autoconf | |||||
| run: ./autogen.sh ; chmod -x INSTALL m4/*.m4 | |||||
| - name: configure | - name: configure | ||||
| run: ./configure | |||||
| run: cmake -Bbuild -DUSE_ASYNC:BOOL=OFF | |||||
| - name: make | - name: make | ||||
| run: make | |||||
| run: cmake --build build | |||||
| - name: make check | - name: make check | ||||
| run: make check | |||||
| - name: make dist | |||||
| run: make dist | |||||
| run: ctest --test-dir build -Ttest -j1 --output-on-failure | |||||
| - name: make package_source | |||||
| run: cmake --build build --target package_source | |||||
| - name: unpack | - name: unpack | ||||
| run: mkdir unpack && tar -C unpack -xf *.tar.gz | |||||
| run: mkdir unpack && tar -C unpack -xf build/espeak-ng-*-Source.tar.bz2 | |||||
| - name: re-configure | - name: re-configure | ||||
| run: cd unpack/espeak-ng-* && ./configure | |||||
| run: cd unpack/espeak-ng-* && cmake -Bbuild -DUSE_ASYNC:BOOL=OFF | |||||
| - name: re-make | - name: re-make | ||||
| run: cd unpack/espeak-ng-* && make | |||||
| run: cd unpack/espeak-ng-* && cmake --build build | |||||
| - name: re-make check | - name: re-make check | ||||
| run: cd unpack/espeak-ng-* && make check | |||||
| run: cd unpack/espeak-ng-* && ctest --test-dir build -Ttest -j1 --output-on-failure |
| name: Windows | |||||
| on: | |||||
| workflow_dispatch: | |||||
| push: | |||||
| branches: [ master ] | |||||
| pull_request: | |||||
| branches: [ master ] | |||||
| jobs: | |||||
| build: | |||||
| runs-on: windows-latest | |||||
| name: build | |||||
| steps: | |||||
| - uses: actions/checkout@v3 | |||||
| - name: configure | |||||
| run: cmake -Bbuild -DUSE_ASYNC:BOOL=OFF | |||||
| - name: make | |||||
| run: cmake --build build | |||||
| - name: make check | |||||
| run: ctest --test-dir build -Ttest -C Debug -j1 --output-on-failure |
| cmake_minimum_required(VERSION 3.8) | |||||
| project(espeak-ng | |||||
| VERSION 1.52.0.1 | |||||
| DESCRIPTION "open source speech synthesizer that supports more than hundred languages and accents" | |||||
| HOMEPAGE_URL "https://github.com/espeak-ng/espeak-ng" | |||||
| ) | |||||
| include(CTest) | |||||
| include(cmake/deps.cmake) | |||||
| include(cmake/config.cmake) | |||||
| add_subdirectory(src) | |||||
| include(cmake/data.cmake) | |||||
| include(cmake/package.cmake) | |||||
| include(CPack) | |||||
| include(CTest) | |||||
| add_subdirectory(tests) | |||||
| option(BUILD_SHARED_LIBS "Build shared libraries" OFF) | |||||
| message(STATUS "Configuration:") | |||||
| message(STATUS " shared: ${BUILD_SHARED_LIBS}") | |||||
| message(STATUS " mbrola: ${USE_MBROLA} (${MBROLA_BIN})") | |||||
| message(STATUS " libsonic: ${USE_LIBSONIC} (${SONIC_LIB} ${SONIC_INC})") | |||||
| message(STATUS " libpcaudio: ${USE_LIBPCAUDIO} (${PCAUDIO_LIB} ${PCAUDIO_INC})") | |||||
| message(STATUS " klatt: ${USE_KLATT}") | |||||
| message(STATUS " speech-player: ${USE_SPEECHPLAYER}") | |||||
| message(STATUS " async: ${USE_ASYNC}") |
| androidTestImplementation 'org.hamcrest:hamcrest-all:1.3' | androidTestImplementation 'org.hamcrest:hamcrest-all:1.3' | ||||
| } | } | ||||
| android { | |||||
| compileSdk 33 | |||||
| ndkVersion "25.1.8937393" | |||||
| namespace "com.reecedunn.espeak" | |||||
| defaultConfig { | |||||
| minSdk 19 | |||||
| targetSdk 33 | |||||
| versionCode 22 | |||||
| versionName "1.52-dev" | |||||
| externalNativeBuild { | |||||
| cmake { | |||||
| arguments "-DUSE_ASYNC:BOOL=OFF", "-DUSE_MBROLA:BOOL=OFF" | |||||
| targets "ttsespeak", "espeak-data" | |||||
| } | |||||
| } | |||||
| } | |||||
| externalNativeBuild { | |||||
| cmake { | |||||
| path "jni/CMakeLists.txt" | |||||
| version "3.22.1" | |||||
| } | |||||
| } | |||||
| sourceSets { | |||||
| main { | |||||
| manifest.srcFile 'AndroidManifest.xml' | |||||
| java.srcDirs = ['src'] | |||||
| res.srcDirs = ['res'] | |||||
| } | |||||
| androidTest.setRoot('eSpeakTests') | |||||
| androidTest { | |||||
| java.srcDirs = ['eSpeakTests/src'] | |||||
| } | |||||
| } | |||||
| lint { | |||||
| abortOnError false | |||||
| } | |||||
| } | |||||
| tasks.register('checkData') { | tasks.register('checkData') { | ||||
| doFirst { | doFirst { | ||||
| assert file("../espeak-ng-data/en_dict").exists() | assert file("../espeak-ng-data/en_dict").exists() | ||||
| } | } | ||||
| tasks.register('createDataArchive', Zip) { | tasks.register('createDataArchive', Zip) { | ||||
| dependsOn tasks.checkData | |||||
| preserveFileTimestamps = false | preserveFileTimestamps = false | ||||
| reproducibleFileOrder = true | reproducibleFileOrder = true | ||||
| archiveFileName = "espeakdata.zip" | archiveFileName = "espeakdata.zip" | ||||
| destinationDirectory = file("res/raw") | destinationDirectory = file("res/raw") | ||||
| from("../espeak-ng-data/") { | |||||
| from("build/generated/espeak-ng-data/") { | |||||
| into "espeak-ng-data" | into "espeak-ng-data" | ||||
| } | } | ||||
| } | } | ||||
| rename { return 'espeakdata_version' } | rename { return 'espeakdata_version' } | ||||
| into file("./res/raw") | into file("./res/raw") | ||||
| } | } | ||||
| preBuild.dependsOn createDataVersion | |||||
| android { | |||||
| compileSdk 33 | |||||
| ndkVersion "25.1.8937393" | |||||
| namespace "com.reecedunn.espeak" | |||||
| defaultConfig { | |||||
| minSdk 19 | |||||
| targetSdk 30 | |||||
| versionCode 22 | |||||
| versionName "1.52-dev" | |||||
| } | |||||
| externalNativeBuild { | |||||
| ndkBuild { | |||||
| path "jni/Android.mk" | |||||
| } | |||||
| } | |||||
| sourceSets { | |||||
| main { | |||||
| manifest.srcFile 'AndroidManifest.xml' | |||||
| java.srcDirs = ['src'] | |||||
| res.srcDirs = ['res'] | |||||
| } | |||||
| androidTest.setRoot('eSpeakTests') | |||||
| androidTest { | |||||
| java.srcDirs = ['eSpeakTests/src'] | |||||
| } | |||||
| } | |||||
| lint { | |||||
| abortOnError false | |||||
| } | |||||
| project.afterEvaluate { | |||||
| tasks.checkData.dependsOn(externalNativeBuildDebug) | |||||
| tasks.createDataArchive.dependsOn(externalNativeBuildDebug) | |||||
| javaPreCompileDebug.dependsOn(tasks.createDataVersion) | |||||
| javaPreCompileRelease.dependsOn(tasks.createDataVersion) | |||||
| } | } |
| LOCAL_PATH:= $(call my-dir) | |||||
| include $(CLEAR_VARS) | |||||
| #LOCAL_CFLAGS = -std=c11 # speechplayer is c++ code | |||||
| # ucd-tools wide-character compatibility support: | |||||
| UCDTOOLS_SRC_PATH := ../../src/ucd-tools/src | |||||
| UCDTOOLS_SRC_FILES := \ | |||||
| $(subst $(LOCAL_PATH)/$(UCDTOOLS_SRC_PATH),$(UCDTOOLS_SRC_PATH),$(wildcard $(LOCAL_PATH)/$(UCDTOOLS_SRC_PATH)/*.c*)) | |||||
| LOCAL_SRC_FILES += $(UCDTOOLS_SRC_FILES) | |||||
| SPEECHPLAYER_SRC_FILES := \ | |||||
| ../../src/speechPlayer/src/frame.cpp \ | |||||
| ../../src/speechPlayer/src/speechPlayer.cpp \ | |||||
| ../../src/speechPlayer/src/speechWaveGenerator.cpp | |||||
| LOCAL_SRC_FILES += $(SPEECHPLAYER_SRC_FILES) | |||||
| ESPEAK_SOURCES := \ | |||||
| src/libespeak-ng/common.c \ | |||||
| src/libespeak-ng/compiledata.c \ | |||||
| src/libespeak-ng/compiledict.c \ | |||||
| src/libespeak-ng/compilembrola.c \ | |||||
| src/libespeak-ng/dictionary.c \ | |||||
| src/libespeak-ng/encoding.c \ | |||||
| src/libespeak-ng/error.c \ | |||||
| src/libespeak-ng/espeak_api.c \ | |||||
| src/libespeak-ng/ieee80.c \ | |||||
| src/libespeak-ng/intonation.c \ | |||||
| src/libespeak-ng/klatt.c \ | |||||
| src/libespeak-ng/langopts.c \ | |||||
| src/libespeak-ng/mnemonics.c \ | |||||
| src/libespeak-ng/numbers.c \ | |||||
| src/libespeak-ng/phoneme.c \ | |||||
| src/libespeak-ng/phonemelist.c \ | |||||
| src/libespeak-ng/readclause.c \ | |||||
| src/libespeak-ng/setlengths.c \ | |||||
| src/libespeak-ng/soundicon.c \ | |||||
| src/libespeak-ng/spect.c \ | |||||
| src/libespeak-ng/speech.c \ | |||||
| src/libespeak-ng/sPlayer.c \ | |||||
| src/libespeak-ng/ssml.c \ | |||||
| src/libespeak-ng/synthdata.c \ | |||||
| src/libespeak-ng/synthesize.c \ | |||||
| src/libespeak-ng/synth_mbrola.c \ | |||||
| src/libespeak-ng/translate.c \ | |||||
| src/libespeak-ng/translateword.c \ | |||||
| src/libespeak-ng/tr_languages.c \ | |||||
| src/libespeak-ng/voices.c \ | |||||
| src/libespeak-ng/wavegen.c | |||||
| ESPEAK_SRC_PATH := ../../src | |||||
| ESPEAK_SRC_FILES := \ | |||||
| $(subst src/,$(ESPEAK_SRC_PATH)/,$(ESPEAK_SOURCES)) | |||||
| LOCAL_CFLAGS += -DINCLUDE_KLATT -DINCLUDE_SPEECHPLAYER -DINCLUDE_SONIC -DHAVE_ENDIAN_H | |||||
| LOCAL_SRC_FILES += \ | |||||
| $(filter-out $(BLACKLIST_SRC_FILES),$(ESPEAK_SRC_FILES)) | |||||
| # JNI | |||||
| LOCAL_SRC_FILES += \ | |||||
| $(subst $(LOCAL_PATH)/jni,jni,$(wildcard $(LOCAL_PATH)/jni/*.c)) | |||||
| # Common | |||||
| LOCAL_C_INCLUDES += \ | |||||
| $(LOCAL_PATH)/include \ | |||||
| $(LOCAL_PATH)/$(UCDTOOLS_SRC_PATH)/include \ | |||||
| $(LOCAL_PATH)/../../src/speechPlayer/include \ | |||||
| $(LOCAL_PATH)/$(ESPEAK_SRC_PATH)/include \ | |||||
| $(LOCAL_PATH)/$(ESPEAK_SRC_PATH)/include/compat | |||||
| LOCAL_LDLIBS := \ | |||||
| -llog | |||||
| LOCAL_MODULE := libttsespeak | |||||
| LOCAL_MODULE_TAGS := optional | |||||
| LOCAL_PRELINK_MODULE := false | |||||
| include $(BUILD_SHARED_LIBRARY) |
| cmake_minimum_required(VERSION 3.8) | |||||
| project(espeak-android) | |||||
| add_subdirectory(../../ espeakng) | |||||
| add_custom_target( | |||||
| espeak-data | |||||
| COMMAND ${CMAKE_COMMAND} -B${CMAKE_CURRENT_BINARY_DIR}/../espeak-data ${CMAKE_CURRENT_SOURCE_DIR}/../../ | |||||
| COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/../espeak-data --target data | |||||
| COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/../espeak-data/espeak-ng-data ${CMAKE_SOURCE_DIR}/../build/generated/espeak-ng-data | |||||
| ) | |||||
| message(STATUS "Data: ${CMAKE_CURRENT_SOURCE_DIR}") | |||||
| find_library(A_LOG log) | |||||
| add_library(ttsespeak SHARED | |||||
| jni/eSpeakService.c | |||||
| ) | |||||
| target_include_directories(ttsespeak PRIVATE | |||||
| include | |||||
| ) | |||||
| target_link_libraries(ttsespeak PRIVATE | |||||
| espeak-ng ${A_LOG} | |||||
| ) |
| #include <unistd.h> | #include <unistd.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <stdbool.h> | #include <stdbool.h> | ||||
| #include <string.h> | |||||
| #include <jni.h> | #include <jni.h> | ||||
| #include <espeak/speak_lib.h> | #include <espeak/speak_lib.h> |
| include(CheckSymbolExists) | |||||
| check_symbol_exists(mkstemp "stdlib.h" HAVE_MKSTEMP) | |||||
| option(USE_MBROLA "Use mbrola for speech synthesis" ${HAVE_MBROLA}) | |||||
| option(USE_LIBSONIC "Use libsonit for faster speech rates" ${HAVE_LIBSONIC}) | |||||
| option(USE_LIBPCAUDIO "Use libPcAudio for sound output" ${HAVE_LIBPCAUDIO}) | |||||
| option(USE_KLATT "Use klatt for speech synthesis" ON) | |||||
| option(USE_SPEECHPLAYER "Use speech-player for speech synthesis" ON) | |||||
| if (HAVE_PTHREAD) | |||||
| option(USE_ASYNC "Support asynchronous speech synthesis" ON) | |||||
| else() | |||||
| set(USE_ASYNC OFF) | |||||
| endif() |
| list(APPEND _dict_compile_list | |||||
| af am an ar as az | |||||
| ba be bg bn bpy bs | |||||
| ca chr cmn cs cv cy | |||||
| da de | |||||
| el en eo es et eu | |||||
| fa fi fr | |||||
| ga gd gn grc gu | |||||
| hak haw he hi hr ht hu hy | |||||
| ia id io is it | |||||
| ja jbo | |||||
| ka kk kl kn kok ko ku ky | |||||
| la lb lfn lt lv | |||||
| mi mk ml mr ms mto mt my | |||||
| nci ne nl nog no | |||||
| om or | |||||
| pap pa piqd pl pt py | |||||
| qdb quc qu qya | |||||
| ro ru | |||||
| sd shn si sjn sk sl smj sq sr sv sw | |||||
| ta te th tk tn tr tt | |||||
| ug uk ur uz | |||||
| vi | |||||
| yue | |||||
| ) | |||||
| list(APPEND _mbrola_lang_list | |||||
| af1 ar1 ar2 | |||||
| ca cmn cr1 cs | |||||
| de2 de4 de6 de8 | |||||
| ee1 en1 es es3 es4 | |||||
| fr | |||||
| gr1 gr2 grc-de6 | |||||
| he hn1 hu1 | |||||
| ic1 id1 in ir1 it1 it3 | |||||
| jp | |||||
| la1 lt | |||||
| ma1 mx1 mx2 | |||||
| nl nz1 | |||||
| pl1 pt1 ptbr ptbr4 | |||||
| ro1 | |||||
| sv sv2 | |||||
| tl1 tr1 | |||||
| us us3 | |||||
| vz | |||||
| ) | |||||
| set(DATA_DIST_ROOT ${CMAKE_CURRENT_BINARY_DIR}) | |||||
| set(DATA_DIST_DIR ${DATA_DIST_ROOT}/espeak-ng-data) | |||||
| set(PHONEME_TMP_DIR ${DATA_DIST_ROOT}/phsource) | |||||
| set(DICT_TMP_DIR ${DATA_DIST_ROOT}/dictsource) | |||||
| set(DATA_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/espeak-ng-data) | |||||
| set(PHONEME_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/phsource) | |||||
| set(DICT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dictsource) | |||||
| file(MAKE_DIRECTORY "${DATA_DIST_DIR}") | |||||
| file(MAKE_DIRECTORY "${DICT_TMP_DIR}") | |||||
| file(COPY "${DATA_SRC_DIR}/lang" DESTINATION "${DATA_DIST_DIR}") | |||||
| file(COPY "${DATA_SRC_DIR}/voices/!v" DESTINATION "${DATA_DIST_DIR}/voices") | |||||
| file(COPY "${PHONEME_SRC_DIR}" DESTINATION "${DATA_DIST_ROOT}") | |||||
| set(ESPEAK_RUN_ENV ${CMAKE_COMMAND} -E env "ESPEAK_DATA_PATH=${DATA_DIST_ROOT}") | |||||
| set(ESPEAK_RUN_CMD ${ESPEAK_RUN_ENV} $ENV{VALGRIND} "$<TARGET_FILE:espeak-ng-bin>") | |||||
| add_custom_command( | |||||
| OUTPUT "${DATA_DIST_DIR}/intonations" | |||||
| COMMAND ${ESPEAK_RUN_CMD} --compile-intonations | |||||
| WORKING_DIRECTORY "${PHONEME_SRC_DIR}" | |||||
| COMMENT "Compile intonations" | |||||
| DEPENDS | |||||
| "$<TARGET_FILE:espeak-ng-bin>" | |||||
| "${PHONEME_SRC_DIR}/intonation" | |||||
| ) | |||||
| set(_phon_deps "") | |||||
| function(check_phon_deps _file) | |||||
| set(_file "${PHONEME_SRC_DIR}/${_file}") | |||||
| list(APPEND _phon_deps "${_file}") | |||||
| file(STRINGS "${_file}" _phon_incs REGEX "include .+") | |||||
| list(TRANSFORM _phon_incs REPLACE "^[ \t]*include[ \t]+" "") | |||||
| foreach(_inc ${_phon_incs}) | |||||
| check_phon_deps(${_inc}) | |||||
| endforeach(_inc) | |||||
| set(_phon_deps ${_phon_deps} PARENT_SCOPE) | |||||
| endfunction(check_phon_deps) | |||||
| check_phon_deps("phonemes") | |||||
| add_custom_command( | |||||
| OUTPUT | |||||
| "${DATA_DIST_DIR}/phondata" | |||||
| "${DATA_DIST_DIR}/phondata-manifest" | |||||
| "${DATA_DIST_DIR}/phonindex" | |||||
| "${DATA_DIST_DIR}/phontab" | |||||
| COMMAND ${ESPEAK_RUN_CMD} --compile-phonemes | |||||
| WORKING_DIRECTORY "${PHONEME_SRC_DIR}" | |||||
| COMMENT "Compile phonemes" | |||||
| DEPENDS | |||||
| "$<TARGET_FILE:espeak-ng-bin>" | |||||
| ${_phon_deps} | |||||
| ) | |||||
| list(APPEND _dict_targets) | |||||
| list(APPEND _mbr_targets) | |||||
| foreach(_dict_name ${_dict_compile_list}) | |||||
| set(_dict_target "${DATA_DIST_DIR}/${_dict_name}_dict") | |||||
| set(_dict_deps "") | |||||
| list(APPEND _dict_targets ${_dict_target}) | |||||
| list(APPEND _dict_deps | |||||
| "${DICT_SRC_DIR}/${_dict_name}_rules" | |||||
| "${DICT_SRC_DIR}/${_dict_name}_list" | |||||
| ) | |||||
| if(EXISTS "${DICT_SRC_DIR}/extra/${_dict_name}_listx") | |||||
| option(EXTRA_${_dict_name} "Compile extra ${_dict_name} dictionary" ON) | |||||
| if(EXTRA_${_dict_name}) | |||||
| list(APPEND _dict_deps "${DICT_SRC_DIR}/extra/${_dict_name}_listx") | |||||
| else() | |||||
| file(REMOVE "${DICT_TMP_DIR}/${_dict_name}_listx") | |||||
| endif() | |||||
| elseif(EXISTS "${DICT_SRC_DIR}/${_dict_name}_listx") | |||||
| list(APPEND _dict_deps "${DICT_SRC_DIR}/${_dict_name}_listx") | |||||
| endif() | |||||
| if(EXISTS "${DICT_SRC_DIR}/${_dict_name}_emoji") | |||||
| list(APPEND _dict_deps "${DICT_SRC_DIR}/${_dict_name}_emoji") | |||||
| endif() | |||||
| add_custom_command( | |||||
| OUTPUT "${_dict_target}" | |||||
| COMMAND ${CMAKE_COMMAND} -E copy ${_dict_deps} "${DICT_TMP_DIR}/" | |||||
| COMMAND ${ESPEAK_RUN_CMD} --compile=${_dict_name} | |||||
| WORKING_DIRECTORY "${DICT_TMP_DIR}" | |||||
| DEPENDS | |||||
| "$<TARGET_FILE:espeak-ng-bin>" | |||||
| "${DATA_DIST_DIR}/phondata" | |||||
| "${DATA_DIST_DIR}/intonations" | |||||
| ${_dict_deps} | |||||
| ) | |||||
| endforeach() | |||||
| if (HAVE_MBROLA AND USE_MBROLA) | |||||
| file(COPY "${DATA_SRC_DIR}/voices/mb" DESTINATION "${DATA_DIST_DIR}/voices") | |||||
| file(MAKE_DIRECTORY "${DATA_DIST_DIR}/mbrola_ph") | |||||
| foreach(_mbl ${_mbrola_lang_list}) | |||||
| set(_mbl_src "${PHONEME_SRC_DIR}/mbrola/${_mbl}") | |||||
| set(_mbl_out "${DATA_DIST_DIR}/mbrola_ph/${_mbl}_phtrans") | |||||
| list(APPEND _mbr_targets ${_mbl_out}) | |||||
| add_custom_command( | |||||
| OUTPUT "${_mbl_out}" | |||||
| COMMAND ${ESPEAK_RUN_CMD} --compile-mbrola="${_mbl_src}" | |||||
| DEPENDS "$<TARGET_FILE:espeak-ng-bin>" "${_mbl_src}" | |||||
| ) | |||||
| endforeach(_mbl) | |||||
| endif() | |||||
| add_custom_target( | |||||
| data ALL | |||||
| DEPENDS | |||||
| "${DATA_DIST_DIR}/intonations" | |||||
| "${DATA_DIST_DIR}/phondata" | |||||
| ${_dict_targets} | |||||
| ${_mbr_targets} | |||||
| ) | |||||
| install(DIRECTORY ${DATA_DIST_DIR} DESTINATION share) |
| find_library(SONIC_LIB sonic) | |||||
| find_path(SONIC_INC "sonic.h") | |||||
| find_library(PCAUDIO_LIB pcaudio) | |||||
| find_path(PCAUDIO_INC "pcaudiolib/audio.h") | |||||
| find_library(PTHREAD_LIB pthread) | |||||
| find_program(MBROLA_BIN mbrola) | |||||
| include(FetchContent) | |||||
| if (PTHREAD_LIB) | |||||
| set(HAVE_PTHREAD ON) | |||||
| endif(PTHREAD_LIB) | |||||
| if (MBROLA_BIN) | |||||
| set(HAVE_MBROLA ON) | |||||
| endif(MBROLA_BIN) | |||||
| if (SONIC_LIB AND SONIC_INC) | |||||
| set(HAVE_LIBSONIC ON) | |||||
| else() | |||||
| FetchContent_Declare(sonic-git | |||||
| GIT_REPOSITORY https://github.com/waywardgeek/sonic.git | |||||
| GIT_TAG fbf75c3d6d846bad3bb3d456cbc5d07d9fd8c104 | |||||
| ) | |||||
| FetchContent_MakeAvailable(sonic-git) | |||||
| FetchContent_GetProperties(sonic-git) | |||||
| add_library(sonic OBJECT ${sonic-git_SOURCE_DIR}/sonic.c) | |||||
| target_include_directories(sonic PUBLIC ${sonic-git_SOURCE_DIR}) | |||||
| set(HAVE_LIBSONIC ON) | |||||
| set(SONIC_LIB sonic) | |||||
| set(SONIC_INC ${sonic-git_SOURCE_DIR}) | |||||
| endif() | |||||
| if (PCAUDIO_LIB AND PCAUDIO_INC) | |||||
| set(HAVE_LIBPCAUDIO ON) | |||||
| endif() |
| list(APPEND CPACK_SOURCE_IGNORE_FILES | |||||
| /\.git/ | |||||
| /\.gitignore | |||||
| /\.github/ | |||||
| /\.tx/ | |||||
| /\.travis.yml | |||||
| /_layouts/ | |||||
| /android/ | |||||
| /build/ | |||||
| /chromium_extension/ | |||||
| /data/ | |||||
| /docs/ | |||||
| /emscripten/ | |||||
| /fastlane/ | |||||
| /tools/ | |||||
| /vim/ | |||||
| ) |
| add_library(espeak-include INTERFACE) | |||||
| target_include_directories(espeak-include INTERFACE include include/compat) | |||||
| add_subdirectory(ucd-tools) | |||||
| add_subdirectory(speechPlayer) | |||||
| add_subdirectory(libespeak-ng) | |||||
| add_executable(espeak-ng-bin espeak-ng.c) | |||||
| set_target_properties(espeak-ng-bin PROPERTIES OUTPUT_NAME espeak-ng) | |||||
| target_link_libraries( | |||||
| espeak-ng-bin PRIVATE espeak-ng espeak-ng-config | |||||
| ) | |||||
| if (MSVC) | |||||
| target_sources(espeak-ng-bin PRIVATE compat/getopt.c) | |||||
| endif() | |||||
| if (NOT WIN32) | |||||
| add_custom_target( | |||||
| speak-ng ALL | |||||
| ${CMAKE_COMMAND} -E create_symlink espeak-ng ${CMAKE_CURRENT_BINARY_DIR}/speak-ng | |||||
| COMMENT "Link espeak-ng to speak-ng" | |||||
| DEPENDS espeak-ng-bin | |||||
| ) | |||||
| endif() | |||||
| install(TARGETS espeak-ng-bin) | |||||
| install(DIRECTORY include/espeak include/espeak-ng TYPE INCLUDE) |
| set(ESPEAK_CONFIG_DIR ${CMAKE_CURRENT_BINARY_DIR}/include) | |||||
| set(ESPEAK_CONFIG_H ${ESPEAK_CONFIG_DIR}/config.h) | |||||
| configure_file(config.h.in ${ESPEAK_CONFIG_H}) | |||||
| add_library(espeak-ng-config INTERFACE) | |||||
| target_include_directories(espeak-ng-config INTERFACE ${ESPEAK_CONFIG_DIR}) | |||||
| add_library(espeak-ng | |||||
| common.c | |||||
| mnemonics.c | |||||
| error.c | |||||
| ieee80.c | |||||
| compiledata.c | |||||
| compiledict.c | |||||
| dictionary.c | |||||
| encoding.c | |||||
| intonation.c | |||||
| langopts.c | |||||
| numbers.c | |||||
| phoneme.c | |||||
| phonemelist.c | |||||
| readclause.c | |||||
| setlengths.c | |||||
| soundicon.c | |||||
| spect.c | |||||
| ssml.c | |||||
| synthdata.c | |||||
| synthesize.c | |||||
| tr_languages.c | |||||
| translate.c | |||||
| translateword.c | |||||
| voices.c | |||||
| wavegen.c | |||||
| speech.c | |||||
| espeak_api.c | |||||
| ) | |||||
| if (NOT MSVC) | |||||
| target_compile_options(espeak-ng PRIVATE | |||||
| "-fPIC" | |||||
| "-fvisibility=hidden" | |||||
| "-fno-exceptions" | |||||
| "-fwrapv" | |||||
| "-pedantic" | |||||
| "-Wunused-parameter" | |||||
| "-Wunused" | |||||
| "-Wuninitialized" | |||||
| "-Wreturn-type" | |||||
| "-Wmissing-prototypes" | |||||
| "-Wint-conversion" | |||||
| "-Wimplicit" | |||||
| ) | |||||
| endif() | |||||
| target_compile_definitions(espeak-ng PRIVATE "LIBESPEAK_NG_EXPORT=1") | |||||
| if (NOT BUILD_SHARED_LIBS) | |||||
| target_compile_definitions(espeak-ng INTERFACE "LIBESPEAK_NG_EXPORT=1") | |||||
| endif() | |||||
| if (USE_ASYNC) | |||||
| target_sources(espeak-ng PRIVATE | |||||
| event.c | |||||
| fifo.c | |||||
| espeak_command.c | |||||
| ) | |||||
| endif(USE_ASYNC) | |||||
| if (USE_MBROLA) | |||||
| target_sources(espeak-ng PRIVATE | |||||
| mbrowrap.c | |||||
| compilembrola.c | |||||
| synth_mbrola.c | |||||
| ) | |||||
| endif(USE_MBROLA) | |||||
| if (USE_KLATT) | |||||
| target_sources(espeak-ng PRIVATE klatt.c) | |||||
| endif(USE_KLATT) | |||||
| if (USE_SPEECHPLAYER) | |||||
| target_sources(espeak-ng PRIVATE sPlayer.c) | |||||
| target_link_libraries(espeak-ng PRIVATE speechPlayer) | |||||
| endif(USE_SPEECHPLAYER) | |||||
| if (HAVE_LIBSONIC AND USE_LIBSONIC) | |||||
| target_link_libraries(espeak-ng PRIVATE ${SONIC_LIB}) | |||||
| target_include_directories(espeak-ng PRIVATE ${SONIC_INC}) | |||||
| endif() | |||||
| if (HAVE_LIBPCAUDIO AND USE_LIBPCAUDIO) | |||||
| target_link_libraries(espeak-ng PRIVATE ${PCAUDIO_LIB}) | |||||
| target_include_directories(espeak-ng PRIVATE ${PCAUDIO_INC}) | |||||
| endif() | |||||
| target_link_libraries(espeak-ng PRIVATE espeak-ng-config ucd) | |||||
| if (NOT MSVC) | |||||
| target_link_libraries(espeak-ng PRIVATE m) | |||||
| endif() | |||||
| target_link_libraries(espeak-ng PUBLIC espeak-include) | |||||
| install(TARGETS espeak-ng LIBRARY) |
| #cmakedefine01 HAVE_MKSTEMP | |||||
| #cmakedefine01 USE_ASYNC | |||||
| #cmakedefine01 USE_KLATT | |||||
| #cmakedefine01 USE_LIBPCAUDIO | |||||
| #cmakedefine01 USE_LIBSONIC | |||||
| #cmakedefine01 USE_MBROLA | |||||
| #cmakedefine01 USE_SPEECHPLAYER | |||||
| #define PACKAGE_VERSION "${PROJECT_VERSION}" |
| add_library(speechPlayer STATIC | |||||
| src/frame.cpp | |||||
| src/speechPlayer.cpp | |||||
| src/speechWaveGenerator.cpp | |||||
| ) | |||||
| target_include_directories(speechPlayer PUBLIC include) | |||||
| if(NOT MSVC) | |||||
| target_compile_options(speechPlayer PRIVATE "-fPIC") | |||||
| endif() | |||||
| install(TARGETS speechPlayer ARCHIVE) |
| add_library(ucd STATIC | |||||
| src/case.c | |||||
| src/categories.c | |||||
| src/ctype.c | |||||
| src/proplist.c | |||||
| src/scripts.c | |||||
| src/tostring.c | |||||
| ) | |||||
| target_include_directories(ucd PUBLIC src/include) | |||||
| install(TARGETS ucd ARCHIVE) |
| include(CTest) | |||||
| list(APPEND _binary_tests) | |||||
| macro(compiled_test _test_name) | |||||
| add_executable(test_${_test_name} | |||||
| $<TARGET_OBJECTS:espeak-ng> | |||||
| ${_test_name}.c | |||||
| ) | |||||
| target_link_libraries(test_${_test_name} PRIVATE | |||||
| $<TARGET_PROPERTY:espeak-ng,LINK_LIBRARIES> | |||||
| ) | |||||
| target_include_directories( | |||||
| test_${_test_name} PRIVATE | |||||
| $<TARGET_PROPERTY:espeak-ng,SOURCE_DIR> | |||||
| $<TARGET_PROPERTY:espeak-ng,SOURCE_DIR>/include/compat | |||||
| $<TARGET_PROPERTY:espeak-ng,INTERFACE_INCLUDE_DIRECTORIES> | |||||
| $<TARGET_PROPERTY:espeak-ng-config,INTERFACE_INCLUDE_DIRECTORIES> | |||||
| ) | |||||
| add_dependencies(test_${_test_name} data) | |||||
| add_test( | |||||
| NAME ${_test_name} | |||||
| COMMAND ${ESPEAK_RUN_ENV} $<TARGET_FILE:test_${_test_name}> | |||||
| WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/.. | |||||
| ) | |||||
| list(APPEND _binary_tests test_${_test_name}) | |||||
| endmacro(compiled_test) | |||||
| find_program(SHELL bash) | |||||
| macro(shell_test _test_name) | |||||
| add_test( | |||||
| NAME ${_test_name} | |||||
| COMMAND ${ESPEAK_RUN_ENV} ESPEAK_BIN=$<TARGET_FILE:espeak-ng-bin> ${SHELL} ${CMAKE_CURRENT_SOURCE_DIR}/${_test_name}.test | |||||
| WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/.. | |||||
| ) | |||||
| endmacro(shell_test) | |||||
| compiled_test(api) | |||||
| compiled_test(encoding) | |||||
| compiled_test(ieee80) | |||||
| compiled_test(readclause) | |||||
| if (SHELL AND UNIX) | |||||
| shell_test(bom) | |||||
| shell_test(non-executable-files-with-executable-bit) | |||||
| shell_test(cmd_options) | |||||
| shell_test(dictionary) | |||||
| shell_test(language-numbers-cardinal) | |||||
| shell_test(language-numbers-ordinal) | |||||
| shell_test(language-phonemes) | |||||
| shell_test(language-pronunciation) | |||||
| shell_test(language-replace) | |||||
| shell_test(ssml) | |||||
| shell_test(translate) | |||||
| shell_test(variants) | |||||
| shell_test(voices) | |||||
| # shell_test(windows-data) | |||||
| # shell_test(windows-installer) | |||||
| if (USE_KLATT) | |||||
| shell_test(klatt) | |||||
| endif() | |||||
| if (USE_MBROLA) | |||||
| shell_test(mbrola) | |||||
| endif() | |||||
| endif() | |||||
| add_custom_target(tests DEPENDS ${_binary_tests}) |
| # TODO checking for other encodings (e.g. UTF-16, UTF-32, UTF-7) needs more elaborate search, | # TODO checking for other encodings (e.g. UTF-16, UTF-32, UTF-7) needs more elaborate search, | ||||
| # otherwise it shows many false positives | # otherwise it shows many false positives | ||||
| grep -ErlI $'\xEF\xBB\xBF' * | tee tests/bom.check >/dev/null # UTF-8 | |||||
| cd $(dirname $0)/.. | |||||
| grep -ErlI $'\xEF\xBB\xBF' * | grep -v '^build/' | tee tests/bom.check >/dev/null # UTF-8 | |||||
| if [ -s tests/bom.check ] ; then | if [ -s tests/bom.check ] ; then | ||||
| echo "found:" | echo "found:" | ||||
| echo "none found" | echo "none found" | ||||
| true | true | ||||
| fi | fi | ||||
| # read column 5 (File) of espeak-ng --voices, skip the directory | # read column 5 (File) of espeak-ng --voices, skip the directory | ||||
| echo "checking if all supported languages have phoneme tests ..." | echo "checking if all supported languages have phoneme tests ..." | ||||
| for lang in $(ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} src/espeak-ng --voices | awk '{print $5}' | cut -d "/" -f 2-2 | tail -n+2); | for lang in $(ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} src/espeak-ng --voices | awk '{print $5}' | cut -d "/" -f 2-2 | tail -n+2); | ||||
| do if ! grep -q "test_phwav $lang" tests/language-phonemes.test | |||||
| do if ! grep -q "test_phwav $lang" $0 | |||||
| then | then | ||||
| echo "$lang missing a phoneme test in tests/language-phonemes.test"; | echo "$lang missing a phoneme test in tests/language-phonemes.test"; | ||||
| exit 1; | exit 1; |
| echo -n "testing files for executable bits that shouldn't be executable ... " | echo -n "testing files for executable bits that shouldn't be executable ... " | ||||
| cd $(dirname $0)/.. | |||||
| find * -executable -type f | \ | find * -executable -type f | \ | ||||
| grep -vE "compile|config\.(guess|status|sub)|configure|depcomp|install-sh|libtool|missing" | # Ignore autotools output \ | grep -vE "compile|config\.(guess|status|sub)|configure|depcomp|install-sh|libtool|missing" | # Ignore autotools output \ | ||||
| grep -vE "build" | # Ignore cmake output \ | |||||
| grep -vE ".*\.test|tests/common|src(/\.libs)?/(e?speak-ng|.*\.so\..*)|src/\.libs/lt-espeak-ng|android" | # Ignore built programs and libraries \ | grep -vE ".*\.test|tests/common|src(/\.libs)?/(e?speak-ng|.*\.so\..*)|src/\.libs/lt-espeak-ng|android" | # Ignore built programs and libraries \ | ||||
| grep -vE ".*\.sh|tools/emoji" | # Ignore helper scripts \ | grep -vE ".*\.sh|tools/emoji" | # Ignore helper scripts \ | ||||
| grep -vE "src/ucd-tools/tools/(.*\.py|mkencodingtable)" | # Ignore ucd-tools helper scripts \ | grep -vE "src/ucd-tools/tools/(.*\.py|mkencodingtable)" | # Ignore ucd-tools helper scripts \ | ||||
| echo "none found" | echo "none found" | ||||
| true | true | ||||
| fi | fi | ||||
| diff expected.txt actual.txt || exit 1 | diff expected.txt actual.txt || exit 1 | ||||
| } | } | ||||
| for i in `ls tests/ssml/*.ssml` ; do test_ssml $i; done | |||||
| for i in `ls tests/ssml/*.ssml2` ; do test_ssml $i punct; done | |||||
| for i in `dirname $0`/ssml/*.ssml ; do test_ssml $i; done | |||||
| for i in `dirname $0`/ssml/*.ssml2 ; do test_ssml $i punct; done | |||||
| test_ssml_audio "<prosody>" 88fccb35536158f25f4ae44a03fb005fef95c99b "<speak><prosody rate=\"x-slow\" pitch=\"low\"> Slow and low </prosody><prosody rate=\"x-fast\" pitch=\"x-high\"> Fast and high.</prosody></speak>" | test_ssml_audio "<prosody>" 88fccb35536158f25f4ae44a03fb005fef95c99b "<speak><prosody rate=\"x-slow\" pitch=\"low\"> Slow and low </prosody><prosody rate=\"x-fast\" pitch=\"x-high\"> Fast and high.</prosody></speak>" | ||||
| # #410 is a bug in SSML. Sentence termination causes prosody stack to misfunction. | # #410 is a bug in SSML. Sentence termination causes prosody stack to misfunction. |