4 |
* * |
* * |
5 |
* Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck * |
6 |
* Copyright (C) 2005-2008 Christian Schoenebeck * |
* Copyright (C) 2005-2008 Christian Schoenebeck * |
7 |
* Copyright (C) 2009-2010 Christian Schoenebeck and Grigor Iliev * |
* Copyright (C) 2009-2013 Christian Schoenebeck and Grigor Iliev * |
8 |
* * |
* * |
9 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
10 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
190 |
// been deleted by the disk thread |
// been deleted by the disk thread |
191 |
if (iPendingStreamDeletions) ProcessPendingStreamDeletions(); |
if (iPendingStreamDeletions) ProcessPendingStreamDeletions(); |
192 |
|
|
193 |
|
// Release the instrument change command. (This has to |
194 |
|
// be done after all voices have been rendered and not |
195 |
|
// in HandleInstrumentChanges, as the RegionsInUse |
196 |
|
// list has been built up by the voice renderers.) |
197 |
|
for (int i = 0; i < engineChannels.size(); i++) { |
198 |
|
EngineChannelBase<V, R, I>* channel = |
199 |
|
static_cast<EngineChannelBase<V, R, I>*>(engineChannels[i]); |
200 |
|
channel->InstrumentChangeCommandReader.Unlock(); |
201 |
|
} |
202 |
FrameTime += Samples; |
FrameTime += Samples; |
203 |
|
|
204 |
EngineDisabled.RttDone(); |
EngineDisabled.RttDone(); |
243 |
} |
} |
244 |
pVoicePool->clear(); |
pVoicePool->clear(); |
245 |
|
|
246 |
|
PostSetMaxVoices(iVoices); |
247 |
ResumeAll(); |
ResumeAll(); |
248 |
} |
} |
249 |
|
|
250 |
|
/** Called after the new max number of voices is set and before resuming the engine. */ |
251 |
|
virtual void PostSetMaxVoices(int iVoices) { } |
252 |
|
|
253 |
virtual uint DiskStreamCount() { return (pDiskThread) ? pDiskThread->GetActiveStreamCount() : 0; } |
virtual uint DiskStreamCount() { return (pDiskThread) ? pDiskThread->GetActiveStreamCount() : 0; } |
254 |
virtual uint DiskStreamCountMax() { return (pDiskThread) ? pDiskThread->ActiveStreamCountMax : 0; } |
virtual uint DiskStreamCountMax() { return (pDiskThread) ? pDiskThread->ActiveStreamCountMax : 0; } |
312 |
// lower minimum release time |
// lower minimum release time |
313 |
const float minReleaseTime = (float) MaxSamplesPerCycle / (float) SampleRate; |
const float minReleaseTime = (float) MaxSamplesPerCycle / (float) SampleRate; |
314 |
for (VoiceIterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) { |
for (VoiceIterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) { |
315 |
iterVoice->pEG1->CalculateFadeOutCoeff(minReleaseTime, SampleRate); |
iterVoice->CalculateFadeOutCoeff(minReleaseTime, SampleRate); |
316 |
} |
} |
317 |
pVoicePool->clear(); |
pVoicePool->clear(); |
318 |
} |
} |
345 |
pDiskThread->StartThread(); |
pDiskThread->StartThread(); |
346 |
dmsg(1,("OK\n")); |
dmsg(1,("OK\n")); |
347 |
|
|
348 |
|
bool printEqInfo = true; |
349 |
for (VoiceIterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) { |
for (VoiceIterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) { |
350 |
if (!iterVoice->pDiskThread) { |
if (!iterVoice->pDiskThread) { |
351 |
dmsg(0,("Engine -> voice::trigger: !pDiskThread\n")); |
dmsg(0,("Engine -> voice::trigger: !pDiskThread\n")); |
352 |
exit(EXIT_FAILURE); |
exit(EXIT_FAILURE); |
353 |
} |
} |
354 |
|
|
355 |
|
iterVoice->CreateEq(); |
356 |
|
|
357 |
|
if(printEqInfo) { |
358 |
|
iterVoice->PrintEqInfo(); |
359 |
|
printEqInfo = false; |
360 |
|
} |
361 |
} |
} |
362 |
pVoicePool->clear(); |
pVoicePool->clear(); |
363 |
|
|
368 |
pDedicatedVoiceChannelLeft = new AudioChannel(0, MaxSamplesPerCycle); |
pDedicatedVoiceChannelLeft = new AudioChannel(0, MaxSamplesPerCycle); |
369 |
pDedicatedVoiceChannelRight = new AudioChannel(1, MaxSamplesPerCycle); |
pDedicatedVoiceChannelRight = new AudioChannel(1, MaxSamplesPerCycle); |
370 |
} |
} |
371 |
|
|
372 |
|
// Implementattion for abstract method derived from Engine. |
373 |
|
virtual void ReconnectAudioOutputDevice() { |
374 |
|
SuspendAll(); |
375 |
|
if (pAudioOutputDevice) Connect(pAudioOutputDevice); |
376 |
|
ResumeAll(); |
377 |
|
} |
378 |
|
|
379 |
/** |
/** |
380 |
* Similar to @c Disable() but this method additionally kills all voices |
* Similar to @c Disable() but this method additionally kills all voices |
429 |
*/ |
*/ |
430 |
virtual void Suspend(RR* pRegion) { |
virtual void Suspend(RR* pRegion) { |
431 |
dmsg(2,("EngineBase: Suspending Region %x ...\n",pRegion)); |
dmsg(2,("EngineBase: Suspending Region %x ...\n",pRegion)); |
432 |
SuspendedRegionsMutex.Lock(); |
{ |
433 |
SuspensionChangeOngoing.Set(true); |
LockGuard lock(SuspendedRegionsMutex); |
434 |
pPendingRegionSuspension = pRegion; |
SuspensionChangeOngoing.Set(true); |
435 |
SuspensionChangeOngoing.WaitAndUnlockIf(true); |
pPendingRegionSuspension = pRegion; |
436 |
SuspendedRegionsMutex.Unlock(); |
SuspensionChangeOngoing.WaitAndUnlockIf(true); |
437 |
|
} |
438 |
dmsg(2,("EngineBase: Region %x suspended.",pRegion)); |
dmsg(2,("EngineBase: Region %x suspended.",pRegion)); |
439 |
} |
} |
440 |
|
|
446 |
*/ |
*/ |
447 |
virtual void Resume(RR* pRegion) { |
virtual void Resume(RR* pRegion) { |
448 |
dmsg(2,("EngineBase: Resuming Region %x ...\n",pRegion)); |
dmsg(2,("EngineBase: Resuming Region %x ...\n",pRegion)); |
449 |
SuspendedRegionsMutex.Lock(); |
{ |
450 |
SuspensionChangeOngoing.Set(true); |
LockGuard lock(SuspendedRegionsMutex); |
451 |
pPendingRegionResumption = pRegion; |
SuspensionChangeOngoing.Set(true); |
452 |
SuspensionChangeOngoing.WaitAndUnlockIf(true); |
pPendingRegionResumption = pRegion; |
453 |
SuspendedRegionsMutex.Unlock(); |
SuspensionChangeOngoing.WaitAndUnlockIf(true); |
454 |
|
} |
455 |
dmsg(2,("EngineBase: Region %x resumed.\n",pRegion)); |
dmsg(2,("EngineBase: Region %x resumed.\n",pRegion)); |
456 |
} |
} |
457 |
|
|
802 |
//TODO: this is a lazy solution ATM and not safe in case somebody is currently editing the instrument we're currently switching to (we should store all suspended regions on instrument manager side and when switching to another instrument copy that list to the engine's local list of suspensions |
//TODO: this is a lazy solution ATM and not safe in case somebody is currently editing the instrument we're currently switching to (we should store all suspended regions on instrument manager side and when switching to another instrument copy that list to the engine's local list of suspensions |
803 |
ResetSuspendedRegions(); |
ResetSuspendedRegions(); |
804 |
} |
} |
|
|
|
|
for (int i = 0; i < engineChannels.size(); i++) { |
|
|
EngineChannelBase<V, R, I>* channel = |
|
|
static_cast<EngineChannelBase<V, R, I>*>(engineChannels[i]); |
|
|
channel->InstrumentChangeCommandReader.Unlock(); |
|
|
} |
|
805 |
} |
} |
806 |
|
|
807 |
/** |
/** |
977 |
} |
} |
978 |
case 10: { // panpot |
case 10: { // panpot |
979 |
//TODO: not sample accurate yet |
//TODO: not sample accurate yet |
|
pChannel->GlobalPanLeft = PanCurve[128 - itControlChangeEvent->Param.CC.Value]; |
|
|
pChannel->GlobalPanRight = PanCurve[itControlChangeEvent->Param.CC.Value]; |
|
980 |
pChannel->iLastPanRequest = itControlChangeEvent->Param.CC.Value; |
pChannel->iLastPanRequest = itControlChangeEvent->Param.CC.Value; |
981 |
break; |
break; |
982 |
} |
} |
1327 |
* control and status variables. This method is protected by a mutex. |
* control and status variables. This method is protected by a mutex. |
1328 |
*/ |
*/ |
1329 |
virtual void ResetInternal() { |
virtual void ResetInternal() { |
1330 |
ResetInternalMutex.Lock(); |
LockGuard lock(ResetInternalMutex); |
1331 |
|
|
1332 |
// make sure that the engine does not get any sysex messages |
// make sure that the engine does not get any sysex messages |
1333 |
// while it's reseting |
// while it's reseting |
1356 |
pEventQueue->init(); |
pEventQueue->init(); |
1357 |
pSysexBuffer->init(); |
pSysexBuffer->init(); |
1358 |
if (sysexDisabled) MidiInputPort::AddSysexListener(this); |
if (sysexDisabled) MidiInputPort::AddSysexListener(this); |
|
ResetInternalMutex.Unlock(); |
|
1359 |
} |
} |
1360 |
|
|
1361 |
/** |
/** |