|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /*
- ZynAddSubFX - a software synthesizer
-
- WaveShapeSmps.cpp - Sample Distortion
- Copyright (C) 2002-2005 Nasca Octavian Paul
- Author: Nasca Octavian Paul
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License
- as published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License (version 2 or later) for more details.
-
- You should have received a copy of the GNU General Public License (version 2)
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- */
-
- #include "WaveShapeSmps.h"
- #include <cmath>
-
- void waveShapeSmps(int n,
- float *smps,
- unsigned char type,
- unsigned char drive)
- {
- int i;
- float ws = drive / 127.0f;
- float tmpv;
-
- switch(type) {
- case 1:
- ws = powf(10, ws * ws * 3.0f) - 1.0f + 0.001f; //Arctangent
- for(i = 0; i < n; ++i)
- smps[i] = atanf(smps[i] * ws) / atanf(ws);
- break;
- case 2:
- ws = ws * ws * 32.0f + 0.0001f; //Asymmetric
- if(ws < 1.0f)
- tmpv = sinf(ws) + 0.1f;
- else
- tmpv = 1.1f;
- for(i = 0; i < n; ++i)
- smps[i] = sinf(smps[i] * (0.1f + ws - ws * smps[i])) / tmpv;
- ;
- break;
- case 3:
- ws = ws * ws * ws * 20.0f + 0.0001f; //Pow
- for(i = 0; i < n; ++i) {
- smps[i] *= ws;
- if(fabs(smps[i]) < 1.0f) {
- smps[i] = (smps[i] - powf(smps[i], 3.0f)) * 3.0f;
- if(ws < 1.0f)
- smps[i] /= ws;
- }
- else
- smps[i] = 0.0f;
- }
- break;
- case 4:
- ws = ws * ws * ws * 32.0f + 0.0001f; //Sine
- if(ws < 1.57f)
- tmpv = sinf(ws);
- else
- tmpv = 1.0f;
- for(i = 0; i < n; ++i)
- smps[i] = sinf(smps[i] * ws) / tmpv;
- break;
- case 5:
- ws = ws * ws + 0.000001f; //Quantisize
- for(i = 0; i < n; ++i)
- smps[i] = floor(smps[i] / ws + 0.5f) * ws;
- break;
- case 6:
- ws = ws * ws * ws * 32 + 0.0001f; //Zigzag
- if(ws < 1.0f)
- tmpv = sinf(ws);
- else
- tmpv = 1.0f;
- for(i = 0; i < n; ++i)
- smps[i] = asinf(sinf(smps[i] * ws)) / tmpv;
- break;
- case 7:
- ws = powf(2.0f, -ws * ws * 8.0f); //Limiter
- for(i = 0; i < n; ++i) {
- float tmp = smps[i];
- if(fabs(tmp) > ws) {
- if(tmp >= 0.0f)
- smps[i] = 1.0f;
- else
- smps[i] = -1.0f;
- }
- else
- smps[i] /= ws;
- }
- break;
- case 8:
- ws = powf(2.0f, -ws * ws * 8.0f); //Upper Limiter
- for(i = 0; i < n; ++i) {
- float tmp = smps[i];
- if(tmp > ws)
- smps[i] = ws;
- smps[i] *= 2.0f;
- }
- break;
- case 9:
- ws = powf(2.0f, -ws * ws * 8.0f); //Lower Limiter
- for(i = 0; i < n; ++i) {
- float tmp = smps[i];
- if(tmp < -ws)
- smps[i] = -ws;
- smps[i] *= 2.0f;
- }
- break;
- case 10:
- ws = (powf(2.0f, ws * 6.0f) - 1.0f) / powf(2.0f, 6.0f); //Inverse Limiter
- for(i = 0; i < n; ++i) {
- float tmp = smps[i];
- if(fabs(tmp) > ws) {
- if(tmp >= 0.0f)
- smps[i] = tmp - ws;
- else
- smps[i] = tmp + ws;
- }
- else
- smps[i] = 0;
- }
- break;
- case 11:
- ws = powf(5, ws * ws * 1.0f) - 1.0f; //Clip
- for(i = 0; i < n; ++i)
- smps[i] = smps[i]
- * (ws + 0.5f) * 0.9999f - floor(
- 0.5f + smps[i] * (ws + 0.5f) * 0.9999f);
- break;
- case 12:
- ws = ws * ws * ws * 30 + 0.001f; //Asym2
- if(ws < 0.3f)
- tmpv = ws;
- else
- tmpv = 1.0f;
- for(i = 0; i < n; ++i) {
- float tmp = smps[i] * ws;
- if((tmp > -2.0f) && (tmp < 1.0f))
- smps[i] = tmp * (1.0f - tmp) * (tmp + 2.0f) / tmpv;
- else
- smps[i] = 0.0f;
- }
- break;
- case 13:
- ws = ws * ws * ws * 32.0f + 0.0001f; //Pow2
- if(ws < 1.0f)
- tmpv = ws * (1 + ws) / 2.0f;
- else
- tmpv = 1.0f;
- for(i = 0; i < n; ++i) {
- float tmp = smps[i] * ws;
- if((tmp > -1.0f) && (tmp < 1.618034f))
- smps[i] = tmp * (1.0f - tmp) / tmpv;
- else
- if(tmp > 0.0f)
- smps[i] = -1.0f;
- else
- smps[i] = -2.0f;
- }
- break;
- case 14:
- ws = powf(ws, 5.0f) * 80.0f + 0.0001f; //sigmoid
- if(ws > 10.0f)
- tmpv = 0.5f;
- else
- tmpv = 0.5f - 1.0f / (expf(ws) + 1.0f);
- for(i = 0; i < n; ++i) {
- float tmp = smps[i] * ws;
- if(tmp < -10.0f)
- tmp = -10.0f;
- else
- if(tmp > 10.0f)
- tmp = 10.0f;
- tmp = 0.5f - 1.0f / (expf(tmp) + 1.0f);
- smps[i] = tmp / tmpv;
- }
- break;
- }
- }
|