Ardour  9.0-pre0-582-g084a23a80d
deinterleaver.h
Go to the documentation of this file.
1 #ifndef AUDIOGRAPHER_DEINTERLEAVER_H
2 #define AUDIOGRAPHER_DEINTERLEAVER_H
3 
5 #include "audiographer/types.h"
6 #include "audiographer/source.h"
7 #include "audiographer/sink.h"
10 
11 #include <vector>
12 
13 namespace AudioGrapher
14 {
15 
17 template<typename T = DefaultSampleType>
18 class /*LIBAUDIOGRAPHER_API*/ DeInterleaver
19  : public Sink<T>
20  , public Throwing<>
21 {
22  private:
23  typedef std::shared_ptr<IdentityVertex<T> > OutputPtr;
24 
25  public:
28  : channels (0)
29  , max_samples (0)
30  , buffer (0)
31  {}
32 
34 
35  typedef std::shared_ptr<Source<T> > SourcePtr;
36 
38  void init (unsigned int num_channels, samplecnt_t max_samples_per_channel)
39  {
40  reset();
41  channels = num_channels;
42  max_samples = max_samples_per_channel;
43  buffer = new T[max_samples];
44 
45  for (unsigned int i = 0; i < channels; ++i) {
46  outputs.push_back (OutputPtr (new IdentityVertex<T>));
47  }
48  }
49 
51  SourcePtr output (unsigned int channel)
52  {
53  if (throw_level (ThrowObject) && channel >= channels) {
54  throw Exception (*this, "channel out of range");
55  }
56 
57  return outputs[channel];
58  }
59 
61  void process (ProcessContext<T> const & c)
62  {
63  samplecnt_t samples = c.samples();
64  T const * data = c.data();
65 
66  samplecnt_t const samples_per_channel = samples / channels;
67 
68  if (throw_level (ThrowProcess) && c.channels() != channels) {
69  throw Exception (*this, "wrong amount of channels given to process()");
70  }
71 
72  if (throw_level (ThrowProcess) && samples_per_channel > max_samples) {
73  throw Exception (*this, "too many samples given to process()");
74  }
75 
76  unsigned int channel = 0;
77  for (typename std::vector<OutputPtr>::iterator it = outputs.begin(); it != outputs.end(); ++it, ++channel) {
78  if (!*it) { continue; }
79 
80  for (unsigned int i = 0; i < samples_per_channel; ++i) {
81  buffer[i] = data[channel + (channels * i)];
82  }
83 
84  ProcessContext<T> c_out (c, buffer, samples_per_channel, 1);
85  (*it)->process (c_out);
86  }
87  }
88 
89  using Sink<T>::process;
90 
91  private:
92 
93  void reset ()
94  {
95  outputs.clear();
96  delete [] buffer;
97  buffer = 0;
98  channels = 0;
99  max_samples = 0;
100  }
101 
102  std::vector<OutputPtr> outputs;
103  unsigned int channels;
105  T * buffer;
106 };
107 
108 } // namespace
109 
110 #endif // AUDIOGRAPHER_DEINTERLEAVER_H
Converts on stream of interleaved data to many streams of uninterleaved data.
Definition: deinterleaver.h:21
DeInterleaver()
Constructor. RT safe.
Definition: deinterleaver.h:27
std::shared_ptr< IdentityVertex< T > > OutputPtr
Definition: deinterleaver.h:23
void process(ProcessContext< T > const &c)
Deinterleaves data and outputs it to the outputs. RT safe.
Definition: deinterleaver.h:61
SourcePtr output(unsigned int channel)
Returns an output indexed by channel RT safe.
Definition: deinterleaver.h:51
void init(unsigned int num_channels, samplecnt_t max_samples_per_channel)
Inits the deinterleaver. Must be called before using. Not RT safe.
Definition: deinterleaver.h:38
std::vector< OutputPtr > outputs
std::shared_ptr< Source< T > > SourcePtr
Definition: deinterleaver.h:35
Outputs its input directly to a number of Sinks.
ChannelCount const & channels() const
T const * data() const
data points to the array of data to process
samplecnt_t const & samples() const
samples tells how many samples the array pointed by data contains
bool throw_level(ThrowLevel level)
Definition: throwing.h:47
@ ThrowObject
Object level stuff, ctors, initalizers etc.
Definition: throwing.h:22
@ ThrowProcess
Process cycle level stuff.
Definition: throwing.h:23