MultiChannelAudioFileWriter.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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"
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
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
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
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
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