| 1 | /* | 
| 2 | Copyright 2018 Google Inc. All Rights Reserved. | 
| 3 |  | 
| 4 | Licensed under the Apache License, Version 2.0 (the "License"); | 
| 5 | you may not use this file except in compliance with the License. | 
| 6 | You may obtain a copy of the License at | 
| 7 |  | 
| 8 |     http://www.apache.org/licenses/LICENSE-2.0 | 
| 9 |  | 
| 10 | Unless required by applicable law or agreed to in writing, software | 
| 11 | distributed under the License is distributed on an "AS-IS" BASIS, | 
| 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
| 13 | See the License for the specific language governing permissions and | 
| 14 | limitations under the License. | 
| 15 | */ | 
| 16 |  | 
| 17 | #ifndef RESONANCE_AUDIO_UTILS_BUFFER_PARTITIONER_H_ | 
| 18 | #define RESONANCE_AUDIO_UTILS_BUFFER_PARTITIONER_H_ | 
| 19 |  | 
| 20 | #include <functional> | 
| 21 | #include <memory> | 
| 22 |  | 
| 23 | #include "base/audio_buffer.h" | 
| 24 | #include "base/logging.h" | 
| 25 |  | 
| 26 | namespace vraudio { | 
| 27 |  | 
| 28 | // Packages input buffers of arbitrary sizes into fixed size |AudioBuffer|s. | 
| 29 | class BufferPartitioner { | 
| 30 |  public: | 
| 31 |   // Callback to receive processed and assign empty |AudioBuffer|s while | 
| 32 |   // processing input buffers. | 
| 33 |   // | 
| 34 |   // @param output Pointer to partitioned |AudioBuffer| with input audio data. | 
| 35 |   // @return Pointer to the next |AudioBuffer| to be filled. | 
| 36 |   typedef std::function<AudioBuffer*(AudioBuffer* output)> NewBufferCallback; | 
| 37 |  | 
| 38 |   // Constructor. | 
| 39 |   // | 
| 40 |   // @param num_channels Number of audio channels in input and output buffers. | 
| 41 |   // @param frames_per_buffer Number of frames in output |AudioBuffer|s. | 
| 42 |   // @param buffer_callback Callback to receive output |AudioBuffer|s. | 
| 43 |   BufferPartitioner(size_t num_channels, size_t frames_per_buffer, | 
| 44 |                     NewBufferCallback buffer_callback); | 
| 45 |  | 
| 46 |   // Predicts the number of generated buffers for a given number of input frames | 
| 47 |   // and based on the current fill state of the internal |temp_buffer_|. | 
| 48 |   // | 
| 49 |   // @param num_input_frames Number of input frames. | 
| 50 |   // @return Number of generated output buffers. | 
| 51 |   size_t GetNumGeneratedBuffersForNumInputFrames(size_t num_input_frames) const; | 
| 52 |  | 
| 53 |   // Returns the number of buffered frames in internal |temp_buffer_|. | 
| 54 |   size_t GetNumBufferedFrames() const; | 
| 55 |  | 
| 56 |   // Adds an interleaved int16 input buffer. This method triggers | 
| 57 |   // |NewBufferCallback| whenever a new |AudioBuffer| has been generated. | 
| 58 |   // | 
| 59 |   // @param interleaved_buffer Interleaved input buffer. | 
| 60 |   // @param num_channels Number of channels in input buffer. | 
| 61 |   // @param num_frames Number of frames in input buffer. | 
| 62 |   void AddBuffer(const int16* interleaved_buffer, size_t num_channels, | 
| 63 |                  size_t num_frames); | 
| 64 |  | 
| 65 |   // Adds an interleaved float input buffer. This method triggers | 
| 66 |   // |NewBufferCallback| whenever a new |AudioBuffer| has been generated. | 
| 67 |   // | 
| 68 |   // @param interleaved_buffer Interleaved input buffer. | 
| 69 |   // @param num_channels Number of channels in input buffer. | 
| 70 |   // @param num_frames Number of frames in input buffer. | 
| 71 |   void AddBuffer(const float* interleaved_buffer, size_t num_channels, | 
| 72 |                  size_t num_frames); | 
| 73 |  | 
| 74 |   // Adds a planar float input buffer. This method triggers | 
| 75 |   // |NewBufferCallback| whenever a new |AudioBuffer| has been generated. | 
| 76 |   // | 
| 77 |   // @param planar_buffer Pointer to array of pointers for each audio channel. | 
| 78 |   // @param num_channels Number of channels in input buffer. | 
| 79 |   // @param num_frames Number of frames in input buffer. | 
| 80 |   void AddBuffer(const float* const* planar_buffer, size_t num_channels, | 
| 81 |                  size_t num_frames); | 
| 82 |  | 
| 83 |   // Adds a planar int16 input buffer. This method triggers | 
| 84 |   // |NewBufferCallback| whenever a new |AudioBuffer| has been generated. | 
| 85 |   // | 
| 86 |   // @param planar_buffer Pointer to array of pointers for each audio channel. | 
| 87 |   // @param num_channels Number of channels in input buffer. | 
| 88 |   // @param num_frames Number of frames in input buffer. | 
| 89 |   void AddBuffer(const int16* const* planar_buffer, size_t num_channels, | 
| 90 |                  size_t num_frames); | 
| 91 |  | 
| 92 |   // Adds an |AudioBuffer|. This method triggers |NewBufferCallback| whenever a | 
| 93 |   // new |AudioBuffer| has been generated. | 
| 94 |   // | 
| 95 |   // @param audio_buffer Planar |AudioBuffer| input. | 
| 96 |   void AddBuffer(const AudioBuffer& audio_buffer); | 
| 97 |  | 
| 98 |   // Adds an |AudioBuffer| and specifies how many of that audio buffers frames | 
| 99 |   // are valid. This method triggers |NewBufferCallback| whenever a new | 
| 100 |   // |AudioBuffer| has been generated. | 
| 101 |   // | 
| 102 |   // @param num_valid_frames Indicates the number of frames which are actually | 
| 103 |   //     valid in the audio buffer passed. Frames after this will be ignored. | 
| 104 |   // @param audio_buffer Planar |AudioBuffer| input. | 
| 105 |   void AddBuffer(size_t num_valid_frames, const AudioBuffer& audio_buffer); | 
| 106 |  | 
| 107 |   // Flushes the internal temporary |AudioBuffer| by filling the remaining | 
| 108 |   // audio frames with silence. | 
| 109 |   // | 
| 110 |   // @return Number of zero padded audio frames. Zero if the internal buffer | 
| 111 |   //    is empty. | 
| 112 |   size_t Flush(); | 
| 113 |  | 
| 114 |   // Clears internal temporary buffer that holds remaining audio frames. | 
| 115 |   void Clear(); | 
| 116 |  | 
| 117 |  private: | 
| 118 |   // Adds an interleaved and planar float and int16 input buffer as well as | 
| 119 |   // planar |AudioBuffer| input. This method triggers |NewBufferCallback| | 
| 120 |   // whenever a new |AudioBuffer| has been generated. | 
| 121 |   // | 
| 122 |   // @tparam BufferType Input buffer type. | 
| 123 |   // @param buffer Input buffer. | 
| 124 |   // @param num_channels Number of channels in input buffer. | 
| 125 |   // @param num_frames Number of frames in input buffer. | 
| 126 |   template <typename BufferType> | 
| 127 |   void AddBufferTemplated(BufferType buffer, size_t num_channels, | 
| 128 |                           size_t num_frames); | 
| 129 |  | 
| 130 |   // Number of channels in input buffers. | 
| 131 |   const size_t num_channels_; | 
| 132 |  | 
| 133 |   // Number of frames per buffer in output buffers. | 
| 134 |   const size_t frames_per_buffer_; | 
| 135 |  | 
| 136 |   // Callback to output generated |AudioBuffer|s. | 
| 137 |   const NewBufferCallback buffer_callback_; | 
| 138 |  | 
| 139 |   // Temporary buffer to remaining samples from input buffers. | 
| 140 |   AudioBuffer* current_buffer_ptr_;  // Not owned. | 
| 141 |  | 
| 142 |   // Current write position in frames in temporary buffer. | 
| 143 |   size_t current_buffer_write_position_frames_; | 
| 144 |  | 
| 145 |   // Helper vector to obtain an array of planar channel pointers from an | 
| 146 |   // |AudioBuffer|. | 
| 147 |   std::vector<const float*> planar_channel_ptrs_; | 
| 148 | }; | 
| 149 |  | 
| 150 | }  // namespace vraudio | 
| 151 |  | 
| 152 | #endif  // RESONANCE_AUDIO_UTILS_BUFFER_PARTITIONER_H_ | 
| 153 |  |