diff options
author | Robin Gareus <robin@gareus.org> | 2018-11-19 03:30:40 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2018-11-19 03:30:40 +0100 |
commit | e4cbd5115e34ff99aa8c85b70870e6ca00ea14d6 (patch) | |
tree | 8a6907f3dd5859c9013886bbef4aeda8f5b441e1 /libs/audiographer | |
parent | a5b38fd6dc9ce9d1fb450da493adbc02b787c5e8 (diff) |
Add Pipe-to-command export backend
A first step towards allowing external encoders without intermediate
temporary file.
Diffstat (limited to 'libs/audiographer')
-rw-r--r-- | libs/audiographer/audiographer/general/cmdpipe_writer.h | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/libs/audiographer/audiographer/general/cmdpipe_writer.h b/libs/audiographer/audiographer/general/cmdpipe_writer.h new file mode 100644 index 0000000000..74dc604b8b --- /dev/null +++ b/libs/audiographer/audiographer/general/cmdpipe_writer.h @@ -0,0 +1,87 @@ +#ifndef AUDIOGRAPHER_CMDPIPE_WRITER_H +#define AUDIOGRAPHER_CMDPIPE_WRITER_H + +#include <string> + +#include <boost/format.hpp> + +#include "audiographer/flag_debuggable.h" +#include "audiographer/sink.h" +#include "audiographer/types.h" + +#include "pbd/signals.h" +#include "pbd/system_exec.h" + +namespace AudioGrapher +{ + +/** Writer for audio files using libsndfile. + * Only short, int and float are valid template parameters + */ +template <typename T = DefaultSampleType> +class CmdPipeWriter + : public Sink<T> + , public Throwing<> + , public FlagDebuggable<> +{ +public: + CmdPipeWriter (PBD::SystemExec* proc, std::string const& path) + : samples_written (0) + , _proc (proc) + , _path (path) + { + add_supported_flag (ProcessContext<T>::EndOfInput); + } + + virtual ~CmdPipeWriter () { + delete _proc; + } + + samplecnt_t get_samples_written() const { return samples_written; } + void reset_samples_written_count() { samples_written = 0; } + + void close (void) + { + _proc->terminate (); + } + + virtual void process (ProcessContext<T> const & c) + { + check_flags (*this, c); + + if (!_proc || !_proc->is_running()) { + throw Exception (*this, boost::str (boost::format + ("Target encoder process is not running"))); + } + + const size_t bytes_per_sample = sizeof (T); + samplecnt_t const written = _proc->write_to_stdin ((const void*) c.data(), c.samples() * bytes_per_sample) / bytes_per_sample; + samples_written += written; + + if (throw_level (ThrowProcess) && written != c.samples()) { + throw Exception (*this, boost::str (boost::format + ("Could not write data to output file"))); + } + + if (c.has_flag(ProcessContext<T>::EndOfInput)) { + _proc->close_stdin (); + FileWritten (_path); + } + } + + using Sink<T>::process; + + PBD::Signal1<void, std::string> FileWritten; + +private: + CmdPipeWriter (CmdPipeWriter const & other) {} + + samplecnt_t samples_written; + PBD::SystemExec* _proc; + std::string _path; +}; + +} // namespace + +#endif + |