MultiChannelAudioFileWriter.cxx

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 #include "MultiChannelAudioFileWriter.hxx"
00023 #include "AudioCodecs_Stream.hxx"
00024 #include "FileSystem.hxx"
00025 #include "AudioInPort.hxx"
00026 #include "Audio.hxx"
00027 #include "XMLStorage.hxx" // TODO: jsut for testing
00028 #include "ProcessingFactory.hxx"
00029 
00030 
00031 
00032 namespace CLAM
00033 {
00034 
00035 namespace Hidden
00036 {
00037         static const char * metadata[] = {
00038                 "key", "MultiChannelAudioFileReaderConfig",
00039                 "category", "Audio File I/O",
00040                 "description", "MultiChannelAudioFileReaderConfig",
00041                 0
00042         };
00043         static FactoryRegistrator<ProcessingFactory, MultiChannelAudioFileWriter> reg = metadata;
00044 }
00045         
00046         
00047         MultiChannelAudioFileWriter::MultiChannelAudioFileWriter()
00048                 : mNativeStream( NULL )
00049         {
00050                 Configure(MultiChannelAudioFileWriterConfig());
00051         }
00052 
00053         MultiChannelAudioFileWriter::MultiChannelAudioFileWriter( const ProcessingConfig& cfg )
00054                 : mNativeStream( NULL )
00055         {
00056                 Configure( cfg );
00057         }
00058 
00059         MultiChannelAudioFileWriter::~MultiChannelAudioFileWriter()
00060         {
00061                 if ( mNativeStream )
00062                         delete mNativeStream;
00063 
00064                 DestroyOldInputs();
00065 
00066                 if ( mConfig.HasTargetFile() )
00067                         FileSystem::GetInstance().UnlockFile( mConfig.GetTargetFile() );
00068 
00069         }
00070 
00071         const char* MultiChannelAudioFileWriter::GetClassName() const
00072         {
00073                 return "MultiChannelAudioFileWriter";
00074         }
00075 
00076         bool MultiChannelAudioFileWriter::ModifiesPortsAndControlsAtConfiguration()
00077         {
00078                 return true;
00079         }
00080 
00081         const ProcessingConfig& MultiChannelAudioFileWriter::GetConfig() const
00082         {
00083                 return mConfig;
00084         }
00085 
00086         bool MultiChannelAudioFileWriter::Do( std::vector<Audio>& inputs )
00087         {
00088                 typedef std::vector<Audio> InputVec;
00089 
00090                 if ( !AbleToExecute() )
00091                         return false;
00092 
00093                 // Checking that all inputs have the same size
00094                 bool  allInputsSameSize = true;
00095                 TSize inputsSize = 0;
00096 
00097                 inputsSize = inputs[0].GetSize();
00098 
00099                 for ( InputVec::iterator i = inputs.begin();
00100                       i!= inputs.end() && allInputsSameSize;
00101                       i++ )
00102                   {
00103                     allInputsSameSize = ( inputsSize == (*i).GetSize() );
00104                   }
00105 
00106 
00107                 CLAM_ASSERT( allInputsSameSize, "Input sizes differ!" );
00108 
00109                 // Now, let's build the samples matrix
00110 
00111                 int j = 0;
00112 
00113                 for( InputVec::iterator i = inputs.begin();
00114                      i != inputs.end(); i++ )
00115                   mSamplesMatrix[ j++ ] = (*i).GetBuffer().GetPtr();
00116 
00117                 mNativeStream->WriteData( mChannelsToWrite.GetPtr(), mChannelsToWrite.Size(),
00118                                          mSamplesMatrix.GetPtr(), inputsSize );
00119 
00120                 return true;
00121 
00122         }
00123 
00124         bool MultiChannelAudioFileWriter::Do()
00125         {
00126                 if ( !AbleToExecute() )
00127                         return false;
00128 
00129                 // Checking that all inputs have the same size
00130                 bool  allInputsSameSize = true;
00131                 TSize inputsSize = 0;
00132 
00133                 InputsRefVector inputsRef;
00134 
00135                 for ( VectorOfInputs::iterator i = mInputs.begin();
00136                       i!= mInputs.end(); i++ )
00137                   {
00138                     inputsRef.push_back( &((*i)->GetAudio()) );
00139                   }
00140 
00141                 inputsSize = inputsRef[0]->GetSize();
00142 
00143                 for ( InputsRefVector::iterator i = inputsRef.begin();
00144                       i!= inputsRef.end() && allInputsSameSize;
00145                       i++ )
00146                   {
00147                     allInputsSameSize = ( inputsSize == (*i)->GetSize() );
00148                   }
00149 
00150 
00151                 CLAM_ASSERT( allInputsSameSize, "Input sizes differ!" );
00152 
00153                 // Now, let's build the samples matrix
00154 
00155                 int j = 0;
00156 
00157                 for( InputsRefVector::iterator i = inputsRef.begin();
00158                      i != inputsRef.end(); i++ )
00159                   mSamplesMatrix[ j++ ] = (*i)->GetBuffer().GetPtr();
00160 
00161                 mNativeStream->WriteData( mChannelsToWrite.GetPtr(), mChannelsToWrite.Size(),
00162                                          mSamplesMatrix.GetPtr(), inputsSize );
00163 
00164                 for( VectorOfInputs::iterator i = mInputs.begin();
00165                      i!=mInputs.end(); i++ )
00166                   {
00167                     (*i)->Consume();
00168                   }
00169 
00170                 return true;
00171         }
00172 
00173         bool MultiChannelAudioFileWriter::ConcreteConfigure( const ProcessingConfig& cfg )
00174         {
00175                 const AudioOutFilename & filename = mConfig.GetTargetFile();
00176                 if ( mConfig.HasTargetFile() )
00177                         FileSystem::GetInstance().UnlockFile( filename );
00178 
00179                 CopyAsConcreteConfig( mConfig, cfg );
00180 
00181                 if (filename=="")
00182                 {
00183                         AddConfigErrorMessage("No file selected");
00184                         return false;
00185                 }
00186                 
00187                 unsigned nChannels = mConfig.HasNChannels()? mConfig.GetNChannels() : 1;
00188                 if ( nChannels < 1 )
00189                 {
00190                         AddConfigErrorMessage("Channels should be, at least, 1.");
00191                         return false;
00192                 }
00193                 AudioFileHeader header;
00194                 header.SetValues(
00195                         mConfig.GetSampleRate(),
00196                         nChannels,
00197                         CLAM::EAudioFileFormat::FormatFromFilename(filename) );
00198                 mAudioFile.CreateNew(filename, header);
00199                 if ( !mAudioFile.IsWritable() )
00200                 {
00201                         AddConfigErrorMessage("The format does not support such number of channels, endiannes or sampling rate.");
00202 
00203                         return false;
00204                 }
00205 
00206                 if ( FileSystem::GetInstance().IsFileLocked( filename ) )
00207                 {
00208                         AddConfigErrorMessage("The file '");
00209                         AddConfigErrorMessage( filename );
00210                         AddConfigErrorMessage("' has been locked by another Processing");
00211 
00212                         return false;
00213                 }
00214 
00215                 FileSystem::GetInstance().LockFile( filename );
00216 
00217 
00218                 if ( !mInputs.empty() )
00219                         DestroyOldInputs();
00220 
00221                 mChannelsToWrite.Resize( nChannels );
00222                 mChannelsToWrite.SetSize( nChannels );
00223                 mSamplesMatrix.Resize( nChannels );
00224                 mSamplesMatrix.SetSize( nChannels );
00225 
00226                 for ( unsigned i = 0; i < nChannels; i++ )
00227                 {
00228                         mChannelsToWrite[ i ] = i;
00229                         mSamplesMatrix[ i ] = NULL;
00230                         std::stringstream sstr;
00231                         sstr << i;
00232                         
00233                         mInputs.push_back( 
00234                                 new AudioInPort( "Channel #" + sstr.str(), this) );
00235                 }
00236 
00237                 mNativeStream = mAudioFile.GetStream();
00238 
00239                 if ( !mNativeStream )
00240                 {
00241                         AddConfigErrorMessage("Could not acquire an audio file stream!");
00242                         return false;
00243                 }
00244 
00245                 return true;
00246         }
00247 
00248         bool MultiChannelAudioFileWriter::ConcreteStart()
00249         {
00250                 if (mNativeStream == NULL )
00251                         mNativeStream = mAudioFile.GetStream();
00252                 mNativeStream->PrepareWriting();
00253 
00254                 return true;
00255         }
00256 
00257         bool MultiChannelAudioFileWriter::ConcreteStop()
00258         {
00259                 mNativeStream->Dispose();
00260                 delete mNativeStream;
00261                 mNativeStream = NULL;
00262 
00263                 return true;
00264         }
00265 
00266         void MultiChannelAudioFileWriter::DestroyOldInputs()
00267         {
00268                 for ( VectorOfInputs::iterator i = mInputs.begin();
00269                       i != mInputs.end(); i++ )
00270                 {
00271                         if ( *i ) delete *i;
00272                 }
00273 
00274                 mInputs.clear();
00275                 GetInPorts().Clear();
00276         }
00277 }
00278 

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