00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "MultiChannelAudioFileReader.hxx"
00023 #include "AudioCodecs_Stream.hxx"
00024 #include "AudioOutPort.hxx"
00025 #include "ProcessingFactory.hxx"
00026
00027
00028 namespace CLAM
00029 {
00030
00031 namespace Hidden
00032 {
00033 static const char * metadata[] = {
00034 "key", "MultiChannelAudioFileReader",
00035 "category", "Audio File I/O",
00036 "description", "MultiChannelAudioFileReader",
00037 0
00038 };
00039 static FactoryRegistrator<ProcessingFactory, MultiChannelAudioFileReader> reg = metadata;
00040 }
00041
00042
00043 MultiChannelAudioFileReader::MultiChannelAudioFileReader()
00044 : mTimeOutput( "Current Time Position", this)
00045 , mNativeStream( NULL )
00046 {
00047 Configure(MultiChannelAudioFileReaderConfig());
00048 }
00049
00050 MultiChannelAudioFileReader::MultiChannelAudioFileReader( const ProcessingConfig& cfg )
00051 : mTimeOutput( "Current Time Position", this)
00052 , mNativeStream( NULL )
00053 {
00054 Configure( cfg );
00055 }
00056
00057 MultiChannelAudioFileReader::~MultiChannelAudioFileReader()
00058 {
00059 if ( mNativeStream )
00060 delete mNativeStream;
00061
00062 DestroyOldOutputs();
00063 }
00064
00065 const char* MultiChannelAudioFileReader::GetClassName() const
00066 {
00067 return "MultiChannelAudioFileReader";
00068 }
00069
00070 bool MultiChannelAudioFileReader::ModifiesPortsAndControlsAtConfiguration()
00071 {
00072 return true;
00073 }
00074
00075 const ProcessingConfig& MultiChannelAudioFileReader::GetConfig() const
00076 {
00077 return mConfig;
00078 }
00079
00080
00081 bool MultiChannelAudioFileReader::Do( std::vector<Audio>& outputs )
00082 {
00083 typedef std::vector<Audio> OutputVec;
00084
00085 if ( !AbleToExecute() )
00086 return false;
00087
00088
00089 bool allOutputsSameSize = true;
00090
00091 TSize sizeTmp = 0;
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 sizeTmp = outputs[0].GetSize();
00102
00103 for( OutputVec::iterator i = outputs.begin();
00104 i!= outputs.end(); i++ )
00105 {
00106 allOutputsSameSize &= ( sizeTmp == i->GetSize() );
00107 }
00108
00109
00110 CLAM_ASSERT( allOutputsSameSize, "Outputs sizes differ!" );
00111
00112
00113 int j = 0;
00114 for ( OutputVec::iterator i = outputs.begin(); i != outputs.end(); i++ )
00115 mSamplesMatrix[ j++ ] = (*i).GetBuffer().GetPtr();
00116
00117
00118 if ( !mEOFReached && !mIsPaused )
00119 {
00120 mEOFReached = mNativeStream->ReadData( mSelectedChannels.GetPtr(),
00121 mSelectedChannels.Size(),
00122 mSamplesMatrix.GetPtr(),
00123 sizeTmp );
00124 }
00125 else
00126 {
00127 if ( mEOFReached )
00128 mCurrentBeginTime = GetHeader().GetLength()/1000;
00129 for ( int i = 0; i != mSamplesMatrix.Size(); i++ )
00130 memset ((void *)mSamplesMatrix[i], 0, sizeTmp*sizeof(TData));
00131 }
00132
00133 for ( OutputVec::iterator i = outputs.begin();
00134 i != outputs.end(); i++ )
00135 {
00136 (*i).SetSampleRate( mAudioFile.GetHeader().GetSampleRate() );
00137 (*i).SetBeginTime( mCurrentBeginTime );
00138 }
00139
00140
00141 if ( !mEOFReached && !mIsPaused )
00142 {
00143 mDeltaTime = TData(sizeTmp)/mAudioFile.GetHeader().GetSampleRate()*1000;
00144 mCurrentBeginTime += mDeltaTime;
00145 }
00146 mTimeOutput.SendControl( mCurrentBeginTime );
00147
00148 return !mEOFReached;
00149 }
00150
00151 bool MultiChannelAudioFileReader::Do()
00152 {
00153 if ( !AbleToExecute() )
00154 return false;
00155
00156
00157 bool allOutputsSameSize = true;
00158
00159 TSize sizeTmp = 0;
00160
00161
00162
00163
00164
00165
00166
00167
00168 OutRefsVector outRefs;
00169
00170 for ( OutputVector::iterator i = mOutputs.begin();
00171 i!= mOutputs.end();
00172 i++ )
00173 outRefs.push_back( &((*i)->GetAudio()) );
00174
00175
00176 sizeTmp = outRefs[0]->GetSize();
00177
00178 for( OutRefsVector::iterator i = outRefs.begin();
00179 i!= outRefs.end(); i++ )
00180 {
00181 allOutputsSameSize = ( sizeTmp == (*i)->GetSize() );
00182 }
00183
00184
00185 CLAM_ASSERT( allOutputsSameSize, "Outputs sizes differ!" );
00186
00187
00188
00189 int j = 0;
00190 for ( OutRefsVector::iterator i = outRefs.begin();
00191 i != outRefs.end(); i++ )
00192 mSamplesMatrix[ j++ ] = (*i)->GetBuffer().GetPtr();
00193
00194
00195
00196 if ( !mEOFReached && !mIsPaused )
00197 {
00198 mEOFReached = mNativeStream->ReadData( mSelectedChannels.GetPtr(),
00199 mSelectedChannels.Size(),
00200 mSamplesMatrix.GetPtr(),
00201 sizeTmp );
00202 }
00203 else
00204 {
00205 if ( mEOFReached )
00206 mCurrentBeginTime = GetHeader().GetLength()/1000;
00207 for ( int i = 0; i != mSamplesMatrix.Size(); i++)
00208 {
00209 memset ((void *)mSamplesMatrix[i], 0, sizeTmp*sizeof(TData));
00210 }
00211 }
00212
00213
00214
00215 for ( OutRefsVector::iterator i = outRefs.begin();
00216 i != outRefs.end(); i++ )
00217 {
00218 (*i)->SetSampleRate( mAudioFile.GetHeader().GetSampleRate() );
00219 (*i)->SetBeginTime( mCurrentBeginTime );
00220 }
00221
00222 if (!mEOFReached && !mIsPaused)
00223 {
00224 mDeltaTime = TData(sizeTmp)/mAudioFile.GetHeader().GetSampleRate()*1000;
00225 mCurrentBeginTime += mDeltaTime;
00226 }
00227
00228 mTimeOutput.SendControl( mCurrentBeginTime );
00229
00230 for ( OutputVector::iterator i = mOutputs.begin();
00231 i!= mOutputs.end(); i++ )
00232 {
00233 (*i)->Produce();
00234 }
00235
00236 return !mEOFReached;
00237 }
00238
00239 bool MultiChannelAudioFileReader::ConcreteConfigure( const ProcessingConfig& cfgObj )
00240 {
00241 CopyAsConcreteConfig( mConfig, cfgObj );
00242
00243 if ( !mConfig.HasSourceFile() )
00244 {
00245 AddConfigErrorMessage("No 'source file' was specified in the configuration!");
00246 return false;
00247 }
00248
00249 if ( mConfig.GetSourceFile() == "" )
00250 {
00251 AddConfigErrorMessage("No file selected");
00252 return false;
00253 }
00254
00255 mAudioFile.OpenExisting(mConfig.GetSourceFile());
00256 if ( !mAudioFile.IsReadable() )
00257 {
00258 AddConfigErrorMessage("The audio file '" + mConfig.GetSourceFile() + "' could not be opened!");
00259 return false;
00260 }
00261
00262 if ( !mConfig.HasSelectedChannels() )
00263 {
00264 mSelectedChannels.Resize( mAudioFile.GetHeader().GetChannels() );
00265 mSelectedChannels.SetSize( mAudioFile.GetHeader().GetChannels() );
00266
00267 DestroyOldOutputs();
00268
00269 for ( int i = 0; i < mSelectedChannels.Size(); i++ )
00270 {
00271 std::stringstream sstr;
00272 sstr << i;
00273
00274 mOutputs.push_back(
00275 new AudioOutPort( "Channel #" + sstr.str(), this )
00276 );
00277
00278 mSelectedChannels[ i ] = i;
00279 }
00280
00281 mSamplesMatrix.Resize( mSelectedChannels.Size() );
00282 mSamplesMatrix.SetSize( mSelectedChannels.Size() );
00283
00284 }
00285 else
00286 {
00287
00288 mSelectedChannels = mConfig.GetSelectedChannels();
00289
00290 if ( mSelectedChannels.Size() != mAudioFile.GetHeader().GetChannels() )
00291 {
00292 AddConfigErrorMessage("The configuration asked for more channels than the audio file has.");
00293 return false;
00294 }
00295
00296 int maxChannels = mAudioFile.GetHeader().GetChannels();
00297
00298 for ( int i = 0; i < mSelectedChannels.Size(); i++ )
00299 if ( mSelectedChannels[i] < 0
00300 || mSelectedChannels[i] >= maxChannels )
00301 {
00302 AddConfigErrorMessage("Invalid channel index in configuration!");
00303 return false;
00304 }
00305
00306
00307 DestroyOldOutputs();
00308
00309 for ( int i = 0; i < mSelectedChannels.Size(); i++ )
00310 {
00311 std::stringstream sstr;
00312 sstr << mSelectedChannels[i];
00313
00314 mOutputs.push_back(
00315 new AudioOutPort( "Channel #" + sstr.str(), this )
00316 );
00317 }
00318
00319 mSamplesMatrix.Resize( maxChannels );
00320 mSamplesMatrix.SetSize( maxChannels );
00321 }
00322
00323 mNativeStream = mAudioFile.GetStream();
00324
00325 if (!mNativeStream )
00326 {
00327 AddConfigErrorMessage("Could not get a valid audio file stream!");
00328 return false;
00329 }
00330
00331 return true;
00332 }
00333
00334 void MultiChannelAudioFileReader::DestroyOldOutputs()
00335 {
00336 for( OutputVector::iterator i = mOutputs.begin();
00337 i != mOutputs.end(); i++ )
00338 if( *i ) delete *i;
00339
00340 mOutputs.clear();
00341 GetOutPorts().Clear();
00342 }
00343
00344 bool MultiChannelAudioFileReader::ConcreteStart()
00345 {
00346 if (mNativeStream == NULL)
00347 mNativeStream = mAudioFile.GetStream();
00348 mNativeStream->PrepareReading();
00349 mCurrentBeginTime = 0.0;
00350 mEOFReached = false;
00351 mIsPaused = false;
00352
00353 return true;
00354 }
00355
00356 bool MultiChannelAudioFileReader::ConcreteStop()
00357 {
00358 mNativeStream->Dispose();
00359 delete mNativeStream;
00360 mNativeStream = NULL;
00361
00362 return true;
00363 }
00364 }
00365