diff options
author | Sakari Bergen <sakari.bergen@beatwaves.net> | 2010-03-15 19:11:48 +0000 |
---|---|---|
committer | Sakari Bergen <sakari.bergen@beatwaves.net> | 2010-03-15 19:11:48 +0000 |
commit | 830911f6f9451d83a58043b3f9084d3caa164b7b (patch) | |
tree | f4ca4e3d86b51d66e7cecfb6b370cc4eb553e2d7 /libs/audiographer/audiographer/general/deinterleaver.h | |
parent | 44f4b84551d36ef4103d09452768f5ba53e0002c (diff) |
Fix export, which has been broken since the boost::signals2 changes. Also update Audiographer, bacause of its incomplete sndfile handling. Audiographer is equal to revision 74
git-svn-id: svn://localhost/ardour2/branches/3.0@6760 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/audiographer/audiographer/general/deinterleaver.h')
-rw-r--r-- | libs/audiographer/audiographer/general/deinterleaver.h | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/libs/audiographer/audiographer/general/deinterleaver.h b/libs/audiographer/audiographer/general/deinterleaver.h new file mode 100644 index 0000000000..2a6ad64ef2 --- /dev/null +++ b/libs/audiographer/audiographer/general/deinterleaver.h @@ -0,0 +1,109 @@ +#ifndef AUDIOGRAPHER_DEINTERLEAVER_H +#define AUDIOGRAPHER_DEINTERLEAVER_H + +#include "audiographer/types.h" +#include "audiographer/source.h" +#include "audiographer/sink.h" +#include "audiographer/exception.h" +#include "audiographer/utils/identity_vertex.h" + +#include <vector> + +namespace AudioGrapher +{ + +/// Converts on stream of interleaved data to many streams of uninterleaved data. +template<typename T = DefaultSampleType> +class DeInterleaver + : public Sink<T> + , public Throwing<> +{ + private: + typedef boost::shared_ptr<IdentityVertex<T> > OutputPtr; + + public: + /// Constructor. \n RT safe + DeInterleaver() + : channels (0) + , max_frames (0) + , buffer (0) + {} + + ~DeInterleaver() { reset(); } + + typedef boost::shared_ptr<Source<T> > SourcePtr; + + /// Inits the deinterleaver. Must be called before using. \n Not RT safe + void init (unsigned int num_channels, nframes_t max_frames_per_channel) + { + reset(); + channels = num_channels; + max_frames = max_frames_per_channel; + buffer = new T[max_frames]; + + for (unsigned int i = 0; i < channels; ++i) { + outputs.push_back (OutputPtr (new IdentityVertex<T>)); + } + } + + /// Returns an output indexed by \a channel \n RT safe + SourcePtr output (unsigned int channel) + { + if (throw_level (ThrowObject) && channel >= channels) { + throw Exception (*this, "channel out of range"); + } + + return outputs[channel]; + } + + /// Deinterleaves data and outputs it to the outputs. \n RT safe + void process (ProcessContext<T> const & c) + { + nframes_t frames = c.frames(); + T const * data = c.data(); + + nframes_t const frames_per_channel = frames / channels; + + if (throw_level (ThrowProcess) && c.channels() != channels) { + throw Exception (*this, "wrong amount of channels given to process()"); + } + + if (throw_level (ThrowProcess) && frames_per_channel > max_frames) { + throw Exception (*this, "too many frames given to process()"); + } + + unsigned int channel = 0; + for (typename std::vector<OutputPtr>::iterator it = outputs.begin(); it != outputs.end(); ++it, ++channel) { + if (!*it) { continue; } + + for (unsigned int i = 0; i < frames_per_channel; ++i) { + buffer[i] = data[channel + (channels * i)]; + } + + ProcessContext<T> c_out (c, buffer, frames_per_channel, 1); + (*it)->process (c_out); + } + } + + using Sink<T>::process; + + private: + + void reset () + { + outputs.clear(); + delete [] buffer; + buffer = 0; + channels = 0; + max_frames = 0; + } + + std::vector<OutputPtr> outputs; + unsigned int channels; + nframes_t max_frames; + T * buffer; +}; + +} // namespace + +#endif // AUDIOGRAPHER_DEINTERLEAVER_H |