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