Remove all use of nframes_t.
[ardour.git] / libs / audiographer / audiographer / general / chunker.h
1 #ifndef AUDIOGRAPHER_CHUNKER_H
2 #define AUDIOGRAPHER_CHUNKER_H
3
4 #include "audiographer/flag_debuggable.h"
5 #include "audiographer/sink.h"
6 #include "audiographer/type_utils.h"
7 #include "audiographer/utils/listed_source.h"
8
9 namespace AudioGrapher
10 {
11
12 /// A class that chunks process cycles into equal sized frames
13 template<typename T = DefaultSampleType>
14 class Chunker
15   : public ListedSource<T>
16   , public Sink<T>
17   , public FlagDebuggable<>
18 {
19   public:
20         /** Constructs a new Chunker with a constant chunk size.
21           * \n NOT RT safe
22           */
23         Chunker (framecnt_t chunk_size)
24           : chunk_size (chunk_size)
25           , position (0)
26         {
27                 buffer = new T[chunk_size];
28                 add_supported_flag (ProcessContext<T>::EndOfInput);
29         }
30         
31         ~Chunker()
32         {
33                 delete [] buffer;
34         }
35         
36         /** Outputs data in \a context in chunks with the size specified in the constructor.
37           * Note that some calls might not produce any output, while others may produce several.
38           * \n RT safe
39           */
40         void process (ProcessContext<T> const & context)
41         {
42                 check_flags (*this, context);
43                 
44                 framecnt_t frames_left = context.frames();
45                 framecnt_t input_position = 0;
46                 
47                 while (position + frames_left >= chunk_size) {
48                         // Copy from context to buffer
49                         framecnt_t const frames_to_copy = chunk_size - position;
50                         TypeUtils<T>::copy (&context.data()[input_position], &buffer[position], frames_to_copy);
51                         
52                         // Output whole buffer
53                         ProcessContext<T> c_out (context, buffer, chunk_size);
54                         ListedSource<T>::output (c_out);
55                         
56                         // Update counters
57                         position = 0;
58                         input_position += frames_to_copy;
59                         frames_left -= frames_to_copy;
60                 }
61                 
62                 if (frames_left) {
63                         // Copy the rest of the data
64                         TypeUtils<T>::copy (&context.data()[input_position], &buffer[position], frames_left);
65                         position += frames_left;
66                 }
67                 
68                 if (context.has_flag (ProcessContext<T>::EndOfInput)) {
69                         ProcessContext<T> c_out (context, buffer, position);
70                         ListedSource<T>::output (c_out);
71                 }
72         }
73         using Sink<T>::process;
74         
75   private:
76         framecnt_t chunk_size;
77         framecnt_t position;
78         T * buffer;
79         
80 };
81
82 } // namespace
83
84 #endif // AUDIOGRAPHER_CHUNKER_H
85