Update audiographer GPL boilerplate and (C) from git log
[ardour.git] / libs / audiographer / audiographer / general / cmdpipe_writer.h
1 #ifndef AUDIOGRAPHER_CMDPIPE_WRITER_H
2 #define AUDIOGRAPHER_CMDPIPE_WRITER_H
3
4 #include <string>
5
6 #include <boost/format.hpp>
7
8 #include "audiographer/flag_debuggable.h"
9 #include "audiographer/sink.h"
10 #include "audiographer/types.h"
11
12 #include "pbd/signals.h"
13 #include "pbd/system_exec.h"
14
15 namespace AudioGrapher
16 {
17
18 /** Writer for audio files using libsndfile.
19   * Only short, int and float are valid template parameters
20   */
21 template <typename T = DefaultSampleType>
22 class CmdPipeWriter
23   : public Sink<T>
24   , public Throwing<>
25   , public FlagDebuggable<>
26 {
27 public:
28         CmdPipeWriter (PBD::SystemExec* proc, std::string const& path)
29                 : samples_written (0)
30                 , _proc (proc)
31                 , _path (path)
32         {
33                 add_supported_flag (ProcessContext<T>::EndOfInput);
34         }
35
36         virtual ~CmdPipeWriter () {
37                 delete _proc;
38         }
39
40         samplecnt_t get_samples_written() const { return samples_written; }
41         void       reset_samples_written_count() { samples_written = 0; }
42
43         void close (void)
44         {
45                 _proc->terminate ();
46         }
47
48         virtual void process (ProcessContext<T> const & c)
49         {
50                 check_flags (*this, c);
51
52                 if (!_proc || !_proc->is_running()) {
53                         throw Exception (*this, boost::str (boost::format
54                                                 ("Target encoder process is not running")));
55                 }
56
57                 const size_t bytes_per_sample = sizeof (T);
58                 samplecnt_t const written = _proc->write_to_stdin ((const void*) c.data(), c.samples() * bytes_per_sample) / bytes_per_sample;
59                 samples_written += written;
60
61                 if (throw_level (ThrowProcess) && written != c.samples()) {
62                         throw Exception (*this, boost::str (boost::format
63                                                 ("Could not write data to output file")));
64                 }
65
66                 if (c.has_flag(ProcessContext<T>::EndOfInput)) {
67                         _proc->close_stdin ();
68                         FileWritten (_path);
69                 }
70         }
71
72         using Sink<T>::process;
73
74         PBD::Signal1<void, std::string> FileWritten;
75
76 private:
77         CmdPipeWriter (CmdPipeWriter const & other) {}
78
79         samplecnt_t samples_written;
80         PBD::SystemExec* _proc;
81         std::string _path;
82 };
83
84 } // namespace
85
86 #endif
87