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
19 * Processing context. Constness only applies to data, not flags
22 template <typename T = DefaultSampleType>
27 BOOST_STATIC_ASSERT (boost::has_trivial_destructor<T>::value);
31 typedef FlagField::Flag Flag;
39 /// Basic constructor with data, frame and channel count
40 ProcessContext (T * data, framecnt_t frames, ChannelCount channels)
41 : _data (data), _frames (frames), _channels (channels)
44 /// Normal copy constructor
45 ProcessContext (ProcessContext<T> const & other)
46 : _data (other._data), _frames (other._frames), _channels (other._channels), _flags (other._flags)
47 { /* No need to validate data */ }
49 /// "Copy constructor" with unique data, frame and channel count, but copies flags
51 ProcessContext (ProcessContext<Y> const & other, T * data, framecnt_t frames, ChannelCount channels)
52 : _data (data), _frames (frames), _channels (channels), _flags (other.flags())
55 /// "Copy constructor" with unique data and frame count, but copies channel count and flags
57 ProcessContext (ProcessContext<Y> const & other, T * data, framecnt_t frames)
58 : _data (data), _frames (frames), _channels (other.channels()), _flags (other.flags())
61 /// "Copy constructor" with unique data, but copies frame and channel count + flags
63 ProcessContext (ProcessContext<Y> const & other, T * data)
64 : _data (data), _frames (other.frames()), _channels (other.channels()), _flags (other.flags())
65 { /* No need to validate data */ }
67 /// Make new Context out of the beginning of this context
68 ProcessContext beginning (framecnt_t frames)
70 if (throw_level (ThrowProcess) && frames > _frames) {
71 throw Exception (*this, boost::str (boost::format
72 ("Trying to use too many frames of %1% for a new Context: %2% instead of %3%")
73 % DebugUtils::demangled_name (*this) % frames % _frames));
77 return ProcessContext (*this, _data, frames);
80 virtual ~ProcessContext () {}
82 /// \a data points to the array of data to process
83 inline T const * data() const { return _data; }
84 inline T * data() { return _data; }
86 /// \a frames tells how many frames the array pointed by data contains
87 inline framecnt_t const & frames() const { return _frames; }
89 /** \a channels tells how many interleaved channels \a data contains
90 * If \a channels is greater than 1, each channel contains \a frames / \a channels frames of data
92 inline ChannelCount const & channels() const { return _channels; }
94 /// Returns the amount of frames per channel
95 inline framecnt_t frames_per_channel() const { return _frames / _channels; }
99 inline bool has_flag (Flag flag) const { return _flags.has (flag); }
100 inline void set_flag (Flag flag) const { _flags.set (flag); }
101 inline void remove_flag (Flag flag) const { _flags.remove (flag); }
102 inline FlagField const & flags () const { return _flags; }
107 ChannelCount _channels;
109 mutable FlagField _flags;
112 inline void validate_data()
114 if (throw_level (ThrowProcess) && (_frames % _channels != 0)) {
115 throw Exception (*this, boost::str (boost::format
116 ("Number of frames given to %1% was not a multiple of channels: %2% frames with %3% channels")
117 % DebugUtils::demangled_name (*this) % _frames % _channels));
122 /// A process context that allocates and owns it's data buffer
123 template <typename T = DefaultSampleType>
124 class AllocatingProcessContext : public ProcessContext<T>
127 /// Allocates uninitialized memory
128 AllocatingProcessContext (framecnt_t frames, ChannelCount channels)
129 : ProcessContext<T> (new T[frames], frames, channels) {}
131 /// Allocates and copies data from raw buffer
132 AllocatingProcessContext (T const * data, framecnt_t frames, ChannelCount channels)
133 : ProcessContext<T> (new T[frames], frames, channels)
134 { TypeUtils<float>::copy (data, ProcessContext<T>::_data, frames); }
136 /// Copy constructor, copies data from other ProcessContext
137 AllocatingProcessContext (ProcessContext<T> const & other)
138 : ProcessContext<T> (other, new T[other._frames])
139 { TypeUtils<float>::copy (ProcessContext<T>::_data, other._data, other._frames); }
141 /// "Copy constructor" with uninitialized data, unique frame and channel count, but copies flags
143 AllocatingProcessContext (ProcessContext<Y> const & other, framecnt_t frames, ChannelCount channels)
144 : ProcessContext<T> (other, new T[frames], frames, channels) {}
146 /// "Copy constructor" with uninitialized data, unique frame count, but copies channel count and flags
148 AllocatingProcessContext (ProcessContext<Y> const & other, framecnt_t frames)
149 : ProcessContext<T> (other, new T[frames], frames, other.channels()) {}
151 /// "Copy constructor" uninitialized data, that copies frame and channel count + flags
153 AllocatingProcessContext (ProcessContext<Y> const & other)
154 : ProcessContext<T> (other, new T[other._frames]) {}
156 ~AllocatingProcessContext () { delete [] ProcessContext<T>::_data; }
159 /// A wrapper for a const ProcesContext which can be created from const data
160 template <typename T = DefaultSampleType>
161 class ConstProcessContext
164 /// Basic constructor with data, frame and channel count
165 ConstProcessContext (T const * data, framecnt_t frames, ChannelCount channels)
166 : context (const_cast<T *>(data), frames, channels) {}
168 /// Copy constructor from const ProcessContext
169 ConstProcessContext (ProcessContext<T> const & other)
170 : context (const_cast<ProcessContext<T> &> (other)) {}
172 /// "Copy constructor", with unique data, frame and channel count, but copies flags
173 template<typename ProcessContext>
174 ConstProcessContext (ProcessContext const & other, T const * data, framecnt_t frames, ChannelCount channels)
175 : context (other, const_cast<T *>(data), frames, channels) {}
177 /// "Copy constructor", with unique data and frame count, but copies channel count and flags
178 template<typename ProcessContext>
179 ConstProcessContext (ProcessContext const & other, T const * data, framecnt_t frames)
180 : context (other, const_cast<T *>(data), frames) {}
182 /// "Copy constructor", with unique data, but copies frame and channel count + flags
183 template<typename ProcessContext>
184 ConstProcessContext (ProcessContext const & other, T const * data)
185 : context (other, const_cast<T *>(data)) {}
187 inline operator ProcessContext<T> const & () { return context; }
188 inline ProcessContext<T> const & operator() () { return context; }
189 inline ProcessContext<T> const * operator& () { return &context; }
192 ProcessContext<T> const context;
197 #endif // AUDIOGRAPHER_PROCESS_CONTEXT_H