|
CLAM-Development
1.3
|
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", "MultiChannelAudioFileWriter", 00039 "category", "Audio File I/O", 00040 "description", "MultiChannelAudioFileWriter", 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 if ( mConfig.HasTargetFile() ) 00176 FileSystem::GetInstance().UnlockFile( mConfig.GetTargetFile() ); 00177 00178 CopyAsConcreteConfig( mConfig, cfg ); 00179 00180 const AudioOutFilename & filename = mConfig.GetTargetFile(); 00181 if (filename=="") 00182 { 00183 return AddConfigErrorMessage("No file selected"); 00184 } 00185 00186 unsigned nChannels = mConfig.HasNChannels()? mConfig.GetNChannels() : 1; 00187 if ( nChannels < 1 ) 00188 { 00189 return AddConfigErrorMessage("Channels should be, at least, 1."); 00190 } 00191 AudioFileHeader header; 00192 header.SetValues( 00193 mConfig.GetSampleRate(), 00194 nChannels, 00195 CLAM::EAudioFileFormat::FormatFromFilename(filename) ); 00196 mAudioFile.CreateNew(filename, header); 00197 if ( !mAudioFile.IsWritable() ) 00198 { 00199 return AddConfigErrorMessage("The format does not support such number of channels, endiannes or sampling rate."); 00200 } 00201 00202 if ( FileSystem::GetInstance().IsFileLocked( filename ) ) 00203 { 00204 AddConfigErrorMessage("The file '"); 00205 AddConfigErrorMessage( filename ); 00206 AddConfigErrorMessage("' has been locked by another Processing"); 00207 00208 return false; 00209 } 00210 00211 FileSystem::GetInstance().LockFile( filename ); 00212 00213 00214 if ( !mInputs.empty() ) 00215 DestroyOldInputs(); 00216 00217 mChannelsToWrite.Resize( nChannels ); 00218 mChannelsToWrite.SetSize( nChannels ); 00219 mSamplesMatrix.Resize( nChannels ); 00220 mSamplesMatrix.SetSize( nChannels ); 00221 00222 for ( unsigned i = 0; i < nChannels; i++ ) 00223 { 00224 mChannelsToWrite[ i ] = i; 00225 mSamplesMatrix[ i ] = NULL; 00226 std::stringstream sstr; 00227 sstr << i; 00228 00229 mInputs.push_back( 00230 new AudioInPort( "Channel #" + sstr.str(), this) ); 00231 } 00232 00233 mNativeStream = mAudioFile.GetStream(); 00234 00235 if ( !mNativeStream ) 00236 { 00237 return AddConfigErrorMessage("Could not acquire an audio file stream!"); 00238 } 00239 00240 return true; 00241 } 00242 00243 bool MultiChannelAudioFileWriter::ConcreteStart() 00244 { 00245 if (mNativeStream == NULL ) 00246 mNativeStream = mAudioFile.GetStream(); 00247 mNativeStream->PrepareWriting(); 00248 00249 return true; 00250 } 00251 00252 bool MultiChannelAudioFileWriter::ConcreteStop() 00253 { 00254 mNativeStream->Dispose(); 00255 delete mNativeStream; 00256 mNativeStream = NULL; 00257 00258 return true; 00259 } 00260 00261 void MultiChannelAudioFileWriter::DestroyOldInputs() 00262 { 00263 for ( VectorOfInputs::iterator i = mInputs.begin(); 00264 i != mInputs.end(); i++ ) 00265 { 00266 if ( *i ) delete *i; 00267 } 00268 00269 mInputs.clear(); 00270 GetInPorts().Clear(); 00271 } 00272 } 00273
1.7.6.1