finalize PROGRAM_NAME change for ardour3
[ardour.git] / libs / audiographer / audiographer / interleaver-inl.h
1 template<typename T>
2 Interleaver<T>::Interleaver()
3   : channels (0)
4   , max_frames (0)
5   , buffer (0)
6 {}
7
8 template<typename T>
9 void
10 Interleaver<T>::init (unsigned int num_channels, nframes_t max_frames_per_channel)
11 {
12         reset();
13         channels = num_channels;
14         max_frames = max_frames_per_channel;
15         
16         buffer = new T[channels * max_frames];
17         
18         for (unsigned int i = 0; i < channels; ++i) {
19                 inputs.push_back (InputPtr (new Input (*this, i)));
20         }
21 }
22
23 template<typename T>
24 typename Source<T>::SinkPtr
25 Interleaver<T>::input (unsigned int channel)
26 {
27         if (channel >= channels) {
28                 throw Exception (*this, "Channel out of range");
29         }
30         
31         return boost::static_pointer_cast<Sink<T> > (inputs[channel]);
32 }
33
34 template<typename T>
35 void
36 Interleaver<T>::reset_channels ()
37 {
38         for (unsigned int i = 0; i < channels; ++i) {
39                 inputs[i]->reset();
40         }
41
42 }
43
44 template<typename T>
45 void
46 Interleaver<T>::reset ()
47 {
48         inputs.clear();
49         delete [] buffer;
50         buffer = 0;
51         channels = 0;
52         max_frames = 0;
53 }
54
55 template<typename T>
56 void
57 Interleaver<T>::write_channel (ProcessContext<T> const & c, unsigned int channel)
58 {
59         if (c.frames() > max_frames) {
60                 reset_channels();
61                 throw Exception (*this, "Too many frames given to an input");
62         }
63         
64         for (unsigned int i = 0; i < c.frames(); ++i) {
65                 buffer[channel + (channels * i)] = c.data()[i];
66         }
67         
68         nframes_t const ready_frames = ready_to_output();
69         if (ready_frames) {
70                 ProcessContext<T> c_out (c, buffer, ready_frames, channels);
71                 ListedSource<T>::output (c_out);
72                 reset_channels ();
73         }
74 }
75
76 template<typename T>
77 nframes_t
78 Interleaver<T>::ready_to_output ()
79 {
80         nframes_t ready_frames = inputs[0]->frames();
81         if (!ready_frames) { return 0; }
82
83         for (unsigned int i = 1; i < channels; ++i) {
84                 nframes_t const frames = inputs[i]->frames();
85                 if (!frames) { return 0; }
86                 if (frames != ready_frames) {
87                         init (channels, max_frames);
88                         throw Exception (*this, "Frames count out of sync");
89                 }
90         }
91         return ready_frames * channels;
92 }