Skip to content

Commit 74c3d05

Browse files
authored
PoC: Enhance/choices param (#108)
* Add ChoiceT parameter type * Add `select` control to `BufStatsClient` to road test `ChoicesParam` * Choices params: Don't use a set because it breaks ordering * SpectralShape: Add select param
1 parent a0627dc commit 74c3d05

File tree

3 files changed

+81
-11
lines changed

3 files changed

+81
-11
lines changed

include/clients/common/ParameterTypes.hpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ under the European Union’s Horizon 2020 research and innovation programme
1515
#include "Result.hpp"
1616
#include "../../data/FluidIndex.hpp"
1717
#include <memory>
18+
#include <bitset>
1819
#include <string>
1920
#include <tuple>
2021
#include <utility>
2122
#include <vector>
22-
23+
#include <set>
2324

2425
namespace fluid {
2526
namespace client {
@@ -126,6 +127,37 @@ struct EnumT : ParamTypeBase
126127
};
127128

128129

130+
struct ChoicesT: ParamTypeBase
131+
{
132+
using type = std::bitset<16>;
133+
134+
135+
template <index... N>
136+
constexpr ChoicesT(const char* name, const char* displayName,
137+
const char (&... string)[N])
138+
: ParamTypeBase(name, displayName), strings{string...}, fixedSize(1),
139+
numOptions(sizeof...(N)), defaultValue((1 << numOptions) - 1)
140+
{
141+
static_assert(sizeof...(N) > 0, "Fluid Param: No choice strings supplied!");
142+
static_assert(sizeof...(N) <= 16,
143+
"Fluid Param: : Maximum 16 things in an choice param");
144+
}
145+
const char* strings[16]; // unilateral descision klaxon: if you have more than
146+
// 16 things in an Enum, you need to rethink
147+
const index fixedSize;
148+
const index numOptions;
149+
const type defaultValue;
150+
151+
index lookup(std::string name)
152+
{
153+
static std::vector<std::string> lookupTable(strings, strings + numOptions);
154+
155+
auto pos = std::find(lookupTable.begin(), lookupTable.end(), name);
156+
return pos != lookupTable.end() ? std::distance(lookupTable.begin(), pos)
157+
: -1;
158+
}
159+
};
160+
129161
// can I avoid making this constexpr and thus using std::string? Let's see;
130162
struct StringT : ParamTypeBase
131163
{
@@ -492,6 +524,15 @@ EnumParam(const char* name, const char* displayName,
492524
std::make_tuple(EnumT::EnumConstraint()), IsFixed{}};
493525
}
494526

527+
template <typename IsFixed = Fixed<false>, size_t... N>
528+
constexpr ParamSpec<ChoicesT, IsFixed>
529+
ChoicesParam(const char* name, const char* displayName, const char (&... strings)[N])
530+
{
531+
return {ChoicesT(name, displayName, strings...), std::make_tuple(),
532+
Fixed<false>{}};
533+
}
534+
535+
495536
template <typename IsFixed = Fixed<false>, size_t N, typename... Constraints>
496537
constexpr ParamSpec<FloatArrayT, IsFixed, Constraints...>
497538
FloatArrayParam(const char* name, const char* displayName,

include/clients/nrt/BufStatsClient.hpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ enum BufferStatsParamIndex {
2828
kStartChan,
2929
kNumChans,
3030
kStats,
31+
kSelect,
3132
kNumDerivatives,
3233
kLow,
3334
kMiddle,
@@ -43,6 +44,7 @@ constexpr auto BufStatsParams = defineParameters(
4344
LongParam("startChan", "Start Channel", 0, Min(0)),
4445
LongParam("numChans", "Number of Channels", -1),
4546
BufferParam("stats", "Stats Buffer"),
47+
ChoicesParam("select","Selection of Statistics","mean","std","skew","kurtosis","low","mid","high"),
4648
LongParam("numDerivs", "Number of Derivatives", 0, Min(0), Max(2)),
4749
FloatParam("low", "Low Percentile", 0, Min(0), Max(100),
4850
UpperLimit<kMiddle>()),
@@ -124,7 +126,9 @@ class BufferStatsClient : public FluidBaseClient,
124126
if (numFrames <= get<kNumDerivatives>())
125127
return {Result::Status::kError, "Not enough frames"};
126128

127-
index outputSize = processor.numStats() * (get<kNumDerivatives>() + 1);
129+
index outputSize = get<kSelect>().count() * (get<kNumDerivatives>() + 1);
130+
index processorOutputSize = processor.numStats() * (get<kNumDerivatives>() + 1);
131+
128132
Result resizeResult =
129133
dest.resize(outputSize, numChannels, source.sampleRate());
130134

@@ -159,14 +163,27 @@ class BufferStatsClient : public FluidBaseClient,
159163
}
160164
}
161165
FluidTensor<double, 2> tmp(numChannels, numFrames);
162-
FluidTensor<double, 2> result(numChannels, outputSize);
166+
FluidTensor<double, 2> result(numChannels, processorOutputSize);
163167
for (int i = 0; i < numChannels; i++)
164168
{
165169
tmp.row(i) <<=
166170
source.samps(get<kOffset>(), numFrames, get<kStartChan>() + i);
167171
}
168172
processor.process(tmp, result, get<kOutliersCutoff>(), weights);
169-
for (int i = 0; i < numChannels; i++) { dest.samps(i) <<= result.row(i); }
173+
174+
auto selection = get<kSelect>();
175+
176+
for (index i = 0; i < numChannels; ++i)
177+
{
178+
auto outputChannel = dest.samps(i);
179+
auto resultChannel = result.row(i);
180+
for(index j = 0, k = 0; j < processorOutputSize; ++j)
181+
{
182+
if(selection[j % 7])
183+
outputChannel(k++) = resultChannel(j);
184+
}
185+
}
186+
170187
return processingResult;
171188
}
172189
};

include/clients/rt/SpectralShapeClient.hpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace spectralshape {
2727
using algorithm::SpectralShape;
2828

2929
enum SpectralShapeParamIndex {
30+
kSelect,
3031
kMinFreq,
3132
kMaxFreq,
3233
kRollOffPercent,
@@ -37,6 +38,7 @@ enum SpectralShapeParamIndex {
3738
};
3839

3940
constexpr auto SpectralShapeParams = defineParameters(
41+
ChoicesParam("select","Selection of Features","centroid","spread","skew","kurtosis","rolloff","flatness","crest"),
4042
FloatParam("minFreq", "Low Frequency Bound", 0, Min(0)),
4143
FloatParam("maxFreq", "High Frequency Bound", -1, Min(-1)),
4244
FloatParam("rolloffPercent", "Rolloff Percent", 95, Min(0), Max(100)),
@@ -70,12 +72,13 @@ class SpectralShapeClient : public FluidBaseClient,
7072
}
7173

7274
SpectralShapeClient(ParamSetViewType& p)
73-
: mParams(p), mSTFTBufferedProcess(get<kMaxFFTSize>(), 1, 0)
75+
: mParams(p), mSTFTBufferedProcess(get<kMaxFFTSize>(), 1, 0),
76+
mMaxOutputSize{asSigned(get<kSelect>().count())}
7477
{
7578
audioChannelsIn(1);
76-
controlChannelsOut({1,7});
79+
controlChannelsOut({1,mMaxOutputSize});
7780
setInputLabels({"audio input"});
78-
setOutputLabels({"centroid, spread, skewness, kurtosis, rolloff, flatness, crest factor"});
81+
setOutputLabels({"spectral features"});
7982
mDescriptors = FluidTensor<double, 1>(7);
8083
}
8184

@@ -101,10 +104,17 @@ class SpectralShapeClient : public FluidBaseClient,
101104
get<kMaxFreq>(), get<kRollOffPercent>(), get<kFreqUnits>() == 1,
102105
get<kAmpMeasure>() == 1);
103106
});
104-
105-
// for (int i = 0; i < 7; ++i)
106-
// output[asUnsigned(i)](0) = static_cast<T>(mDescriptors(i));
107-
output[0] <<= mDescriptors;
107+
108+
auto selection = get<kSelect>();
109+
index numSelected = asSigned(selection.count());
110+
index numOuts = std::min<index>(mMaxOutputSize,numSelected);
111+
for(index i = 0, j = 0 ; i < 7 && j < numOuts; ++i)
112+
{
113+
if(selection[asUnsigned(i)]) output[0](j++) = static_cast<T>(mDescriptors(i));
114+
}
115+
if(mMaxOutputSize > numSelected)
116+
for(index i = (mMaxOutputSize - numSelected); i < mMaxOutputSize; ++i)
117+
output[0](i) = 0;
108118
}
109119

110120
index latency() { return get<kFFT>().winSize(); }
@@ -123,6 +133,8 @@ class SpectralShapeClient : public FluidBaseClient,
123133
SpectralShape mAlgorithm;
124134
FluidTensor<double, 1> mMagnitude;
125135
FluidTensor<double, 1> mDescriptors;
136+
137+
index mMaxOutputSize;
126138
};
127139
} // namespace spectralshape
128140

0 commit comments

Comments
 (0)