/usr/include/CLAM/PortMonitor.hxx is in libclam-dev 1.4.0-5build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | #ifndef __PortMonitor_hxx__
#define __PortMonitor_hxx__
#include "Processing.hxx"
#include "ProcessingConfig.hxx"
#include "Mutex.hxx"
// Temporary until concrete classes will be separated
#include "SpectralPeakArray.hxx"
#include "Spectrum.hxx"
#include "Fundamental.hxx"
#include "InPort.hxx"
#include "Audio.hxx"
#include "AudioInPort.hxx"
// sigslot
#include "Signalv0.hxx"
#include "Slotv0.hxx"
namespace CLAM
{
/**
* A processing that allows other (GUI) thread to monitor a port in a thread safe way.
* Subclass specializations of this template in order to use it.
* @code
* class SpectrumPortMonitor : public CLAM::PortMonitor<CLAM::Spectrum>
* {
* public:
* const char * GetClassName() const {return "SpectrumPortMonitor";}
* };
* @endcode
*
* In order to get data from a GUI thread you should use a PortMonitor::DataLocker
* @code
*
* // Supose 'monitor' being a SpectrumPortMonitor reference.
* ...
* {
* const Spectrum & spectrum = monitor.FreezeAndGetData();
* // The monitor won't overwrite the current copy until Release.
*
* // Do what ever with the object
*
* visualize(spectrum);
*
* monitor.UnfreezeData();
* // After unfreezing, 'spectrum' is not safe to use.
* // and the monitor will be allowed to swap copies
* }
* @endcode
*/
template <typename TheDataType, typename ThePortType=InPort<TheDataType> >
class PortMonitor : public Processing
{
public:
typedef TheDataType DataType;
typedef ThePortType PortType;
inline PortMonitor(const Config & cfg= Config() );
inline virtual ~PortMonitor();
inline bool Do();
const char * GetClassName() const {return "PortMonitor";}
inline const DataType & FreezeAndGetData();
inline void UnfreezeData();
void AttachStartSlot(SigSlot::Slotv0& slot) {mSigStart.Connect(slot);}
void AttachStopSlot(SigSlot::Slotv0& slot) { mSigStop.Connect(slot);}
void AttachSlotNewData(SigSlot::Slotv0& slot) { mSigNewData.Connect(slot);}
protected:
bool ConcreteStart() { mSigStart.Emit(); return true;}
bool ConcreteStop() { mSigStop.Emit(); return true;}
private:
PortType mInput;
DataType mData[2];
TryMutex mSwitchMutex;
unsigned mWhichDataToRead;
SigSlot::Signalv0 mSigStart;
SigSlot::Signalv0 mSigStop;
SigSlot::Signalv0 mSigNewData;
};
namespace Hidden
{
template <typename T>
static void initData(DynamicType * selector, T & data)
{
data.AddAll();
data.UpdateData();
}
template <typename T>
static void initData(void * selector, T & data)
{
}
}
template <typename PortDataType, typename PortType>
PortMonitor<PortDataType,PortType>::PortMonitor(const Config& cfg)
: mInput("Input", this)
, mWhichDataToRead(0)
{
Configure(cfg);
Hidden::initData(&mData[0],mData[0]);
Hidden::initData(&mData[1],mData[1]);
}
template <typename PortDataType, typename PortType>
PortMonitor<PortDataType,PortType>::~PortMonitor()
{
}
template <typename PortDataType, typename PortType>
const typename PortMonitor<PortDataType,PortType>::DataType & PortMonitor<PortDataType,PortType>::FreezeAndGetData()
{
Hidden::LockOps<TryMutex>::Lock(mSwitchMutex);
return mData[mWhichDataToRead];
}
template <typename PortDataType, typename PortType>
void PortMonitor<PortDataType,PortType>::UnfreezeData()
{
Hidden::LockOps<TryMutex>::Unlock(mSwitchMutex);
}
template <typename PortDataType, typename PortType>
bool PortMonitor<PortDataType,PortType>::Do()
{
if(!AbleToExecute()) return true;
unsigned whichDataToWrite = mWhichDataToRead?0:1;
mData[whichDataToWrite] = mInput.GetData();
mSigNewData.Emit();
{
TryMutex::ScopedTryLock lock(mSwitchMutex,true);
if (lock.Locked())
mWhichDataToRead = whichDataToWrite;
}
mInput.Consume();
return true;
}
class PeaksPortMonitor : public PortMonitor <SpectralPeakArray>
{
public:
const char * GetClassName() const {return "PeaksPortMonitor";}
};
class SinTracksPortMonitor : public PortMonitor<SpectralPeakArray>
{
public:
const char * GetClassName() const {return "SinTracksPortMonitor";}
};
class SpectrumPortMonitor : public PortMonitor <Spectrum>
{
public:
const char * GetClassName() const {return "SpectrumPortMonitor";}
};
class SpecgramPortMonitor : public PortMonitor<Spectrum>
{
public:
const char * GetClassName() const {return "SpecgramPortMonitor";}
};
class FundamentalPortMonitor : public PortMonitor <Fundamental>
{
public:
const char * GetClassName() const {return "FundamentalPortMonitor";}
};
class FundTrackPortMonitor : public PortMonitor<Fundamental>
{
public:
const char * GetClassName() const {return "FundTrackPortMonitor";}
};
template <>
bool PortMonitor<Audio,AudioInPort>::Do();
template <>
PortMonitor<Audio,AudioInPort>::PortMonitor(const Config& cfg);
class AudioPortMonitor : public PortMonitor <Audio,AudioInPort>
{
public:
const char * GetClassName() const {return "AudioPortMonitor";}
};
class AudioBuffPortMonitor : public PortMonitor<Audio,AudioInPort>
{
public:
const char * GetClassName() const {return "AudioBuffPortMonitor";}
};
}
#endif
|