| 1 | package com.txt_nifty.sketch.flmml {
|
|---|
| 2 | /**
|
|---|
| 3 | * This class was created based on "ADSREnvelope.as".
|
|---|
| 4 | The original code is in "nu.mine.flashnet.sound.synthesis".
|
|---|
| 5 | See following URL; http://www.flexiblefactory.co.uk
|
|---|
| 6 | Thanks to his great works!
|
|---|
| 7 | */
|
|---|
| 8 |
|
|---|
| 9 | import de.popforge.audio.output.*;
|
|---|
| 10 |
|
|---|
| 11 | public class MEnvelope {
|
|---|
| 12 | public var m_attack:Number;
|
|---|
| 13 | public var m_decay:Number;
|
|---|
| 14 | public var m_sustain:Number;
|
|---|
| 15 | public var m_release:Number;
|
|---|
| 16 | private var m_currentVal:Number;
|
|---|
| 17 | private var m_releaseStep:Number;
|
|---|
| 18 | private var m_releasing:Boolean;
|
|---|
| 19 | private var m_playing:Boolean;
|
|---|
| 20 | private var m_timeInSamples:int;
|
|---|
| 21 | private var m_startAmplitude:Number;
|
|---|
| 22 |
|
|---|
| 23 | public function MEnvelope(attack:Number, decay:Number, sustain:Number, release:Number) {
|
|---|
| 24 | m_playing = false;
|
|---|
| 25 | m_attack = attack;
|
|---|
| 26 | m_decay = decay;
|
|---|
| 27 | m_sustain = sustain;
|
|---|
| 28 | m_release = release;
|
|---|
| 29 | m_currentVal = 0;
|
|---|
| 30 | m_releasing = true;
|
|---|
| 31 | m_releaseStep = 0;
|
|---|
| 32 | }
|
|---|
| 33 |
|
|---|
| 34 | public function setAD(attack:Number, decay:Number):void {
|
|---|
| 35 | m_attack = attack;
|
|---|
| 36 | m_decay = decay;
|
|---|
| 37 | }
|
|---|
| 38 |
|
|---|
| 39 | public function setSR(sustain:Number, release:Number):void {
|
|---|
| 40 | m_sustain = sustain;
|
|---|
| 41 | m_release = (release > 0) ? release : 1;
|
|---|
| 42 | }
|
|---|
| 43 |
|
|---|
| 44 | public function triggerEnvelope():void {
|
|---|
| 45 | m_playing = true;
|
|---|
| 46 | m_releasing = false;
|
|---|
| 47 | m_startAmplitude = m_currentVal;
|
|---|
| 48 | m_timeInSamples = 1; //no point in starting at zero as this gives a sample worth of zero before onset of env.
|
|---|
| 49 | }
|
|---|
| 50 |
|
|---|
| 51 | public function releaseEnvelope():void {
|
|---|
| 52 | m_releasing = true;
|
|---|
| 53 | var releaseTimeInSamples:int = (m_release * Audio.RATE44100);
|
|---|
| 54 | m_releaseStep = (m_currentVal / releaseTimeInSamples);
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 | public function getNextAmplitude():Number {
|
|---|
| 58 | if (!m_playing) return 0;
|
|---|
| 59 | var val:Number;
|
|---|
| 60 | var offset:Number = (m_timeInSamples as Number) / Audio.RATE44100;
|
|---|
| 61 |
|
|---|
| 62 | if (!m_releasing) {
|
|---|
| 63 | if (offset < m_attack) { // attack phase
|
|---|
| 64 | val = m_startAmplitude + (1 - m_startAmplitude) * offset / m_attack;
|
|---|
| 65 | }
|
|---|
| 66 | else if (offset < (m_attack + m_decay)) { //decay phase
|
|---|
| 67 | val = 1.0 - ((offset - m_attack) / m_decay) * (1.0 - m_sustain);
|
|---|
| 68 | }
|
|---|
| 69 | else if (offset >= (m_attack + m_decay)) { //sustain phase
|
|---|
| 70 | val = m_sustain;
|
|---|
| 71 | }
|
|---|
| 72 | }
|
|---|
| 73 | else {
|
|---|
| 74 | val = m_currentVal - m_releaseStep; //release phase
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | if (val < 0) {
|
|---|
| 78 | m_playing = false;
|
|---|
| 79 | }
|
|---|
| 80 | m_currentVal = Math.max(0, val);
|
|---|
| 81 | ++m_timeInSamples;
|
|---|
| 82 | return m_currentVal;
|
|---|
| 83 | }
|
|---|
| 84 | }
|
|---|
| 85 | }
|
|---|