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>
9 #include "debug_utils.h"
11 #include "flag_field.h"
13 #include "type_utils.h"
15 namespace AudioGrapher
20 * Processing context. Constness only applies to data, not flags
23 template <typename T = DefaultSampleType>
27 // Support older compilers that don't support template base class initialization without template parameters
28 // This will need to be modified if if it's modified above
29 static const ThrowLevel throwLevel = DEFAULT_THROW_LEVEL;
31 BOOST_STATIC_ASSERT (boost::has_trivial_destructor<T>::value);
35 typedef FlagField::Flag Flag;
43 /// Basic constructor with data, frame and channel count
44 ProcessContext (T * data, framecnt_t frames, ChannelCount channels)
45 : _data (data), _frames (frames), _channels (channels)
48 /// Normal copy constructor
49 ProcessContext (ProcessContext<T> const & other)
50 : Throwing<throwLevel>(), _data (other._data), _frames (other._frames), _channels (other._channels), _flags (other._flags)
51 { /* No need to validate data */ }
53 /// "Copy constructor" with unique data, frame and channel count, but copies flags
55 ProcessContext (ProcessContext<Y> const & other, T * data, framecnt_t frames, ChannelCount channels)
56 : Throwing<throwLevel>(), _data (data), _frames (frames), _channels (channels), _flags (other.flags())
59 /// "Copy constructor" with unique data and frame count, but copies channel count and flags
61 ProcessContext (ProcessContext<Y> const & other, T * data, framecnt_t frames)
62 : Throwing<throwLevel>(), _data (data), _frames (frames), _channels (other.channels()), _flags (other.flags())
65 /// "Copy constructor" with unique data, but copies frame and channel count + flags
67 ProcessContext (ProcessContext<Y> const & other, T * data)
68 : Throwing<throwLevel>(), _data (data), _frames (other.frames()), _channels (other.channels()), _flags (other.flags())
69 { /* No need to validate data */ }
71 /// Make new Context out of the beginning of this context
72 ProcessContext beginning (framecnt_t frames)
74 if (throw_level (ThrowProcess) && frames > _frames) {
75 throw Exception (*this, boost::str (boost::format
76 ("Trying to use too many frames of %1% for a new Context: %2% instead of %3%")
77 % DebugUtils::demangled_name (*this) % frames % _frames));
81 return ProcessContext (*this, _data, frames);
84 virtual ~ProcessContext () {}
86 /// \a data points to the array of data to process
87 inline T const * data() const { return _data; }
88 inline T * data() { return _data; }
90 /// \a frames tells how many frames the array pointed by data contains
91 inline framecnt_t const & frames() const { return _frames; }
93 /** \a channels tells how many interleaved channels \a data contains
94 * If \a channels is greater than 1, each channel contains \a frames / \a channels frames of data
96 inline ChannelCount const & channels() const { return _channels; }
98 /// Returns the amount of frames per channel
99 inline framecnt_t frames_per_channel() const { return _frames / _channels; }
103 inline bool has_flag (Flag flag) const { return _flags.has (flag); }
104 inline void set_flag (Flag flag) const { _flags.set (flag); }
105 inline void remove_flag (Flag flag) const { _flags.remove (flag); }
106 inline FlagField const & flags () const { return _flags; }
111 ChannelCount _channels;
113 mutable FlagField _flags;
116 inline void validate_data()
118 if (throw_level (ThrowProcess) && (_frames % _channels != 0)) {
119 throw Exception (*this, boost::str (boost::format
120 ("Number of frames given to %1% was not a multiple of channels: %2% frames with %3% channels")
121 % DebugUtils::demangled_name (*this) % _frames % _channels));
126 /// A process context that allocates and owns it's data buffer
127 template <typename T = DefaultSampleType>
128 class AllocatingProcessContext : public ProcessContext<T>
131 /// Allocates uninitialized memory
132 AllocatingProcessContext (framecnt_t frames, ChannelCount channels)
133 : ProcessContext<T> (new T[frames], frames, channels) {}
135 /// Allocates and copies data from raw buffer
136 AllocatingProcessContext (T const * data, framecnt_t frames, ChannelCount channels)
137 : ProcessContext<T> (new T[frames], frames, channels)
138 { TypeUtils<float>::copy (data, ProcessContext<T>::_data, frames); }
140 /// Copy constructor, copies data from other ProcessContext
141 AllocatingProcessContext (ProcessContext<T> const & other)
142 : ProcessContext<T> (other, new T[other._frames])
143 { TypeUtils<float>::copy (ProcessContext<T>::_data, other._data, other._frames); }
145 /// "Copy constructor" with uninitialized data, unique frame and channel count, but copies flags
147 AllocatingProcessContext (ProcessContext<Y> const & other, framecnt_t frames, ChannelCount channels)
148 : ProcessContext<T> (other, new T[frames], frames, channels) {}
150 /// "Copy constructor" with uninitialized data, unique frame count, but copies channel count and flags
152 AllocatingProcessContext (ProcessContext<Y> const & other, framecnt_t frames)
153 : ProcessContext<T> (other, new T[frames], frames, other.channels()) {}
155 /// "Copy constructor" uninitialized data, that copies frame and channel count + flags
157 AllocatingProcessContext (ProcessContext<Y> const & other)
158 : ProcessContext<T> (other, new T[other._frames]) {}
160 ~AllocatingProcessContext () { delete [] ProcessContext<T>::_data; }
163 /// A wrapper for a const ProcesContext which can be created from const data
164 template <typename T = DefaultSampleType>
165 class ConstProcessContext
168 /// Basic constructor with data, frame and channel count
169 ConstProcessContext (T const * data, framecnt_t frames, ChannelCount channels)
170 : context (const_cast<T *>(data), frames, channels) {}
172 /// Copy constructor from const ProcessContext
173 ConstProcessContext (ProcessContext<T> const & other)
174 : context (const_cast<ProcessContext<T> &> (other)) {}
176 /// "Copy constructor", with unique data, frame and channel count, but copies flags
177 template<typename ProcessContext>
178 ConstProcessContext (ProcessContext const & other, T const * data, framecnt_t frames, ChannelCount channels)
179 : context (other, const_cast<T *>(data), frames, channels) {}
181 /// "Copy constructor", with unique data and frame count, but copies channel count and flags
182 template<typename ProcessContext>
183 ConstProcessContext (ProcessContext const & other, T const * data, framecnt_t frames)
184 : context (other, const_cast<T *>(data), frames) {}
186 /// "Copy constructor", with unique data, but copies frame and channel count + flags
187 template<typename ProcessContext>
188 ConstProcessContext (ProcessContext const & other, T const * data)
189 : context (other, const_cast<T *>(data)) {}
191 inline operator ProcessContext<T> const & () { return context; }
192 inline ProcessContext<T> const & operator() () { return context; }
193 inline ProcessContext<T> const * operator& () { return &context; }
196 ProcessContext<T> const context;
201 #endif // AUDIOGRAPHER_PROCESS_CONTEXT_H