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