--- linuxsampler/trunk/src/Sampler.cpp 2007/12/04 18:09:26 1541 +++ linuxsampler/trunk/src/Sampler.cpp 2008/09/06 16:44:42 1765 @@ -3,7 +3,7 @@ * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * - * Copyright (C) 2005 - 2007 Christian Schoenebeck * + * Copyright (C) 2005 - 2008 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 * @@ -32,6 +32,8 @@ #include "drivers/audio/AudioOutputDeviceFactory.h" #include "drivers/midi/MidiInputDeviceFactory.h" #include "drivers/midi/MidiInstrumentMapper.h" +#include "common/Features.h" +#include "network/lscpserver.h" namespace LinuxSampler { @@ -76,12 +78,13 @@ } } + fireEngineToBeChanged(); + // create new engine channel EngineChannel* pNewEngineChannel = EngineChannelFactory::Create(EngineType); if (!pNewEngineChannel) throw Exception("Unknown engine type"); - //FIXME: hack to allow fast retrieval of engine channel's sampler channel index - pNewEngineChannel->iSamplerChannelIndex = Index(); + pNewEngineChannel->SetSamplerChannel(this); // dereference midi input port. MidiInputPort* pMidiInputPort = __GetMidiInputDevicePort(GetMidiInputPort()); @@ -213,6 +216,10 @@ throw Exception("Internal error: SamplerChannel index not found"); } + Sampler* SamplerChannel::GetSampler() { + return pSampler; + } + void SamplerChannel::AddEngineChangeListener(EngineChangeListener* l) { llEngineChangeListeners.AddListener(l); } @@ -225,6 +232,12 @@ llEngineChangeListeners.RemoveAllListeners(); } + void SamplerChannel::fireEngineToBeChanged() { + for (int i = 0; i < llEngineChangeListeners.GetListenerCount(); i++) { + llEngineChangeListeners.GetListener(i)->EngineToBeChanged(Index()); + } + } + void SamplerChannel::fireEngineChanged() { for (int i = 0; i < llEngineChangeListeners.GetListenerCount(); i++) { llEngineChangeListeners.GetListener(i)->EngineChanged(Index()); @@ -270,6 +283,18 @@ } } + void Sampler::fireChannelAdded(SamplerChannel* pChannel) { + for (int i = 0; i < llChannelCountListeners.GetListenerCount(); i++) { + llChannelCountListeners.GetListener(i)->ChannelAdded(pChannel); + } + } + + void Sampler::fireChannelToBeRemoved(SamplerChannel* pChannel) { + for (int i = 0; i < llChannelCountListeners.GetListenerCount(); i++) { + llChannelCountListeners.GetListener(i)->ChannelToBeRemoved(pChannel); + } + } + void Sampler::AddAudioDeviceCountListener(AudioDeviceCountListener* l) { llAudioDeviceCountListeners.AddListener(l); } @@ -298,6 +323,18 @@ } } + void Sampler::fireMidiDeviceToBeDestroyed(MidiInputDevice* pDevice) { + for (int i = 0; i < llMidiDeviceCountListeners.GetListenerCount(); i++) { + llMidiDeviceCountListeners.GetListener(i)->MidiDeviceToBeDestroyed(pDevice); + } + } + + void Sampler::fireMidiDeviceCreated(MidiInputDevice* pDevice) { + for (int i = 0; i < llMidiDeviceCountListeners.GetListenerCount(); i++) { + llMidiDeviceCountListeners.GetListener(i)->MidiDeviceCreated(pDevice); + } + } + void Sampler::AddVoiceCountListener(VoiceCountListener* l) { llVoiceCountListeners.AddListener(l); } @@ -382,6 +419,10 @@ } } + void Sampler::EventHandler::EngineToBeChanged(int ChannelId) { + // nothing to do here + } + void Sampler::EventHandler::EngineChanged(int ChannelId) { EngineChannel* engineChannel = pSampler->GetSamplerChannel(ChannelId)->GetEngineChannel(); if(engineChannel == NULL) return; @@ -398,6 +439,7 @@ if (!mSamplerChannels.size()) { SamplerChannel* pChannel = new SamplerChannel(this); mSamplerChannels[0] = pChannel; + fireChannelAdded(pChannel); fireChannelCountChanged(1); pChannel->AddEngineChangeListener(&eventHandler); return pChannel; @@ -414,6 +456,7 @@ // we found an unused index, so insert the new channel there SamplerChannel* pChannel = new SamplerChannel(this); mSamplerChannels[i] = pChannel; + fireChannelAdded(pChannel); fireChannelCountChanged(SamplerChannels()); pChannel->AddEngineChangeListener(&eventHandler); return pChannel; @@ -424,6 +467,7 @@ // we have not reached the index limit so we just add the channel past the highest index SamplerChannel* pChannel = new SamplerChannel(this); mSamplerChannels[lastIndex + 1] = pChannel; + fireChannelAdded(pChannel); fireChannelCountChanged(SamplerChannels()); pChannel->AddEngineChangeListener(&eventHandler); return pChannel; @@ -441,6 +485,7 @@ SamplerChannelMap::iterator iterChan = mSamplerChannels.begin(); for (; iterChan != mSamplerChannels.end(); iterChan++) { if (iterChan->second == pSamplerChannel) { + fireChannelToBeRemoved(pSamplerChannel); pSamplerChannel->RemoveAllEngineChangeListeners(); mSamplerChannels.erase(iterChan); delete pSamplerChannel; @@ -531,6 +576,8 @@ for (uint i = 0; i < SamplerChannels(); i++) if (GetSamplerChannel(i)->GetMidiInputDevice() == pDevice) throw Exception("Sampler channel " + ToString(i) + " is still connected to the midi input device."); + fireMidiDeviceToBeDestroyed(pDevice); + // disable device pDevice->StopListen(); @@ -558,6 +605,7 @@ } } + fireMidiDeviceCreated(pDevice); fireMidiDeviceCountChanged(MidiInputDevices()); return pDevice; } @@ -637,4 +685,37 @@ InstrumentEditorFactory::ClosePlugins(); } + bool Sampler::EnableDenormalsAreZeroMode() { + Features::detect(); + return Features::enableDenormalsAreZeroMode(); + } + + void Sampler::fireStatistics() { + static const LSCPEvent::event_t eventsArr[] = { + LSCPEvent::event_voice_count, LSCPEvent::event_stream_count, + LSCPEvent::event_buffer_fill, LSCPEvent::event_total_voice_count + }; + static const std::list events(eventsArr, eventsArr + 4); + + if (LSCPServer::EventSubscribers(events)) + { + LSCPServer::LockRTNotify(); + std::map channels = GetSamplerChannels(); + std::map::iterator iter = channels.begin(); + for (; iter != channels.end(); iter++) { + SamplerChannel* pSamplerChannel = iter->second; + EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel(); + if (!pEngineChannel) continue; + Engine* pEngine = pEngineChannel->GetEngine(); + if (!pEngine) continue; + fireVoiceCountChanged(iter->first, pEngineChannel->GetVoiceCount()); + fireStreamCountChanged(iter->first, pEngineChannel->GetDiskStreamCount()); + fireBufferFillChanged(iter->first, pEngine->DiskStreamBufferFillPercentage()); + fireTotalStreamCountChanged(GetDiskStreamCount()); + fireTotalVoiceCountChanged(GetVoiceCount()); + } + LSCPServer::UnlockRTNotify(); + } + } + } // namespace LinuxSampler