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/OpenALOutputModule.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: OpenALOutputModule.cpp,v $
00026  * Date modified: $Date: 2002/04/05 22:47:55 $
00027  * Version:       $Revision: 1.22 $
00028  * -----------------------------------------------------------------
00029  *
00030  ****************** <SYN heading END do not edit this line> ******************/
00031 #include "syn/Core/SampleBufferQueue.h"
00032 #include "syn/Module/OpenALOutputModule.h"
00033 #ifdef HAVE_VPR
00034 #include <vpr/Thread/Thread.h>
00035 #endif
00036 
00037 namespace syn
00038 {
00039    syn::OpenALAudioContext OpenALOutputModule::ctx;
00040    bool OpenALOutputModule::mCtxInit = false;
00041 
00042    OpenALOutputModule::OpenALOutputModule() : Module(), mReadBuf( NULL ),
00043       mBufSize( 4096 )
00044    {
00045       // HACK... replace with some refcounting singleton object
00046       if (OpenALOutputModule::mCtxInit == false)
00047       {
00048          OpenALOutputModule::ctx.open();
00049          OpenALOutputModule::mCtxInit = true;
00050       }
00051       
00052       mWavStream.setContext( ctx );
00053       
00054       // terminal setup
00055       mAmplitudeControlInput = this->createInput( "amplitude" );
00056       mMonoAudioInput = this->createInput( "mono audio" );
00057    }
00058 
00059    // TODO: this might be wrong, we may be to update fmt
00060    // when ever there is a new connection
00061    bool OpenALOutputModule::open()
00062    {
00063       mTempBuf.resize( mBufSize );
00064       mTempBufIt = 0;
00065       
00066       // setup the temp buffer.
00067       // for now olpenal's hard coded to this format...
00068       mOutputFmt = AudioFormat( AudioFormat::SIGNED16, 1, 44100 );
00069       mWavStream.open( mOutputFmt );
00070       return mWavStream.isOpen();
00071    }
00072    
00073    void OpenALOutputModule::close()
00074    {
00075       mWavStream.close();
00076    }
00077    
00078    void OpenALOutputModule::writeSomeSilence()
00079    {
00080       // send silence data so that openal isn't starved...
00081       assert( mTempBuf.bytes() > 0 );
00082       memset( mTempBuf.data(), 0, mTempBuf.bytes() );
00083       //std::cout<<"waiting..."<<std::endl;
00084       while (mWavStream.canAcceptMoreData() == false)
00085       {
00086 #ifdef HAVE_VPR
00087          vpr::Thread::yield();
00088 #endif
00089          //std::cout<<".";
00090       }
00091       //std::cout<<"writing"<<std::endl;
00092       mWavStream.write( mTempBuf.data(), mTempBuf.size() );
00093       //std::cout<<"done"<<std::endl;
00094       this->setPutCount( mWavStream.pcount() );
00095       //std::cout<<"silence...\n"<<std::flush;
00096    }
00097    
00098    void OpenALOutputModule::update()
00099    {
00100       //std::cout<<"OpenALOutputModule::update()\n"<<std::flush;
00101       this->setPutCount( 0 );
00102       //SampleBufferQueuePtr input_queue;
00103       
00104       // and if no data in the pipe
00105       if (mMonoAudioInput->empty()  ||
00106           !this->isOpen())
00107       {
00108          this->writeSomeSilence();
00109          //std::cout<<"[syn]oalmod: done (input queue empty)\n"<<std::flush;
00110          return;
00111       }
00112 
00114       // we know there is something to read.  now copy it to openal.
00115       
00116       // block until openal is ready to receive more data...
00117       while (mWavStream.canAcceptMoreData() == false)
00118       {
00119 #ifdef HAVE_VPR
00120          vpr::Thread::yield();
00121 #endif
00122       }
00123 
00124       // openal is ready, send it a chunk of data smaller than SampleBufferRepos::instance()->bufsize()
00125       if (mReadBuf == NULL)
00126       {
00127          mReadBuf = mMonoAudioInput->front();
00128          mMonoAudioInput->pop();
00129          mReadBufIt = 0;
00130       }
00131       
00132       while (mTempBufIt < mTempBuf.size() && mReadBufIt < mReadBuf->size())
00133       {
00134          syn::audio_convert( (*mReadBuf)[mReadBufIt], mTempBuf[mTempBufIt] );
00135          ++mTempBufIt;
00136          ++mReadBufIt;
00137       }
00138       
00139       // if buffer has been filled, then write it to oal
00140       if (mTempBufIt >= mTempBuf.size())
00141       {
00142          mWavStream.write( mTempBuf.data(), mTempBuf.size() );
00143          mTempBufIt = 0;
00144          this->setPutCount( mWavStream.pcount() );
00145       }
00146       
00147       // if buffer has been emptied, then put it back so we can get a new one next.
00148       if (mReadBufIt >= mReadBuf->size())
00149       {
00150          mReadBufIt = 0;
00151          SampleBufferRepos::instance()->putback( mReadBuf );
00152          mReadBuf = NULL;
00153       }
00154       
00155       //std::cout<<"[syn]oalmod: convert: c:"<<read_buf->format().channels<<" dt:"<<read_buf->format().datatype
00156       //         <<" -> c:"<<mOutputFmt.channels<<" dt:"<<mOutputFmt.datatype<<std::endl;
00157       //std::cout<<"[syn]oalmod: read:"<<rd<<" write:"<<mWavStream.pcount()<<" buf1:"<<buf1<<std::endl;
00158       
00159       
00160          
00161       //std::cout<<"[syn]oalmod: dequeue empty buffer qsize before:"<<input_queue->size();
00162    }
00163 
00164 }                                               
00165 

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