1 /* 2 * Copyright 2015 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 #include <algorithm> 18 #include <unistd.h> 19 #include "FlowGraphNode.h" 20 #include "RampLinear.h" 21 22 using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph; 23 RampLinear(int32_t channelCount)24RampLinear::RampLinear(int32_t channelCount) 25 : FlowGraphFilter(channelCount) { 26 mTarget.store(1.0f); 27 } 28 setLengthInFrames(int32_t frames)29void RampLinear::setLengthInFrames(int32_t frames) { 30 mLengthInFrames = frames; 31 } 32 setTarget(float target)33void RampLinear::setTarget(float target) { 34 mTarget.store(target); 35 // If the ramp has not been used then start immediately at this level. 36 if (mLastCallCount == kInitialCallCount) { 37 forceCurrent(target); 38 } 39 } 40 interpolateCurrent()41float RampLinear::interpolateCurrent() { 42 return mLevelTo - (mRemaining * mScaler); 43 } 44 onProcess(int32_t numFrames)45int32_t RampLinear::onProcess(int32_t numFrames) { 46 const float *inputBuffer = input.getBuffer(); 47 float *outputBuffer = output.getBuffer(); 48 int32_t channelCount = output.getSamplesPerFrame(); 49 50 float target = getTarget(); 51 if (target != mLevelTo) { 52 // Start new ramp. Continue from previous level. 53 mLevelFrom = interpolateCurrent(); 54 mLevelTo = target; 55 mRemaining = mLengthInFrames; 56 mScaler = (mLevelTo - mLevelFrom) / mLengthInFrames; // for interpolation 57 } 58 59 int32_t framesLeft = numFrames; 60 61 if (mRemaining > 0) { // Ramping? This doesn't happen very often. 62 int32_t framesToRamp = std::min(framesLeft, mRemaining); 63 framesLeft -= framesToRamp; 64 while (framesToRamp > 0) { 65 float currentLevel = interpolateCurrent(); 66 for (int ch = 0; ch < channelCount; ch++) { 67 *outputBuffer++ = *inputBuffer++ * currentLevel; 68 } 69 mRemaining--; 70 framesToRamp--; 71 } 72 } 73 74 // Process any frames after the ramp. 75 int32_t samplesLeft = framesLeft * channelCount; 76 for (int i = 0; i < samplesLeft; i++) { 77 *outputBuffer++ = *inputBuffer++ * mLevelTo; 78 } 79 80 return numFrames; 81 } 82