aa3c0cc89920115738e0306b65c8ab89e4e5ccb0
[ardour.git] / libs / audiographer / audiographer / sndfile / sndfile_reader.h
1 #ifndef AUDIOGRAPHER_SNDFILE_READER_H
2 #define AUDIOGRAPHER_SNDFILE_READER_H
3
4 #include "audiographer/utils/listed_source.h"
5 #include "audiographer/process_context.h"
6 #include "audiographer/sndfile/sndfile_base.h"
7
8 namespace AudioGrapher
9 {
10
11 /** Reader for audio files using libsndfile.
12   * Only short, int and float are valid template parameters
13   */
14 template<typename T = DefaultSampleType>
15 class SndfileReader
16   : public virtual SndfileBase
17   , public ListedSource<T>
18   , public Throwing<>
19 {
20   public:
21         
22         SndfileReader (std::string const & path) : SndfileHandle (path) {}
23         virtual ~SndfileReader () {}
24
25         SndfileReader (SndfileReader const & other) : SndfileHandle (other) {}
26         using SndfileHandle::operator=;
27         
28         /** Read data into buffer in \a context, only the data is modified (not frame count)
29          *  Note that the data read is output to the outputs, as well as read into the context
30          *  \return number of frames read
31          */
32         framecnt_t read (ProcessContext<T> & context)
33         {
34                 if (throw_level (ThrowStrict) && context.channels() != channels() ) {
35                         throw Exception (*this, boost::str (boost::format
36                                 ("Wrong number of channels given to process(), %1% instead of %2%")
37                                 % context.channels() % channels()));
38                 }
39                 
40                 framecnt_t const frames_read = SndfileHandle::read (context.data(), context.frames());
41                 ProcessContext<T> c_out = context.beginning (frames_read);
42                 
43                 if (frames_read < context.frames()) {
44                         c_out.set_flag (ProcessContext<T>::EndOfInput);
45                 }
46                 this->output (c_out);
47                 return frames_read;
48         }
49         
50   protected:
51         /// SndfileHandle has to be constructed directly by deriving classes
52         SndfileReader () {}
53 };
54
55 } // namespace
56
57 #endif // AUDIOGRAPHER_SNDFILE_READER_H