1 /* 2 * Copyright 2017 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 AAUDIO_LINEAR_RAMP_H 18 #define AAUDIO_LINEAR_RAMP_H 19 20 #include <atomic> 21 #include <stdint.h> 22 23 /** 24 * Generate segments along a linear ramp. 25 * The ramp target can be updated from another thread. 26 * When the target is updated, a new ramp is started from the current position. 27 * 28 * The first ramp starts at 0.0. 29 * 30 */ 31 class LinearRamp { 32 public: LinearRamp()33 LinearRamp() { 34 mTarget.store(1.0f); 35 } 36 setLengthInFrames(int32_t frames)37 void setLengthInFrames(int32_t frames) { 38 mLengthInFrames = frames; 39 } 40 getLengthInFrames()41 int32_t getLengthInFrames() { 42 return mLengthInFrames; 43 } 44 45 /** 46 * This may be called by another thread. 47 * @param target 48 */ setTarget(float target)49 void setTarget(float target) { 50 mTarget.store(target); 51 } 52 getTarget()53 float getTarget() { 54 return mTarget.load(); 55 } 56 57 /** 58 * Force the nextSegment to start from this level. 59 * 60 * WARNING: this can cause a discontinuity if called while the ramp is being used. 61 * Only call this when setting the initial ramp. 62 * 63 * @param level 64 */ forceCurrent(float level)65 void forceCurrent(float level) { 66 mLevelFrom = level; 67 mLevelTo = level; // forces a ramp if it does not match target 68 } 69 getCurrent()70 float getCurrent() { 71 return mLevelFrom; 72 } 73 74 /** 75 * Get levels for next ramp segment. 76 * 77 * @param frames number of frames in the segment 78 * @param levelFrom pointer to starting amplitude 79 * @param levelTo pointer to ending amplitude 80 * @return true if ramp is still moving towards the target 81 */ 82 bool nextSegment(int32_t frames, float *levelFrom, float *levelTo); 83 84 private: 85 86 bool isRamping(); 87 88 std::atomic<float> mTarget; 89 90 int32_t mLengthInFrames = 48000 / 100; // 10 msec at 48000 Hz 91 int32_t mRemaining = 0; 92 float mLevelFrom = 0.0f; 93 float mLevelTo = 0.0f; 94 }; 95 96 97 #endif //AAUDIO_LINEAR_RAMP_H 98