--- linuxsampler/trunk/src/engines/gig/Engine.cpp 2006/01/14 14:07:47 829 +++ linuxsampler/trunk/src/engines/gig/Engine.cpp 2006/03/25 13:05:59 849 @@ -116,6 +116,7 @@ * Destructor */ Engine::~Engine() { + MidiInputPort::RemoveSysexListener(this); if (pDiskThread) { dmsg(1,("Stopping disk thread...")); pDiskThread->StopThread(); @@ -165,9 +166,14 @@ /** * Reset all voices and disk thread and clear input event queue and all - * control and status variables. This method is not thread safe! + * control and status variables. This method is protected by a mutex. */ void Engine::ResetInternal() { + ResetInternalMutex.Lock(); + + // make sure that the engine does not get any sysex messages + // while it's reseting + bool sysexDisabled = MidiInputPort::RemoveSysexListener(this); ActiveVoiceCount = 0; ActiveVoiceCountMax = 0; @@ -191,6 +197,8 @@ // delete all input events pEventQueue->init(); pSysexBuffer->init(); + if (sysexDisabled) MidiInputPort::AddSysexListener(this); + ResetInternalMutex.Unlock(); } /** @@ -1234,15 +1242,14 @@ } case 7: { // volume //TODO: not sample accurate yet - pEngineChannel->GlobalVolume = (float) itControlChangeEvent->Param.CC.Value / 127.0f * CONFIG_GLOBAL_ATTENUATION; + pEngineChannel->GlobalVolume = VolumeCurve[itControlChangeEvent->Param.CC.Value] * CONFIG_GLOBAL_ATTENUATION; pEngineChannel->bStatusChanged = true; // engine channel status has changed, so set notify flag break; } case 10: { // panpot //TODO: not sample accurate yet - const int pan = (int) itControlChangeEvent->Param.CC.Value - 64; - pEngineChannel->GlobalPanLeft = 1.0f - float(RTMath::Max(pan, 0)) / 63.0f; - pEngineChannel->GlobalPanRight = 1.0f - float(RTMath::Min(pan, 0)) / -64.0f; + pEngineChannel->GlobalPanLeft = PanCurve[128 - itControlChangeEvent->Param.CC.Value]; + pEngineChannel->GlobalPanRight = PanCurve[itControlChangeEvent->Param.CC.Value]; break; } case 64: { // sustain @@ -1350,7 +1357,9 @@ break; } case 123: { // all notes off + #if CONFIG_PROCESS_ALL_NOTES_OFF ReleaseAllVoices(pEngineChannel, itControlChangeEvent); + #endif // CONFIG_PROCESS_ALL_NOTES_OFF break; } case 126: { // mono mode on @@ -1558,8 +1567,50 @@ } String Engine::Version() { - String s = "$Revision: 1.57 $"; + String s = "$Revision: 1.61 $"; return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword } + // static constant initializers + const float* Engine::VolumeCurve(InitVolumeCurve()); + const float* Engine::PanCurve(InitPanCurve()); + const float* Engine::CrossfadeCurve(InitCrossfadeCurve()); + + float* Engine::InitVolumeCurve() { + // line-segment approximation + const float segments[] = { + 0, 0, 2, 0.0046, 16, 0.016, 31, 0.051, 45, 0.115, 54.5, 0.2, + 64.5, 0.39, 74, 0.74, 92, 1.03, 114, 1.94, 119.2, 2.2, 127, 2.2 + }; + return InitCurve(segments); + } + + float* Engine::InitPanCurve() { + // line-segment approximation + const float segments[] = { + 0, 0, 1, 0, + 2, 0.05, 31.5, 0.7, 51, 0.851, 74.5, 1.12, + 127, 1.41, 128, 1.41 + }; + return InitCurve(segments, 129); + } + + float* Engine::InitCrossfadeCurve() { + // line-segment approximation + const float segments[] = { + 0, 0, 1, 0.03, 10, 0.1, 51, 0.58, 127, 1 + }; + return InitCurve(segments); + } + + float* Engine::InitCurve(const float* segments, int size) { + float* y = new float[size]; + for (int x = 0 ; x < size ; x++) { + if (x > segments[2]) segments += 2; + y[x] = segments[1] + (x - segments[0]) * + (segments[3] - segments[1]) / (segments[2] - segments[0]); + } + return y; + } + }} // namespace LinuxSampler::gig