SMSTransformationChain.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef _SMSTransformationChain_
00023 #define _SMSTransformationChain_
00024 
00025 
00026 #include "SegmentTransformation.hxx"
00027 #include "SMSTransformationChainConfig.hxx"
00028 #include "ProcessingComposite.hxx"
00029 #include "ProcessingData.hxx"
00030 #include "InPort.hxx"
00031 #include "OutPort.hxx"
00032 #include "InControlTmplArray.hxx"
00033 #include "ProcessingFactory.hxx"
00034 #include "Array.hxx"
00035 
00036 #include "FrameTransformation.hxx"
00037 
00038 namespace CLAM {
00039 
00044         class SMSTransformationChain: public ProcessingComposite
00045         {
00046                 
00047                 InControlTmplArray<SMSTransformationChain> *mpOnCtrlArray;
00048 
00050                 Array<Segment*> mpTmpDataArray;
00052                 SMSTransformationChainConfig* mpConfig;
00053                 Segment* mpChainInput;
00054                 Segment* mpChainOutput;
00055 
00056 
00057         public:
00058 
00059                 void AttachIn(Segment& data) { mpChainInput = &data; }
00060                 void AttachOut(Segment& data) { mpChainOutput = &data; }
00061                 
00062                 SMSTransformationChain() : 
00063                         mpChainInput(0),
00064                         mpChainOutput(0)
00065                         {
00066                                 mpConfig=NULL;
00067                                 mpOnCtrlArray=NULL;
00068                         }
00072                 virtual ~SMSTransformationChain(){
00073                 
00074                         for(int i=0;i<mpTmpDataArray.Size();i++)
00075                                 if(mpTmpDataArray[i]) delete mpTmpDataArray[i];
00076                         if (mpConfig) delete mpConfig;
00077                         
00078                         for(iterator obj=composite_begin();obj!=composite_end();obj++)
00079                         {
00080                                 delete (*obj);
00081                         }
00082                 }
00083                 
00084                 virtual bool DoChildren()
00085                 {
00086                         CLAM_DEBUG_ASSERT(IsRunning(),
00087                                 "SMSTransformationChain: Do(): Not in execution mode");
00088 
00089                         bool result=true;
00090                         int i=0;
00091                         //We iterate through all chainees and call their Do()
00092                         for (iterator obj=composite_begin(); obj!=composite_end(); obj++,i++)
00093                         {
00094                                 Processing & proc = *(*obj);
00095                                 SegmentTransformation& trans = dynamic_cast<SegmentTransformation&>(proc);
00096                                 //TODO have a list instead of being a composite
00097                                 
00098                                 if((*mpOnCtrlArray)[i].GetLastValue()||i==0||i==int(composite_size())-1)
00099                                 //Note: First and last chainee's will always be active regartheless the value
00100                                 //of their On control.
00101                                 {
00102                                         CLAM_DEBUG_ASSERT(proc.IsRunning(), "child is not running" );
00103                                         result &= trans.DoWithSegments();
00104                                 }
00105                         }
00106                         return result;
00107                 }
00108 
00109                 bool Do()
00110                 {
00111                         if(IsLastFrame())
00112                         {
00113                                 printf("TransChain::Do() is last frame\n");
00114                                 return false;
00115                         }
00116                         NextFrame();
00117                         return DoChildren();
00118                 }
00119 
00120                 bool ConcreteStart()
00121                 {
00122                         void InitSegmentArray(); 
00123                         
00124                         Segment* pCurrentData;
00125                         pCurrentData=new Segment(*mpChainInput);
00126                         mpTmpDataArray.AddElem(pCurrentData);
00127                         
00128                         // set up connections:     inSegment<--trans-->outSegment
00129                         
00130                         iterator obj;
00131                         for(obj=composite_begin();obj!=composite_end();obj++)
00132                         {
00133                                 //connecting ports for non-supervised mode
00134                                 Processing & processing = *(*(obj));
00135                                 SegmentTransformation&concreteObj = dynamic_cast<SegmentTransformation&>(processing);
00136                                 
00137                                 concreteObj.AttachIn(*pCurrentData);
00138                                 if(!(*obj)->CanProcessInplace())
00139                                 {
00140                                         printf("Can't process inplace: setting a temporal segment\n");
00141                                         pCurrentData=new Segment(*mpChainInput);
00142                                         mpTmpDataArray.AddElem(pCurrentData);
00143                                 }
00144                                 concreteObj.AttachOut(*pCurrentData);
00145                         }
00146                         // now we have to restore the inSegment of the first child
00147                         obj=composite_begin();
00148                         SegmentTransformation& concreteObj = dynamic_cast<SegmentTransformation&>( *(*(obj)) );
00149                         concreteObj.AttachIn(*mpChainInput);
00150                         
00151                         obj=composite_end();
00152                         obj--;
00153                         SegmentTransformation& concreteObj2 = dynamic_cast<SegmentTransformation&>( *(*(obj)) );
00154 
00155                         concreteObj2.AttachOut( *mpChainOutput);
00156 
00157                         InitAllFrameIndex();
00158                         
00159                         return ProcessingComposite::ConcreteStart();
00160 
00161                 }
00162                 
00163                 void InitSegmentArray() 
00164                 {
00165                         for(int i=0;i<mpTmpDataArray.Size();i++)
00166                                 if(mpTmpDataArray[i])
00167                                         delete mpTmpDataArray[i];
00168                         mpTmpDataArray.SetSize(0);
00169                 }
00170 
00171                 void InitAllFrameIndex()
00172                 {
00173                         for(int i=0;i<mpTmpDataArray.Size();i++)
00174                                 mpTmpDataArray[i]->mCurrentFrameIndex=0;
00175                         mpChainInput->mCurrentFrameIndex=0;
00176                 }
00177 
00179                 void TurnOn(TIndex index)
00180                 {
00181                         (*mpOnCtrlArray)[index].DoControl(1);
00182                 }
00183 
00185                 void TurnOff(TIndex index)
00186                 {
00187                         (*mpOnCtrlArray)[index].DoControl(0);
00188                 }
00189 
00190                 const ProcessingConfig& GetConfig() const
00191                 {
00192                         return *mpConfig;
00193                 }
00194 
00195                 bool ConcreteConfigure(const ProcessingConfig& c)
00196                 {
00197                         mpConfig=new SMSTransformationChainConfig(dynamic_cast<const SMSTransformationChainConfig&>(c));
00198                         bool result=true;
00199                         iterator obj;
00200                         
00202                         obj=composite_begin();
00203                         while(obj!=composite_end())
00204                         {
00205                                 Remove(*(*obj));
00206                                 obj=composite_begin();
00207                         }
00208                         
00209                         SMSTransformationChainConfig::iterator cfg;
00210                         for(cfg=mpConfig->ConfigList_begin();cfg!=mpConfig->ConfigList_end();cfg++)
00211                         {
00212                                 AddChainee((*cfg).GetConcreteClassName());
00213                                 obj=composite_end();
00214                                 obj--;
00215                                 result&=(*obj)->Configure((*cfg).GetConcreteConfig());
00216                         }
00217                         CLAM_ASSERT(mpConfig->GetConfigurations().size()==composite_size(),"Number of configurations should be the same as number of children");
00218                 
00219                         //TODO: right now there is no way to add or remove controls than to instantiate control array again
00220                         CLAM_ASSERT(mpConfig->GetOnArray().Size()==(int)composite_size(),"SMSTransformationChain::ConcreteConfigure: On array does not have same size as number of configurations");
00221                         TSize nControls=composite_size();
00222                         if(mpOnCtrlArray) delete mpOnCtrlArray;
00223                         mpOnCtrlArray= new InControlTmplArray<SMSTransformationChain>(nControls,"OnControlArray",this,NULL);
00224                         
00225                         for(int i=0;i<nControls;i++)
00226                         {
00227                                 (*mpOnCtrlArray)[i].DoControl(mpConfig->GetOnArray()[i]);
00228                         }
00229                         return result;
00230                 }
00231                 
00235                 SegmentTransformation* GetTransformation(const std::string& name)
00236                 {
00237                         for(iterator obj=composite_begin(); obj!=composite_end(); obj++)
00238                         {
00239                                 if(name == (*obj)->GetClassName()) return dynamic_cast<SegmentTransformation*>((*obj));;
00240                         }
00241                         return NULL;
00242                 }
00243                 
00244 
00245         private:
00246 
00247                 void AddChainee(const std::string& classname)
00248                 {
00249                         //TODO: Instead of connecting controls, use the publishing mechanism
00250                         //TODO2: If all amount controls were named the same I might be able to get rid of the string comparison
00251                         ProcessingFactory & theFactory = ProcessingFactory::GetInstance();
00252                         
00253                         if ( classname=="SMSFreqShift") 
00254                         {
00255                                 SegmentTransformation* wrapper = new SegmentTransformation;     
00256                                 Processing * proc = theFactory.Create(classname);
00257                                 FrameTransformation* freqshift = dynamic_cast<FrameTransformation*>(proc); 
00258                                 wrapper->WrapFrameTransformation(freqshift);
00259                                 wrapper->mAmountCtrl.PublishInControl(freqshift->GetInControls().Get("Shift Steps"));
00260 //                              ConnectControls(*wrapper,"Out Control", *freqshift, "Shift Amount");
00261                                 Insert( *wrapper );
00262                                 return;
00263                         }
00264                         
00265                         if ( classname=="SMSSinusoidalGain") 
00266                         {
00267                                 SegmentTransformation* wrapper = new SegmentTransformation;     
00268                                 Processing * proc = theFactory.Create(classname);
00269                                 FrameTransformation* singain = dynamic_cast<FrameTransformation*>(proc); 
00270                                 wrapper->WrapFrameTransformation(singain);
00271                                 wrapper->mAmountCtrl.PublishInControl(singain->GetInControls().Get("Gain"));
00272 //                              ConnectControls(*wrapper,"Out Control", *singain, "Gain Amount");
00273                                 Insert( *wrapper );
00274                                 return;
00275                         }
00276 
00277                         if ( classname=="SMSResidualGain") 
00278                         {
00279                                 SegmentTransformation* wrapper = new SegmentTransformation;     
00280                                 Processing * proc = theFactory.Create(classname);
00281                                 FrameTransformation* resgain = dynamic_cast<FrameTransformation*>(proc); 
00282                                 wrapper->WrapFrameTransformation(resgain);
00283                                 wrapper->mAmountCtrl.PublishInControl(resgain->GetInControls().Get("Gain"));
00284 //                              ConnectControls(*wrapper,"Out Control", *resgain, "Gain Amount");
00285                                 Insert( *wrapper );
00286                                 return;
00287                         }
00288 
00289                         if ( classname=="SMSPitchShift") 
00290                         {
00291                                 SegmentTransformation* wrapper = new SegmentTransformation;     
00292                                 Processing * proc = theFactory.Create(classname);
00293                                 FrameTransformation* pitchshift = dynamic_cast<FrameTransformation*>(proc); 
00294                                 wrapper->WrapFrameTransformation(pitchshift);
00295                                 wrapper->mAmountCtrl.PublishInControl(pitchshift->GetInControls().Get("PitchSteps"));
00296 //                              ConnectControls(*wrapper,"Out Control", *pitchshift, "Shift Amount");
00297                                 Insert( *wrapper );
00298                                 return;
00299                         }
00300 
00301                         if ( classname=="SMSOddEvenHarmonicRatio") 
00302                         {
00303                                 SegmentTransformation* wrapper = new SegmentTransformation;     
00304                                 Processing * proc = theFactory.Create(classname);
00305                                 FrameTransformation* oddEvenHarmRatio = dynamic_cast<FrameTransformation*>(proc); 
00306                                 wrapper->WrapFrameTransformation(oddEvenHarmRatio);
00307                                 wrapper->mAmountCtrl.PublishInControl(oddEvenHarmRatio->GetInControls().Get("Odd Factor"));
00308 //                              ConnectControls(*wrapper,"Out Control", *oddEvenHarmRatio, "Odd Harmonics Factor");
00309                                 Insert( *wrapper );
00310                                 return;
00311                         }
00312 
00313                         if ( classname=="SMSSpectralShapeShift") 
00314                         {
00315                                 SegmentTransformation* wrapper = new SegmentTransformation;     
00316                                 Processing * proc = theFactory.Create(classname);
00317                                 FrameTransformation* spectralShapeShift = dynamic_cast<FrameTransformation*>(proc); 
00318                                 wrapper->WrapFrameTransformation(spectralShapeShift);
00319                                 wrapper->mAmountCtrl.PublishInControl(spectralShapeShift->GetInControls().Get("Shift Steps"));
00320 //                              ConnectControls(*wrapper,"Out Control", *spectralShapeShift, "Shift Amount");
00321                                 Insert( *wrapper );
00322                                 return;
00323                         }
00324 
00325                         if ( classname=="SMSPitchDiscretization") 
00326                         {
00327                                 SegmentTransformation* wrapper = new SegmentTransformation;     
00328                                 Processing * proc = theFactory.Create(classname);
00329                                 FrameTransformation* pitchDiscretization = dynamic_cast<FrameTransformation*>(proc); 
00330                                 wrapper->WrapFrameTransformation(pitchDiscretization);
00331                                 Insert( *wrapper );
00332                                 return;
00333                         }
00334 
00335                         if ( classname=="SMSGenderChange") 
00336                         {
00337                                 SegmentTransformation* wrapper = new SegmentTransformation;     
00338                                 Processing * proc = theFactory.Create(classname);
00339                                 FrameTransformation* genderChange = dynamic_cast<FrameTransformation*>(proc); 
00340                                 wrapper->WrapFrameTransformation(genderChange);
00341                                 wrapper->mAmountCtrl.PublishInControl(genderChange->GetInControls().Get("Amount"));
00342 //                              ConnectControls(*wrapper,"Out Control", *genderChange, "Gender Factor");
00343                                 Insert( *wrapper );
00344                                 return;
00345                         }
00346 
00347                         if ( classname=="SMSSineFilter") 
00348                         {
00349                                 SegmentTransformation* wrapper = new SegmentTransformation;     
00350                                 Processing * proc = theFactory.Create(classname);
00351                                 FrameTransformation* sineFilter = dynamic_cast<FrameTransformation*>(proc); 
00352                                 wrapper->WrapFrameTransformation(sineFilter);
00353                                 Insert( *wrapper );
00354                                 return;
00355                         }
00356                         Insert( *( theFactory.Create( classname ) ) );
00357                 }
00359                 void NextFrame()
00360                 {
00361                         mpChainInput->mCurrentFrameIndex++;
00362                 }
00366                 bool IsLastFrame()
00367                 {
00368                         for(iterator obj=composite_begin(); obj!=composite_end(); obj++)
00369                         {
00370                                 SegmentTransformation* transf =dynamic_cast<SegmentTransformation*>((*obj));
00371                                 if(!transf->IsLastFrame()) return false;
00372                         }
00373                         return true;
00374 
00375                 }
00376 
00377 
00378         };
00379 
00380 
00381 } // namespace CLAM
00382 
00383 #endif // _SMSTransformationChain_
00384 

Generated on Tue Aug 12 22:33:45 2008 for CLAM by  doxygen 1.5.5