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/MixerModule.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: MixerModule.cpp,v $
00026  * Date modified: $Date: 2002/04/14 19:52:05 $
00027  * Version:       $Revision: 1.14 $
00028  * -----------------------------------------------------------------
00029  *
00030  ****************** <SYN heading END do not edit this line> ******************/
00031 #include "syn/Module/MixerModule.h"
00032 #include <syn/Stream/SampleBufferIStream.h>
00033 
00034 namespace syn
00035 {
00036    MixerModule::MixerModule() : Module(), mIsOpen( false ), mWriteBuf( NULL )
00037    {
00038       this->createOutput( "output" );
00039       
00040       bool result = this->getOutput( "output", mTerminal );
00041       assert( result && "this isn't right" );
00042    }
00043 
00044    bool MixerModule::open()
00045    {
00046       mIsOpen = true;
00047       return mIsOpen;
00048    }
00049    
00050    void MixerModule::close()
00051    {
00052       mIsOpen = false;
00053    }
00054    
00056    bool MixerModule::areInputsDone()
00057    {
00058       std::map<std::string, TerminalPtr>::const_iterator input_itr;
00059       for (input_itr = this->inputs().begin(); input_itr != this->inputs().end(); ++input_itr)
00060       {
00061          // if any input is not done, then return false - inputs are not done.
00062          if (!(*input_itr).second->done())
00063             return false;
00064       }
00065          
00066       return true; // all inputs have a done state.
00067    }
00068   
00070    bool MixerModule::needToWait()
00071    {
00072       std::map<std::string, TerminalPtr>::const_iterator input_itr;
00073       for (input_itr = this->inputs().begin(); input_itr != this->inputs().end(); ++input_itr)
00074       {
00075          if ((*input_itr).second->empty() && !(*input_itr).second->done())
00076             return true;
00077       }
00078          
00079       return false; // all inputs have a done state.
00080    }
00081    
00082    void MixerModule::update()
00083    {
00084       mPutCount = 0;
00085 
00087       if (this->needToWait())
00088       {
00089          //std::cout<<"[syn]mix: waiting\n"<<std::flush;
00090          return;
00091       }
00092       
00093       // get a buffer to write to.
00094       if (mWriteBuf == NULL)
00095       {
00096          // find the terminals that are not empty 
00097          // (also ensure there is at least one term before we do anything)
00098          std::list<TerminalPtr> terms;
00099          {
00100             std::map<std::string, TerminalPtr>::iterator input_itr;
00101             for (input_itr = this->inputs().begin(); input_itr != this->inputs().end(); ++input_itr)
00102             {
00103                TerminalPtr input_term = (*input_itr).second;
00104                if (!input_term->empty())
00105                {
00106                   terms.push_back( (*input_itr).second );
00107                   //std::cout<<"[syn]mix: good term:\n"<<std::flush;
00108                }
00109             }
00110             if (terms.size() == 0)
00111                return;
00112          }
00113          
00114          // start combining all the terms into one...
00115          std::list<TerminalPtr>::iterator input_itr = terms.begin();
00116          
00117          // take the first buffer, then pop it, later we'll use this to 
00118          // accumulate the other inputs additively...
00119          mWriteBuf = (*input_itr)->front();
00120          (*input_itr)->pop();
00121          ++input_itr;
00122          
00123          // for now we assume all buffers are the same size, just read the size of the first one.
00124          mPutCount = mWriteBuf->size();
00125          //std::cout<<"[syn]mix: pc:"<<mPutCount<<"\n"<<std::flush;
00126 
00127          // mixdown each input terminal (additive)
00128          // accumulate the other inputs into mWriteBuf...
00129          for (; input_itr != terms.end(); ++input_itr)
00130          {
00131             TerminalPtr input_term = (*input_itr);
00132             if (!input_term->empty())
00133             {
00134                SampleBuffer1f* read_buf = input_term->front();
00135 
00136                // accumulate the readbuf values into the writebuf using addition.
00137                (*mWriteBuf) += (*read_buf);
00138 
00139                // if done with the buffer, get rid of it...
00140                SampleBufferRepos::instance()->putback( read_buf );
00141                input_term->pop();
00142             }
00143          }
00144 
00145          // clamp data
00146          //dfclamp( *mWriteBuf );
00147       }
00148 
00149       mTerminal->setDone( false );
00150       
00151       // nothing to do if the output queue is full
00152       if (!mTerminal->high())
00153       {
00154          mTerminal->push( mWriteBuf );
00155          mWriteBuf = NULL;
00156       }      
00157    }
00158 }// 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