| 
							- /*
 -   ZynAddSubFX - a software synthesizer
 - 
 -   Resonance.cpp - Resonance
 -   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 <math.h>
 - #include <stdlib.h>
 - #include "Resonance.h"
 - 
 - Resonance::Resonance():Presets()
 - {
 -     setpresettype("Presonance");
 -     defaults();
 - }
 - 
 - Resonance::~Resonance()
 - {}
 - 
 - 
 - void Resonance::defaults()
 - {
 -     Penabled     = 0;
 -     PmaxdB       = 20;
 -     Pcenterfreq  = 64; //1 kHz
 -     Poctavesfreq = 64;
 -     Pprotectthefundamental = 0;
 -     ctlcenter = 1.0f;
 -     ctlbw     = 1.0f;
 -     for(int i = 0; i < N_RES_POINTS; ++i)
 -         Prespoints[i] = 64;
 - }
 - 
 - /*
 -  * Set a point of resonance function with a value
 -  */
 - void Resonance::setpoint(int n, unsigned char p)
 - {
 -     if((n < 0) || (n >= N_RES_POINTS))
 -         return;
 -     Prespoints[n] = p;
 - }
 - 
 - /*
 -  * Apply the resonance to FFT data
 -  */
 - void Resonance::applyres(int n, fft_t *fftdata, float freq)
 - {
 -     if(Penabled == 0)
 -         return;             //if the resonance is disabled
 -     float sum = 0.0f,
 -           l1  = logf(getfreqx(0.0f) * ctlcenter),
 -           l2  = logf(2.0f) * getoctavesfreq() * ctlbw;
 - 
 -     for(int i = 0; i < N_RES_POINTS; ++i)
 -         if(sum < Prespoints[i])
 -             sum = Prespoints[i];
 -     if(sum < 1.0f)
 -         sum = 1.0f;
 - 
 -     for(int i = 1; i < n; ++i) {
 -         float x = (logf(freq * i) - l1) / l2; //compute where the n-th hamonics fits to the graph
 -         if(x < 0.0f)
 -             x = 0.0f;
 - 
 -         x *= N_RES_POINTS;
 -         float dx = x - floor(x);
 -         x = floor(x);
 -         int kx1 = (int)x;
 -         if(kx1 >= N_RES_POINTS)
 -             kx1 = N_RES_POINTS - 1;
 -         int kx2 = kx1 + 1;
 -         if(kx2 >= N_RES_POINTS)
 -             kx2 = N_RES_POINTS - 1;
 -         float y =
 -             (Prespoints[kx1]
 -              * (1.0f - dx) + Prespoints[kx2] * dx) / 127.0f - sum / 127.0f;
 - 
 -         y = powf(10.0f, y * PmaxdB / 20.0f);
 - 
 -         if((Pprotectthefundamental != 0) && (i == 1))
 -             y = 1.0f;
 - 
 -         fftdata[i] *= y;
 -     }
 - }
 - 
 - /*
 -  * Gets the response at the frequency "freq"
 -  */
 - 
 - float Resonance::getfreqresponse(float freq)
 - {
 -     float l1 = logf(getfreqx(0.0f) * ctlcenter),
 -           l2 = logf(2.0f) * getoctavesfreq() * ctlbw, sum = 0.0f;
 - 
 -     for(int i = 0; i < N_RES_POINTS; ++i)
 -         if(sum < Prespoints[i])
 -             sum = Prespoints[i];
 -     if(sum < 1.0f)
 -         sum = 1.0f;
 - 
 -     float x = (logf(freq) - l1) / l2; //compute where the n-th hamonics fits to the graph
 -     if(x < 0.0f)
 -         x = 0.0f;
 -     x *= N_RES_POINTS;
 -     float dx = x - floor(x);
 -     x = floor(x);
 -     int kx1 = (int)x;
 -     if(kx1 >= N_RES_POINTS)
 -         kx1 = N_RES_POINTS - 1;
 -     int kx2 = kx1 + 1;
 -     if(kx2 >= N_RES_POINTS)
 -         kx2 = N_RES_POINTS - 1;
 -     float result =
 -         (Prespoints[kx1]
 -          * (1.0f - dx) + Prespoints[kx2] * dx) / 127.0f - sum / 127.0f;
 -     result = powf(10.0f, result * PmaxdB / 20.0f);
 -     return result;
 - }
 - 
 - 
 - /*
 -  * Smooth the resonance function
 -  */
 - void Resonance::smooth()
 - {
 -     float old = Prespoints[0];
 -     for(int i = 0; i < N_RES_POINTS; ++i) {
 -         old = old * 0.4f + Prespoints[i] * 0.6f;
 -         Prespoints[i] = (int) old;
 -     }
 -     old = Prespoints[N_RES_POINTS - 1];
 -     for(int i = N_RES_POINTS - 1; i > 0; i--) {
 -         old = old * 0.4f + Prespoints[i] * 0.6f;
 -         Prespoints[i] = (int) old + 1;
 -         if(Prespoints[i] > 127)
 -             Prespoints[i] = 127;
 -     }
 - }
 - 
 - /*
 -  * Randomize the resonance function
 -  */
 - void Resonance::randomize(int type)
 - {
 -     int r = (int)(RND * 127.0f);
 -     for(int i = 0; i < N_RES_POINTS; ++i) {
 -         Prespoints[i] = r;
 -         if((RND < 0.1f) && (type == 0))
 -             r = (int)(RND * 127.0f);
 -         if((RND < 0.3f) && (type == 1))
 -             r = (int)(RND * 127.0f);
 -         if(type == 2)
 -             r = (int)(RND * 127.0f);
 -     }
 -     smooth();
 - }
 - 
 - /*
 -  * Interpolate the peaks
 -  */
 - void Resonance::interpolatepeaks(int type)
 - {
 -     int x1 = 0, y1 = Prespoints[0];
 -     for(int i = 1; i < N_RES_POINTS; ++i)
 -         if((Prespoints[i] != 64) || (i + 1 == N_RES_POINTS)) {
 -             int y2 = Prespoints[i];
 -             for(int k = 0; k < i - x1; ++k) {
 -                 float x = (float) k / (i - x1);
 -                 if(type == 0)
 -                     x = (1 - cosf(x * PI)) * 0.5f;
 -                 Prespoints[x1 + k] = (int)(y1 * (1.0f - x) + y2 * x);
 -             }
 -             x1 = i;
 -             y1 = y2;
 -         }
 - }
 - 
 - /*
 -  * Get the frequency from x, where x is [0..1]; x is the x coordinate
 -  */
 - float Resonance::getfreqx(float x)
 - {
 -     if(x > 1.0f)
 -         x = 1.0f;
 -     float octf = powf(2.0f, getoctavesfreq());
 -     return getcenterfreq() / sqrt(octf) * powf(octf, x);
 - }
 - 
 - /*
 -  * Get the x coordinate from frequency (used by the UI)
 -  */
 - float Resonance::getfreqpos(float freq)
 - {
 -     return (logf(freq) - logf(getfreqx(0.0f))) / logf(2.0f) / getoctavesfreq();
 - }
 - 
 - /*
 -  * Get the center frequency of the resonance graph
 -  */
 - float Resonance::getcenterfreq()
 - {
 -     return 10000.0f * powf(10, -(1.0f - Pcenterfreq / 127.0f) * 2.0f);
 - }
 - 
 - /*
 -  * Get the number of octave that the resonance functions applies to
 -  */
 - float Resonance::getoctavesfreq()
 - {
 -     return 0.25f + 10.0f * Poctavesfreq / 127.0f;
 - }
 - 
 - void Resonance::sendcontroller(MidiControllers ctl, float par)
 - {
 -     if(ctl == C_resonance_center)
 -         ctlcenter = par;
 -     else
 -         ctlbw = par;
 - }
 - 
 - 
 - 
 - 
 - void Resonance::add2XML(XMLwrapper *xml)
 - {
 -     xml->addparbool("enabled", Penabled);
 - 
 -     if((Penabled == 0) && (xml->minimal))
 -         return;
 - 
 -     xml->addpar("max_db", PmaxdB);
 -     xml->addpar("center_freq", Pcenterfreq);
 -     xml->addpar("octaves_freq", Poctavesfreq);
 -     xml->addparbool("protect_fundamental_frequency", Pprotectthefundamental);
 -     xml->addpar("resonance_points", N_RES_POINTS);
 -     for(int i = 0; i < N_RES_POINTS; ++i) {
 -         xml->beginbranch("RESPOINT", i);
 -         xml->addpar("val", Prespoints[i]);
 -         xml->endbranch();
 -     }
 - }
 - 
 - 
 - void Resonance::getfromXML(XMLwrapper *xml)
 - {
 -     Penabled = xml->getparbool("enabled", Penabled);
 - 
 -     PmaxdB       = xml->getpar127("max_db", PmaxdB);
 -     Pcenterfreq  = xml->getpar127("center_freq", Pcenterfreq);
 -     Poctavesfreq = xml->getpar127("octaves_freq", Poctavesfreq);
 -     Pprotectthefundamental = xml->getparbool("protect_fundamental_frequency",
 -                                              Pprotectthefundamental);
 -     for(int i = 0; i < N_RES_POINTS; ++i) {
 -         if(xml->enterbranch("RESPOINT", i) == 0)
 -             continue;
 -         Prespoints[i] = xml->getpar127("val", Prespoints[i]);
 -         xml->exitbranch();
 -     }
 - }
 
 
  |