1b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson/* 2b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * Copyright (C) 2011 The Android Open Source Project 3b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * 4b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * Licensed under the Apache License, Version 2.0 (the "License"); 5b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * you may not use this file except in compliance with the License. 6b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * You may obtain a copy of the License at 7b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * 8b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * http://www.apache.org/licenses/LICENSE-2.0 9b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * 10b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * Unless required by applicable law or agreed to in writing, software 11b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * distributed under the License is distributed on an "AS IS" BASIS, 12b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * See the License for the specific language governing permissions and 14b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * limitations under the License. 15b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson */ 16b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 17b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#ifndef FRAMEWORKS_EX_VARIABLESPEED_JNI_RING_BUFFER_H_ 18b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#define FRAMEWORKS_EX_VARIABLESPEED_JNI_RING_BUFFER_H_ 19b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 20b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include <vector> 21b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 22b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include "integral_types.h" 23b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include "macros.h" 24b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 25b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Circular buffer of multichannel audio, maintaining the position of the 26b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// writing head and several reading head, and providing a method for 27b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// accessing a contiguous block (through direct reference or the copy in a 28b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// temporary read buffer in case the requested block crosses the buffer 29b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// boundaries). 30b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// 31b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// This code is not thread-safe. 32b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 33b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonnamespace video_editing { 34b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 35b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonclass RingBuffer { 36b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson public: 37b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson RingBuffer(); 38b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson virtual ~RingBuffer(); 39b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 40b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Initializes a RingBuffer. 41b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param size: size of the buffer in frames. 42b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param num_channels: number of channels of the original audio. 43b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param num_readers: number of reading heads. 44b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson void Init(int size, int num_channels, int num_readers); 45b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 46b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Gets the position of a reading head. 47b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param reader reading head index. 48b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @returns position pointed to by the #reader reading head. 49b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int64 Tell(int reader) const; 50b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 51b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Moves a reading head. 52b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param reader reading head index. 53b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param position target position. 54b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson void Seek(int reader, int64 position); 55b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 56b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Reads samples for a reading head. 57b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param reader reading head index. 58b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param num_frames number of frames to read. 59b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param destination float buffer to which the samples will be written. 60b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson void Copy(int reader, float* destination, int num_frames) const; 61b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 62b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Writes samples. 63b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param samples float buffer containing the samples. 64b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param num_frames number of frames to write. 65b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson void Write(const float* samples, int num_frames); 66b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 67b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Flushes the content of the buffer and reset the position of the heads. 68b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson void Reset(); 69b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 70b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Returns the number of frames we can still write. 71b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int overhead() const; 72b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 73b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Returns the number of frames we can read for a given reader. 74b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param reader reading head index. 75b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int available(int reader) const; 76b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 77b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Returns a pointer to num_frames x num_channels contiguous samples for 78b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // a given reader. In most cases this directly returns a pointer to the 79b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // data in the ring buffer. However, if the required block wraps around the 80b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // boundaries of the ring buffer, the data is copied to a temporary buffer 81b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // owned by the RingBuffer object. 82b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param reader reading head index. 83b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param num_frames number of frames to read. 84b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @returns pointer to a continuous buffer containing num_frames. 85b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson float* GetPointer(int reader, int num_frames); 86b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 87b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Merges updated data back into the ring buffer, if it was updated in 88b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // the temporary buffer. This operation follows a GetPointer() that 89b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // was used to obtain data to rewrite. The buffer address supplied 90b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // here must match the one returned by GetPointer(). 91b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param reader reading head index. 92b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param source pointer to a continuous buffer containing num_frames. 93b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // @param num_frames number of frames to copy back to the ring buffer. 94b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson void MergeBack(int reader, const float* source, int num_frames); 95b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 96b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson private: 97b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson // Returns the position of the laziest reader. 98b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int64 GetTail() const; 99b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 100b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson bool initialized_; 101b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson float* samples_; 102b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson std::vector<int64> readers_; 103b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int size_; 104b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int num_channels_; 105b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int num_readers_; 106b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int64 head_logical_; 107b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int head_; 108b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 109b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson float* temp_read_buffer_; 110b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson int temp_read_buffer_size_; 111b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 112b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson DISALLOW_COPY_AND_ASSIGN(RingBuffer); 113b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}; 114b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 115b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson} // namespace video_editing 116b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson 117b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#endif // FRAMEWORKS_EX_VARIABLESPEED_JNI_RING_BUFFER_H_ 118