• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SOLA_TIME_SCALER_H_
18 #define FRAMEWORKS_EX_VARIABLESPEED_JNI_SOLA_TIME_SCALER_H_
19 
20 #include <android/log.h>
21 
22 #include <no_synchronization.h>
23 
24 #include <list>
25 #include <vector>
26 
27 #include "macros.h"
28 
29 // Time-domain audio playback rate scaler using phase-aligned Synchronized
30 // OverLap Add (SOLA).
31 
32 namespace video_editing {
33 
34 class RingBuffer;
35 
36 // The default SolaAnalyzer implements a sign-bit cross-correlation
37 // function for determining the best fit between two signals.
38 class SolaAnalyzer {
39  public:
SolaAnalyzer()40   SolaAnalyzer() : initialized_(false) { }
~SolaAnalyzer()41   virtual ~SolaAnalyzer() { }
42 
43   // Initializes a SolaAnalyzer.
44   // @param sample_rate sample rate of the audio signal.
45   // @param num_channels number of interleaved channels in the signal.
Init(int sample_rate,int num_channels)46   void Init(int sample_rate, int num_channels) {
47     sample_rate_ = sample_rate;
48     num_channels_ = num_channels;
49     initialized_ = true;
50   }
51 
52   // Returns a cross-correlation score for the specified buffers.
53   // The correlation is performed over all channels of a multi-channel signal.
54   // @param buffer1 pointer to interleaved input samples
55   // @param buffer2 pointer to interleaved input samples
56   // @param num_frames number of input frames (that is to say, number of
57   //                   samples / number of channels)
58   // @param returns a correlation score in the range zero to num_frames
59   virtual int Correlate(const float* buffer1, const float* buffer2,
60                         int num_frames);
61 
62  protected:
63   bool initialized_;
64   int sample_rate_;
65   int num_channels_;
66 
67   DISALLOW_COPY_AND_ASSIGN(SolaAnalyzer);
68 };
69 
70 
71 class SolaTimeScaler {
72  public:
73   // Default constructor.
74   SolaTimeScaler();
75   virtual ~SolaTimeScaler();
76 
77   // Injects a SolaAnalyzer instance for analyzing signal frames.
78   // The scaler takes ownership of this instance.
79   // This is normally called once, before Init().
80   // @param analyzer SolaAnalyzer instance
81   void set_analyzer(SolaAnalyzer* analyzer);
82 
83   // Initializes a SOLA timescaler.
84   // @param sample_rate sample rate of the signal to process
85   // @param num_channels number of channels of the signal to process
86   // @param initial_speed starting rate scaling factor
87   // @param window_duration processing window size, in seconds
88   // @param overlap_duration correlation overlap size, in seconds
89   void Init(double sample_rate, int num_channels, double initial_speed,
90             double window_duration, double overlap_duration);
91 
92   // Adjusts the rate scaling factor.
93   // This may be called concurrently with processing, and will
94   // take effect on the next processing window.
95   // @param speed rate scaling factor
96   void set_speed(double speed);
97 
98   // Indicates that we are done with the input and won't call Process anymore
99   // This processes all the data reamining in the analysis buffer.
100   void Drain();
101 
102   // Flushes the buffers associated with the scaler.
103   void Reset();
104 
105   // Feeds audio to the timescaler, and processes as much data as possible.
106   // @param buffer pointer to interleaved float input samples
107   // @param num_frames number of frames (num_samples / num_channels)
108   // @returns number of frames actually accepted
109   int InjectSamples(float* buffer, int num_frames);
110 
111   // Retrieves audio data from the timescaler.
112   // @param buffer pointer to buffer to receive interleaved float output
113   // @param num_frames maximum desired number of frames
114   // @returns number of frames actually returned
115   int RetrieveSamples(float* buffer, int num_frames);
116 
117   // Returns the number of frames that the input buffer can accept.
118   // @returns number of frames for the next Process() call
119   int input_limit() const;
120 
121   // Returns the number of available output frames.
122   // @returns number of frames that can be retrieved
123   int available();
124 
num_channels()125   int num_channels() const { return num_channels_; }
126 
127  private:
128   mutable Mutex mutex_;       // allows concurrent produce/consume/param change
129   bool initialized_;          // set true when input parameters have been set
130   bool draining_;             // set true to drain latency
131 
132   // Input parameters.
133   int num_channels_;          // channel valence of audio stream
134   double sample_rate_;        // sample rate of audio stream
135   double window_duration_;    // the nominal time quantum for processing
136   double overlap_duration_;   // the maximum slip for correlating windows
137   double speed_;              // varispeed rate
138 
139   // Derived parameters.
140   double ratio_;              // inverse of speed
141   int num_window_frames_;     // window_duration_ expressed as frame count
142   int num_overlap_frames_;    // overlap_duration_ expressed as frame count
143   int half_overlap_frames_;   // half of the overlap
144   int input_window_offset_;   // frame delta between input windows
145   int target_merge_offset_;   // ideal frame delta between output windows
146   int max_frames_to_merge_;   // ideal frame count to merge to output
147   int min_output_to_hold_;    // number of output frames needed for next merge
148 
149   RingBuffer* input_buffer_;
150   RingBuffer* output_buffer_;
151   SolaAnalyzer* analyzer_;
152 
153   // Generates processing parameters from the current settings.
154   void GenerateParameters();
155 
156   // Munges input samples to produce output.
157   // @returns true if any output samples were generated
158   bool Process();
159 
160   DISALLOW_COPY_AND_ASSIGN(SolaTimeScaler);
161 };
162 
163 }  // namespace video_editing
164 
165 #endif  // FRAMEWORKS_EX_VARIABLESPEED_JNI_SOLA_TIME_SCALER_H_
166