1 /* 2 * Copyright (C) 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 package com.example.android.common.midi.synth; 18 19 /** 20 * Very simple Attack, Decay, Sustain, Release envelope with linear ramps. 21 * 22 * Times are in seconds. 23 */ 24 public class EnvelopeADSR extends SynthUnit { 25 private static final int IDLE = 0; 26 private static final int ATTACK = 1; 27 private static final int DECAY = 2; 28 private static final int SUSTAIN = 3; 29 private static final int RELEASE = 4; 30 private static final int FINISHED = 5; 31 private static final float MIN_TIME = 0.001f; 32 33 private float mAttackRate; 34 private float mRreleaseRate; 35 private float mSustainLevel; 36 private float mDecayRate; 37 private float mCurrent; 38 private int mSstate = IDLE; 39 EnvelopeADSR()40 public EnvelopeADSR() { 41 setAttackTime(0.003f); 42 setDecayTime(0.08f); 43 setSustainLevel(0.3f); 44 setReleaseTime(1.0f); 45 } 46 setAttackTime(float time)47 public void setAttackTime(float time) { 48 if (time < MIN_TIME) 49 time = MIN_TIME; 50 mAttackRate = 1.0f / (SynthEngine.FRAME_RATE * time); 51 } 52 setDecayTime(float time)53 public void setDecayTime(float time) { 54 if (time < MIN_TIME) 55 time = MIN_TIME; 56 mDecayRate = 1.0f / (SynthEngine.FRAME_RATE * time); 57 } 58 setSustainLevel(float level)59 public void setSustainLevel(float level) { 60 if (level < 0.0f) 61 level = 0.0f; 62 mSustainLevel = level; 63 } 64 setReleaseTime(float time)65 public void setReleaseTime(float time) { 66 if (time < MIN_TIME) 67 time = MIN_TIME; 68 mRreleaseRate = 1.0f / (SynthEngine.FRAME_RATE * time); 69 } 70 on()71 public void on() { 72 mSstate = ATTACK; 73 } 74 off()75 public void off() { 76 mSstate = RELEASE; 77 } 78 79 @Override render()80 public float render() { 81 switch (mSstate) { 82 case ATTACK: 83 mCurrent += mAttackRate; 84 if (mCurrent > 1.0f) { 85 mCurrent = 1.0f; 86 mSstate = DECAY; 87 } 88 break; 89 case DECAY: 90 mCurrent -= mDecayRate; 91 if (mCurrent < mSustainLevel) { 92 mCurrent = mSustainLevel; 93 mSstate = SUSTAIN; 94 } 95 break; 96 case RELEASE: 97 mCurrent -= mRreleaseRate; 98 if (mCurrent < 0.0f) { 99 mCurrent = 0.0f; 100 mSstate = FINISHED; 101 } 102 break; 103 } 104 return mCurrent; 105 } 106 isDone()107 public boolean isDone() { 108 return mSstate == FINISHED; 109 } 110 111 } 112