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/WaveTableOscModule.cpp

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: WaveTableOscModule.cpp,v $
00026  * Date modified: $Date: 2002/04/14 18:03:17 $
00027  * Version:       $Revision: 1.16 $
00028  * -----------------------------------------------------------------
00029  *
00030  ****************** <SYN heading END do not edit this line> ******************/
00031 #include "syn/Util/Generator.h"
00032 #include "syn/Core/SampleBufferRepos.h"
00033 #include "syn/Module/WaveTableOscModule.h"
00034 
00035 namespace syn
00036 {
00037 
00038    WaveTableOscModule::WaveTableOscModule(): Module(), 
00039                            mWriteBuf( NULL ), mReadBuf( NULL ), 
00040                            mFreqControl( 0.0f ), mFreqControlSens( 1.0f ),
00041                            mRetrig( true ), mPlaying( false ), mLoop( true ),
00042                            mInterp( LINEAR ), mSkipFreqInputs( 0 ),
00043                            mIncrement( 1.0f ), mIncrementScalar( 1.0f )
00044    {
00045       mFreqControlInput = this->createInput( "freq" );
00046       mMonoAudioOutput = this->createOutput( "mono audio" );
00047       this->setFreqControl( 0 );
00048    }
00049    
00050    WaveTableOscModule::~WaveTableOscModule()
00051    {
00052    }
00053 
00054    bool WaveTableOscModule::isOpen() { return true; }
00055    
00056    bool WaveTableOscModule::open()
00057    {
00058       // init the wavetable to some default tri wave......
00059       if (mWaveTable.size() == 0)
00060       {
00061          TriangleOsc osc;
00062          mWaveTable.resize( osc.samplesPerOsc() );
00063          for (unsigned int x = 0; x < osc.samplesPerOsc(); ++x)
00064          {
00065             mWaveTable[x] = osc.generate();
00066          }
00067       }
00068 
00069       // configure the output terminals
00070       mMonoAudioOutput->setHighMark( 2 ); 
00071       mMonoAudioOutput->setLowMark( 1 );
00072 
00073       return true;
00074    }
00075    
00076    void WaveTableOscModule::close()
00077    {
00078    }
00079 
00081    void WaveTableOscModule::update()
00082    {  
00083       // wait for input if it isn't here yet.
00084       // if we need to wait, but it is empty - or
00085       // if the output is already too full...
00086       if ((!mFreqControlInput->done() && mFreqControlInput->empty()) || mMonoAudioOutput->high())
00087       {
00088          mMonoAudioOutput->setDone( false );
00089          return;
00090       }
00091 
00092       //std::cout<<"wto] increment:"<<mIncrement<<" freq:"<<mFreqControl<<" sens:"<<mFreqControlSens<<std::endl;
00093       
00094       this->setPutCount( 0 );
00095       
00096       // emit data only when playing...
00097       if (mPlaying == true)
00098       {
00099          // Freq input terminal is connected case...
00100          if (!mFreqControlInput->done())
00101          {
00102             if (mReadBuf == NULL)
00103             {
00104                mReadBuf = mFreqControlInput->front();
00105                mFreqControlInput->pop();
00106                mReadBufIt = 0;
00107             }
00108 
00109             if (mWriteBuf == NULL)
00110             {
00111                SampleBufferRepos::instance()->take( mWriteBuf );
00112                mWriteBufIt = 0;
00113             }
00114 
00115             // fill the buffer with what was in the wave table.
00116             switch (mInterp)
00117             {
00118                // no interpolation (select nearest)
00119                case NONE:
00120                {
00121                   while (mReadBufIt < mReadBuf->size() && mWriteBufIt < mWriteBuf->size() && mPlaying)
00122                   {
00123                      // read freqcontrol from the frequency control stream...
00124                      // recalculate increment from this.
00125                      mSkipFreqInputs = (mSkipFreqInputs + 1) % 10;
00126                      if (mSkipFreqInputs == 0)
00127                      {
00128                         mFreqControl = (*(mReadBuf))[mReadBufIt];
00129                         mIncrementScalar = Math::fast_exp2( mFreqControl * mFreqControlSens );
00130                      }
00131 
00132                      // copy from wavetable to the output terminal
00133                      (*mWriteBuf)[mWriteBufIt] = mWaveTable[(int)mWaveTableIterator];
00134 
00135                      // advance wavetable ptr, loop back to beginning if at end
00136                      // keep the current, and the next sample for linear interpolation
00137                      mWaveTableIterator += mIncrement * mIncrementScalar;
00138                      float next_wt_it = fmod( mWaveTableIterator, (float)mWaveTable.size() );
00139                      if (mWaveTableIterator != next_wt_it)
00140                      {
00141                         mWaveTableIterator = next_wt_it;
00142                         if (mLoop == false) 
00143                            mPlaying = false; // done playing in the single shot case.
00144                      }
00145                      
00146                      ++mReadBufIt;
00147                      ++mWriteBufIt;
00148                   }
00149                }
00150                break;
00151 
00152                // linear interpolation
00153                case LINEAR:
00154                {
00155                   while (mReadBufIt < mReadBuf->size() && mWriteBufIt < mWriteBuf->size() && mPlaying)
00156                   {
00157                      // read freqcontrol from the frequency control stream...
00158                      // recalculate increment from this.
00159                      mSkipFreqInputs = (mSkipFreqInputs + 1) % 10;
00160                      if (mSkipFreqInputs == 0)
00161                      {
00162                         mFreqControl = (*(mReadBuf))[mReadBufIt];
00163                         mIncrement = Math::fast_exp2( mFreqControl * mFreqControlSens );
00164                      }
00165 
00166                      // get the next sample for interpolation
00167                      float next = mWaveTableIterator + 1.0f; 
00168                      if (next >= (float)mWaveTable.size())
00169                         next = next - (float)mWaveTable.size();
00170 
00171                      float first = mWaveTable[(int)mWaveTableIterator];
00172                      float second = mWaveTable[(int)next];
00173                      float weight = mWaveTableIterator - (float)(int)mWaveTableIterator;
00174                      (*mWriteBuf)[mWriteBufIt] = first + ((second - first) * weight);
00175 
00176                      // advance wavetable ptr, loop back to beginning if at end
00177                      // keep the current, and the next sample for linear interpolation
00178                      mWaveTableIterator += mIncrement * mIncrementScalar;
00179                      float next_wt_it = fmod( mWaveTableIterator, (float)mWaveTable.size() );
00180                      if (mWaveTableIterator != next_wt_it)
00181                      {
00182                         mWaveTableIterator = next_wt_it;
00183                         if (mLoop == false) 
00184                            mPlaying = false; // done playing in the single shot case.
00185                      }
00186                      
00187                      ++mReadBufIt;
00188                      ++mWriteBufIt;
00189                   }
00190                }
00191                break;
00192 
00193                default:
00194                   assert( false && "undefined interpolation param" );
00195                   break;
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          // use constant instead
00218          else
00219          {
00220             SampleBufferRepos::instance()->take( mWriteBuf );
00221 
00222             // fill the buffer with what was in the wave table.
00223             switch (mInterp)
00224             {
00225                // no interpolation (select nearest)
00226                case NONE:
00227                {
00228                   for (unsigned int x = 0; x < mWriteBuf->size() && mPlaying; ++x)
00229                   {
00230                      (*mWriteBuf)[x] = mWaveTable[(int)mWaveTableIterator];
00231 
00232                      // advance wavetable ptr, loop back to beginning if at end
00233                      // keep the current, and the next sample for linear interpolation
00234                      mWaveTableIterator += mIncrement * mIncrementScalar;
00235                      float next_wt_it = fmod( mWaveTableIterator, (float)mWaveTable.size() );
00236                      if (mWaveTableIterator != next_wt_it)
00237                      {
00238                         mWaveTableIterator = next_wt_it;
00239                         if (mLoop == false) 
00240                            mPlaying = false; // done playing in the single shot case.
00241                      }
00242                   }
00243                }
00244                break;
00245 
00246                // linear interpolation
00247                case LINEAR:
00248                {
00249                   for (unsigned int x = 0; x < mWriteBuf->size() && mPlaying; ++x)
00250                   {
00251                      // get the next sample for interpolation
00252                      float next = mWaveTableIterator + 1.0f; 
00253                      if (next >= (float)mWaveTable.size())
00254                         next = next - (float)mWaveTable.size();
00255 
00256                      float first = mWaveTable[(int)mWaveTableIterator];
00257                      float second = mWaveTable[(int)next];
00258                      float weight = mWaveTableIterator - (float)(int)mWaveTableIterator;
00259                      (*mWriteBuf)[x] = first + ((second - first) * weight);
00260 
00261                      // advance wavetable ptr, loop back to beginning if at end
00262                      // keep the current, and the next sample for linear interpolation
00263                      mWaveTableIterator += mIncrement * mIncrementScalar;
00264                      float next_wt_it = fmod( mWaveTableIterator, (float)mWaveTable.size() );
00265                      if (mWaveTableIterator != next_wt_it)
00266                      {
00267                         mWaveTableIterator = next_wt_it;
00268                         if (mLoop == false) 
00269                            mPlaying = false; // done playing in the single shot case.
00270                      }
00271                   }
00272                }
00273                break;
00274 
00275                default:
00276                   assert( false && "undefined interpolation param" );
00277                   break;
00278             }
00279 
00280             this->setPutCount( mWriteBuf->size() );
00281             mMonoAudioOutput->push( mWriteBuf );
00282             mWriteBuf = NULL;
00283             mMonoAudioOutput->setDone( false ); // never done...
00284          }
00285       }
00286       
00287       // if not playing
00288       else
00289       {
00290          mMonoAudioOutput->setDone( true ); // done...
00291       }
00292    }
00293 }// end of namespace.

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