1 #ifndef AUDIOGRAPHER_DEINTERLEAVER_H
2 #define AUDIOGRAPHER_DEINTERLEAVER_H
4 #include "audiographer/types.h"
5 #include "audiographer/source.h"
6 #include "audiographer/sink.h"
7 #include "audiographer/exception.h"
8 #include "audiographer/utils/identity_vertex.h"
12 namespace AudioGrapher
15 /// Converts on stream of interleaved data to many streams of uninterleaved data.
16 template<typename T = DefaultSampleType>
22 typedef boost::shared_ptr<IdentityVertex<T> > OutputPtr;
25 /// Constructor. \n RT safe
32 ~DeInterleaver() { reset(); }
34 typedef boost::shared_ptr<Source<T> > SourcePtr;
36 /// Inits the deinterleaver. Must be called before using. \n Not RT safe
37 void init (unsigned int num_channels, framecnt_t max_frames_per_channel)
40 channels = num_channels;
41 max_frames = max_frames_per_channel;
42 buffer = new T[max_frames];
44 for (unsigned int i = 0; i < channels; ++i) {
45 outputs.push_back (OutputPtr (new IdentityVertex<T>));
49 /// Returns an output indexed by \a channel \n RT safe
50 SourcePtr output (unsigned int channel)
52 if (throw_level (ThrowObject) && channel >= channels) {
53 throw Exception (*this, "channel out of range");
56 return outputs[channel];
59 /// Deinterleaves data and outputs it to the outputs. \n RT safe
60 void process (ProcessContext<T> const & c)
62 framecnt_t frames = c.frames();
63 T const * data = c.data();
65 framecnt_t const frames_per_channel = frames / channels;
67 if (throw_level (ThrowProcess) && c.channels() != channels) {
68 throw Exception (*this, "wrong amount of channels given to process()");
71 if (throw_level (ThrowProcess) && frames_per_channel > max_frames) {
72 throw Exception (*this, "too many frames given to process()");
75 unsigned int channel = 0;
76 for (typename std::vector<OutputPtr>::iterator it = outputs.begin(); it != outputs.end(); ++it, ++channel) {
77 if (!*it) { continue; }
79 for (unsigned int i = 0; i < frames_per_channel; ++i) {
80 buffer[i] = data[channel + (channels * i)];
83 ProcessContext<T> c_out (c, buffer, frames_per_channel, 1);
84 (*it)->process (c_out);
88 using Sink<T>::process;
101 std::vector<OutputPtr> outputs;
102 unsigned int channels;
103 framecnt_t max_frames;
109 #endif // AUDIOGRAPHER_DEINTERLEAVER_H