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