Ardour  9.0-pre0-582-g084a23a80d
interleaver.h
Go to the documentation of this file.
1 #ifndef AUDIOGRAPHER_INTERLEAVER_H
2 #define AUDIOGRAPHER_INTERLEAVER_H
3 
5 #include "audiographer/types.h"
6 #include "audiographer/sink.h"
10 
11 #include <vector>
12 #include <cmath>
13 
14 namespace AudioGrapher
15 {
16 
18 template<typename T = DefaultSampleType>
19 class /*LIBAUDIOGRAPHER_API*/ Interleaver
20  : public ListedSource<T>
21  , public Throwing<>
22 {
23  public:
24 
27  : channels (0)
28  , max_samples (0)
29  , buffer (0)
30  {}
31 
33 
35  void init (unsigned int num_channels, samplecnt_t max_samples_per_channel)
36  {
37  reset();
38  channels = num_channels;
39  max_samples = max_samples_per_channel;
40 
41  buffer = new T[channels * max_samples];
42 
43  for (unsigned int i = 0; i < channels; ++i) {
44  inputs.push_back (InputPtr (new Input (*this, i)));
45  }
46  }
47 
51  typename Source<T>::SinkPtr input (unsigned int channel)
52  {
53  if (throw_level (ThrowObject) && channel >= channels) {
54  throw Exception (*this, "Channel out of range");
55  }
56 
57  return std::static_pointer_cast<Sink<T> > (inputs[channel]);
58  }
59 
60  private:
61 
62  class Input : public Sink<T>
63  {
64  public:
65  Input (Interleaver & parent, unsigned int channel)
67 
68  void process (ProcessContext<T> const & c)
69  {
70  if (parent.throw_level (ThrowProcess) && c.channels() > 1) {
71  throw Exception (*this, "Data input has more than on channel");
72  }
74  throw Exception (*this, "Input channels out of sync");
75  }
78  }
79 
80  using Sink<T>::process;
81 
83  void reset() { samples_written = 0; }
84 
85  private:
88  unsigned int channel;
89  };
90 
91  void reset ()
92  {
93  inputs.clear();
94  delete [] buffer;
95  buffer = 0;
96  channels = 0;
97  max_samples = 0;
98  }
99 
101  {
102  for (unsigned int i = 0; i < channels; ++i) {
103  inputs[i]->reset();
104  }
105 
106  }
107 
108  void write_channel (ProcessContext<T> const & c, unsigned int channel)
109  {
110  if (throw_level (ThrowProcess) && c.samples() > max_samples) {
111  reset_channels();
112  throw Exception (*this, "Too many samples given to an input");
113  }
114 
115  for (unsigned int i = 0; i < c.samples(); ++i) {
116  buffer[channel + (channels * i)] = c.data()[i];
117  }
118 
119  samplecnt_t const ready_samples = ready_to_output();
120  if (ready_samples) {
121  ProcessContext<T> c_out (c, buffer, ready_samples, channels);
122  ListedSource<T>::output (c_out);
123  reset_channels ();
124  }
125  }
126 
128  {
129  samplecnt_t ready_samples = inputs[0]->samples();
130  if (!ready_samples) { return 0; }
131 
132  for (unsigned int i = 1; i < channels; ++i) {
133  samplecnt_t const samples = inputs[i]->samples();
134  if (!samples) { return 0; }
135  if (throw_level (ThrowProcess) && samples != ready_samples) {
137  throw Exception (*this, "Samples count out of sync");
138  }
139  }
140  return ready_samples * channels;
141  }
142 
143  typedef std::shared_ptr<Input> InputPtr;
144  std::vector<InputPtr> inputs;
145 
146  unsigned int channels;
148  T * buffer;
149 };
150 
151 } // namespace
152 
153 #endif // AUDIOGRAPHER_INTERLEAVER_H
Input(Interleaver &parent, unsigned int channel)
Definition: interleaver.h:65
void process(ProcessContext< T > const &c)
Definition: interleaver.h:68
Interleaves many streams of non-interleaved data into one interleaved stream.
Definition: interleaver.h:22
samplecnt_t ready_to_output()
Definition: interleaver.h:127
void init(unsigned int num_channels, samplecnt_t max_samples_per_channel)
Inits the interleaver. Must be called before using. Not RT safe.
Definition: interleaver.h:35
Source< T >::SinkPtr input(unsigned int channel)
Definition: interleaver.h:51
void write_channel(ProcessContext< T > const &c, unsigned int channel)
Definition: interleaver.h:108
Interleaver()
Constructs an interleaver RT safe.
Definition: interleaver.h:26
std::vector< InputPtr > inputs
Definition: interleaver.h:144
std::shared_ptr< Input > InputPtr
Definition: interleaver.h:143
An generic Source that uses a std::list for managing outputs.
Definition: listed_source.h:17
void output(ProcessContext< T > const &c)
Helper for derived classes.
Definition: listed_source.h:28
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
std::shared_ptr< Sink< T > > SinkPtr
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
@ ThrowStrict
Stricter checks than ThrowProcess, less than ThrowSample.
Definition: throwing.h:24