1 #ifndef AUDIOGRAPHER_PROCESS_CONTEXT_H
2 #define AUDIOGRAPHER_PROCESS_CONTEXT_H
4 #include <boost/static_assert.hpp>
5 #include <boost/type_traits.hpp>
6 #include <boost/format.hpp>
8 #include "audiographer/visibility.h"
10 #include "debug_utils.h"
12 #include "flag_field.h"
14 #include "type_utils.h"
16 namespace AudioGrapher
21 * Processing context. Constness only applies to data, not flags
24 template <typename T = DefaultSampleType>
25 class LIBAUDIOGRAPHER_API ProcessContext
28 // Support older compilers that don't support template base class initialization without template parameters
29 // This will need to be modified if if it's modified above
30 static const ThrowLevel throwLevel = DEFAULT_THROW_LEVEL;
32 BOOST_STATIC_ASSERT (boost::has_trivial_destructor<T>::value);
36 typedef FlagField::Flag Flag;
44 /// Basic constructor with data, frame and channel count
45 ProcessContext (T * data, framecnt_t frames, ChannelCount channels)
46 : _data (data), _frames (frames), _channels (channels)
49 /// Normal copy constructor
50 ProcessContext (ProcessContext<T> const & other)
51 : Throwing<throwLevel>(), _data (other._data), _frames (other._frames), _channels (other._channels), _flags (other._flags)
52 { /* No need to validate data */ }
54 /// "Copy constructor" with unique data, frame and channel count, but copies flags
56 ProcessContext (ProcessContext<Y> const & other, T * data, framecnt_t frames, ChannelCount channels)
57 : Throwing<throwLevel>(), _data (data), _frames (frames), _channels (channels), _flags (other.flags())
60 /// "Copy constructor" with unique data and frame count, but copies channel count and flags
62 ProcessContext (ProcessContext<Y> const & other, T * data, framecnt_t frames)
63 : Throwing<throwLevel>(), _data (data), _frames (frames), _channels (other.channels()), _flags (other.flags())
66 /// "Copy constructor" with unique data, but copies frame and channel count + flags
68 ProcessContext (ProcessContext<Y> const & other, T * data)
69 : Throwing<throwLevel>(), _data (data), _frames (other.frames()), _channels (other.channels()), _flags (other.flags())
70 { /* No need to validate data */ }
72 /// Make new Context out of the beginning of this context
73 ProcessContext beginning (framecnt_t frames)
75 if (throw_level (ThrowProcess) && frames > _frames) {
76 throw Exception (*this, boost::str (boost::format
77 ("Trying to use too many frames of %1% for a new Context: %2% instead of %3%")
78 % DebugUtils::demangled_name (*this) % frames % _frames));
82 return ProcessContext (*this, _data, frames);
85 virtual ~ProcessContext () {}
87 /// \a data points to the array of data to process
88 inline T const * data() const { return _data; }
89 inline T * data() { return _data; }
91 /// \a frames tells how many frames the array pointed by data contains
92 inline framecnt_t const & frames() const { return _frames; }
94 /** \a channels tells how many interleaved channels \a data contains
95 * If \a channels is greater than 1, each channel contains \a frames / \a channels frames of data
97 inline ChannelCount const & channels() const { return _channels; }
99 /// Returns the amount of frames per channel
100 inline framecnt_t frames_per_channel() const { return _frames / _channels; }
104 inline bool has_flag (Flag flag) const { return _flags.has (flag); }
105 inline void set_flag (Flag flag) const { _flags.set (flag); }
106 inline void remove_flag (Flag flag) const { _flags.remove (flag); }
107 inline FlagField const & flags () const { return _flags; }
112 ChannelCount _channels;
114 mutable FlagField _flags;
117 inline void validate_data()
119 if (throw_level (ThrowProcess) && (_frames % _channels != 0)) {
120 throw Exception (*this, boost::str (boost::format
121 ("Number of frames given to %1% was not a multiple of channels: %2% frames with %3% channels")
122 % DebugUtils::demangled_name (*this) % _frames % _channels));
127 /// A process context that allocates and owns it's data buffer
128 template <typename T = DefaultSampleType>
129 class LIBAUDIOGRAPHER_API AllocatingProcessContext : public ProcessContext<T>
132 /// Allocates uninitialized memory
133 AllocatingProcessContext (framecnt_t frames, ChannelCount channels)
134 : ProcessContext<T> (new T[frames], frames, channels) {}
136 /// Allocates and copies data from raw buffer
137 AllocatingProcessContext (T const * data, framecnt_t frames, ChannelCount channels)
138 : ProcessContext<T> (new T[frames], frames, channels)
139 { TypeUtils<float>::copy (data, ProcessContext<T>::_data, frames); }
141 /// Copy constructor, copies data from other ProcessContext
142 AllocatingProcessContext (ProcessContext<T> const & other)
143 : ProcessContext<T> (other, new T[other._frames])
144 { TypeUtils<float>::copy (ProcessContext<T>::_data, other._data, other._frames); }
146 /// "Copy constructor" with uninitialized data, unique frame and channel count, but copies flags
148 AllocatingProcessContext (ProcessContext<Y> const & other, framecnt_t frames, ChannelCount channels)
149 : ProcessContext<T> (other, new T[frames], frames, channels) {}
151 /// "Copy constructor" with uninitialized data, unique frame count, but copies channel count and flags
153 AllocatingProcessContext (ProcessContext<Y> const & other, framecnt_t frames)
154 : ProcessContext<T> (other, new T[frames], frames, other.channels()) {}
156 /// "Copy constructor" uninitialized data, that copies frame and channel count + flags
158 AllocatingProcessContext (ProcessContext<Y> const & other)
159 : ProcessContext<T> (other, new T[other._frames]) {}
161 ~AllocatingProcessContext () { delete [] ProcessContext<T>::_data; }
164 /// A wrapper for a const ProcesContext which can be created from const data
165 template <typename T = DefaultSampleType>
166 class LIBAUDIOGRAPHER_API ConstProcessContext
169 /// Basic constructor with data, frame and channel count
170 ConstProcessContext (T const * data, framecnt_t frames, ChannelCount channels)
171 : context (const_cast<T *>(data), frames, channels) {}
173 /// Copy constructor from const ProcessContext
174 ConstProcessContext (ProcessContext<T> const & other)
175 : context (const_cast<ProcessContext<T> &> (other)) {}
177 /// "Copy constructor", with unique data, frame and channel count, but copies flags
178 template<typename ProcessContext>
179 ConstProcessContext (ProcessContext const & other, T const * data, framecnt_t frames, ChannelCount channels)
180 : context (other, const_cast<T *>(data), frames, channels) {}
182 /// "Copy constructor", with unique data and frame count, but copies channel count and flags
183 template<typename ProcessContext>
184 ConstProcessContext (ProcessContext const & other, T const * data, framecnt_t frames)
185 : context (other, const_cast<T *>(data), frames) {}
187 /// "Copy constructor", with unique data, but copies frame and channel count + flags
188 template<typename ProcessContext>
189 ConstProcessContext (ProcessContext const & other, T const * data)
190 : context (other, const_cast<T *>(data)) {}
192 inline operator ProcessContext<T> const & () { return context; }
193 inline ProcessContext<T> const & operator() () { return context; }
194 inline ProcessContext<T> const * operator& () { return &context; }
197 ProcessContext<T> const context;
202 #endif // AUDIOGRAPHER_PROCESS_CONTEXT_H