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                 // if the metadata has defined the number of milliseconds to preload
00037                 // preload the corresponding number of frames.
00038                 if ( config.HasNumberOfFramesToPreload() )
00039                 {
00040                         //std::cout << "Preloading " << config.GetNumberOfFramesToPreload()+1 << " frames" << std::endl;
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                 //std::cout << "Retrieving buffer pos: " << frameBufferPosition << ", size: " << frameBuffer.size() << std::endl;
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         // when we read in the SDIFFrames, let's first put them in a temporary
00120         // list object so we can avoid locking the frameBuffer every iteration
00121         // of the loop
00122         std::deque<Frame*> tempFrameBuffer;
00123 
00124         // this object locks the mSDIFFileReader until the scopedlock goes
00125         // out of scope and is garbage collected. its destructor frees the lock
00126         {
00127                 Mutex::ScopedLock lock( readSDIFMutex );
00128                 
00129                 // here's the loop where we read in the desired number of buffers
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                         // we read in the frame
00142                         mReaderHasMoreFrames = mSDIFFileReader.ReadFrame( aFrame->GetFundamental(), aFrame->GetSpectralPeakArray(), aFrame->GetResidualSpec(), frameCenterTime );
00143 
00144                         // we'll update the frame position variable when we actually add these to 
00145                         // the frameVector
00146                 
00147                         // as long as there was something to read, add the frame to the temporary buffer
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         // now let's copy the frames from the temporary buffer to the frameBuffer
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 // Note the exception handling
00187         {
00188                 mThreadPtr->SetThreadCode( mFunctor );
00189 
00190                 mThreadPtr->Start();
00191 
00192                 //mThreadPtr->Stop();
00193 
00194         }
00195         catch( std::exception& e ) // Here we handle standard library exceptions
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 // Note the exception handling
00206         {
00207                 if ( mThreadPtr != NULL)
00208                 {
00209                         mThreadPtr = NULL;
00210                 }
00211         }
00212         catch( std::exception& e ) // Here we handle standard library exceptions
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                 //std::cout << "Thread <" << mThreadPtr << "> this <" << this << "> is loading buffers." << std::endl;
00231                 mReaderHasMoreFrames = LoadFramesIntoBuffer(mFrameLoadChunkSize);
00232                 iterationsSinceLastExecution = 0;
00233                 mThreadPtr->Yield();
00234         }
00235 }
00236 
00237 
00238 
00239 } // END CLAM
00240 
00241 
Generated by  doxygen 1.6.3