Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

/root/src/subsynth/syn/Module/OscModule.h

Go to the documentation of this file.
00001 
00002 /****************** <SYN heading BEGIN do not edit this line> *****************
00003  *
00004  * subsynth - modular audio synthesizer
00005  * subsynth is (C) Copyright 2001-2002 by Kevin Meinert
00006  *
00007  * Original Author: Kevin Meinert
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Library General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Library General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Library General Public
00020  * License along with this library; if not, write to the
00021  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00022  * Boston, MA 02111-1307, USA.
00023  *
00024  * -----------------------------------------------------------------
00025  * File:          $RCSfile: OscModule.h,v $
00026  * Date modified: $Date: 2002/04/15 07:28:46 $
00027  * Version:       $Revision: 1.13 $
00028  * -----------------------------------------------------------------
00029  *
00030  ****************** <SYN heading END do not edit this line> ******************/
00031 
00032 #ifndef SUBSYNTH_OSC_MODULE_H
00033 #define SUBSYNTH_OSC_MODULE_H
00034 
00035 #include <map>
00036 #include "syn/Util/Generator.h" // for some predefined OSCs
00037 #include "syn/Core/SampleBuffer.h"
00038 #include "syn/Core/SampleBufferQueue.h"
00039 #include "syn/Core/Module.h"
00040 #include "syn/Core/Terminal.h"
00041 
00042 namespace syn
00043 {
00048    class OscModuleBase : public Module
00049    {
00050    public:
00051       OscModuleBase() : Module() {}
00052    
00054       virtual ~OscModuleBase()
00055       {
00056       }
00057       
00061       virtual void setFreq( float freq ) = 0;
00062 
00075       virtual void setFreqControl( float param ) = 0;
00076       
00080       virtual void setFreqControlSensitivity( float octaves = 1.0f ) = 0;
00081       
00082       virtual float freq() const = 0;
00083       virtual float freqControl() const = 0;
00084       virtual float freqControlSensitivity() const = 0;
00085       
00089       virtual void getParam( const std::string& key, MultivariateType& value )
00090       {
00091          if (key == "freq")
00092             value.setValue<float>( this->freq() );
00093          else if (key == "freqcontrol")
00094             value.setValue<float>( this->freqControl() );
00095          else if (key == "freqcontrolsens")
00096             value.setValue<float>( this->freqControlSensitivity() );
00097       }
00098 
00100       virtual void setParam( const std::string& key, const MultivariateType& value )
00101       {
00102          if (key == "freq")
00103             this->setFreq( value.getValue<float>() );
00104          else if (key == "freqcontrol")
00105             this->setFreqControl( value.getValue<float>() );
00106          else if (key == "freqcontrolsens")
00107             this->setFreqControl( value.getValue<float>() );
00108       }
00110    };
00111    
00118    template <typename OSC_TYPE>
00119    class OscModule : public OscModuleBase
00120    {
00121    public:
00123       OscModule(): OscModuleBase(), 
00124          mWriteBuf( NULL ), 
00125          mReadBuf( NULL ),
00126          mFreq( 440.0f ), 
00127          mFreqControl( 0.0f ), 
00128          mFreqControlSens( 1.0f ),
00129          mSkipFreqInputs( 0 )
00130       {
00131          mFreqControlInput = this->createInput( "freq" );
00132          mMonoAudioOutput = this->createOutput( "mono audio" );
00133       }
00134    
00136       virtual ~OscModule()
00137       {
00138       }
00139 
00141       virtual Module* clone() const
00142       {
00143          OscModule<OSC_TYPE>* mod = new OscModule<OSC_TYPE>;
00144          mod->setFreq( this->freq() );
00145          mod->setFreqControl( this->freqControl() );
00146          mod->setFreqControlSensitivity( this->freqControlSensitivity() );
00147          return mod;
00148       }
00149 
00150       virtual float freq() const { return mFreq; }
00151       virtual float freqControl() const { return mFreqControl; }
00152       virtual float freqControlSensitivity() const { return mFreqControlSens; }
00153 
00155       virtual void update()
00156       {  
00157          // wait for input if it isn't here yet.
00158          // if we need to wait, but it is empty - or
00159          // if the output is already too full...
00160          if ((!mFreqControlInput->done() && mFreqControlInput->empty()) || mMonoAudioOutput->high())
00161          {
00162             mMonoAudioOutput->setDone( false );
00163             return;
00164          }
00165          
00166          // CASE: Freq input terminal is connected
00167          if (!mFreqControlInput->done())
00168          {
00169             if (mReadBuf == NULL)
00170             {
00171                mReadBuf = mFreqControlInput->front();
00172                mFreqControlInput->pop();
00173                mReadBufIt = 0;
00174             }
00175 
00176             if (mWriteBuf == NULL)
00177             {
00178                SampleBufferRepos::instance()->take( mWriteBuf );
00179                mWriteBufIt = 0;
00180             }
00181 
00182             // combine...
00183             while (mReadBufIt < mReadBuf->size() && mWriteBufIt < mWriteBuf->size())
00184             {
00185                // recompute the freq from the input every 10
00186                mSkipFreqInputs = (mSkipFreqInputs + 1) % 10;
00187                if (mSkipFreqInputs == 0)
00188                {
00189                   mFreqControl = (*(mReadBuf))[mReadBufIt];
00190                   float freq = Math::fast_exp2( mFreqControl * mFreqControlSens ) * mFreq;
00191                   mOsc.setFreq( freq );
00192                }
00193                (*mWriteBuf)[mWriteBufIt] = mOsc.generate();
00194                ++mReadBufIt;
00195                ++mWriteBufIt;
00196             }
00197 
00198             // if buffer has been emptied, then put it back so we can get a new one next.
00199             if (mReadBufIt >= mReadBuf->size())
00200             {
00201                SampleBufferRepos::instance()->putback( mReadBuf );
00202                mReadBufIt = 0;
00203                mReadBuf = NULL;
00204             }
00205 
00206             // if buffer has been filled, then send it
00207             if (mWriteBufIt >= mWriteBuf->size())
00208             {
00209                mMonoAudioOutput->push( mWriteBuf );
00210                mMonoAudioOutput->setDone( false );
00211                this->setPutCount( mWriteBuf->size() );
00212                mWriteBuf = NULL;
00213                mWriteBufIt = 0;
00214             }
00215          }
00216 
00217          // CASE: not connected, use constant instead
00218          else
00219          {
00220             // compute exponential base2 controlled frequency
00221             // from the specified control params
00222             float freq = Math::fast_exp2( mFreqControl * mFreqControlSens ) * mFreq;
00223             mOsc.setFreq( freq );
00224 
00225             this->setPutCount( 0 );
00226 
00227             SampleBufferRepos::instance()->take( mWriteBuf );
00228 
00229             // fill the buffer values from the osc.
00230             for (unsigned int x = 0; x < mWriteBuf->size(); ++x)
00231             {
00232                (*mWriteBuf)[x] = mOsc.generate();
00233             }
00234 
00235             this->setPutCount( mWriteBuf->size() );
00236             mMonoAudioOutput->push( mWriteBuf );
00237             mWriteBuf = NULL;
00238             mMonoAudioOutput->setDone( false ); // never done...
00239          }
00240       }
00241 
00243       virtual bool open()
00244       {
00245          // configure the output terminals
00246          mMonoAudioOutput->setHighMark( 2 );
00247          mMonoAudioOutput->setLowMark( 1 );
00248 
00249          return true;
00250       }
00251 
00253       virtual bool isOpen() { return true; }
00254       
00256       virtual void close()
00257       {
00258       }
00259 
00263       virtual void setFreq( float freq )
00264       {
00265          mFreq = freq;
00266       } 
00267 
00280       virtual void setFreqControl( float param )
00281       {
00282          mFreqControl = param;
00283       }    
00284       
00288       virtual void setFreqControlSensitivity( float octaves = 1.0f )
00289       {
00290          mFreqControlSens = octaves;
00291       } 
00292       
00293       OSC_TYPE& osc() { return mOsc; }
00294 
00295    private:
00296       TerminalPtr mFreqControlInput;
00297       TerminalPtr mMonoAudioOutput;
00298 
00299       SampleBuffer1f* mWriteBuf, *mReadBuf;
00300       float mFreq, mFreqControl, mFreqControlSens;
00301 
00302       OSC_TYPE mOsc;
00303       unsigned int mSkipFreqInputs, mWriteBufIt, mReadBufIt;
00304             
00306       /*#  Terminal lnkTerminal; */
00307 
00309       /*#  Terminal lnkTerminal; */
00310    };
00311 
00315    typedef OscModule<TriangleOsc> TriangleOscModule;
00316    
00318    typedef OscModule<WhiteNoiseOsc> WhiteNoiseOscModule;
00319    
00321    typedef OscModule<PinkNoiseOsc> PinkNoiseOscModule;
00322    
00324    typedef OscModule<SineOsc> SineOscModule;
00325    
00327    typedef OscModule<SquareOsc> SquareOscModule;
00328    
00330    typedef OscModule<AdsrEnvOsc> AdsrOscModule;
00332 }
00333 #endif

Generated at Mon Apr 15 09:26:07 2002 for subsynth by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001