Set cursor to hint that you can drag automation up and down in object/range link...
[ardour.git] / libs / audiographer / audiographer / sndfile / sndfile_writer.h
1 #ifndef AUDIOGRAPHER_SNDFILE_WRITER_H
2 #define AUDIOGRAPHER_SNDFILE_WRITER_H
3
4 #include <boost/signals2.hpp>
5 #include <boost/format.hpp>
6 #include <string>
7
8 #include "audiographer/flag_debuggable.h"
9 #include "audiographer/sink.h"
10 #include "audiographer/types.h"
11 #include "audiographer/sndfile/sndfile_base.h"
12
13 #include "pbd/signals.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 SndfileWriter
23   : public virtual SndfileBase
24   , public Sink<T>
25   , public Throwing<>
26   , public FlagDebuggable<>
27 {
28   public:
29         SndfileWriter (std::string const & path, int format, ChannelCount channels, nframes_t samplerate)
30           : SndfileHandle (path, Write, format, channels, samplerate)
31           , path (path)
32         {
33                 add_supported_flag (ProcessContext<T>::EndOfInput);
34         }
35         
36         virtual ~SndfileWriter () {}
37         
38         SndfileWriter (SndfileWriter const & other) : SndfileHandle (other) {}
39         using SndfileHandle::operator=;
40         
41         /// Writes data to file
42         void process (ProcessContext<T> const & c)
43         {
44                 check_flags (*this, c);
45                 
46                 if (throw_level (ThrowStrict) && c.channels() != channels()) {
47                         throw Exception (*this, boost::str (boost::format
48                                 ("Wrong number of channels given to process(), %1% instead of %2%")
49                                 % c.channels() % channels()));
50                 }
51                 
52                 nframes_t written = write (c.data(), c.frames());
53                 if (throw_level (ThrowProcess) && written != c.frames()) {
54                         throw Exception (*this, boost::str (boost::format
55                                 ("Could not write data to output file (%1%)")
56                                 % strError()));
57                 }
58
59                 if (c.has_flag(ProcessContext<T>::EndOfInput)) {
60                         writeSync();
61                         FileWritten (path);
62                 }
63         }
64         
65         using Sink<T>::process;
66         
67         PBD::Signal1<void, std::string> FileWritten;
68
69   protected:
70         /// SndfileHandle has to be constructed directly by deriving classes
71         SndfileWriter ()
72         {
73                 add_supported_flag (ProcessContext<T>::EndOfInput);
74         }
75         
76   protected:
77         std::string path;
78 };
79
80 } // namespace
81
82 #endif // AUDIOGRAPHER_SNDFILE_WRITER_H