From 2c67e71e98dd29337797c720d16b1031f2d2436c Mon Sep 17 00:00:00 2001 From: Tim Mayberry Date: Sun, 4 Dec 2016 22:31:06 +1000 Subject: [PATCH] Always signal writing to file is complete at end of the export process With end trim enabled, the only case that would successfully export was if there was at least some samples above the silence threshold in the last export processing block. The issue was that the EndOfInput flag was not being passed to AudioGrapher::SndFileWriter::process which would then call sf_write_sync and emit the FileWritten signal to start post processing. Fix that by always passing the EndOfInput flag in the last export process cycle. Related: #6412 --- .../audiographer/general/silence_trimmer.h | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/libs/audiographer/audiographer/general/silence_trimmer.h b/libs/audiographer/audiographer/general/silence_trimmer.h index 25f23039c7..82981d58b6 100644 --- a/libs/audiographer/audiographer/general/silence_trimmer.h +++ b/libs/audiographer/audiographer/general/silence_trimmer.h @@ -149,10 +149,10 @@ class /*LIBAUDIOGRAPHER_API*/ SilenceTrimmer if (throw_level (ThrowStrict) && in_end) { throw Exception(*this, "process() after reaching end of input"); } - in_end = c.has_flag (ProcessContext::EndOfInput); - // If adding to end, delay end of input propagation - if (add_to_end) { c.remove_flag(ProcessContext::EndOfInput); } + // delay end of input propagation until after all output is complete + in_end = c.has_flag (ProcessContext::EndOfInput); + c.remove_flag (ProcessContext::EndOfInput); framecnt_t frame_index = 0; @@ -194,12 +194,8 @@ class /*LIBAUDIOGRAPHER_API*/ SilenceTrimmer " adding to beginning" << std::endl; } - ConstProcessContext c_copy (c); - if (has_data) { // There will be more output, so remove flag - c_copy().remove_flag (ProcessContext::EndOfInput); - } add_to_beginning *= c.channels(); - output_silence_frames (c_copy, add_to_beginning); + output_silence_frames (c, add_to_beginning); } // If we are not trimming the beginning, output everything @@ -249,10 +245,6 @@ class /*LIBAUDIOGRAPHER_API*/ SilenceTrimmer ListedSource::output (c); } - if (in_end) { - c.set_flag (ProcessContext::EndOfInput); - } - // Finally, if in end, add silence to end if (in_end && add_to_end) { if (debug_level (DebugVerbose)) { @@ -261,8 +253,19 @@ class /*LIBAUDIOGRAPHER_API*/ SilenceTrimmer } add_to_end *= c.channels(); - output_silence_frames (c, add_to_end, true); + output_silence_frames (c, add_to_end); } + + if (in_end) { + // reset flag removed previous to processing above + c.set_flag (ProcessContext::EndOfInput); + + // Finally mark write complete by writing nothing with EndOfInput set + ConstProcessContext c_out(c, silence_buffer, 0); + c_out().set_flag (ProcessContext::EndOfInput); + ListedSource::output (c_out); + } + } using Sink::process; @@ -282,10 +285,9 @@ class /*LIBAUDIOGRAPHER_API*/ SilenceTrimmer return false; } - void output_silence_frames (ProcessContext const & c, framecnt_t & total_frames, bool adding_to_end = false) + void output_silence_frames (ProcessContext const & c, framecnt_t & total_frames) { - bool end_of_input = c.has_flag (ProcessContext::EndOfInput); - c.remove_flag (ProcessContext::EndOfInput); + assert (!c.has_flag (ProcessContext::EndOfInput)); while (total_frames > 0) { framecnt_t frames = std::min (silence_buffer_size, total_frames); @@ -296,18 +298,8 @@ class /*LIBAUDIOGRAPHER_API*/ SilenceTrimmer total_frames -= frames; ConstProcessContext c_out (c, silence_buffer, frames); - - // boolean commentation :) - bool const no_more_silence_will_be_added = adding_to_end || (add_to_end == 0); - bool const is_last_frame_output_in_this_function = (total_frames == 0); - if (end_of_input && no_more_silence_will_be_added && is_last_frame_output_in_this_function) { - c_out().set_flag (ProcessContext::EndOfInput); - } ListedSource::output (c_out); } - - // Add the flag back if it was removed - if (end_of_input) { c.set_flag (ProcessContext::EndOfInput); } }