|
- /*
- 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 the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- */
-
- #include "WaveShapeSmps.h"
- #include <cmath>
-
- namespace zyncarla {
-
- 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;
- }
- }
-
- }
|