1/* 2 YC-20 percussion circuit emulation in Faust 3 Copyright(C) 2010 Sampo Savolainen <v2@iki.fi> 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 RMS code by Yann Orlarey from the Faust project 19*/ 20 21reduce(op, n, x) = compute ~ (_,_,_) : (!,!,_) 22 with { 23 compute (acc, count, val) = 24 if(count<n, op(acc,x), x), // new acc 25 if(count<n, count+1, 1), // new count 26 if(count<n, val, acc); // new val 27 if (c, then, else) = select2(c, else, then); 28 }; 29 30 31// the sum of the amplitudes of the input signal 32sumn(n) = reduce(+,n); 33 34// the maximum amplitude of the input signal 35maxn(n) = reduce(max,n); 36 37// the minimum amplitude of the input signal 38minn(n) = reduce(min,n); 39 40// the average amplitude of the input signal 41mean(n) = sumn(n)/n; 42 43// RMS 44RMS(n) = float : square : mean(n) : sqrt 45with { 46 square(x) = x*x; 47}; 48 49co2db(coeff) = 20.0*log10(coeff); 50 51percussion_envelope = detect : apply_envelope : apply_realism : *(4.5) 52with { 53 rms_approx(n) = square : (sumit ~ _) : sqrt 54 with { 55 square(x) = x * x; 56 sumit(x,prev) = prev *((n-1.0)/n) + x / n; 57 }; 58 59 measured_bleed = 0.01357; 60 61 apply_realism = max( select2(realism_control > (3.0/6.0), 0.0, measured_bleed)); 62 63 rms_detect_speed = int(max(22050.0,min(192000.0,float(SR))) * 0.001); 64 65 threshold = -25.0; 66 threshold_hyst = threshold - 10.0; 67 68 detect = +(noise*0.000001) : max(-1.0) : min(1.0) : RMS(rms_detect_speed) : co2db : impulse_detector; 69 70 impulse_detector = (hysteresis_detector ~ _) : impulsify; 71 hysteresis_detector(prev, x) = prev + detect_rise(x) - detect_fall(x) : max(0.0) : min(1.0); 72 73 impulsify(sig) = 74 select2( sig > 0.5, 0.0, 75 select2( sig' < 0.5, 0.0, 1.0)); 76 77 detect_rise(sig) = 78 select2( sig > threshold, 0.0, 79 select2( sig' < threshold, 0.0, 1.0)); 80 81 detect_fall(sig) = 82 select2( sig' > threshold_hyst, 0.0, 83 select2( sig < threshold_hyst, 0.0, 1.0)); 84 85 86 envelope_speed = 0.05; 87 envelope_coeff = envelope_speed : exp(1.0) / (1.5 * float(SR) * _) : (1.0 - _); 88 89 apply_envelope = +(_*(1.0-envelope_coeff)) ~ *(envelope_coeff) 90 : *(1.0/(1.0-envelope_coeff)) : min(1.0) 91 : sum_it; 92 93 sum_it(x) = x + x'' + x''' + x'''' : /(4.0); 94}; 95 96