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 } 36 interpolateCurrent()37float RampLinear::interpolateCurrent() { 38 return mLevelTo - (mRemaining * mScaler); 39 } 40 onProcess(int32_t numFrames)41int32_t RampLinear::onProcess(int32_t numFrames) { 42 const float *inputBuffer = input.getBuffer(); 43 float *outputBuffer = output.getBuffer(); 44 int32_t channelCount = output.getSamplesPerFrame(); 45 46 float target = getTarget(); 47 if (target != mLevelTo) { 48 // Start new ramp. Continue from previous level. 49 mLevelFrom = interpolateCurrent(); 50 mLevelTo = target; 51 mRemaining = mLengthInFrames; 52 mScaler = (mLevelTo - mLevelFrom) / mLengthInFrames; // for interpolation 53 } 54 55 int32_t framesLeft = numFrames; 56 57 if (mRemaining > 0) { // Ramping? This doesn't happen very often. 58 int32_t framesToRamp = std::min(framesLeft, mRemaining); 59 framesLeft -= framesToRamp; 60 while (framesToRamp > 0) { 61 float currentLevel = interpolateCurrent(); 62 for (int ch = 0; ch < channelCount; ch++) { 63 *outputBuffer++ = *inputBuffer++ * currentLevel; 64 } 65 mRemaining--; 66 framesToRamp--; 67 } 68 } 69 70 // Process any frames after the ramp. 71 int32_t samplesLeft = framesLeft * channelCount; 72 for (int i = 0; i < samplesLeft; i++) { 73 *outputBuffer++ = *inputBuffer++ * mLevelTo; 74 } 75 76 return numFrames; 77 } 78