Refactoring: Split code into multiple projects

This commit is contained in:
Daniel Wolf 2016-11-15 21:56:39 +01:00
parent c19ad1c8d0
commit 3e34425c11
65 changed files with 376 additions and 173 deletions

View File

@ -64,26 +64,34 @@ set(Boost_USE_MULTITHREADED ON) # Enable multithreading support
set(Boost_USE_STATIC_RUNTIME ON) # Use static C++ runtime set(Boost_USE_STATIC_RUNTIME ON) # Use static C++ runtime
find_package(Boost 1.54 REQUIRED COMPONENTS filesystem locale system) find_package(Boost 1.54 REQUIRED COMPONENTS filesystem locale system)
include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
link_libraries(${Boost_LIBRARIES}) # Just about every project needs Boost
# ... C++ Format # ... C++ Format
include_directories(SYSTEM "lib/cppformat")
FILE(GLOB cppFormatFiles "lib/cppformat/*.cc") FILE(GLOB cppFormatFiles "lib/cppformat/*.cc")
add_library(cppFormat ${cppFormatFiles}) add_library(cppFormat ${cppFormatFiles})
target_include_directories(cppFormat SYSTEM PUBLIC "lib/cppformat")
target_compile_options(cppFormat PRIVATE ${disableWarningsFlags}) target_compile_options(cppFormat PRIVATE ${disableWarningsFlags})
set_target_properties(cppFormat PROPERTIES FOLDER lib) set_target_properties(cppFormat PROPERTIES FOLDER lib)
# ... sphinxbase # ... sphinxbase
include_directories(SYSTEM "lib/sphinxbase-rev13216/include" "lib/sphinxbase-rev13216/src" "lib/sphinx_config")
FILE(GLOB_RECURSE sphinxbaseFiles "lib/sphinxbase-rev13216/src/libsphinxbase/*.c") FILE(GLOB_RECURSE sphinxbaseFiles "lib/sphinxbase-rev13216/src/libsphinxbase/*.c")
add_library(sphinxbase ${sphinxbaseFiles}) add_library(sphinxbase ${sphinxbaseFiles})
target_include_directories(sphinxbase SYSTEM PUBLIC
"lib/sphinxbase-rev13216/include"
"lib/sphinxbase-rev13216/src"
"lib/sphinx_config"
)
target_compile_options(sphinxbase PRIVATE ${disableWarningsFlags}) target_compile_options(sphinxbase PRIVATE ${disableWarningsFlags})
target_compile_definitions(sphinxbase PUBLIC __SPHINXBASE_EXPORT_H__=1 SPHINXBASE_EXPORT=) # Compile as static lib target_compile_definitions(sphinxbase PUBLIC __SPHINXBASE_EXPORT_H__=1 SPHINXBASE_EXPORT=) # Compile as static lib
set_target_properties(sphinxbase PROPERTIES FOLDER lib) set_target_properties(sphinxbase PROPERTIES FOLDER lib)
# ... PocketSphinx # ... PocketSphinx
include_directories(SYSTEM "lib/pocketsphinx-rev13216/include" "lib/pocketsphinx-rev13216/src/libpocketsphinx")
FILE(GLOB pocketSphinxFiles "lib/pocketsphinx-rev13216/src/libpocketsphinx/*.c") FILE(GLOB pocketSphinxFiles "lib/pocketsphinx-rev13216/src/libpocketsphinx/*.c")
add_library(pocketSphinx ${pocketSphinxFiles}) add_library(pocketSphinx ${pocketSphinxFiles})
target_include_directories(pocketSphinx SYSTEM PUBLIC
"lib/pocketsphinx-rev13216/include"
"lib/pocketsphinx-rev13216/src/libpocketsphinx"
)
target_link_libraries(pocketSphinx sphinxbase) target_link_libraries(pocketSphinx sphinxbase)
target_compile_options(pocketSphinx PRIVATE ${disableWarningsFlags}) target_compile_options(pocketSphinx PRIVATE ${disableWarningsFlags})
target_compile_definitions(pocketSphinx PUBLIC __POCKETSPHINX_EXPORT_H__=1 POCKETSPHINX_EXPORT=) # Compile as static lib target_compile_definitions(pocketSphinx PUBLIC __POCKETSPHINX_EXPORT_H__=1 POCKETSPHINX_EXPORT=) # Compile as static lib
@ -103,7 +111,6 @@ set_target_properties(gtest_main PROPERTIES FOLDER lib)
include_directories(SYSTEM "lib/gsl/include") include_directories(SYSTEM "lib/gsl/include")
# ... WebRTC # ... WebRTC
include_directories(SYSTEM "lib/webrtc-8d2248ff")
set(webRTCFiles set(webRTCFiles
lib/webrtc-8d2248ff/webrtc/common_audio/signal_processing/cross_correlation.c lib/webrtc-8d2248ff/webrtc/common_audio/signal_processing/cross_correlation.c
lib/webrtc-8d2248ff/webrtc/common_audio/signal_processing/division_operations.c lib/webrtc-8d2248ff/webrtc/common_audio/signal_processing/division_operations.c
@ -124,6 +131,7 @@ set(webRTCFiles
lib/webrtc-8d2248ff/webrtc/common_audio/vad/webrtc_vad.c lib/webrtc-8d2248ff/webrtc/common_audio/vad/webrtc_vad.c
) )
add_library(webRTC ${webRTCFiles}) add_library(webRTC ${webRTCFiles})
target_include_directories(webRTC SYSTEM PUBLIC "lib/webrtc-8d2248ff")
target_compile_options(webRTC PRIVATE ${disableWarningsFlags}) target_compile_options(webRTC PRIVATE ${disableWarningsFlags})
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(webRTC PRIVATE -pthread -lpthread) target_compile_options(webRTC PRIVATE -pthread -lpthread)
@ -134,12 +142,11 @@ endif()
set_target_properties(webRTC PROPERTIES FOLDER lib) set_target_properties(webRTC PROPERTIES FOLDER lib)
# ... whereami # ... whereami
include_directories(SYSTEM "lib/whereami/src")
add_library(whereami lib/whereami/src/whereami.c) add_library(whereami lib/whereami/src/whereami.c)
target_include_directories(whereami SYSTEM PUBLIC "lib/whereami/src")
set_target_properties(whereami PROPERTIES FOLDER lib) set_target_properties(whereami PROPERTIES FOLDER lib)
# ... Flite # ... Flite
include_directories("lib/flite-1.4/include" "lib/flite-1.4")
set(fliteFiles set(fliteFiles
lib/flite-1.4/lang/cmulex/cmu_lex.c lib/flite-1.4/lang/cmulex/cmu_lex.c
lib/flite-1.4/lang/cmulex/cmu_lex_data.c lib/flite-1.4/lang/cmulex/cmu_lex_data.c
@ -200,54 +207,184 @@ set(fliteFiles
lib/flite-1.4/src/utils/cst_val_user.c lib/flite-1.4/src/utils/cst_val_user.c
) )
add_library(flite ${fliteFiles}) add_library(flite ${fliteFiles})
target_include_directories(flite SYSTEM PUBLIC
"lib/flite-1.4/include"
"lib/flite-1.4"
)
target_compile_options(flite PRIVATE ${disableWarningsFlags}) target_compile_options(flite PRIVATE ${disableWarningsFlags})
set_target_properties(flite PROPERTIES FOLDER lib) set_target_properties(flite PROPERTIES FOLDER lib)
# Define executable # Define Rhubarb libraries
include_directories("src" "src/audio_input")
configure_file(src/appInfo.cpp.in src/appInfo.cpp ESCAPE_QUOTES) # ... rhubarb-animation
set(SOURCE_FILES add_library(rhubarb-animation
${CMAKE_CURRENT_BINARY_DIR}/src/appInfo.cpp src/animation/mouthAnimation.cpp
src/main.cpp src/animation/mouthAnimation.h
src/Phone.cpp src/Phone.h src/animation/Viseme.cpp
src/Shape.cpp src/Shape.h src/animation/Viseme.h
src/centiseconds.cpp src/centiseconds.h )
src/EnumConverter.h target_include_directories(rhubarb-animation PUBLIC "src/animation")
src/Viseme.cpp src/Viseme.h target_link_libraries(rhubarb-animation
src/mouthAnimation.cpp src/mouthAnimation.h rhubarb-core
src/phoneRecognition.cpp src/phoneRecognition.h rhubarb-logging
src/platformTools.cpp src/platformTools.h rhubarb-time
src/tools.cpp src/tools.h )
src/audio/AudioClip.cpp src/audio/AudioClip.h
src/audio/AudioSegment.cpp src/audio/AudioSegment.h # ... rhubarb-audio
src/audio/DCOffset.cpp src/audio/DCOffset.h add_library(rhubarb-audio
src/audio/SampleRateConverter.cpp src/audio/SampleRateConverter.h src/audio/AudioClip.cpp
src/audio/voiceActivityDetection.cpp src/audio/voiceActivityDetection.h src/audio/AudioClip.h
src/audio/WaveFileReader.cpp src/audio/WaveFileReader.h src/audio/AudioSegment.cpp
src/audio/waveFileWriting.cpp src/audio/waveFileWriting.h src/audio/AudioSegment.h
src/audio/processing.cpp src/audio/processing.h src/audio/DCOffset.cpp
src/stringTools.cpp src/stringTools.h src/audio/DCOffset.h
src/NiceCmdLineOutput.cpp src/NiceCmdLineOutput.h src/audio/ioTools.h
src/TablePrinter.cpp src/TablePrinter.h src/audio/processing.cpp
src/ProgressBar.cpp src/ProgressBar.h src/audio/processing.h
src/logging.cpp src/logging.h src/audio/SampleRateConverter.cpp
src/Timed.h src/audio/SampleRateConverter.h
src/TimeRange.cpp src/TimeRange.h src/audio/voiceActivityDetection.cpp
src/Timeline.h src/audio/voiceActivityDetection.h
src/BoundedTimeline.h src/audio/WaveFileReader.cpp
src/ContinuousTimeline.h src/audio/WaveFileReader.h
src/pairs.h src/audio/waveFileWriting.cpp
src/Exporter.cpp src/Exporter.h src/audio/waveFileWriting.h
src/tokenization.cpp src/tokenization.h )
src/g2p.cpp src/g2p.h target_include_directories(rhubarb-audio PUBLIC "src/audio")
src/languageModels.cpp src/languageModels.h target_link_libraries(rhubarb-audio
src/tupleHash.h webRTC
src/parallel.h rhubarb-logging
src/ObjectPool.h rhubarb-time
src/Lazy.h rhubarb-tools
)
# ... rhubarb-core
configure_file(src/core/appInfo.cpp.in appInfo.cpp ESCAPE_QUOTES)
add_library(rhubarb-core
${CMAKE_CURRENT_BINARY_DIR}/appInfo.cpp
src/core/appInfo.h
src/core/Phone.cpp
src/core/Phone.h
src/core/Shape.cpp
src/core/Shape.h
)
target_include_directories(rhubarb-core PUBLIC "src/core")
target_link_libraries(rhubarb-core
rhubarb-tools
)
# ... rhubarb-exporters
add_library(rhubarb-exporters
src/exporters/Exporter.cpp
src/exporters/Exporter.h
)
target_include_directories(rhubarb-exporters PUBLIC "src/exporters")
target_link_libraries(rhubarb-exporters
rhubarb-core
rhubarb-time
)
# ... rhubarb-lib
add_library(rhubarb-lib
src/lib/rhubarbLib.cpp
src/lib/rhubarbLib.h
)
target_include_directories(rhubarb-lib PUBLIC "src/lib")
target_link_libraries(rhubarb-lib
rhubarb-animation
rhubarb-audio
rhubarb-core
rhubarb-recognition
rhubarb-time
rhubarb-tools
)
# ... rhubarb-logging
add_library(rhubarb-logging
src/logging/logging.cpp
src/logging/logging.h
)
target_include_directories(rhubarb-logging PUBLIC "src/logging")
target_link_libraries(rhubarb-logging
rhubarb-tools
)
# ... rhubarb-recognition
add_library(rhubarb-recognition
src/recognition/g2p.cpp
src/recognition/g2p.h
src/recognition/languageModels.cpp
src/recognition/languageModels.h
src/recognition/phoneRecognition.cpp
src/recognition/phoneRecognition.h
src/recognition/tokenization.cpp
src/recognition/tokenization.h
)
target_include_directories(rhubarb-recognition PUBLIC "src/recognition")
target_link_libraries(rhubarb-recognition
flite
pocketSphinx
rhubarb-audio
rhubarb-core
rhubarb-logging
)
# ... rhubarb-time
add_library(rhubarb-time
src/time/BoundedTimeline.h
src/time/centiseconds.cpp
src/time/centiseconds.h
src/time/ContinuousTimeline.h
src/time/Timed.h
src/time/timedLogging.h
src/time/Timeline.h
src/time/TimeRange.cpp
src/time/TimeRange.h
)
target_include_directories(rhubarb-time PUBLIC "src/time")
target_link_libraries(rhubarb-time
cppFormat
rhubarb-logging
)
# ... rhubarb-tools
add_library(rhubarb-tools
src/tools/EnumConverter.h
src/tools/exceptions.cpp
src/tools/exceptions.h
src/tools/Lazy.h
src/tools/NiceCmdLineOutput.cpp
src/tools/NiceCmdLineOutput.h
src/tools/ObjectPool.h
src/tools/pairs.h
src/tools/parallel.h
src/tools/platformTools.cpp
src/tools/platformTools.h
src/tools/ProgressBar.cpp
src/tools/ProgressBar.h
src/tools/stringTools.cpp
src/tools/stringTools.h
src/tools/TablePrinter.cpp
src/tools/TablePrinter.h
src/tools/textFiles.cpp
src/tools/textFiles.h
src/tools/tools.cpp
src/tools/tools.h
src/tools/tupleHash.h
)
target_include_directories(rhubarb-tools PUBLIC "src/tools")
target_link_libraries(rhubarb-tools
cppFormat
whereami
)
# Define Rhubarb executable
add_executable(rhubarb src/main.cpp)
target_include_directories(rhubarb PUBLIC "src")
target_link_libraries(rhubarb
rhubarb-exporters
rhubarb-lib
) )
add_executable(rhubarb ${SOURCE_FILES})
target_link_libraries(rhubarb ${Boost_LIBRARIES} cppFormat sphinxbase pocketSphinx flite webRTC whereami)
target_compile_options(rhubarb PUBLIC ${enableWarningsFlags}) target_compile_options(rhubarb PUBLIC ${enableWarningsFlags})
# Define test project # Define test project
@ -261,21 +398,15 @@ set(TEST_FILES
tests/tokenizationTests.cpp tests/tokenizationTests.cpp
tests/g2pTests.cpp tests/g2pTests.cpp
tests/LazyTests.cpp tests/LazyTests.cpp
src/stringTools.cpp src/stringTools.h
src/platformTools.cpp src/platformTools.h
src/Timeline.h
src/TimeRange.cpp src/TimeRange.h
src/centiseconds.cpp src/centiseconds.h
src/pairs.h
src/Phone.cpp src/Phone.h
src/tokenization.cpp src/tokenization.h
src/g2p.cpp src/g2p.h
src/logging.cpp src/logging.h
src/tools.cpp src/tools.h
src/Lazy.h
) )
add_executable(runTests ${TEST_FILES}) add_executable(runTests ${TEST_FILES})
target_link_libraries(runTests ${Boost_LIBRARIES} gtest gmock gmock_main flite cppFormat whereami) target_link_libraries(runTests
gtest
gmock
gmock_main
rhubarb-recognition
rhubarb-time
)
set(CPACK_PACKAGE_NAME ${appName}) set(CPACK_PACKAGE_NAME ${appName})
string(REPLACE " " "-" CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME}") string(REPLACE " " "-" CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")

View File

@ -4,6 +4,7 @@
#include <unordered_map> #include <unordered_map>
#include <boost/algorithm/clamp.hpp> #include <boost/algorithm/clamp.hpp>
#include "Viseme.h" #include "Viseme.h"
#include "timedLogging.h"
using std::map; using std::map;
using std::unordered_set; using std::unordered_set;
@ -278,7 +279,7 @@ ContinuousTimeline<Shape> animate(const BoundedTimeline<Phone> &phones) {
} }
for (const auto& timedShape : shapes) { for (const auto& timedShape : shapes) {
logging::logTimedEvent("shape", timedShape); logTimedEvent("shape", timedShape);
} }
return shapes; return shapes;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "TimeRange.h" #include "TimeRange.h"
#include <functional> #include <functional>

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "AudioClip.h" #include "AudioClip.h"
class AudioSegment : public AudioClip { class AudioSegment : public AudioClip {

View File

@ -2,7 +2,7 @@
#include <vector> #include <vector>
#include <functional> #include <functional>
#include "audio/AudioClip.h" #include "AudioClip.h"
#include "ProgressBar.h" #include "ProgressBar.h"
void process16bitAudioClip(const AudioClip& audioClip, std::function<void(const std::vector<int16_t>&)> processBuffer, size_t bufferCapacity, ProgressSink& progressSink); void process16bitAudioClip(const AudioClip& audioClip, std::function<void(const std::vector<int16_t>&)> processBuffer, size_t bufferCapacity, ProgressSink& progressSink);

View File

@ -1,13 +1,13 @@
#include "voiceActivityDetection.h" #include "voiceActivityDetection.h"
#include <audio/DCOffset.h> #include "DCOffset.h"
#include <audio/SampleRateConverter.h> #include "SampleRateConverter.h"
#include <logging.h> #include "logging.h"
#include <pairs.h> #include "pairs.h"
#include <boost/range/adaptor/transformed.hpp> #include <boost/range/adaptor/transformed.hpp>
#include <webrtc/common_audio/vad/include/webrtc_vad.h> #include <webrtc/common_audio/vad/include/webrtc_vad.h>
#include "processing.h" #include "processing.h"
#include <gsl_util.h> #include <gsl_util.h>
#include <parallel.h> #include "parallel.h"
#include "AudioSegment.h" #include "AudioSegment.h"
using std::vector; using std::vector;

39
src/lib/rhubarbLib.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "rhubarbLib.h"
#include "Phone.h"
#include "phoneRecognition.h"
#include "textFiles.h"
#include "mouthAnimation.h"
#include "WaveFileReader.h"
using boost::optional;
using std::u32string;
using boost::filesystem::path;
using std::unique_ptr;
ContinuousTimeline<Shape> animateAudioClip(
const AudioClip& audioClip,
optional<u32string> dialog,
int maxThreadCount,
ProgressSink& progressSink)
{
BoundedTimeline<Phone> phones = recognizePhones(audioClip, dialog, maxThreadCount, progressSink);
ContinuousTimeline<Shape> result = animate(phones);
return result;
}
unique_ptr<AudioClip> createWaveAudioClip(path filePath) {
try {
return std::make_unique<WaveFileReader>(filePath);
} catch (...) {
std::throw_with_nested(std::runtime_error(fmt::format("Could not open sound file '{0}'.", filePath.string())));
}
}
ContinuousTimeline<Shape> animateWaveFile(
path filePath,
optional<u32string> dialog,
int maxThreadCount,
ProgressSink& progressSink)
{
return animateAudioClip(*createWaveAudioClip(filePath), dialog, maxThreadCount, progressSink);
}

19
src/lib/rhubarbLib.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include "Shape.h"
#include "ContinuousTimeline.h"
#include "AudioClip.h"
#include "ProgressBar.h"
#include <boost/filesystem.hpp>
ContinuousTimeline<Shape> animateAudioClip(
const AudioClip& audioClip,
boost::optional<std::u32string> dialog,
int maxThreadCount,
ProgressSink& progressSink);
ContinuousTimeline<Shape> animateWaveFile(
boost::filesystem::path filePath,
boost::optional<std::u32string> dialog,
int maxThreadCount,
ProgressSink& progressSink);

View File

@ -1,10 +1,8 @@
#pragma once #pragma once
#include <string>
#include <vector> #include <vector>
#include <mutex> #include <mutex>
#include "tools.h" #include "tools.h"
#include "Timed.h"
#include "EnumConverter.h" #include "EnumConverter.h"
namespace logging { namespace logging {
@ -124,20 +122,4 @@ namespace logging {
LOG_WITH_LEVEL(warn, Warn) LOG_WITH_LEVEL(warn, Warn)
LOG_WITH_LEVEL(error, Error) LOG_WITH_LEVEL(error, Error)
LOG_WITH_LEVEL(fatal, Fatal) LOG_WITH_LEVEL(fatal, Fatal)
template<typename TValue>
void logTimedEvent(const std::string& eventName, const Timed<TValue> timedValue) {
debugFormat("##{0}[{1}-{2}]: {3}",
eventName, formatDuration(timedValue.getStart()), formatDuration(timedValue.getEnd()), timedValue.getValue());
}
template<typename TValue>
void logTimedEvent(const std::string& eventName, const TimeRange& timeRange, const TValue& value) {
logTimedEvent(eventName, Timed<TValue>(timeRange, value));
}
template<typename TValue>
void logTimedEvent(const std::string& eventName, centiseconds start, centiseconds end, const TValue& value) {
logTimedEvent(eventName, Timed<TValue>(start, end, value));
}
} }

View File

@ -1,10 +1,6 @@
#include <iostream> #include <iostream>
#include <boost/optional.hpp>
#include <format.h> #include <format.h>
#include <tclap/CmdLine.h> #include <tclap/CmdLine.h>
#include "audio/WaveFileReader.h"
#include "phoneRecognition.h"
#include "mouthAnimation.h"
#include "appInfo.h" #include "appInfo.h"
#include "NiceCmdLineOutput.h" #include "NiceCmdLineOutput.h"
#include "ProgressBar.h" #include "ProgressBar.h"
@ -17,6 +13,9 @@
#include <boost/range/adaptor/transformed.hpp> #include <boost/range/adaptor/transformed.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include "parallel.h" #include "parallel.h"
#include "exceptions.h"
#include "textFiles.h"
#include "rhubarbLib.h"
using std::exception; using std::exception;
using std::string; using std::string;
@ -34,25 +33,6 @@ using boost::adaptors::transformed;
namespace tclap = TCLAP; namespace tclap = TCLAP;
string getMessage(const exception& e) {
string result(e.what());
try {
std::rethrow_if_nested(e);
} catch(const exception& innerException) {
result += "\n" + getMessage(innerException);
} catch(...) {}
return result;
}
unique_ptr<AudioClip> createAudioClip(path filePath) {
try {
return std::make_unique<WaveFileReader>(filePath);
} catch (...) {
std::throw_with_nested(std::runtime_error(fmt::format("Could not open sound file '{0}'.", filePath.string())));
}
}
// Tell TCLAP how to handle our types // Tell TCLAP how to handle our types
namespace TCLAP { namespace TCLAP {
template<> template<>
@ -82,22 +62,16 @@ void addFileSink(path path, logging::Level minLevel) {
logging::addSink(levelFilter); logging::addSink(levelFilter);
} }
u32string readTextFile(path filePath) { unique_ptr<Exporter> createExporter(ExportFormat exportFormat) {
if (!exists(filePath)) { switch (exportFormat) {
throw std::invalid_argument(fmt::format("File {} does not exist.", filePath)); case ExportFormat::TSV:
} return make_unique<TSVExporter>();
try { case ExportFormat::XML:
boost::filesystem::ifstream file; return make_unique<XMLExporter>();
file.exceptions(std::ifstream::failbit | std::ifstream::badbit); case ExportFormat::JSON:
file.open(filePath); return make_unique<JSONExporter>();
string utf8Text((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); default:
try { throw std::runtime_error("Unknown export format.");
return utf8ToUtf32(utf8Text);
} catch (...) {
std::throw_with_nested(std::runtime_error(fmt::format("File encoding is not ASCII or UTF-8.", filePath)));
}
} catch (...) {
std::throw_with_nested(std::runtime_error(fmt::format("Error reading file {0}.", filePath)));
} }
} }
@ -146,44 +120,24 @@ int main(int argc, char *argv[]) {
logging::infoFormat("Application startup. Command line: {}", join( logging::infoFormat("Application startup. Command line: {}", join(
vector<char*>(argv, argv + argc) | transformed([](char* arg) { return fmt::format("\"{}\"", arg); }), " ")); vector<char*>(argv, argv + argc) | transformed([](char* arg) { return fmt::format("\"{}\"", arg); }), " "));
// Detect phones std::cerr << "Processing input file. ";
const int columnWidth = 30; ContinuousTimeline<Shape> animation(TimeRange::zero(), Shape::X);
std::cerr << std::left;
std::cerr << std::setw(columnWidth) << "Analyzing input file";
BoundedTimeline<Phone> phones(TimeRange::zero());
{ {
ProgressBar progressBar; ProgressBar progressBar;
phones = recognizePhones(
*createAudioClip(inputFileName.getValue()), // Animate the recording
dialogFile.isSet() ? readTextFile(path(dialogFile.getValue())) : boost::optional<u32string>(), animation = animateWaveFile(
inputFileName.getValue(),
dialogFile.isSet() ? readUTF8File(path(dialogFile.getValue())) : boost::optional<u32string>(),
maxThreadCount.getValue(), maxThreadCount.getValue(),
progressBar); progressBar);
} }
std::cerr << "Done" << std::endl; std::cerr << "Done." << std::endl << std::endl;
// Generate mouth shapes // Export animation
std::cerr << std::setw(columnWidth) << "Generating mouth shapes"; unique_ptr<Exporter> exporter = createExporter(exportFormat.getValue());
ContinuousTimeline<Shape> shapes = animate(phones); exporter->exportShapes(path(inputFileName.getValue()), animation, std::cout);
std::cerr << "Done" << std::endl;
std::cerr << std::endl;
// Export
unique_ptr<Exporter> exporter;
switch (exportFormat.getValue()) {
case ExportFormat::TSV:
exporter = make_unique<TSVExporter>();
break;
case ExportFormat::XML:
exporter = make_unique<XMLExporter>();
break;
case ExportFormat::JSON:
exporter = make_unique<JSONExporter>();
break;
default:
throw std::runtime_error("Unknown export format.");
}
exporter->exportShapes(path(inputFileName.getValue()), shapes, std::cout);
logging::info("Exiting application normally."); logging::info("Exiting application normally.");
return 0; return 0;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include "tools.h" #include "tools.h"

View File

@ -1,6 +1,6 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "phoneRecognition.h" #include "phoneRecognition.h"
#include "audio/SampleRateConverter.h" #include "SampleRateConverter.h"
#include "platformTools.h" #include "platformTools.h"
#include "tools.h" #include "tools.h"
#include <format.h> #include <format.h>
@ -8,18 +8,19 @@
#include <regex> #include <regex>
#include <gsl_util.h> #include <gsl_util.h>
#include <logging.h> #include <logging.h>
#include <audio/DCOffset.h> #include "DCOffset.h"
#include <Timeline.h> #include "Timeline.h"
#include <audio/voiceActivityDetection.h> #include "voiceActivityDetection.h"
#include "audio/AudioSegment.h" #include "AudioSegment.h"
#include "languageModels.h" #include "languageModels.h"
#include "tokenization.h" #include "tokenization.h"
#include "g2p.h" #include "g2p.h"
#include "ContinuousTimeline.h" #include "ContinuousTimeline.h"
#include "audio/processing.h" #include "processing.h"
#include "parallel.h" #include "parallel.h"
#include <boost/version.hpp> #include <boost/version.hpp>
#include "ObjectPool.h" #include "ObjectPool.h"
#include "timedLogging.h"
extern "C" { extern "C" {
#include <pocketsphinx.h> #include <pocketsphinx.h>
@ -372,12 +373,12 @@ Timeline<Phone> utteranceToPhones(
} }
text += word; text += word;
} }
logging::logTimedEvent("utterance", utteranceTimeRange, text); logTimedEvent("utterance", utteranceTimeRange, text);
// Log words // Log words
for (Timed<string> timedWord : words) { for (Timed<string> timedWord : words) {
timedWord.getTimeRange().shift(paddedTimeRange.getStart()); timedWord.getTimeRange().shift(paddedTimeRange.getStart());
logging::logTimedEvent("word", timedWord); logTimedEvent("word", timedWord);
} }
// Convert word strings to word IDs using dictionary // Convert word strings to word IDs using dictionary
@ -398,7 +399,7 @@ Timeline<Phone> utteranceToPhones(
// Log raw phones // Log raw phones
for (const auto& timedPhone : utterancePhones) { for (const auto& timedPhone : utterancePhones) {
logging::logTimedEvent("rawPhone", timedPhone); logTimedEvent("rawPhone", timedPhone);
} }
// Guess positions of noise sounds // Guess positions of noise sounds
@ -409,7 +410,7 @@ Timeline<Phone> utteranceToPhones(
// Log phones // Log phones
for (const auto& timedPhone : utterancePhones) { for (const auto& timedPhone : utterancePhones) {
logging::logTimedEvent("phone", timedPhone); logTimedEvent("phone", timedPhone);
} }
return utterancePhones; return utterancePhones;

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "audio/AudioClip.h" #include "AudioClip.h"
#include "Phone.h" #include "Phone.h"
#include "ProgressBar.h" #include "ProgressBar.h"
#include "BoundedTimeline.h" #include "BoundedTimeline.h"

22
src/time/timedLogging.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include "centiseconds.h"
#include "TimeRange.h"
#include "Timed.h"
#include "logging.h"
template<typename TValue>
void logTimedEvent(const std::string& eventName, const Timed<TValue> timedValue) {
logging::debugFormat("##{0}[{1}-{2}]: {3}",
eventName, formatDuration(timedValue.getStart()), formatDuration(timedValue.getEnd()), timedValue.getValue());
}
template<typename TValue>
void logTimedEvent(const std::string& eventName, const TimeRange& timeRange, const TValue& value) {
logTimedEvent(eventName, Timed<TValue>(timeRange, value));
}
template<typename TValue>
void logTimedEvent(const std::string& eventName, centiseconds start, centiseconds end, const TValue& value) {
logTimedEvent(eventName, Timed<TValue>(start, end, value));
}

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <mutex> #include <mutex>

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <initializer_list> #include <initializer_list>
#include <ostream> #include <ostream>
#include <vector> #include <vector>

15
src/tools/exceptions.cpp Normal file
View File

@ -0,0 +1,15 @@
#include "exceptions.h"
using std::string;
using std::exception;
string getMessage(const exception& e) {
string result(e.what());
try {
rethrow_if_nested(e);
} catch (const exception& innerException) {
result += "\n" + getMessage(innerException);
} catch (...) {}
return result;
}

5
src/tools/exceptions.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include <string>
std::string getMessage(const std::exception& e);

View File

@ -6,7 +6,6 @@
#include <boost/uuid/uuid_io.hpp> #include <boost/uuid/uuid_io.hpp>
#include "platformTools.h" #include "platformTools.h"
#include <whereami.h> #include <whereami.h>
#include "logging.h"
using boost::filesystem::path; using boost::filesystem::path;
using std::string; using std::string;
@ -19,7 +18,6 @@ path getBinPath() {
if (pathLength == -1) { if (pathLength == -1) {
throw std::runtime_error("Error determining path length."); throw std::runtime_error("Error determining path length.");
} }
logging::debugFormat("Bin path has length {}.", pathLength);
// Get path // Get path
// Note: According to documentation, pathLength does *not* include the trailing zero. Actually, it does. // Note: According to documentation, pathLength does *not* include the trailing zero. Actually, it does.
@ -32,7 +30,6 @@ path getBinPath() {
// Convert to boost::filesystem::path // Convert to boost::filesystem::path
string pathString(buffer.data()); string pathString(buffer.data());
logging::debugFormat("Bin path: '{}'", pathString);
path result(boost::filesystem::canonical(pathString).make_preferred()); path result(boost::filesystem::canonical(pathString).make_preferred());
return result; return result;
} catch (...) { } catch (...) {

29
src/tools/textFiles.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "textFiles.h"
#include <boost/filesystem/operations.hpp>
#include <format.h>
#include <boost/filesystem/fstream.hpp>
#include "stringTools.h"
using std::string;
using std::u32string;
using boost::filesystem::path;
u32string readUTF8File(path filePath) {
if (!exists(filePath)) {
throw std::invalid_argument(fmt::format("File {} does not exist.", filePath));
}
try {
boost::filesystem::ifstream file;
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
file.open(filePath);
string utf8Text((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
try {
return utf8ToUtf32(utf8Text);
} catch (...) {
std::throw_with_nested(std::runtime_error(fmt::format("File encoding is not ASCII or UTF-8.", filePath)));
}
} catch (...) {
std::throw_with_nested(std::runtime_error(fmt::format("Error reading file {0}.", filePath)));
}
}

5
src/tools/textFiles.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include <boost/filesystem/path.hpp>
std::u32string readUTF8File(boost::filesystem::path filePath);