Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/engine/engineflanger.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           engineflanger.cpp  -  description
00003                              -------------------
00004     copyright            : (C) 2002 by Tue and Ken Haste Andersen
00005     email                :
00006 ***************************************************************************/
00007 
00008 /***************************************************************************
00009 *                                                                         *
00010 *   This program is free software; you can redistribute it and/or modify  *
00011 *   it under the terms of the GNU General Public License as published by  *
00012 *   the Free Software Foundation; either version 2 of the License, or     *
00013 *   (at your option) any later version.                                   *
00014 *                                                                         *
00015 ***************************************************************************/
00016 
00017 #include <QtDebug>
00018 
00019 #include "controlpushbutton.h"
00020 #include "controlpotmeter.h"
00021 #include "engineflanger.h"
00022 #include "mathstuff.h"
00023 #include "sampleutil.h"
00024 
00025 
00026 /*----------------------------------------------------------------
00027    A flanger effect.
00028    The flanger is controlled by the following variables:
00029     average_delay_length - The average length of the delay, which is modulated by the LFO.
00030     LFOperiod - the period of LFO given in samples.
00031     LFOamplitude - the amplitude of the modulation of the delay length.
00032     depth - the depth of the flanger, controlled by a ControlPotmeter.
00033    ----------------------------------------------------------------*/
00034 EngineFlanger::EngineFlanger(const char * group)
00035 {
00036     // Init. buffers:
00037     delay_buffer = SampleUtil::alloc(max_delay + 1);
00038     SampleUtil::applyGain(delay_buffer, 0.0f, max_delay+1);
00039 
00040     // Init. potmeters
00041 
00042     // rryan 6/2010 This is gross. The flanger was originally written as this
00043     // hack that hard-coded the two channels, and while pulling it apart, I have
00044     // to keep these global [Flanger]-group controls, except there is one
00045     // EngineFlanger per deck, so create these controls if they don't exist,
00046     // otherwise look them up.
00047 
00048     potmeterDepth = ControlObject::getControl(ConfigKey("[Flanger]", "lfoDepth"));
00049     potmeterDelay = ControlObject::getControl(ConfigKey("[Flanger]", "lfoDelay"));
00050     potmeterLFOperiod = ControlObject::getControl(ConfigKey("[Flanger]", "lfoPeriod"));
00051 
00052     if (potmeterDepth == NULL)
00053         potmeterDepth = new ControlPotmeter(ConfigKey("[Flanger]", "lfoDepth"), 0., 1.);
00054     if (potmeterDelay == NULL)
00055         potmeterDelay = new ControlPotmeter(ConfigKey("[Flanger]", "lfoDelay"), 50., 10000.);
00056     if (potmeterLFOperiod == NULL)
00057         potmeterLFOperiod = new ControlPotmeter(ConfigKey("[Flanger]", "lfoPeriod"), 50000., 2000000.);
00058 
00059     // Create an enable key on a per-deck basis.
00060     flangerEnable = new ControlPushButton(ConfigKey(group, "flanger"));
00061     flangerEnable->setToggleButton(true);
00062 
00063     // Fixed values of controls:
00064     LFOamplitude = 240;
00065     average_delay_length = 250;
00066 
00067     // Set initial values for vars
00068     delay_pos=0;
00069     time = 0;
00070 }
00071 
00072 EngineFlanger::~EngineFlanger()
00073 {
00074     // Don't delete the controls anymore since we don't know if we created them.
00075     // delete potmeterDepth;
00076     // delete potmeterDelay;
00077     // delete potmeterLFOperiod;
00078 
00079     delete flangerEnable;
00080 
00081     SampleUtil::free(delay_buffer);
00082 }
00083 
00084 void EngineFlanger::process(const CSAMPLE * pIn, const CSAMPLE * pOut, const int iBufferSize)
00085 {
00086     CSAMPLE * pOutput = (CSAMPLE *)pOut;
00087     CSAMPLE delayed_sample,prev,next;
00088     FLOAT_TYPE frac;
00089 
00090     if (flangerEnable->get() == 0.0f) {
00091         // SampleUtil handles shortcuts when aliased, and gains of 1.0, etc.
00092         return SampleUtil::copyWithGain(pOutput, pIn, 1.0f, iBufferSize);
00093     }
00094 
00095     for (int i=0; i<iBufferSize; ++i)
00096     {
00097         // put sample into delay buffer:
00098         delay_buffer[delay_pos] = pIn[i];
00099         delay_pos++;
00100         if (delay_pos >= max_delay)
00101             delay_pos=0;
00102 
00103         // Update the LFO to find the current delay:
00104         time++;
00105         if (time==potmeterLFOperiod->get()) time=0;
00106         delay = average_delay_length + LFOamplitude *sin( two_pi * ((FLOAT_TYPE) time)/((FLOAT_TYPE) potmeterLFOperiod->get()) );
00107 
00108         // Make a linear interpolation to find the delayed sample:
00109         prev = delay_buffer[(delay_pos-(int)delay+max_delay-1) % max_delay];
00110         next = delay_buffer[(delay_pos-(int)delay+max_delay) % max_delay];
00111         frac = delay - floor(delay);
00112         delayed_sample = prev + frac*(next-prev);
00113 
00114         // Take the sample from the delay buffer and mix it with the source buffer:
00115         pOutput[i] = pIn[i] + potmeterDepth->get()*delayed_sample;
00116     }
00117 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines