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