1 #ifndef AUDIOGRAPHER_DEINTERLEAVER_H
2 #define AUDIOGRAPHER_DEINTERLEAVER_H
4 #include "audiographer/visibility.h"
5 #include "audiographer/types.h"
6 #include "audiographer/source.h"
7 #include "audiographer/sink.h"
8 #include "audiographer/exception.h"
9 #include "audiographer/utils/identity_vertex.h"
13 namespace AudioGrapher
16 /// Converts on stream of interleaved data to many streams of uninterleaved data.
17 template<typename T = DefaultSampleType>
18 class /*LIBAUDIOGRAPHER_API*/ DeInterleaver
23 typedef boost::shared_ptr<IdentityVertex<T> > OutputPtr;
26 /// Constructor. \n RT safe
33 ~DeInterleaver() { reset(); }
35 typedef boost::shared_ptr<Source<T> > SourcePtr;
37 /// Inits the deinterleaver. Must be called before using. \n Not RT safe
38 void init (unsigned int num_channels, samplecnt_t max_samples_per_channel)
41 channels = num_channels;
42 max_samples = max_samples_per_channel;
43 buffer = new T[max_samples];
45 for (unsigned int i = 0; i < channels; ++i) {
46 outputs.push_back (OutputPtr (new IdentityVertex<T>));
50 /// Returns an output indexed by \a channel \n RT safe
51 SourcePtr output (unsigned int channel)
53 if (throw_level (ThrowObject) && channel >= channels) {
54 throw Exception (*this, "channel out of range");
57 return outputs[channel];
60 /// Deinterleaves data and outputs it to the outputs. \n RT safe
61 void process (ProcessContext<T> const & c)
63 samplecnt_t samples = c.samples();
64 T const * data = c.data();
66 samplecnt_t const samples_per_channel = samples / channels;
68 if (throw_level (ThrowProcess) && c.channels() != channels) {
69 throw Exception (*this, "wrong amount of channels given to process()");
72 if (throw_level (ThrowProcess) && samples_per_channel > max_samples) {
73 throw Exception (*this, "too many samples given to process()");
76 unsigned int channel = 0;
77 for (typename std::vector<OutputPtr>::iterator it = outputs.begin(); it != outputs.end(); ++it, ++channel) {
78 if (!*it) { continue; }
80 for (unsigned int i = 0; i < samples_per_channel; ++i) {
81 buffer[i] = data[channel + (channels * i)];
84 ProcessContext<T> c_out (c, buffer, samples_per_channel, 1);
85 (*it)->process (c_out);
89 using Sink<T>::process;
102 std::vector<OutputPtr> outputs;
103 unsigned int channels;
104 samplecnt_t max_samples;
110 #endif // AUDIOGRAPHER_DEINTERLEAVER_H