CLAM-Development  1.4.0
BufferedSDIFFileReader.cxx
Go to the documentation of this file.
2 #include "DataUtil.hxx"
3 #include <limits.h>
4 
5 namespace CLAM
6 {
7 
9  mSDIFFileReader(argSDIFInConfig),
10  frameBufferPosition(1),
11  mFrameLoadChunkSize( DEFAULT_FRAME_LOAD_CHUNK_SIZE ),
12  mThreshholdForPreloading( DEFAULT_THRESHHOLD_FOR_PRELOADING ),
13  mThreshholdForPreloadingOnThread( DEFAULT_THRESHHOLD_FOR_PRELOADING_ON_THREAD ),
14  mReaderHasMoreFrames( true ),
15  dequeMutex(),
16  readSDIFMutex()
17 {
18  mFunctor = makeMemberFunctor0( *this, BufferedSDIFFileReader, Run );
19 
20  Configure(argSDIFInConfig);
21 }
22 
24 {
25  for (unsigned int counter = 0; counter < frameBuffer.size(); counter++)
26  {
27  delete frameBuffer[counter];
28  }
29 }
30 
32 {
33  bool response;
34  if ( response = mSDIFFileReader.Configure(config) )
35  {
36  // if the metadata has defined the number of milliseconds to preload
37  // preload the corresponding number of frames.
38  if ( config.HasNumberOfFramesToPreload() )
39  {
40  //std::cout << "Preloading " << config.GetNumberOfFramesToPreload()+1 << " frames" << std::endl;
41  LoadFramesIntoBuffer( config.GetNumberOfFramesToPreload()+1 );
42  }
43  else
44  {
45  LoadFramesIntoBuffer( DEFAULT_INITIAL_NUMBER_OF_FRAMES_TO_BUFFER );
46  }
47 
48  if ( config.HasNumberOfFramesToLoad() )
49  {
50  totalNumberOfFramesToLoad = config.GetNumberOfFramesToLoad();
51  }
52  else
53  {
54  if (config.HasNumberOfFramesToPreload())
55  totalNumberOfFramesToLoad = config.GetNumberOfFramesToPreload()+1;
56  else
57  totalNumberOfFramesToLoad = INT_MAX;
58  }
59  }
60 
61  return response;
62 }
63 
65 {
66  return dynamic_cast<const SDIFInConfig&>(mSDIFFileReader.GetConfig());
67 }
68 
70 {
71  return frameBufferPosition;
72 }
73 
74 void BufferedSDIFFileReader::SetFrameBufferPosition(int argFrameBufferPosition)
75 {
76  frameBufferPosition = argFrameBufferPosition;
77 }
78 
79 Frame* BufferedSDIFFileReader::GetFrame( int frameBufferPosition )
80 {
81  Mutex::ScopedLock lock( dequeMutex );
82 
83  Frame* requestedFrame = frameBuffer.at(frameBufferPosition);
84 
85  return requestedFrame;
86 }
87 
89 {
90  int framesTillTheEnd = frameBuffer.size() - frameBufferPosition;
91  if ((mReaderHasMoreFrames == true) && (framesTillTheEnd < mThreshholdForPreloading))
92  {
93  mReaderHasMoreFrames = LoadFramesIntoBuffer(mFrameLoadChunkSize);
94  }
95 
96  if ( frameBuffer.size() == 0 )
97  {
98  return NULL;
99  }
100  else
101  {
102  Mutex::ScopedLock lock( dequeMutex );
103 
104  //std::cout << "Retrieving buffer pos: " << frameBufferPosition << ", size: " << frameBuffer.size() << std::endl;
105  Frame* nextFrame = frameBuffer.at(frameBufferPosition);
106  frameBufferPosition++;
107 
108  if (nextFrame == NULL)
109  {
110  std::cout << "next frame is null" << std::endl;
111  }
112 
113  return nextFrame;
114  }
115 }
116 
117 bool BufferedSDIFFileReader::LoadFramesIntoBuffer(int argNumberOfBuffers)
118 {
119  // when we read in the SDIFFrames, let's first put them in a temporary
120  // list object so we can avoid locking the frameBuffer every iteration
121  // of the loop
122  std::deque<Frame*> tempFrameBuffer;
123 
124  // this object locks the mSDIFFileReader until the scopedlock goes
125  // out of scope and is garbage collected. its destructor frees the lock
126  {
127  Mutex::ScopedLock lock( readSDIFMutex );
128 
129  // here's the loop where we read in the desired number of buffers
130  for (int counter = 0; counter < argNumberOfBuffers; counter++)
131  {
132  Frame* aFrame = new Frame();
133  aFrame->AddSpectralPeakArray();
134  aFrame->AddResidualSpec();
135  aFrame->AddFundamental();
136  aFrame->AddSynthAudioFrame();
137  aFrame->UpdateData();
138 
139  TTime frameCenterTime;
140 
141  // we read in the frame
142  mReaderHasMoreFrames = mSDIFFileReader.ReadFrame( aFrame->GetFundamental(), aFrame->GetSpectralPeakArray(), aFrame->GetResidualSpec(), frameCenterTime );
143 
144  // we'll update the frame position variable when we actually add these to
145  // the frameVector
146 
147  // as long as there was something to read, add the frame to the temporary buffer
148  if (mReaderHasMoreFrames)
149  {
150  aFrame->SetCenterTime(frameCenterTime);
151 
152  tempFrameBuffer.push_back( aFrame );
153  }
154  else
155  {
156  std::cout << "BufferedSDIFReader: could only load " << counter << " of ";
157  std::cout << argNumberOfBuffers << " frames." << std::endl;
158  delete aFrame;
159  break;
160  }
161  }
162  }
163 
164  // now let's copy the frames from the temporary buffer to the frameBuffer
165  Mutex::ScopedLock lock( dequeMutex );
166  for (unsigned int counter = 0; counter < tempFrameBuffer.size(); counter++)
167  {
168  Frame* aFrame = tempFrameBuffer.at(counter);
169  frameBuffer.push_back( aFrame );
170  }
171 
172  return mReaderHasMoreFrames;
173 }
174 
176 {
177  Mutex::ScopedLock lock( dequeMutex );
178  return frameBuffer.size();
179 }
180 
182 {
183  CLAM_ASSERT(argThread != NULL, "Thread* given to BufferedSDIFFileReader may not be null!");
184 
185  mThreadPtr = argThread;
186  try // Note the exception handling
187  {
188  mThreadPtr->SetThreadCode( mFunctor );
189 
190  mThreadPtr->Start();
191 
192  //mThreadPtr->Stop();
193 
194  }
195  catch( std::exception& e ) // Here we handle standard library exceptions
196  {
197  std::cerr << e.what() << std::endl;
198  std::string msg("BufferedSDIFFileReader: exception when starting thread. SDIFFile will be loaded on main thread.");
199  std::cerr << msg << std::endl;
200  }
201 }
202 
204 {
205  try // Note the exception handling
206  {
207  if ( mThreadPtr != NULL)
208  {
209  mThreadPtr = NULL;
210  }
211  }
212  catch( std::exception& e ) // Here we handle standard library exceptions
213  {
214  std::cerr << e.what() << std::endl;
215  std::string msg("BufferedSDIFFileReader: exception when stopping thread.");
216  std::cerr << msg << std::endl;
217  }
218 }
219 
221 {
222  return mThreadPtr != NULL;
223 }
224 
225 void BufferedSDIFFileReader::Run()
226 {
227  int iterationsSinceLastExecution = 0;
228  while ( mReaderHasMoreFrames && totalNumberOfFramesToLoad <= frameBuffer.size() )
229  {
230  //std::cout << "Thread <" << mThreadPtr << "> this <" << this << "> is loading buffers." << std::endl;
231  mReaderHasMoreFrames = LoadFramesIntoBuffer(mFrameLoadChunkSize);
232  iterationsSinceLastExecution = 0;
233  mThreadPtr->Yield();
234  }
235 }
236 
237 
238 
239 } // END CLAM
240 
241