BufferedSDIFFileReader.cxx
Go to the documentation of this file.00001 #include "BufferedSDIFFileReader.hxx"
00002 #include "DataUtil.hxx"
00003 #include <limits.h>
00004
00005 namespace CLAM
00006 {
00007
00008 BufferedSDIFFileReader::BufferedSDIFFileReader(const SDIFInConfig& argSDIFInConfig) :
00009 mSDIFFileReader(argSDIFInConfig),
00010 frameBufferPosition(1),
00011 mFrameLoadChunkSize( DEFAULT_FRAME_LOAD_CHUNK_SIZE ),
00012 mThreshholdForPreloading( DEFAULT_THRESHHOLD_FOR_PRELOADING ),
00013 mThreshholdForPreloadingOnThread( DEFAULT_THRESHHOLD_FOR_PRELOADING_ON_THREAD ),
00014 mReaderHasMoreFrames( true ),
00015 dequeMutex(),
00016 readSDIFMutex()
00017 {
00018 mFunctor = makeMemberFunctor0( *this, BufferedSDIFFileReader, Run );
00019
00020 Configure(argSDIFInConfig);
00021 }
00022
00023 BufferedSDIFFileReader::~BufferedSDIFFileReader()
00024 {
00025 for (unsigned int counter = 0; counter < frameBuffer.size(); counter++)
00026 {
00027 delete frameBuffer[counter];
00028 }
00029 }
00030
00031 bool BufferedSDIFFileReader::Configure(const SDIFInConfig& config)
00032 {
00033 bool response;
00034 if ( response = mSDIFFileReader.Configure(config) )
00035 {
00036
00037
00038 if ( config.HasNumberOfFramesToPreload() )
00039 {
00040
00041 LoadFramesIntoBuffer( config.GetNumberOfFramesToPreload()+1 );
00042 }
00043 else
00044 {
00045 LoadFramesIntoBuffer( DEFAULT_INITIAL_NUMBER_OF_FRAMES_TO_BUFFER );
00046 }
00047
00048 if ( config.HasNumberOfFramesToLoad() )
00049 {
00050 totalNumberOfFramesToLoad = config.GetNumberOfFramesToLoad();
00051 }
00052 else
00053 {
00054 if (config.HasNumberOfFramesToPreload())
00055 totalNumberOfFramesToLoad = config.GetNumberOfFramesToPreload()+1;
00056 else
00057 totalNumberOfFramesToLoad = INT_MAX;
00058 }
00059 }
00060
00061 return response;
00062 }
00063
00064 const SDIFInConfig BufferedSDIFFileReader::GetConfig()
00065 {
00066 return dynamic_cast<const SDIFInConfig&>(mSDIFFileReader.GetConfig());
00067 }
00068
00069 int BufferedSDIFFileReader::GetFrameBufferPosition()
00070 {
00071 return frameBufferPosition;
00072 }
00073
00074 void BufferedSDIFFileReader::SetFrameBufferPosition(int argFrameBufferPosition)
00075 {
00076 frameBufferPosition = argFrameBufferPosition;
00077 }
00078
00079 Frame* BufferedSDIFFileReader::GetFrame( int frameBufferPosition )
00080 {
00081 Mutex::ScopedLock lock( dequeMutex );
00082
00083 Frame* requestedFrame = frameBuffer.at(frameBufferPosition);
00084
00085 return requestedFrame;
00086 }
00087
00088 Frame* BufferedSDIFFileReader::ReadFrame()
00089 {
00090 int framesTillTheEnd = frameBuffer.size() - frameBufferPosition;
00091 if ((mReaderHasMoreFrames == true) && (framesTillTheEnd < mThreshholdForPreloading))
00092 {
00093 mReaderHasMoreFrames = LoadFramesIntoBuffer(mFrameLoadChunkSize);
00094 }
00095
00096 if ( frameBuffer.size() == 0 )
00097 {
00098 return NULL;
00099 }
00100 else
00101 {
00102 Mutex::ScopedLock lock( dequeMutex );
00103
00104
00105 Frame* nextFrame = frameBuffer.at(frameBufferPosition);
00106 frameBufferPosition++;
00107
00108 if (nextFrame == NULL)
00109 {
00110 std::cout << "next frame is null" << std::endl;
00111 }
00112
00113 return nextFrame;
00114 }
00115 }
00116
00117 bool BufferedSDIFFileReader::LoadFramesIntoBuffer(int argNumberOfBuffers)
00118 {
00119
00120
00121
00122 std::deque<Frame*> tempFrameBuffer;
00123
00124
00125
00126 {
00127 Mutex::ScopedLock lock( readSDIFMutex );
00128
00129
00130 for (int counter = 0; counter < argNumberOfBuffers; counter++)
00131 {
00132 Frame* aFrame = new Frame();
00133 aFrame->AddSpectralPeakArray();
00134 aFrame->AddResidualSpec();
00135 aFrame->AddFundamental();
00136 aFrame->AddSynthAudioFrame();
00137 aFrame->UpdateData();
00138
00139 TTime frameCenterTime;
00140
00141
00142 mReaderHasMoreFrames = mSDIFFileReader.ReadFrame( aFrame->GetFundamental(), aFrame->GetSpectralPeakArray(), aFrame->GetResidualSpec(), frameCenterTime );
00143
00144
00145
00146
00147
00148 if (mReaderHasMoreFrames)
00149 {
00150 aFrame->SetCenterTime(frameCenterTime);
00151
00152 tempFrameBuffer.push_back( aFrame );
00153 }
00154 else
00155 {
00156 std::cout << "BufferedSDIFReader: could only load " << counter << " of ";
00157 std::cout << argNumberOfBuffers << " frames." << std::endl;
00158 delete aFrame;
00159 break;
00160 }
00161 }
00162 }
00163
00164
00165 Mutex::ScopedLock lock( dequeMutex );
00166 for (unsigned int counter = 0; counter < tempFrameBuffer.size(); counter++)
00167 {
00168 Frame* aFrame = tempFrameBuffer.at(counter);
00169 frameBuffer.push_back( aFrame );
00170 }
00171
00172 return mReaderHasMoreFrames;
00173 }
00174
00175 int BufferedSDIFFileReader::GetNumberOfFramesLoaded()
00176 {
00177 Mutex::ScopedLock lock( dequeMutex );
00178 return frameBuffer.size();
00179 }
00180
00181 void BufferedSDIFFileReader::LoadFramesIntoBufferOnThread(Thread* argThread)
00182 {
00183 CLAM_ASSERT(argThread != NULL, "Thread* given to BufferedSDIFFileReader may not be null!");
00184
00185 mThreadPtr = argThread;
00186 try
00187 {
00188 mThreadPtr->SetThreadCode( mFunctor );
00189
00190 mThreadPtr->Start();
00191
00192
00193
00194 }
00195 catch( std::exception& e )
00196 {
00197 std::cerr << e.what() << std::endl;
00198 std::string msg("BufferedSDIFFileReader: exception when starting thread. SDIFFile will be loaded on main thread.");
00199 std::cerr << msg << std::endl;
00200 }
00201 }
00202
00203 void BufferedSDIFFileReader::StopLoadingFramesIntoBufferOnThread()
00204 {
00205 try
00206 {
00207 if ( mThreadPtr != NULL)
00208 {
00209 mThreadPtr = NULL;
00210 }
00211 }
00212 catch( std::exception& e )
00213 {
00214 std::cerr << e.what() << std::endl;
00215 std::string msg("BufferedSDIFFileReader: exception when stopping thread.");
00216 std::cerr << msg << std::endl;
00217 }
00218 }
00219
00220 bool BufferedSDIFFileReader::IsThreaded()
00221 {
00222 return mThreadPtr != NULL;
00223 }
00224
00225 void BufferedSDIFFileReader::Run()
00226 {
00227 int iterationsSinceLastExecution = 0;
00228 while ( mReaderHasMoreFrames && totalNumberOfFramesToLoad <= frameBuffer.size() )
00229 {
00230
00231 mReaderHasMoreFrames = LoadFramesIntoBuffer(mFrameLoadChunkSize);
00232 iterationsSinceLastExecution = 0;
00233 mThreadPtr->Yield();
00234 }
00235 }
00236
00237
00238
00239 }
00240
00241