1 #ifndef INCLUDED_SAMPLEBUFFER_ITERATORS_H
2 #define INCLUDED_SAMPLEBUFFER_ITERATORS_H
3 
4 #include "samplebuffer.h"
5 
6 /**
7  * Iterate through all samples. No specific order.
8  *
9  * Related design patterns:
10  *     - Iterator (GoF257)
11  */
12 class SAMPLE_ITERATOR {
13 
14  private:
15 
16   SAMPLE_BUFFER* target;
17   SAMPLE_BUFFER::buf_size_t index;     // index of the current sample
18   SAMPLE_BUFFER::channel_size_t channel_index;  // index of current channel
19 
20  public:
21 
22   /**
23    * Prepare iterator for processing.
24    */
init(SAMPLE_BUFFER * buf)25   void init(SAMPLE_BUFFER* buf) { target = buf; }
26 
27   /**
28    * Start iteration from the first audio item;
29    */
30   void begin(void);
31 
32   /**
33    * True if iterator is past the last audio item.
34    */
end(void)35   inline bool end(void) { return(channel_index >= static_cast<int>(target->channel_count_rep)); }
36 
37   /**
38    * Move iterator to the next audio item.
39    */
40   void next(void);
41 
42   /**
43    * Returns a pointer to the current sample.
44    */
current(void)45   inline SAMPLE_SPECS::sample_t* current(void) { return(&(target->buffer[channel_index][index])); }
46 };
47 
48 /**
49  * Iterate through all samples of one channel.
50  *
51  * Notice! This iterator can be used to add extra
52  * channels to the sample data.
53  *
54  * Related design patterns:
55  *     - Iterator (GoF257)
56  */
57 class SAMPLE_ITERATOR_CHANNEL {
58 
59  private:
60 
61   SAMPLE_BUFFER* target;
62   SAMPLE_BUFFER::buf_size_t index;     // index of the current sample
63   SAMPLE_BUFFER::channel_size_t channel_index;  // index of current channel
64 
65  public:
66 
67   /**
68    * Prepare iterator for processing.
69    */
70   void init(SAMPLE_BUFFER* buf, int channel = 0);
71 
72   /**
73    * Start iteration from the first sample of 'channel'. More channels
74    * are allocated, if sample buffer has fewer channels than asked for.
75    *
76    * @param channel number of iterated channel (0, 1, ... , n)
77    */
78   void begin(int channel);
79 
80   /**
81    * Start iteration from the first audio item (using the previously
82    * set channel).
83    */
begin(void)84   void begin(void) { index = 0; }
85 
86   /**
87    * Move iterator to the next audio item.
88    */
next(void)89   void next(void) { ++index; }
90 
91   /**
92    * True if iterator is past the last audio item.
93    */
end(void)94   inline bool end(void) { return(static_cast<long int>(index) >= target->buffersize_rep); }
95 
96   /**
97    * Returns a pointer to the current sample.
98    */
current(void)99   inline SAMPLE_SPECS::sample_t* current(void) { return(&target->buffer[channel_index][index]); }
100 };
101 
102 /**
103  * Iterate through all samples, one channel at a time.
104  *
105  * Related design patterns:
106  *     - Iterator (GoF257)
107  */
108 class SAMPLE_ITERATOR_CHANNELS {
109 
110  private:
111 
112   SAMPLE_BUFFER* target;
113   SAMPLE_BUFFER::buf_size_t index;     // index of the current sample
114   SAMPLE_BUFFER::channel_size_t channel_index;  // index of current channel
115 
116  public:
117 
118   /**
119    * Prepare iterator for processing.
120    */
init(SAMPLE_BUFFER * buf)121   void init(SAMPLE_BUFFER* buf) { target = buf; }
122 
123   /**
124    * Start iteration from the first audio item;
125    */
126   void begin(void);
127 
128   /**
129    * Move iterator to the next audio item.
130    */
131   void next(void);
132 
133   /**
134    * True if iterator is past the last audio item.
135    */
end(void)136   inline bool end(void) { return(channel_index >= static_cast<int>(target->channel_count_rep)); }
137 
138   /**
139    * Returns a pointer to the current sample.
140    */
current(void)141   inline SAMPLE_SPECS::sample_t* current(void) { return(&(target->buffer[channel_index][index])); }
142 
143   /**
144    * Returns current channel index (starting from 0)
145    */
channel(void)146   inline int channel(void) const { return(channel_index); }
147 };
148 
149 /**
150  * Iterate through all samples, one sample frame (interleaved) at a time.
151  *
152  * Related design patterns:
153  *     - Iterator (GoF257)
154  */
155 class SAMPLE_ITERATOR_INTERLEAVED {
156 
157  private:
158 
159   SAMPLE_BUFFER* target;
160   SAMPLE_BUFFER::buf_size_t  index;     // index of the current sample
161 
162  public:
163 
164   /**
165    * Prepare iterator for processing.
166    */
init(SAMPLE_BUFFER * buf)167   void init(SAMPLE_BUFFER* buf) { target = buf; }
168 
169   /**
170    * Start iteration from the first audio item;
171    */
begin(void)172   void begin(void) { index = 0; }
173 
174   /**
175    * Move iterator to the next audio item.
176    */
next(void)177   inline void next(void) { ++index; }
178 
179   /**
180    * True if iterator is past the last audio item.
181    */
end(void)182   inline bool end(void) { return(static_cast<long int>(index) >= target->buffersize_rep); }
183 
184   /**
185    * Returns a pointer to the current sample.
186    */
current(int channel)187   inline SAMPLE_SPECS::sample_t* current(int channel) { return(&target->buffer[channel][index]); }
188 };
189 
190 #endif
191