diff --git a/src/animation/pauseAnimation.cpp b/src/animation/pauseAnimation.cpp index 8e775c2..4f1281e 100644 --- a/src/animation/pauseAnimation.cpp +++ b/src/animation/pauseAnimation.cpp @@ -28,10 +28,10 @@ Shape getPauseShape(Shape previous, Shape next, centiseconds duration) { return Shape::X; } -JoiningContinuousTimeline animatePauses(const JoiningContinuousTimeline& shapes) { - JoiningContinuousTimeline result(shapes); +JoiningContinuousTimeline animatePauses(const JoiningContinuousTimeline& animation) { + JoiningContinuousTimeline result(animation); - for_each_adjacent(shapes.begin(), shapes.end(), [&](const Timed& previous, const Timed& pause, const Timed& next) { + for_each_adjacent(animation.begin(), animation.end(), [&](const Timed& previous, const Timed& pause, const Timed& next) { if (pause.getValue() != Shape::X) return; result.set(pause.getTimeRange(), getPauseShape(previous.getValue(), next.getValue(), pause.getDuration())); diff --git a/src/animation/pauseAnimation.h b/src/animation/pauseAnimation.h index 8b38a36..eb28bae 100644 --- a/src/animation/pauseAnimation.h +++ b/src/animation/pauseAnimation.h @@ -4,4 +4,4 @@ #include "ContinuousTimeline.h" // Takes an existing animation and modifies the pauses (X shapes) to look better. -JoiningContinuousTimeline animatePauses(const JoiningContinuousTimeline& shapes); +JoiningContinuousTimeline animatePauses(const JoiningContinuousTimeline& animation); diff --git a/src/animation/roughAnimation.cpp b/src/animation/roughAnimation.cpp index 918a019..0bb540c 100644 --- a/src/animation/roughAnimation.cpp +++ b/src/animation/roughAnimation.cpp @@ -12,7 +12,7 @@ using boost::optional; // * When speaking, we anticipate vowels, trying to form their shape before the actual vowel. // So whenever we come across a one-shape vowel, we backtrack a little, spreating that shape to the left. JoiningContinuousTimeline animateRough(const ContinuousTimeline& shapeRules) { - JoiningContinuousTimeline shapes(shapeRules.getRange(), Shape::X); + JoiningContinuousTimeline animation(shapeRules.getRange(), Shape::X); Shape referenceShape = Shape::X; // Animate forwards @@ -21,7 +21,7 @@ JoiningContinuousTimeline animateRough(const ContinuousTimelinegetValue(); const ShapeSet shapeSet = std::get(shapeRule); const Shape shape = getClosestShape(referenceShape, shapeSet); - shapes.set(it->getTimeRange(), shape); + animation.set(it->getTimeRange(), shape); const auto phone = std::get>(shapeRule); const bool anticipateShape = phone && isVowel(*phone) && shapeSet.size() == 1; if (anticipateShape) { @@ -41,7 +41,7 @@ JoiningContinuousTimeline animateRough(const ContinuousTimeline(reverseIt->getValue())); - shapes.set(reverseIt->getTimeRange(), anticipatingShape); + animation.set(reverseIt->getTimeRange(), anticipatingShape); // Make sure the new, backwards-animated shape still resembles the anticipated shape if (getBasicShape(anticipatingShape) != getBasicShape(anticipatedShape)) break; @@ -53,5 +53,5 @@ JoiningContinuousTimeline animateRough(const ContinuousTimeline convertToTargetShapeSet(const ContinuousTimeline convertToTargetShapeSet(const JoiningContinuousTimeline& shapes, const ShapeSet& targetShapeSet) { - JoiningContinuousTimeline result(shapes); - for (const auto& timedShape : shapes) { +JoiningContinuousTimeline convertToTargetShapeSet(const JoiningContinuousTimeline& animation, const ShapeSet& targetShapeSet) { + JoiningContinuousTimeline result(animation); + for (const auto& timedShape : animation) { result.set(timedShape.getTimeRange(), convertToTargetShapeSet(timedShape.getValue(), targetShapeSet)); } return result; diff --git a/src/animation/targetShapeSet.h b/src/animation/targetShapeSet.h index ef473f0..476353a 100644 --- a/src/animation/targetShapeSet.h +++ b/src/animation/targetShapeSet.h @@ -12,5 +12,5 @@ ShapeSet convertToTargetShapeSet(const ShapeSet& shapes, const ShapeSet& targetS // Replaces each shape in each rule with the closest shape that occurs in the target shape set. ContinuousTimeline convertToTargetShapeSet(const ContinuousTimeline& shapeRules, const ShapeSet& targetShapeSet); -// Replaces each shape in the specified timeline with the closest shape that occurs in the target shape set. -JoiningContinuousTimeline convertToTargetShapeSet(const JoiningContinuousTimeline& shapes, const ShapeSet& targetShapeSet); +// Replaces each shape in the specified animation with the closest shape that occurs in the target shape set. +JoiningContinuousTimeline convertToTargetShapeSet(const JoiningContinuousTimeline& animation, const ShapeSet& targetShapeSet); diff --git a/src/animation/timingOptimization.cpp b/src/animation/timingOptimization.cpp index 9c33055..2e5456a 100644 --- a/src/animation/timingOptimization.cpp +++ b/src/animation/timingOptimization.cpp @@ -85,8 +85,8 @@ JoiningContinuousTimeline retime(const JoiningContinuousTimeline& return targetShapes; } -JoiningContinuousTimeline retime(const JoiningContinuousTimeline& shapes, TimeRange sourceRange, TimeRange targetRange) { - const auto sourceShapes = JoiningContinuousTimeline(sourceRange, Shape::X, shapes); +JoiningContinuousTimeline retime(const JoiningContinuousTimeline& animation, TimeRange sourceRange, TimeRange targetRange) { + const auto sourceShapes = JoiningContinuousTimeline(sourceRange, Shape::X, animation); return retime(sourceShapes, targetRange); } @@ -96,10 +96,10 @@ enum class MouthState { Open }; -JoiningContinuousTimeline optimizeTiming(const JoiningContinuousTimeline& shapes) { +JoiningContinuousTimeline optimizeTiming(const JoiningContinuousTimeline& animation) { // Identify segments with idle, closed, and open mouth shapes - JoiningContinuousTimeline segments(shapes.getRange(), MouthState::Idle); - for (const auto& timedShape : shapes) { + JoiningContinuousTimeline segments(animation.getRange(), MouthState::Idle); + for (const auto& timedShape : animation) { const Shape shape = timedShape.getValue(); const MouthState mouthState = shape == Shape::X ? MouthState::Idle : shape == Shape::A ? MouthState::Closed : MouthState::Open; segments.set(timedShape.getTimeRange(), mouthState); @@ -112,7 +112,7 @@ JoiningContinuousTimeline optimizeTiming(const JoiningContinuousTimeline< // Make sure all open and closed segments are long enough to register visually. // We don't care about idle shapes at this point. - JoiningContinuousTimeline result(shapes.getRange(), Shape::X); + JoiningContinuousTimeline result(animation.getRange(), Shape::X); // ... we're filling the result timeline from right to left, so `resultStart` points to the earliest shape already written centiseconds resultStart = result.getRange().getEnd(); for (auto segmentIt = segments.rbegin(); segmentIt != segments.rend(); ++segmentIt) { @@ -122,7 +122,7 @@ JoiningContinuousTimeline optimizeTiming(const JoiningContinuousTimeline< if (segmentTargetEnd - segmentIt->getStart() >= minSegmentDuration) { // The segment is long enough; we don't have to extend it to the left. const TimeRange targetRange(segmentIt->getStart(), segmentTargetEnd); - const auto retimedSegment = retime(shapes, segmentIt->getTimeRange(), targetRange); + const auto retimedSegment = retime(animation, segmentIt->getTimeRange(), targetRange); for (const auto& timedShape : retimedSegment) { result.set(timedShape); } @@ -148,7 +148,7 @@ JoiningContinuousTimeline optimizeTiming(const JoiningContinuousTimeline< size_t remainingShortSegmentCount = std::distance(shortSegmentIt, end); const centiseconds segmentDuration = (resultStart - shortSegmentsTargetStart) / remainingShortSegmentCount; const TimeRange segmentTargetRange(resultStart - segmentDuration, resultStart); - const auto retimedSegment = retime(shapes, shortSegmentIt->getTimeRange(), segmentTargetRange); + const auto retimedSegment = retime(animation, shortSegmentIt->getTimeRange(), segmentTargetRange); for (const auto& timedShape : retimedSegment) { result.set(timedShape); } diff --git a/src/animation/timingOptimization.h b/src/animation/timingOptimization.h index b02219f..d781c22 100644 --- a/src/animation/timingOptimization.h +++ b/src/animation/timingOptimization.h @@ -5,4 +5,4 @@ // Changes the timing of an existing animation to reduce jitter and to make sure all shapes register visually. // In some cases, shapes may be omitted. -JoiningContinuousTimeline optimizeTiming(const JoiningContinuousTimeline& shapes); +JoiningContinuousTimeline optimizeTiming(const JoiningContinuousTimeline& animation); diff --git a/src/animation/tweening.cpp b/src/animation/tweening.cpp index 73ffdbf..d58e153 100644 --- a/src/animation/tweening.cpp +++ b/src/animation/tweening.cpp @@ -1,14 +1,14 @@ #include "tweening.h" #include "animationRules.h" -JoiningContinuousTimeline insertTweens(const JoiningContinuousTimeline& shapes) { +JoiningContinuousTimeline insertTweens(const JoiningContinuousTimeline& animation) { centiseconds minTweenDuration = 4_cs; centiseconds maxTweenDuration = 8_cs; - JoiningContinuousTimeline result(shapes); + JoiningContinuousTimeline result(animation); - for (auto first = shapes.begin(), second = std::next(shapes.begin()); - first != shapes.end() && second != shapes.end(); + for (auto first = animation.begin(), second = std::next(animation.begin()); + first != animation.end() && second != animation.end(); ++first, ++second) { auto pair = getTween(first->getValue(), second->getValue()); diff --git a/src/animation/tweening.h b/src/animation/tweening.h index 4a2d8f7..cb4073b 100644 --- a/src/animation/tweening.h +++ b/src/animation/tweening.h @@ -4,4 +4,4 @@ #include "ContinuousTimeline.h" // Takes an existing animation and inserts inbetween shapes for smoother results. -JoiningContinuousTimeline insertTweens(const JoiningContinuousTimeline& shapes); +JoiningContinuousTimeline insertTweens(const JoiningContinuousTimeline& animation); diff --git a/src/core/Shape.h b/src/core/Shape.h index 41f9246..f192f47 100644 --- a/src/core/Shape.h +++ b/src/core/Shape.h @@ -3,7 +3,7 @@ #include "EnumConverter.h" #include -// The classic Hanna-Barbera mouth shapes A-F phus the common supplements G-H +// The classic Hanna-Barbera mouth shapes A-F plus the common supplements G-H // For reference, see http://sunewatts.dk/lipsync/lipsync/article_02.php // For visual examples, see https://flic.kr/s/aHsj86KR4J. Their shapes "BMP".."L" map to A..H. enum class Shape { diff --git a/src/exporters/Exporter.h b/src/exporters/Exporter.h index 5c63479..d09aa80 100644 --- a/src/exporters/Exporter.h +++ b/src/exporters/Exporter.h @@ -7,5 +7,5 @@ class Exporter { public: virtual ~Exporter() {} - virtual void exportShapes(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& shapes, const ShapeSet& targetShapeSet, std::ostream& outputStream) = 0; + virtual void exportAnimation(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& animation, const ShapeSet& targetShapeSet, std::ostream& outputStream) = 0; }; diff --git a/src/exporters/JsonExporter.cpp b/src/exporters/JsonExporter.cpp index c1f5783..be76a3b 100644 --- a/src/exporters/JsonExporter.cpp +++ b/src/exporters/JsonExporter.cpp @@ -25,17 +25,17 @@ string escapeJsonString(const string& s) { return result; } -void JsonExporter::exportShapes(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& shapes, const ShapeSet& targetShapeSet, std::ostream& outputStream) { +void JsonExporter::exportAnimation(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& animation, const ShapeSet& targetShapeSet, std::ostream& outputStream) { // Export as JSON. // I'm not using a library because the code is short enough without one and it lets me control the formatting. outputStream << "{\n"; outputStream << " \"metadata\": {\n"; outputStream << " \"soundFile\": \"" << escapeJsonString(inputFilePath.string()) << "\",\n"; - outputStream << " \"duration\": " << formatDuration(shapes.getRange().getDuration()) << "\n"; + outputStream << " \"duration\": " << formatDuration(animation.getRange().getDuration()) << "\n"; outputStream << " },\n"; outputStream << " \"mouthCues\": [\n"; bool isFirst = true; - for (auto& timedShape : dummyShapeIfEmpty(shapes, targetShapeSet)) { + for (auto& timedShape : dummyShapeIfEmpty(animation, targetShapeSet)) { if (!isFirst) outputStream << ",\n"; isFirst = false; outputStream << " { \"start\": " << formatDuration(timedShape.getStart()) diff --git a/src/exporters/JsonExporter.h b/src/exporters/JsonExporter.h index ead85e4..2782129 100644 --- a/src/exporters/JsonExporter.h +++ b/src/exporters/JsonExporter.h @@ -4,5 +4,5 @@ class JsonExporter : public Exporter { public: - void exportShapes(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& shapes, const ShapeSet& targetShapeSet, std::ostream& outputStream) override; + void exportAnimation(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& animation, const ShapeSet& targetShapeSet, std::ostream& outputStream) override; }; diff --git a/src/exporters/TsvExporter.cpp b/src/exporters/TsvExporter.cpp index 14d4ed7..543d8fa 100644 --- a/src/exporters/TsvExporter.cpp +++ b/src/exporters/TsvExporter.cpp @@ -1,14 +1,14 @@ #include "TsvExporter.h" #include "targetShapeSet.h" -void TsvExporter::exportShapes(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& shapes, const ShapeSet& targetShapeSet, std::ostream& outputStream) { +void TsvExporter::exportAnimation(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& animation, const ShapeSet& targetShapeSet, std::ostream& outputStream) { UNUSED(inputFilePath); // Output shapes with start times - for (auto& timedShape : shapes) { + for (auto& timedShape : animation) { outputStream << formatDuration(timedShape.getStart()) << "\t" << timedShape.getValue() << "\n"; } // Output closed mouth with end time - outputStream << formatDuration(shapes.getRange().getEnd()) << "\t" << convertToTargetShapeSet(Shape::X, targetShapeSet) << "\n"; + outputStream << formatDuration(animation.getRange().getEnd()) << "\t" << convertToTargetShapeSet(Shape::X, targetShapeSet) << "\n"; } diff --git a/src/exporters/TsvExporter.h b/src/exporters/TsvExporter.h index b950f4c..fd226b9 100644 --- a/src/exporters/TsvExporter.h +++ b/src/exporters/TsvExporter.h @@ -4,6 +4,6 @@ class TsvExporter : public Exporter { public: - void exportShapes(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& shapes, const ShapeSet& targetShapeSet, std::ostream& outputStream) override; + void exportAnimation(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& animation, const ShapeSet& targetShapeSet, std::ostream& outputStream) override; }; diff --git a/src/exporters/XmlExporter.cpp b/src/exporters/XmlExporter.cpp index 3f38c1d..11ab591 100644 --- a/src/exporters/XmlExporter.cpp +++ b/src/exporters/XmlExporter.cpp @@ -6,15 +6,15 @@ using std::string; using boost::property_tree::ptree; -void XmlExporter::exportShapes(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& shapes, const ShapeSet& targetShapeSet, std::ostream& outputStream) { +void XmlExporter::exportAnimation(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& animation, const ShapeSet& targetShapeSet, std::ostream& outputStream) { ptree tree; // Add metadata tree.put("rhubarbResult.metadata.soundFile", inputFilePath.string()); - tree.put("rhubarbResult.metadata.duration", formatDuration(shapes.getRange().getDuration())); + tree.put("rhubarbResult.metadata.duration", formatDuration(animation.getRange().getDuration())); // Add mouth cues - for (auto& timedShape : dummyShapeIfEmpty(shapes, targetShapeSet)) { + for (auto& timedShape : dummyShapeIfEmpty(animation, targetShapeSet)) { ptree& mouthCueElement = tree.add("rhubarbResult.mouthCues.mouthCue", timedShape.getValue()); mouthCueElement.put(".start", formatDuration(timedShape.getStart())); mouthCueElement.put(".end", formatDuration(timedShape.getEnd())); diff --git a/src/exporters/XmlExporter.h b/src/exporters/XmlExporter.h index 8495352..81aa939 100644 --- a/src/exporters/XmlExporter.h +++ b/src/exporters/XmlExporter.h @@ -4,5 +4,5 @@ class XmlExporter : public Exporter { public: - void exportShapes(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& shapes, const ShapeSet& targetShapeSet, std::ostream& outputStream) override; + void exportAnimation(const boost::filesystem::path& inputFilePath, const JoiningContinuousTimeline& animation, const ShapeSet& targetShapeSet, std::ostream& outputStream) override; }; diff --git a/src/exporters/exporterTools.cpp b/src/exporters/exporterTools.cpp index f0e5c57..3b4eb79 100644 --- a/src/exporters/exporterTools.cpp +++ b/src/exporters/exporterTools.cpp @@ -2,9 +2,9 @@ #include "targetShapeSet.h" // Makes sure there is at least one mouth shape -std::vector> dummyShapeIfEmpty(const JoiningTimeline& shapes, const ShapeSet& targetShapeSet) { +std::vector> dummyShapeIfEmpty(const JoiningTimeline& animation, const ShapeSet& targetShapeSet) { std::vector> result; - std::copy(shapes.begin(), shapes.end(), std::back_inserter(result)); + std::copy(animation.begin(), animation.end(), std::back_inserter(result)); if (result.empty()) { // Add zero-length empty mouth result.push_back(Timed(0_cs, 0_cs, convertToTargetShapeSet(Shape::X, targetShapeSet))); diff --git a/src/exporters/exporterTools.h b/src/exporters/exporterTools.h index d0b28fc..70fccbb 100644 --- a/src/exporters/exporterTools.h +++ b/src/exporters/exporterTools.h @@ -4,4 +4,4 @@ #include "Timeline.h" // Makes sure there is at least one mouth shape -std::vector> dummyShapeIfEmpty(const JoiningTimeline& shapes, const ShapeSet& targetShapeSet); +std::vector> dummyShapeIfEmpty(const JoiningTimeline& animation, const ShapeSet& targetShapeSet); diff --git a/src/main.cpp b/src/main.cpp index 8b0f6f2..ff05e59 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -163,7 +163,7 @@ int main(int argc, char *argv[]) { // Export animation unique_ptr exporter = createExporter(exportFormat.getValue()); - exporter->exportShapes(inputFilePath, animation, targetShapeSet, std::cout); + exporter->exportAnimation(inputFilePath, animation, targetShapeSet, std::cout); logging::info("Exiting application normally."); } catch (...) {