1 /* 2 * Bypass.cpp 3 * 4 * Created on: 22 янв. 2020 г. 5 * Author: Vladimir Sadovnikov <lsp.plugin@gmail.com> 6 * 7 * This file is part of tamgamp.lv2 <https://github.com/sadko4u/tamgamp.lv2>. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 3 of the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public License 20 * along with this program; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 */ 23 24 #include "../../../include/tamgamp.lv2/util/Bypass.h" 25 26 #include <string.h> 27 28 namespace tamgamp_lv2 29 { 30 Bypass()31 Bypass::Bypass() 32 { 33 nState = S_OFF; 34 fDelta = 0; 35 fGain = 0; 36 } 37 ~Bypass()38 Bypass::~Bypass() 39 { 40 } 41 set_bypass(bool bypass)42 bool Bypass::set_bypass(bool bypass) 43 { 44 // Trigger state change 45 switch (nState) 46 { 47 case S_ON: 48 if (bypass) 49 return false; 50 nState = S_ACTIVE; 51 break; 52 case S_OFF: 53 if (!bypass) 54 return false; 55 nState = S_ACTIVE; 56 break; 57 case S_ACTIVE: 58 { 59 bool off = (fDelta < 0.0f); 60 if (bypass == off) 61 return false; 62 break; 63 } 64 default: 65 return false; 66 } 67 68 // Change sign of the applying delta 69 fDelta = -fDelta; 70 return true; 71 } 72 bypassing() const73 bool Bypass::bypassing() const 74 { 75 switch (nState) 76 { 77 case S_ON: return true; 78 case S_OFF: return false; 79 case S_ACTIVE: return fDelta < 0.0f; 80 default: return false; 81 } 82 } 83 init(int sample_rate,float time)84 void Bypass::init(int sample_rate, float time) 85 { 86 // Off by default 87 float length= sample_rate * time; 88 if (length < 1.0f) 89 length = 1.0f; 90 nState = S_OFF; 91 fDelta = 1.0 / length; 92 fGain = 1.0; 93 } 94 process(float * dst,const float * dry,const float * wet,size_t count)95 void Bypass::process(float *dst, const float *dry, const float *wet, size_t count) 96 { 97 // Skip empty buffers 98 if (count == 0) 99 return; 100 101 if (dry != NULL) 102 { 103 // Analyze direction 104 if (fDelta > 0.0f) 105 { 106 // Process transition 107 while (fGain < 1.0) 108 { 109 *dst = *dry + (*wet - *dry) * fGain; 110 111 fGain += fDelta; 112 dry ++; 113 wet ++; 114 dst ++; 115 116 if ((--count) <= 0) // Last sample? 117 return; 118 } 119 120 // Copy wet data 121 fGain = 1.0; 122 nState = S_OFF; 123 if (count > 0) 124 ::memcpy(dst, wet, count*sizeof(float)); 125 } 126 else 127 { 128 // Process transition 129 while (fGain > 0.0) 130 { 131 *dst = *dry + (*wet - *dry) * fGain; 132 133 fGain += fDelta; 134 dry ++; 135 wet ++; 136 dst ++; 137 138 if ((--count) <= 0) // Last sample? 139 return; 140 } 141 142 // Copy dry data 143 fGain = 0.0; 144 nState = S_ON; 145 if (count > 0) 146 ::memcpy(dst, dry, count*sizeof(float)); 147 } 148 } 149 else 150 { 151 // Analyze direction 152 if (fDelta > 0.0f) 153 { 154 // Process transition 155 while (fGain < 1.0) 156 { 157 *dst = (*wet) * fGain; 158 159 fGain += fDelta; 160 wet ++; 161 dst ++; 162 163 if ((--count) <= 0) // Last sample? 164 return; 165 } 166 167 // Copy wet data 168 fGain = 1.0; 169 nState = S_OFF; 170 if (count > 0) 171 ::memcpy(dst, wet, count*sizeof(float)); 172 } 173 else 174 { 175 // Process transition 176 while (fGain > 0.0) 177 { 178 *dst = (*wet) * fGain; 179 180 fGain += fDelta; 181 wet ++; 182 dst ++; 183 184 if ((--count) <= 0) // Last sample? 185 return; 186 } 187 188 // Zero dry data 189 fGain = 0.0; 190 nState = S_ON; 191 if (count > 0) 192 ::bzero(dst, count*sizeof(float)); 193 } 194 } 195 } 196 197 } 198 199 200