1/*
2 * Copyright (C) 2011 The Android Open Source Project
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 FRAMEWORKS_EX_VARIABLESPEED_JNI_RING_BUFFER_H_
18#define FRAMEWORKS_EX_VARIABLESPEED_JNI_RING_BUFFER_H_
19
20#include <vector>
21
22#include "integral_types.h"
23#include "macros.h"
24
25// Circular buffer of multichannel audio, maintaining the position of the
26// writing head and several reading head, and providing a method for
27// accessing a contiguous block (through direct reference or the copy in a
28// temporary read buffer in case the requested block crosses the buffer
29// boundaries).
30//
31// This code is not thread-safe.
32
33namespace video_editing {
34
35class RingBuffer {
36 public:
37  RingBuffer();
38  virtual ~RingBuffer();
39
40  // Initializes a RingBuffer.
41  // @param size: size of the buffer in frames.
42  // @param num_channels: number of channels of the original audio.
43  // @param num_readers: number of reading heads.
44  void Init(int size, int num_channels, int num_readers);
45
46  // Gets the position of a reading head.
47  // @param reader reading head index.
48  // @returns position pointed to by the #reader reading head.
49  int64 Tell(int reader) const;
50
51  // Moves a reading head.
52  // @param reader reading head index.
53  // @param position target position.
54  void Seek(int reader, int64 position);
55
56  // Reads samples for a reading head.
57  // @param reader reading head index.
58  // @param num_frames number of frames to read.
59  // @param destination float buffer to which the samples will be written.
60  void Copy(int reader, float* destination, int num_frames) const;
61
62  // Writes samples.
63  // @param samples float buffer containing the samples.
64  // @param num_frames number of frames to write.
65  void Write(const float* samples, int num_frames);
66
67  // Flushes the content of the buffer and reset the position of the heads.
68  void Reset();
69
70  // Returns the number of frames we can still write.
71  int overhead() const;
72
73  // Returns the number of frames we can read for a given reader.
74  // @param reader reading head index.
75  int available(int reader) const;
76
77  // Returns a pointer to num_frames x num_channels contiguous samples for
78  // a given reader. In most cases this directly returns a pointer to the
79  // data in the ring buffer. However, if the required block wraps around the
80  // boundaries of the ring buffer, the data is copied to a temporary buffer
81  // owned by the RingBuffer object.
82  // @param reader reading head index.
83  // @param num_frames number of frames to read.
84  // @returns pointer to a continuous buffer containing num_frames.
85  float* GetPointer(int reader, int num_frames);
86
87  // Merges updated data back into the ring buffer, if it was updated in
88  // the temporary buffer.  This operation follows a GetPointer() that
89  // was used to obtain data to rewrite.  The buffer address supplied
90  // here must match the one returned by GetPointer().
91  // @param reader reading head index.
92  // @param source pointer to a continuous buffer containing num_frames.
93  // @param num_frames number of frames to copy back to the ring buffer.
94  void MergeBack(int reader, const float* source, int num_frames);
95
96 private:
97  // Returns the position of the laziest reader.
98  int64 GetTail() const;
99
100  bool initialized_;
101  float* samples_;
102  std::vector<int64> readers_;
103  int size_;
104  int num_channels_;
105  int num_readers_;
106  int64 head_logical_;
107  int head_;
108
109  float* temp_read_buffer_;
110  int temp_read_buffer_size_;
111
112  DISALLOW_COPY_AND_ASSIGN(RingBuffer);
113};
114
115}  // namespace video_editing
116
117#endif  // FRAMEWORKS_EX_VARIABLESPEED_JNI_RING_BUFFER_H_
118