|
CLAM-Development
1.3
|
00001 /* 00002 * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 00023 #include "ADSR.hxx" 00024 #include "ProcessingFactory.hxx" 00025 00026 00027 namespace CLAM 00028 { 00029 00030 namespace Hidden 00031 { 00032 static const char * metadata[] = { 00033 "key", "ADSR", 00034 "category", "Generators", 00035 "description", "ADSR", 00036 0 00037 }; 00038 static FactoryRegistrator<ProcessingFactory, ADSR> reg = metadata; 00039 } 00040 00041 void ADSRConfig::DefaultInit(void) 00042 { 00043 AddAttackTime(); 00044 AddDecayTime(), 00045 AddSustainLevel(); 00046 AddReleaseTime(); 00047 AddSampleRate(); 00048 00049 UpdateData(); 00050 00051 SetSampleRate( 8000 ); 00052 } 00053 00054 ADSR::ADSR( const ADSRConfig& cfg ) 00055 : mOutput("Audio Output",this) 00056 , mAmplitude("Amplitude",this, &ADSR::UpdateAmp ) 00057 , mAmpValue(0) 00058 , mLevel(0) 00059 , mDLevel(0) 00060 , mStatus(Done) 00061 , mState( "State", this ) 00062 { 00063 Configure( cfg ); 00064 } 00065 00066 bool ADSR::ConcreteConfigure( const ProcessingConfig& c ) 00067 { 00068 CopyAsConcreteConfig(mConfig, c); 00069 00070 mAttackTime = mConfig.GetAttackTime(); 00071 mDecayTime = mConfig.GetDecayTime(); 00072 mSustainLevel = mConfig.GetSustainLevel(); 00073 mReleaseTime = mConfig.GetReleaseTime(); 00074 mSamplingRate = mConfig.GetSampleRate(); 00075 00076 return true; 00077 } 00078 00079 void ADSR::HandleAttack(void) 00080 { 00081 mStatus = Attack; 00082 mLevel = 0; 00083 mDLevel = mAmpValue / ( mAttackTime * mSamplingRate ); 00084 } 00085 00086 void ADSR::HandleDecay(void) 00087 { 00088 mStatus = Decay; 00089 mDLevel = ( mSustainLevel * mAmpValue - mAmpValue ) / ( mDecayTime * mSamplingRate ) ; 00090 } 00091 00092 void ADSR::HandleRelease(void) 00093 { 00094 mStatus = Release; 00095 mDLevel = - mLevel / ( mReleaseTime * mSamplingRate ); 00096 } 00097 00098 bool ADSR::Do( Audio& out) 00099 { 00100 /*** this is the "clean" version: 00101 00102 TData* ptr = out.GetBuffer().GetPtr(); 00103 00104 for ( int i = 0; i < out.GetSize() ; i++ ) 00105 { 00106 (*ptr++) = mLevel ; 00107 mLevel += mDLevel ; 00108 00109 if ( ( mStatus == Attack ) && ( mLevel >= mAmpValue ) ) 00110 { 00111 mStatus = Decay ; 00112 HandleDecay(); 00113 } 00114 else if ( ( mStatus == Decay ) && ( mLevel <= mSustainLevel ) ) 00115 { 00116 mStatus = Sustain ; 00117 mDLevel = 0 ; 00118 } 00119 else if ( ( mStatus == Release ) && ( mLevel <= 0 ) ) 00120 { 00121 mDLevel = 0; 00122 mLevel = 0; 00123 mStatus = Done; 00124 } 00125 } 00126 */ 00127 00128 /* 00129 the following does the same, but more efficient, by moving part of the conditions 00130 outside of the for loop 00131 */ 00132 00133 TData* ptr = out.GetBuffer().GetPtr(); 00134 TData* endptr = ptr+out.GetSize(); 00135 00136 if (mStatus==Attack) 00137 { 00138 while ( ptr!=endptr ) 00139 { 00140 (*ptr++) = mLevel ; 00141 mLevel += mDLevel ; 00142 00143 if (mLevel >= mAmpValue) 00144 { 00145 mStatus = Decay ; 00146 HandleDecay(); 00147 break; 00148 } 00149 } 00150 } 00151 if (mStatus==Decay) 00152 { 00153 while ( ptr!=endptr ) 00154 { 00155 (*ptr++) = mLevel ; 00156 mLevel += mDLevel ; 00157 00158 if (mLevel <= mSustainLevel ) 00159 { 00160 mStatus = Sustain ; 00161 mDLevel = 0 ; 00162 break; 00163 } 00164 } 00165 } 00166 if (mStatus==Sustain) 00167 { 00168 while ( ptr!=endptr ) 00169 { 00170 (*ptr++) = mLevel ; 00171 } 00172 } 00173 if (mStatus==Release) 00174 { 00175 while ( ptr!=endptr ) 00176 { 00177 (*ptr++) = mLevel ; 00178 mLevel += mDLevel ; 00179 00180 if (mLevel <=0 ) 00181 { 00182 mDLevel = 0; 00183 mLevel = 0; 00184 mStatus = Done; 00185 break; 00186 } 00187 } 00188 } 00189 if (mStatus==Done) 00190 { 00191 while ( ptr!=endptr ) 00192 { 00193 (*ptr++) = 0 ; 00194 } 00195 } 00196 00197 UpdateState(); 00198 00199 return true; 00200 00201 } 00202 00203 bool ADSR::Do() 00204 { 00205 bool res = false; 00206 res = Do(mOutput.GetAudio()); 00207 mOutput.Produce(); 00208 return res; 00209 00210 00211 } 00212 00213 } 00214
1.7.6.1