summaryrefslogtreecommitdiff
path: root/libs/audiographer/audiographer/general/deinterleaver.h
diff options
context:
space:
mode:
authorSakari Bergen <sakari.bergen@beatwaves.net>2010-03-15 19:11:48 +0000
committerSakari Bergen <sakari.bergen@beatwaves.net>2010-03-15 19:11:48 +0000
commit830911f6f9451d83a58043b3f9084d3caa164b7b (patch)
treef4ca4e3d86b51d66e7cecfb6b370cc4eb553e2d7 /libs/audiographer/audiographer/general/deinterleaver.h
parent44f4b84551d36ef4103d09452768f5ba53e0002c (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.h109
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