166 |
} |
} |
167 |
|
|
168 |
/** |
/** |
169 |
|
* Give back an instrument. This should be used instead of |
170 |
|
* HandBack if there are some dimension regions that are still in |
171 |
|
* use. (When an instrument is changed, the voices currently |
172 |
|
* playing is allowed to keep playing with the old instrument |
173 |
|
* until note off arrives. New notes will use the new instrument.) |
174 |
|
*/ |
175 |
|
void InstrumentResourceManager::HandBackInstrument(::gig::Instrument* pResource, InstrumentConsumer* pConsumer, |
176 |
|
::gig::DimensionRegion** dimRegionsInUse) { |
177 |
|
DimRegInfoMutex.Lock(); |
178 |
|
for (int i = 0 ; dimRegionsInUse[i] ; i++) { |
179 |
|
DimRegInfo[dimRegionsInUse[i]].refCount++; |
180 |
|
SampleRefCount[dimRegionsInUse[i]->pSample]++; |
181 |
|
} |
182 |
|
HandBack(pResource, pConsumer, true); |
183 |
|
DimRegInfoMutex.Unlock(); |
184 |
|
} |
185 |
|
|
186 |
|
/** |
187 |
|
* Give back a dimension region that belongs to an instrument that |
188 |
|
* was previously handed back. |
189 |
|
*/ |
190 |
|
void InstrumentResourceManager::HandBackDimReg(::gig::DimensionRegion* pDimReg) { |
191 |
|
DimRegInfoMutex.Lock(); |
192 |
|
dimreg_info_t& dimRegInfo = DimRegInfo[pDimReg]; |
193 |
|
int dimRegRefCount = --dimRegInfo.refCount; |
194 |
|
int sampleRefCount = --SampleRefCount[pDimReg->pSample]; |
195 |
|
if (dimRegRefCount == 0) { |
196 |
|
::gig::File* gig = dimRegInfo.file; |
197 |
|
::RIFF::File* riff = dimRegInfo.riff; |
198 |
|
DimRegInfo.erase(pDimReg); |
199 |
|
// TODO: we could delete Region and Instrument here if |
200 |
|
// they have become unused |
201 |
|
|
202 |
|
if (sampleRefCount == 0) { |
203 |
|
SampleRefCount.erase(pDimReg->pSample); |
204 |
|
|
205 |
|
if (gig) { |
206 |
|
gig->DeleteSample(pDimReg->pSample); |
207 |
|
if (!gig->GetFirstSample()) { |
208 |
|
dmsg(2,("No more samples in use - freeing gig\n")); |
209 |
|
delete gig; |
210 |
|
delete riff; |
211 |
|
} |
212 |
|
} |
213 |
|
} |
214 |
|
} |
215 |
|
DimRegInfoMutex.Unlock(); |
216 |
|
} |
217 |
|
|
218 |
|
/** |
219 |
* Caches a certain size at the beginning of the given sample in RAM. If the |
* Caches a certain size at the beginning of the given sample in RAM. If the |
220 |
* sample is very short, the whole sample will be loaded into RAM and thus |
* sample is very short, the whole sample will be loaded into RAM and thus |
221 |
* no disk streaming is needed for this sample. Caching an initial part of |
* no disk streaming is needed for this sample. Caching an initial part of |
270 |
|
|
271 |
void InstrumentResourceManager::GigResourceManager::Destroy(::gig::File* pResource, void* pArg) { |
void InstrumentResourceManager::GigResourceManager::Destroy(::gig::File* pResource, void* pArg) { |
272 |
dmsg(1,("Freeing gig file from memory...")); |
dmsg(1,("Freeing gig file from memory...")); |
273 |
delete pResource; |
|
274 |
delete (::RIFF::File*) pArg; |
// Delete as much as possible of the gig file. Some of the |
275 |
|
// dimension regions and samples may still be in use - these |
276 |
|
// will be deleted later by the HandBackDimReg function. |
277 |
|
bool deleteFile = true; |
278 |
|
::gig::Instrument* nextInstrument; |
279 |
|
for (::gig::Instrument* instrument = pResource->GetFirstInstrument() ; |
280 |
|
instrument ; |
281 |
|
instrument = nextInstrument) { |
282 |
|
nextInstrument = pResource->GetNextInstrument(); |
283 |
|
bool deleteInstrument = true; |
284 |
|
::gig::Region* nextRegion; |
285 |
|
for (::gig::Region *region = instrument->GetFirstRegion() ; |
286 |
|
region ; |
287 |
|
region = nextRegion) { |
288 |
|
nextRegion = instrument->GetNextRegion(); |
289 |
|
bool deleteRegion = true; |
290 |
|
for (int i = 0 ; i < region->DimensionRegions ; i++) |
291 |
|
{ |
292 |
|
::gig::DimensionRegion *d = region->pDimensionRegions[i]; |
293 |
|
std::map< ::gig::DimensionRegion*, dimreg_info_t>::iterator iter = parent->DimRegInfo.find(d); |
294 |
|
if (iter != parent->DimRegInfo.end()) { |
295 |
|
dimreg_info_t& dimRegInfo = (*iter).second; |
296 |
|
dimRegInfo.file = pResource; |
297 |
|
dimRegInfo.riff = (::RIFF::File*)pArg; |
298 |
|
deleteFile = deleteInstrument = deleteRegion = false; |
299 |
|
} |
300 |
|
} |
301 |
|
if (deleteRegion) instrument->DeleteRegion(region); |
302 |
|
} |
303 |
|
if (deleteInstrument) pResource->DeleteInstrument(instrument); |
304 |
|
} |
305 |
|
if (deleteFile) { |
306 |
|
delete pResource; |
307 |
|
delete (::RIFF::File*) pArg; |
308 |
|
} else { |
309 |
|
dmsg(2,("keeping some samples that are in use...")); |
310 |
|
::gig::Sample* nextSample; |
311 |
|
for (::gig::Sample* sample = pResource->GetFirstSample() ; |
312 |
|
sample ; |
313 |
|
sample = nextSample) { |
314 |
|
nextSample = pResource->GetNextSample(); |
315 |
|
if (parent->SampleRefCount.find(sample) == parent->SampleRefCount.end()) { |
316 |
|
pResource->DeleteSample(sample); |
317 |
|
} |
318 |
|
} |
319 |
|
} |
320 |
dmsg(1,("OK\n")); |
dmsg(1,("OK\n")); |
321 |
} |
} |
322 |
|
|