1 #ifndef AUDIOGRAPHER_CHUNKER_H
2 #define AUDIOGRAPHER_CHUNKER_H
4 #include "audiographer/visibility.h"
5 #include "audiographer/flag_debuggable.h"
6 #include "audiographer/sink.h"
7 #include "audiographer/type_utils.h"
8 #include "audiographer/utils/listed_source.h"
10 namespace AudioGrapher
13 /// A class that chunks process cycles into equal sized samples
14 template<typename T = DefaultSampleType>
15 class /*LIBAUDIOGRAPHER_API*/ Chunker
16 : public ListedSource<T>
18 , public FlagDebuggable<>
21 /** Constructs a new Chunker with a constant chunk size.
24 Chunker (samplecnt_t chunk_size)
25 : chunk_size (chunk_size)
28 buffer = new T[chunk_size];
29 add_supported_flag (ProcessContext<T>::EndOfInput);
37 /** Outputs data in \a context in chunks with the size specified in the constructor.
38 * Note that some calls might not produce any output, while others may produce several.
41 void process (ProcessContext<T> const & context)
43 check_flags (*this, context);
45 samplecnt_t samples_left = context.samples();
46 samplecnt_t input_position = 0;
48 while (position + samples_left >= chunk_size) {
49 // Copy from context to buffer
50 samplecnt_t const samples_to_copy = chunk_size - position;
51 TypeUtils<T>::copy (&context.data()[input_position], &buffer[position], samples_to_copy);
55 input_position += samples_to_copy;
56 samples_left -= samples_to_copy;
58 // Output whole buffer
59 ProcessContext<T> c_out (context, buffer, chunk_size);
60 if (samples_left) { c_out.remove_flag(ProcessContext<T>::EndOfInput); }
61 ListedSource<T>::output (c_out);
65 // Copy the rest of the data
66 TypeUtils<T>::copy (&context.data()[input_position], &buffer[position], samples_left);
67 position += samples_left;
70 if (context.has_flag (ProcessContext<T>::EndOfInput) && position > 0) {
71 ProcessContext<T> c_out (context, buffer, position);
72 ListedSource<T>::output (c_out);
75 using Sink<T>::process;
78 samplecnt_t chunk_size;
86 #endif // AUDIOGRAPHER_CHUNKER_H