--- linuxsampler/trunk/src/engines/FxSend.cpp 2006/12/27 16:17:08 1001 +++ linuxsampler/trunk/src/engines/FxSend.cpp 2010/08/10 12:05:19 2114 @@ -3,7 +3,7 @@ * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * - * Copyright (C) 2005, 2006 Christian Schoenebeck * + * Copyright (C) 2005 - 2010 Christian Schoenebeck * * * * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -23,20 +23,19 @@ #include "FxSend.h" +#include "../common/global_private.h" #include "../drivers/audio/AudioOutputDevice.h" +#include "../common/RTMath.h" #include -namespace LinuxSampler { +#define DEFAULT_FX_SEND_LEVEL 0.0f - /* - FIXME: we create fx send indeces globally for now, although we might - want them to be an individual sequence per sampler channel, beside that - we don't handle the cases yet where __indexer overflows back to 0 - */ - static uint __indexer = 0; +namespace LinuxSampler { - FxSend::FxSend(EngineChannel* pEngineChannel, uint8_t MidiCtrl, String Name) { + FxSend::FxSend(EngineChannel* pEngineChannel, uint8_t MidiCtrl, String Name) throw (Exception) + : iMasterEffectChain(-1), iMasterEffect(-1), bInfoChanged(false) + { this->pEngineChannel = pEngineChannel; AudioOutputDevice* pDevice = pEngineChannel->GetAudioOutputDevice(); const int iChanOffset = (pDevice) ? pDevice->ChannelCount() - pEngineChannel->Channels() : 0; @@ -44,11 +43,64 @@ const int iDestination = iChanOffset + i; Routing.push_back(iDestination); } - MidiFxSendController = MidiCtrl; + SetMidiController(MidiCtrl); sName = Name; - iId = __indexer; - __indexer++; - fLevel = 0.3f; // default FX send level + + // create an EngineChannel unique ID for this FxSend instance + if (!pEngineChannel->GetFxSendCount()) iId = 0; + else { + // get the highest existing map ID + uint highestIndex = 0; + for (uint i = 0; i < pEngineChannel->GetFxSendCount(); i++) + highestIndex = RTMath::Max(highestIndex, pEngineChannel->GetFxSend(i)->Id()); + // check if we reached the index limit + if (highestIndex + 1 < highestIndex) { + // search for an unoccupied map ID starting from 0 + for (uint i = 0; i < highestIndex; i++) { + bool bOccupied = false; + for (uint j = 0; j < pEngineChannel->GetFxSendCount(); j++) { + if (pEngineChannel->GetFxSend(j)->Id() == i) { + bOccupied = true; + break; + } + } + if (!bOccupied) { + iId = i; + goto __done; + } + } + throw Exception("Internal error: could not find unoccupied FxSend ID."); + } + iId = highestIndex + 1; + } + __done: + + fLevel = DEFAULT_FX_SEND_LEVEL; + } + + int FxSend::DestinationMasterEffectChain() const { + return iMasterEffectChain; + } + + int FxSend::DestinationMasterEffect() const { + return iMasterEffect; + } + + void FxSend::SetDestinationMasterEffect(int iChain, int iEffect) throw (Exception) { + AudioOutputDevice* pDevice = pEngineChannel->GetAudioOutputDevice(); + if (iChain < 0 || iChain >= pDevice->MasterEffectChainCount()) + throw Exception( + "Could not assign FX Send to master effect chain " + + ToString(iChain) + ": effect chain doesn't exist." + ); + if (iEffect < 0 || iEffect >= pDevice->MasterEffectChain(iChain)->EffectCount()) + throw Exception( + "Could not assign FX Send to master effect " + + ToString(iEffect) + " of effect chain " + ToString(iChain) + + ": effect doesn't exist." + ); + iMasterEffectChain = iChain; + iMasterEffect = iEffect; } int FxSend::DestinationChannel(int SrcChan) { @@ -94,11 +146,18 @@ } void FxSend::SetLevel(float f) { + if(fLevel == f) return; fLevel = f; + SetInfoChanged(true); } void FxSend::SetLevel(uint8_t iMidiValue) { fLevel = float(iMidiValue & 0x7f) / 127.0f; + SetInfoChanged(true); + } + + void FxSend::Reset() { + SetLevel(DEFAULT_FX_SEND_LEVEL); } uint8_t FxSend::MidiController() { @@ -106,8 +165,8 @@ } void FxSend::SetMidiController(uint8_t MidiCtrl) throw (Exception) { - if (MidiCtrl & 0x7f) - throw Exception("Invalid MIDI controller"); + if (MidiCtrl >> 7) + throw Exception("Invalid MIDI controller " + ToString((int)MidiCtrl)); MidiFxSendController = MidiCtrl; } @@ -115,8 +174,20 @@ return sName; } + void FxSend::SetName(String Name) { + sName = Name; + } + uint FxSend::Id() { return iId; } + void FxSend::SetInfoChanged(bool b) { + bInfoChanged = b; + } + + bool FxSend::IsInfoChanged() { + return bInfoChanged; + } + } // namespace LinuxSampler