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: IStreamModule.cpp,v $ 00026 * Date modified: $Date: 2002/04/14 18:03:17 $ 00027 * Version: $Revision: 1.10 $ 00028 * ----------------------------------------------------------------- 00029 * 00030 ****************** <SYN heading END do not edit this line> ******************/ 00031 #include "syn/Stream/AudioIStream.h" 00032 #include "syn/Core/SampleBufferRepos.h" 00033 #include "syn/Module/IStreamModule.h" 00034 00035 namespace syn 00036 { 00037 00038 IStreamModule::IStreamModule(): Module(), mStream( NULL ), 00039 mTrigger( false ), mWriteBuf( NULL ) 00040 { 00041 mAmplitudeControlInput = this->createInput( "amplitude" ); 00042 mPitchControlInput = this->createInput( "pitch" ); 00043 mTriggerControlInput = this->createInput( "trigger" ); 00044 mMonoAudioOutput = this->createOutput( "mono audio" ); 00045 } 00046 00047 IStreamModule::~IStreamModule() 00048 { 00049 } 00050 00051 bool IStreamModule::isOpen() { return mStream->isOpen(); } 00052 bool IStreamModule::open() 00053 { 00054 if (mStream.get() == NULL) 00055 return false; 00056 00057 // configure the output terminals 00058 mMonoAudioOutput->setHighMark( 2 ); 00059 mMonoAudioOutput->setLowMark( 1 ); 00060 00061 mStream->open( AudioFormat( AudioFormat::FLOAT32, 1, 44100 ) ); 00062 assert( mStream->isOpen() == true ); 00063 return mStream->isOpen(); 00064 } 00065 00066 void IStreamModule::close() 00067 { 00068 if (mStream.get() != NULL) 00069 { 00070 mStream->close(); 00071 } 00072 } 00073 00074 void IStreamModule::setStream( AudioIStreamPtr& istream ) 00075 { 00076 mStream = istream; 00077 } 00078 00079 void IStreamModule::trigger( float t ) 00080 { 00081 mTrigger = true; 00082 00083 // restart the stream on a trigger. 00084 if (mStream.get() != NULL) 00085 mStream->seek( 0 ); 00086 } 00087 void IStreamModule::release() 00088 { 00089 mTrigger = false; 00090 } 00091 00092 void IStreamModule::update() 00093 { 00094 this->setPutCount( 0 ); 00095 00096 // debug... 00097 if (mStream.get()) 00098 { 00099 // std::cout<<"[syn]ismod: state: strOpn:"<<mStream->isOpen()<<" eof:"<<mStream->eof() 00100 // <<" con:"<<mMonoAudioOutput->isConnected() 00101 // <<" thsOpn:"<<this->isOpen()<<" trig:"<<mTrigger<<std::endl; 00102 } 00103 00104 // if no input, or no output, if we're not open or triggering, 00105 // then return. 00106 if (((mStream.get() != NULL && mStream->isOpen() && !mStream->eof()) && 00107 this->isOpen() && mTrigger == true) == false) 00108 { 00109 mMonoAudioOutput->setDone( true ); 00110 //std::cout<<"[syn]ismod: done\n"<<std::flush; 00111 return; 00112 } 00113 00114 /* 00115 // get the control events for amplitude modulation 00116 SampleBufferQueuePtr queue; 00117 if (mAmplitudeControlInput->isConnected() && 00118 mAmplitudeControlInput->getQueue( queue ) && 00119 mAmplitudeControlInput->isDone() == false) 00120 { 00121 mTrigger = true; 00122 00123 if (!queue->empty()) 00124 { 00125 SampleBuffer& read_buf = queue->read(); 00126 00127 AudioFormat src_fmt = queue->format(); 00128 src_fmt.channels == mFmt 00129 00130 char buf[8]; 00131 float control_param; 00132 read_buf.drain( buf, 1 ); 00133 audio_format_convert( src_fmt, float_fmt, buf, 1, &control_param ); 00134 00135 read_buf.updateReadPointer( read_buf.size() ); // empty it 00136 queue->pop(); // pop the buffer away... we're done with it. 00137 00138 // todo: set up the input terminal to be a bufsize of 1, queuesize of 2, and format of float. 00139 } 00140 } 00141 */ 00142 // get the output queue 00143 if (mWriteBuf == NULL) 00144 { 00145 SampleBufferRepos::instance()->take( mWriteBuf ); 00146 mStream->read( mWriteBuf->data(), mWriteBuf->size() ); 00147 this->setPutCount( mStream->gcount() ); 00148 } 00149 //std::cout<<"[syn]ismod: tried to read "<<mWriteBuf->free()<<" got "<<mStream->gcount()<<"\n"<<std::flush; 00150 //std::cout<<"[syn]ismod: type:"<<mStream->format().datatype<<" chan:"<<mStream->format().channels<<" rate:"<<mStream->format().samplingRateHz<<"\n"<<std::flush; 00151 00152 // if there is more data coming, then we need the readers to wait 00153 // if I don't provide, then I could starve them, so be careful.... 00154 mMonoAudioOutput->setDone( mStream->eof() ); // if eof, then we're done... 00155 00156 //std::cout<<"[syn]ismod: qhigh:"<<queue->high()<<" eof:"<<mStream->eof()<<" qsize:"<<queue->size()<<" qdone:"<<queue->done()<<" full:"<<mWriteBuf->full()<<"\n"<<std::flush; 00157 00158 if (mWriteBuf != NULL && !mMonoAudioOutput->high()) 00159 { 00160 mMonoAudioOutput->push( mWriteBuf ); 00161 mWriteBuf = NULL; 00162 } 00163 } 00164 }// end of namespace.