home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 November / CMCD1104.ISO / Software / Complet / ZynAddFX / Setup_ZynAddSubFX-2.1.1.exe / Distorsion.C < prev    next >
Encoding:
C/C++ Source or Header  |  2004-07-26  |  8.7 KB  |  385 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   Distorsion.C - Distorsion effect
  5.   Copyright (C) 2002-2004 Nasca Octavian Paul
  6.   Author: Nasca Octavian Paul
  7.  
  8.   This program is free software; you can redistribute it and/or modify
  9.   it under the terms of version 2 of the GNU General Public License 
  10.   as published by the Free Software Foundation.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License (version 2) for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License (version 2)
  18.   along with this program; if not, write to the Free Software Foundation,
  19.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20.  
  21. */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <math.h>
  26. #include "Distorsion.h"
  27.  
  28.  
  29. /*
  30.  * Waveshape (this is called by OscilGen::waveshape and Distorsion::process)
  31.  */
  32.  
  33. void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive){
  34.     int i;
  35.     REALTYPE ws=drive/127.0;
  36.     REALTYPE tmpv;
  37.  
  38.     switch(type){
  39.     case 1:    ws=pow(10,ws*ws*3.0)-1.0+0.001;//Arctangent
  40.         for (i=0;i<n;i++) 
  41.             smps[i]=atan(smps[i]*ws)/atan(ws);
  42.         break;
  43.     case 2:    ws=ws*ws*32.0+0.0001;//Asymmetric
  44.         if (ws<1.0) tmpv=sin(ws)+0.1;
  45.             else tmpv=1.1;
  46.         for (i=0;i<n;i++) {
  47.             smps[i]=sin(smps[i]*(0.1+ws-ws*smps[i]))/tmpv;
  48.         };
  49.         break;
  50.     case 3:    ws=ws*ws*ws*20.0+0.0001;//Pow
  51.         for (i=0;i<n;i++) {
  52.             smps[i]*=ws;
  53.             if (fabs(smps[i])<1.0) {
  54.             smps[i]=(smps[i]-pow(smps[i],3.0))*3.0;
  55.             if (ws<1.0) smps[i]/=ws;
  56.             } else smps[i]=0.0;
  57.         };
  58.         break;
  59.     case 4:    ws=ws*ws*ws*32.0+0.0001;//Sine
  60.         if (ws<1.57) tmpv=sin(ws);
  61.             else tmpv=1.0;
  62.         for (i=0;i<n;i++) smps[i]=sin(smps[i]*ws)/tmpv;
  63.         break;
  64.     case 5:    ws=ws*ws+0.000001;//Quantisize
  65.         for (i=0;i<n;i++) 
  66.             smps[i]=floor(smps[i]/ws+0.5)*ws;
  67.         break;
  68.     case 6:    ws=ws*ws*ws*32+0.0001;//Zigzag
  69.         if (ws<1.0) tmpv=sin(ws);
  70.             else tmpv=1.0;
  71.         for (i=0;i<n;i++) 
  72.               smps[i]=asin(sin(smps[i]*ws))/tmpv;
  73.         break;
  74.     case 7:    ws=pow(2.0,-ws*ws*8.0); //Limiter
  75.         for (i=0;i<n;i++) {
  76.             REALTYPE tmp=smps[i];
  77.             if (fabs(tmp)>ws) {
  78.             if (tmp>=0.0) smps[i]=1.0;
  79.                 else smps[i]=-1.0;
  80.             } else smps[i]/=ws;
  81.         };
  82.         break;
  83.     case 8:    ws=pow(2.0,-ws*ws*8.0); //Upper Limiter
  84.         for (i=0;i<n;i++) {
  85.             REALTYPE tmp=smps[i];
  86.             if (tmp>ws) smps[i]=ws;
  87.             smps[i]*=2.0;
  88.         };
  89.         break;
  90.     case 9:    ws=pow(2.0,-ws*ws*8.0); //Lower Limiter
  91.         for (i=0;i<n;i++) {
  92.             REALTYPE tmp=smps[i];
  93.             if (tmp<-ws) smps[i]=-ws;
  94.             smps[i]*=2.0;
  95.         };
  96.         break;
  97.     case 10:ws=(pow(2.0,ws*6.0)-1.0)/pow(2.0,6.0); //Inverse Limiter
  98.         for (i=0;i<n;i++) {
  99.             REALTYPE tmp=smps[i];
  100.             if (fabs(tmp)>ws) {
  101.             if (tmp>=0.0) smps[i]=tmp-ws;
  102.                 else smps[i]=tmp+ws;
  103.             } else smps[i]=0;
  104.         };
  105.         break;
  106.     case 11:ws=pow(5,ws*ws*1.0)-1.0;//Clip
  107.         for (i=0;i<n;i++) 
  108.             smps[i]=smps[i]*(ws+0.5)*0.9999-floor(0.5+smps[i]*(ws+0.5)*0.9999);
  109.         break;
  110.     case 12:ws=ws*ws*ws*30+0.001;//Asym2
  111.         if (ws<0.3) tmpv=ws;
  112.            else tmpv=1.0;
  113.         for (i=0;i<n;i++) {
  114.             REALTYPE tmp=smps[i]*ws;
  115.             if ((tmp>-2.0) && (tmp<1.0)) smps[i]=tmp*(1.0-tmp)*(tmp+2.0)/tmpv;
  116.             else smps[i]=0.0;
  117.         };
  118.         break;
  119.     case 13:ws=ws*ws*ws*32.0+0.0001;//Pow2
  120.         if (ws<1.0) tmpv=ws*(1+ws)/2.0;
  121.             else tmpv=1.0;
  122.         for (i=0;i<n;i++) {
  123.             REALTYPE tmp=smps[i]*ws;
  124.             if ((tmp>-1.0)&&(tmp<1.618034)) smps[i]=tmp*(1.0-tmp)/tmpv;
  125.             else if (tmp>0.0) smps[i]=-1.0;
  126.                 else smps[i]=-2.0;
  127.         };
  128.         break;
  129.     case 14:ws=pow(ws,5.0)*80.0+0.0001;//sigmoid
  130.         if (ws>10.0) tmpv=0.5;
  131.             else tmpv=0.5-1.0/(exp(ws)+1.0);
  132.         for (i=0;i<n;i++) {
  133.             REALTYPE tmp=smps[i]*ws;
  134.             if (tmp<-10.0) tmp=-10.0;
  135.             else if (tmp>10.0) tmp=10.0;
  136.             tmp=0.5-1.0/(exp(tmp)+1.0);
  137.             smps[i]=tmp/tmpv;
  138.         };
  139.         break;
  140.     //update to Distorsion::changepar (Ptype max) if there is added more waveshapings functions
  141.     };
  142.  
  143. };
  144.  
  145.  
  146. Distorsion::Distorsion(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){
  147.     efxoutl=efxoutl_;
  148.     efxoutr=efxoutr_;
  149.  
  150.     lpfl=new AnalogFilter(2,22000,1,0);
  151.     lpfr=new AnalogFilter(2,22000,1,0);
  152.     hpfl=new AnalogFilter(3,20,1,0);
  153.     hpfr=new AnalogFilter(3,20,1,0);
  154.     
  155.     filterpars=NULL;
  156.  
  157.     insertion=insertion_;
  158.     //default values
  159.     Ppreset=0;
  160.     Pvolume=50;
  161.     Plrcross=40; 
  162.     Pdrive=90;
  163.     Plevel=64;
  164.     Ptype=0;
  165.     Pnegate=0;
  166.     Plpf=127;
  167.     Phpf=0;
  168.     Pstereo=0;
  169.     Pprefiltering=0;
  170.  
  171.     setpreset(Ppreset);           
  172.     cleanup();
  173. };
  174.  
  175. Distorsion::~Distorsion(){
  176.     delete (lpfl);
  177.     delete (lpfr);
  178.     delete (hpfl);
  179.     delete (hpfr);
  180.     
  181. };
  182.  
  183. /*
  184.  * Cleanup the effect
  185.  */
  186. void Distorsion::cleanup(){
  187.     lpfl->cleanup();
  188.     hpfl->cleanup();
  189.     lpfr->cleanup();
  190.     hpfr->cleanup();
  191. };
  192.  
  193.  
  194. /*
  195.  * Apply the filters
  196.  */
  197.  
  198. void Distorsion::applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr){
  199.     lpfl->filterout(efxoutl);
  200.     hpfl->filterout(efxoutl);
  201.     if (Pstereo!=0){//stereo
  202.     lpfr->filterout(efxoutr);
  203.         hpfr->filterout(efxoutr);
  204.     };
  205.  
  206. };
  207.  
  208.  
  209. /*
  210.  * Effect output
  211.  */
  212. void Distorsion::out(REALTYPE *smpsl,REALTYPE *smpsr){
  213.     int i;
  214.     REALTYPE l,r,lout,rout;
  215.  
  216.     REALTYPE inputvol=pow(5.0,(Pdrive-32.0)/127.0);
  217.     if (Pnegate!=0) inputvol*=-1.0;
  218.     
  219.     if (Pstereo!=0){//Stereo
  220.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  221.         efxoutl[i]=smpsl[i]*inputvol*panning;
  222.         efxoutr[i]=smpsr[i]*inputvol*(1.0-panning);
  223.     };
  224.     } else {
  225.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  226.         efxoutl[i]=( smpsl[i]*panning + smpsr[i]*(1.0-panning) ) * inputvol;
  227.     };
  228.     };
  229.     
  230.     if (Pprefiltering!=0) applyfilters(efxoutl,efxoutr);
  231.  
  232.     //no optimised, yet (no look table)
  233.     waveshapesmps(SOUND_BUFFER_SIZE,efxoutl,Ptype+1,Pdrive);
  234.     if (Pstereo!=0) waveshapesmps(SOUND_BUFFER_SIZE,efxoutr,Ptype+1,Pdrive);
  235.  
  236.     if (Pprefiltering==0) applyfilters(efxoutl,efxoutr);
  237.     
  238.     if (Pstereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) efxoutr[i]=efxoutl[i];
  239.     
  240.     REALTYPE level=dB2rap(60.0*Plevel/127.0-40.0);
  241.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  242.     lout=efxoutl[i];
  243.     rout=efxoutr[i];
  244.     l=lout*(1.0-lrcross)+rout*lrcross;
  245.     r=rout*(1.0-lrcross)+lout*lrcross;
  246.     lout=l;rout=r;
  247.     
  248.     efxoutl[i]=lout*2.0*level;
  249.     efxoutr[i]=rout*2.0*level;
  250.  
  251.     };
  252.     
  253. };
  254.  
  255.  
  256. /*
  257.  * Parameter control
  258.  */
  259. void Distorsion::setvolume(unsigned char Pvolume){
  260.     this->Pvolume=Pvolume;
  261.  
  262.     if (insertion==0) {
  263.     outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0;
  264.     volume=1.0;
  265.     } else {
  266.     volume=outvolume=Pvolume/127.0;
  267.     };
  268.     if (Pvolume==0) cleanup();
  269.  
  270. };
  271.  
  272. void Distorsion::setpanning(unsigned char Ppanning){
  273.     this->Ppanning=Ppanning;
  274.     panning=(Ppanning+0.5)/127.0;
  275. };
  276.  
  277.  
  278. void Distorsion::setlrcross(unsigned char Plrcross){
  279.     this->Plrcross=Plrcross;
  280.     lrcross=Plrcross/127.0*1.0;
  281. };
  282.  
  283. void Distorsion::setlpf(unsigned char Plpf){
  284.     this->Plpf=Plpf;
  285.     REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40;
  286.     lpfl->setfreq(fr);
  287.     lpfr->setfreq(fr);
  288. };
  289.  
  290. void Distorsion::sethpf(unsigned char Phpf){
  291.     this->Phpf=Phpf;
  292.     REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(25000.0))+20.0;
  293.     hpfl->setfreq(fr);
  294.     hpfr->setfreq(fr);
  295. };
  296.  
  297.  
  298. void Distorsion::setpreset(unsigned char npreset){
  299.     const int PRESET_SIZE=11;
  300.     const int NUM_PRESETS=6;
  301.     unsigned char presets[NUM_PRESETS][PRESET_SIZE]={
  302.     //Overdrive 1
  303.     {127,64,35,56,70,0,0,96,0,0,0},
  304.     //Overdrive 2
  305.     {127,64,35,29,75,1,0,127,0,0,0},
  306.     //A. Exciter 1
  307.     {64,64,35,75,80,5,0,127,105,1,0},
  308.     //A. Exciter 2
  309.     {64,64,35,85,62,1,0,127,118,1,0},
  310.     //Guitar Amp
  311.     {127,64,35,63,75,2,0,55,0,0,0},
  312.     //Quantisize
  313.     {127,64,35,88,75,4,0,127,0,1,0}};
  314.  
  315.  
  316.     if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1;
  317.     for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]);
  318.     if (insertion==0) changepar(0,(int) (presets[npreset][0]/1.5));//lower the volume if this is system effect
  319.     Ppreset=npreset;
  320.     cleanup();
  321. };
  322.  
  323.  
  324. void Distorsion::changepar(int npar,unsigned char value){
  325.     switch (npar){
  326.     case 0: setvolume(value);
  327.         break;
  328.     case 1: setpanning(value);
  329.         break;
  330.     case 2: setlrcross(value);
  331.         break;
  332.     case 3: Pdrive=value;
  333.         break;
  334.     case 4: Plevel=value;
  335.         break;
  336.     case 5: if (value>13) value=13;//this must be increased if more distorsion types are added
  337.         Ptype=value;
  338.         break;
  339.     case 6: if (value>1) value=1;
  340.         Pnegate=value;
  341.         break;
  342.     case 7: setlpf(value);
  343.         break;
  344.     case 8: sethpf(value);
  345.         break;
  346.     case 9: if (value>1) value=1;
  347.         Pstereo=value;
  348.         break;
  349.     case 10:Pprefiltering=value;
  350.         break;
  351.     };
  352. };
  353.  
  354. unsigned char Distorsion::getpar(int npar){
  355.     switch (npar){
  356.     case 0: return(Pvolume);
  357.         break;
  358.     case 1: return(Ppanning);
  359.         break;
  360.     case 2: return(Plrcross);
  361.         break;
  362.     case 3: return(Pdrive);
  363.         break;
  364.     case 4: return(Plevel);
  365.         break;
  366.     case 5: return(Ptype);
  367.         break;
  368.     case 6: return(Pnegate);
  369.         break;
  370.     case 7: return(Plpf);
  371.         break;
  372.     case 8: return(Phpf);
  373.         break;
  374.     case 9: return(Pstereo);
  375.         break;
  376.     case 10:return(Pprefiltering);
  377.         break;
  378.     };
  379.     return(0);//in case of bogus parameter number
  380. };
  381.  
  382.  
  383.  
  384.  
  385.