New OSC Filter attribute of source

Adding attribute for setting filter:  set filter by name, set method by name, set first argument value
This commit is contained in:
Bruno Herbelin
2024-02-17 23:42:03 +01:00
parent 47ff1a2dd8
commit 8e28eba959
8 changed files with 555 additions and 39 deletions

View File

@@ -33,6 +33,7 @@
#include "Mixer.h"
#include "Source.h"
#include "TextSource.h"
#include "CloneSource.h"
#include "SourceCallback.h"
#include "ImageProcessingShader.h"
#include "ActionManager.h"
@@ -252,24 +253,28 @@ std::string Control::RequestListener::FullMessage( const osc::ReceivedMessage& m
osc::ReceivedMessage::const_iterator arg = m.ArgumentsBegin();
while (arg != m.ArgumentsEnd()) {
if( arg->IsBool() ){
bool a = (arg++)->AsBoolUnchecked();
bool a = (arg)->AsBoolUnchecked();
message << (a ? "T" : "F");
}
else if( arg->IsInt32() ){
int a = (arg++)->AsInt32Unchecked();
int a = (arg)->AsInt32Unchecked();
message << "i";
arguments << " " << a;
}
else if( arg->IsFloat() ){
float a = (arg++)->AsFloatUnchecked();
float a = (arg)->AsFloatUnchecked();
message << "f";
arguments << " " << std::fixed << std::setprecision(2) << a;
}
else if( arg->IsString() ){
const char *a = (arg++)->AsStringUnchecked();
const char *a = (arg)->AsStringUnchecked();
message << "s";
arguments << " " << a;
}
else if (arg->IsNil()) {
message << "N";
}
arg++;
}
}
catch( osc::Exception& e ){
@@ -882,6 +887,46 @@ bool Control::receiveSourceAttribute(Source *target, const std::string &attribut
textsrc->contents()->setText(label);
}
}
/// e.g. '/vimix/current/filter sf blur 0.5'
else if (attribute.compare(OSC_SOURCE_FILTER) == 0) {
std::string filter_name;
std::string filter_method;
float filter_value = NAN;
float t = 0.f;
try {
const char *str = nullptr;
arguments >> str;
filter_name = std::string(str);
}
// ignore invalid or Nil types
catch (osc::WrongArgumentTypeException &) {
}
if (arguments.Eos())
arguments >> osc::EndMessage;
else {
try {
const char *str = nullptr;
arguments >> str;
filter_method = std::string(str);
}
// ignore invalid or Nil types
catch (osc::WrongArgumentTypeException &) {
}
if (arguments.Eos())
arguments >> osc::EndMessage;
else {
arguments >> filter_value;
if (arguments.Eos())
arguments >> osc::EndMessage;
else {
arguments >> t >> osc::EndMessage;
}
}
}
// operate on source
target->call( new SetFilter(filter_name, filter_method, filter_value, t), true);
}
/// e.g. '/vimix/name/sync'
else if ( attribute.compare(OSC_SYNC) == 0) {
// this will require to send feedback status about source

View File

@@ -63,6 +63,11 @@
#define OSC_SOURCE_POSTERIZE "/posterize"
#define OSC_SOURCE_INVERT "/invert"
#define OSC_SOURCE_CORRECTION "/correction"
#define OSC_SOURCE_CROP "/crop"
#define OSC_SOURCE_TEXPOSITION "/texture_position"
#define OSC_SOURCE_TEXSIZE "/texture_size"
#define OSC_SOURCE_TEXANGLE "/texture_angle"
#define OSC_SOURCE_FILTER "/filter"
#define OSC_SESSION "/session"
#define OSC_SESSION_VERSION "/version"

View File

@@ -1228,32 +1228,6 @@ void ImGuiVisitor::visit (AlphaFilter& f)
if ( m == AlphaFilter::ALPHA_CHROMAKEY || m == AlphaFilter::ALPHA_LUMAKEY)
{
float t = filter_parameters["Threshold"];
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::SliderFloat( "##Threshold", &t, 0.f, 1.f, "%.2f")) {
f.setProgramParameter("Threshold", t);
}
if (ImGui::IsItemHovered() && io.MouseWheel != 0.f ){
t = CLAMP( t + 0.01f * io.MouseWheel, 0.f, 1.f);
f.setProgramParameter("Threshold", t);
oss << AlphaFilter::operation_label[ f.operation() ];
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
Action::manager().store(oss.str());
}
if (ImGui::IsItemDeactivatedAfterEdit()) {
oss << AlphaFilter::operation_label[ f.operation() ];
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
Action::manager().store(oss.str());
}
ImGui::SameLine(0, IMGUI_SAME_LINE);
if (ImGuiToolkit::TextButton("Threshold")) {
t = 0.f;
f.setProgramParameter("Threshold", t);
oss << AlphaFilter::operation_label[ f.operation() ];
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
Action::manager().store(oss.str());
}
float v = filter_parameters["Tolerance"];
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::SliderFloat( "##Tolerance", &v, 0.f, 1.f, "%.2f")) {
@@ -1279,6 +1253,32 @@ void ImGuiVisitor::visit (AlphaFilter& f)
oss << " : " << "Tolerance" << " " << std::setprecision(3) << v;
Action::manager().store(oss.str());
}
float t = filter_parameters["Threshold"];
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::SliderFloat( "##Threshold", &t, 0.f, 1.f, "%.2f")) {
f.setProgramParameter("Threshold", t);
}
if (ImGui::IsItemHovered() && io.MouseWheel != 0.f ){
t = CLAMP( t + 0.01f * io.MouseWheel, 0.f, 1.f);
f.setProgramParameter("Threshold", t);
oss << AlphaFilter::operation_label[ f.operation() ];
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
Action::manager().store(oss.str());
}
if (ImGui::IsItemDeactivatedAfterEdit()) {
oss << AlphaFilter::operation_label[ f.operation() ];
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
Action::manager().store(oss.str());
}
ImGui::SameLine(0, IMGUI_SAME_LINE);
if (ImGuiToolkit::TextButton("Threshold")) {
t = 0.f;
f.setProgramParameter("Threshold", t);
oss << AlphaFilter::operation_label[ f.operation() ];
oss << " : " << "Threshold" << " " << std::setprecision(3) << t;
Action::manager().store(oss.str());
}
}
if ( m == AlphaFilter::ALPHA_CHROMAKEY || m == AlphaFilter::ALPHA_FILL)

View File

@@ -22,7 +22,6 @@
#include <glm/gtc/matrix_access.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "defines.h"
#include "Resource.h"
#include "Visitor.h"
#include "FrameBuffer.h"
@@ -465,6 +464,34 @@ void ResampleFilter::setFactor(int factor)
input_ = nullptr;
}
bool ResampleFilter::setFactor(const std::string &label)
{
std::string target_factor = label;
std::transform(target_factor.begin(), target_factor.end(), target_factor.begin(), ::tolower);
// find method by name
int __f = ResampleFilter::RESAMPLE_DOUBLE;
for (; __f != ResampleFilter::RESAMPLE_INVALID; __f++) {
std::string _b = ResampleFilter::factor_label[__f];
auto loc = _b.find_first_of(" ");
if (loc != std::string::npos)
_b = _b.erase(loc);
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
if (target_factor.compare(_b) == 0)
break;
}
// invalid filter name
if (__f == ResampleFilter::RESAMPLE_INVALID)
return false;
// Apply if provided method name is different from current
if (factor() != __f)
setFactor(__f);
return true;
}
void ResampleFilter::draw (FrameBuffer *input)
{
bool forced = false;
@@ -579,6 +606,34 @@ void BlurFilter::setMethod(int method)
setProgram( programs_[ (int) method_] );
}
bool BlurFilter::setMethod(const std::string &label)
{
std::string target_method = label;
std::transform(target_method.begin(), target_method.end(), target_method.begin(), ::tolower);
// find method by name
int __m = BlurFilter::BLUR_GAUSSIAN;
for (; __m != BlurFilter::BLUR_INVALID; __m++) {
std::string _b = BlurFilter::method_label[__m];
auto loc = _b.find_first_of(" ");
if (loc != std::string::npos)
_b = _b.erase(loc);
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
if (target_method.compare(_b) == 0)
break;
}
// invalid filter name
if (__m == BlurFilter::BLUR_INVALID)
return false;
// Apply if provided method name is different from current
if (method() != __m)
setMethod(__m);
return true;
}
void BlurFilter::draw (FrameBuffer *input)
{
bool forced = false;
@@ -684,6 +739,34 @@ void SharpenFilter::setMethod(int method)
setProgram( programs_[ (int) method_] );
}
bool SharpenFilter::setMethod(const std::string &label)
{
std::string target_method = label;
std::transform(target_method.begin(), target_method.end(), target_method.begin(), ::tolower);
// find method by name
int __m = SharpenFilter::SHARPEN_MASK;
for (; __m != SharpenFilter::SHARPEN_INVALID; __m++) {
// get first word of label, in lower case
std::string _b = SharpenFilter::method_label[__m];
auto loc = _b.find_first_of(" ");
if (loc != std::string::npos)
_b = _b.erase(loc);
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
if (target_method.compare(_b) == 0)
break;
}
if (__m == SharpenFilter::SHARPEN_INVALID)
return false;
// Apply if provided method name is different from current
if (method() != __m)
setMethod(__m);
return true;
}
void SharpenFilter::draw (FrameBuffer *input)
{
// Default
@@ -708,7 +791,7 @@ void SharpenFilter::accept (Visitor& v)
////////////////////////////////////////
const char* SmoothFilter::method_label[SmoothFilter::SMOOTH_INVALID] = {
"Bilateral", "Kuwahara", "Opening", "Closing", "Erosion", "Dilation", "Remove noise", "Add noise", "Add grain"
"Bilateral", "Kuwahara", "Opening", "Closing", "Erosion", "Dilation", "Denoise", "Noise add", "Grain add"
};
std::vector< FilteringProgram > SmoothFilter::programs_ = {
@@ -733,6 +816,33 @@ void SmoothFilter::setMethod(int method)
setProgram( programs_[ (int) method_] );
}
bool SmoothFilter::setMethod(const std::string &label)
{
std::string target_method = label;
std::transform(target_method.begin(), target_method.end(), target_method.begin(), ::tolower);
// find method by name
int __m = SmoothFilter::SMOOTH_BILINEAR;
for (; __m != SmoothFilter::SMOOTH_INVALID; __m++) {
std::string _b = SmoothFilter::method_label[__m];
auto loc = _b.find_first_of(" ");
if (loc != std::string::npos)
_b = _b.erase(loc);
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
if (target_method.compare(_b) == 0)
break;
}
if (__m == SmoothFilter::SMOOTH_INVALID)
return false;
// Apply if provided method name is different from current
if (method() != __m)
setMethod(__m);
return true;
}
void SmoothFilter::draw (FrameBuffer *input)
{
// Default
@@ -776,6 +886,33 @@ void EdgeFilter::setMethod(int method)
setProgram( programs_[ (int) method_] );
}
bool EdgeFilter::setMethod(const std::string &label)
{
std::string target_method = label;
std::transform(target_method.begin(), target_method.end(), target_method.begin(), ::tolower);
// find method by name
int __m = EdgeFilter::EDGE_SOBEL;
for (; __m != EdgeFilter::EDGE_INVALID; __m++) {
std::string _b = EdgeFilter::method_label[__m];
auto loc = _b.find_first_of(" ");
if (loc != std::string::npos)
_b = _b.erase(loc);
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
if (target_method.compare(_b) == 0)
break;
}
if (__m == EdgeFilter::EDGE_INVALID)
return false;
// Apply if provided method name is different from current
if (method() != __m)
setMethod(__m);
return true;
}
void EdgeFilter::draw (FrameBuffer *input)
{
// Default
@@ -804,8 +941,8 @@ const char* AlphaFilter::operation_label[AlphaFilter::ALPHA_INVALID] = {
};
std::vector< FilteringProgram > AlphaFilter::programs_ = {
FilteringProgram("Chromakey","shaders/filters/chromakey.glsl", "", { { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0}, { "Threshold", 0.5}, { "Tolerance", 0.5} }),
FilteringProgram("Lumakey", "shaders/filters/lumakey.glsl", "", { { "Luminance", 0.0}, { "Threshold", 0.5}, { "Tolerance", 0.5} } ),
FilteringProgram("Chromakey","shaders/filters/chromakey.glsl", "", { { "Threshold", 0.5}, { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0}, { "Tolerance", 0.5} } ),
FilteringProgram("Lumakey", "shaders/filters/lumakey.glsl", "", { { "Threshold", 0.5}, { "Luminance", 0.0}, { "Tolerance", 0.5} } ),
FilteringProgram("coloralpha","shaders/filters/coloralpha.glsl", "", { { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0} } )
};
@@ -819,6 +956,33 @@ void AlphaFilter::setOperation(int op)
setProgram( programs_[ (int) operation_] );
}
bool AlphaFilter::setOperation(const std::string &label)
{
std::string target_op = label;
std::transform(target_op.begin(), target_op.end(), target_op.begin(), ::tolower);
// find method by name
int __o = AlphaFilter::ALPHA_CHROMAKEY;
for (; __o != AlphaFilter::ALPHA_INVALID; __o++) {
std::string _b = AlphaFilter::operation_label[__o];
auto loc = _b.find_first_of(" ");
if (loc != std::string::npos)
_b = _b.erase(loc);
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
if (target_op.compare(_b) == 0)
break;
}
if (__o == AlphaFilter::ALPHA_INVALID)
return false;
// Apply if provided method name is different from current
if (operation() != __o)
setOperation(__o);
return true;
}
void AlphaFilter::draw (FrameBuffer *input)
{
// Default

View File

@@ -154,6 +154,7 @@ public:
} ResampleFactor;
static const char* factor_label[RESAMPLE_INVALID];
ResampleFactor factor () const { return factor_; }
bool setFactor(const std::string &label);
void setFactor(int factor);
// implementation of FrameBufferFilter
@@ -187,6 +188,7 @@ public:
} BlurMethod;
static const char* method_label[BLUR_INVALID];
BlurMethod method () const { return method_; }
bool setMethod(const std::string &label);
void setMethod(int method);
// implementation of FrameBufferFilter
@@ -221,6 +223,7 @@ public:
} SharpenMethod;
static const char* method_label[SHARPEN_INVALID];
SharpenMethod method () const { return method_; }
bool setMethod(const std::string &label);
void setMethod(int method);
// implementation of FrameBufferFilter
@@ -255,7 +258,10 @@ public:
SMOOTH_INVALID
} SmoothMethod;
static const char* method_label[SMOOTH_INVALID];
static std::vector< FilteringProgram > programs_;
SmoothMethod method () const { return method_; }
bool setMethod(const std::string &label);
void setMethod(int method);
// implementation of FrameBufferFilter
@@ -266,7 +272,6 @@ public:
private:
SmoothMethod method_;
static std::vector< FilteringProgram > programs_;
};
@@ -286,6 +291,7 @@ public:
} EdgeMethod;
static const char* method_label[EDGE_INVALID];
EdgeMethod method () const { return method_; }
bool setMethod(const std::string &label);
void setMethod(int method);
// implementation of FrameBufferFilter
@@ -317,6 +323,7 @@ public:
} AlphaOperation;
static const char* operation_label[ALPHA_INVALID];
AlphaOperation operation () const { return operation_; }
bool setOperation(const std::string &label);
void setOperation(int op);
// implementation of FrameBufferFilter

View File

@@ -16,13 +16,18 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
**/
#include <fstream>
#include "defines.h"
#include "Source.h"
#include "ImageProcessingShader.h"
#include "CloneSource.h"
#include "ImageFilter.h"
#include "DelayFilter.h"
#include "MediaSource.h"
#include "MediaPlayer.h"
#include "Visitor.h"
#include "Log.h"
#include "SourceCallback.h"
@@ -98,6 +103,9 @@ SourceCallback *SourceCallback::create(CallbackType type)
case SourceCallback::CALLBACK_POSTERIZE:
loadedcallback = new SetPosterize;
break;
case SourceCallback::CALLBACK_FILTER:
loadedcallback = new SetFilter;
break;
default:
break;
}
@@ -1086,3 +1094,217 @@ void SetGamma::accept(Visitor& v)
SourceCallback::accept(v);
v.visit(*this);
}
SetFilter::SetFilter(const std::string &filter, const std::string &method, float value, float ms)
: SourceCallback()
, target_filter_(filter)
, target_method_(method)
, target_value_(value)
, duration_(ms)
{
imagefilter = nullptr;
delayfilter = nullptr;
}
void SetFilter::update(Source *s, float dt)
{
SourceCallback::update(s, dt);
CloneSource *clonesrc = dynamic_cast<CloneSource *>(s);
if (s->locked() || !clonesrc)
status_ = FINISHED;
// apply when ready
if (status_ == READY) {
///
/// Set Filter
///
// convert target_filter_ to lower case to avoid mistakes
std::transform(target_filter_.begin(),
target_filter_.end(),
target_filter_.begin(),
::tolower);
if (!target_filter_.empty()) {
// find filter type ID of the filter name provided, if valid
size_t __t = FrameBufferFilter::FILTER_PASSTHROUGH;
for (; __t != FrameBufferFilter::FILTER_INVALID; __t++) {
// get first word of filter label, in lower case
std::string _b = std::get<2>(FrameBufferFilter::Types[__t]);
auto loc = _b.find_first_of(" ");
if (loc != std::string::npos)
_b = _b.erase(loc);
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
// end search if found same as target filter name (success)
if (target_filter_.compare(_b) == 0)
break;
}
// Provided filter name is valid
FrameBufferFilter::Type __type = FrameBufferFilter::Type(__t);
if (__type != FrameBufferFilter::FILTER_INVALID) {
// change filter if different from source
if (clonesrc->filter()->type() != __type)
clonesrc->setFilter(__type);
} else
Log::Info("Filter : unknown type '%s'", target_filter_.c_str());
}
///
/// Set Method
///
if (!target_method_.empty()) {
// treat image filter types differently
// ignore invalid or Nil types
switch (clonesrc->filter()->type()) {
case FrameBufferFilter::FILTER_RESAMPLE: {
// get resamplig filter
ResampleFilter *__f = dynamic_cast<ResampleFilter *>(clonesrc->filter());
if ( !__f->setFactor(target_method_) )
Log::Info("Filter Resample: unknown factor '%s'", target_method_.c_str());
} break;
case FrameBufferFilter::FILTER_BLUR: {
// get blur filter
BlurFilter *__f = dynamic_cast<BlurFilter *>(clonesrc->filter());
if ( !__f->setMethod(target_method_) )
Log::Info("Filter Blur: unknown method '%s'", target_method_.c_str());
} break;
case FrameBufferFilter::FILTER_SHARPEN: {
// get sharpen filter
SharpenFilter *__f = dynamic_cast<SharpenFilter *>(clonesrc->filter());
if ( !__f->setMethod(target_method_) )
Log::Info("Filter Sharpen: unknown method '%s'", target_method_.c_str());
} break;
case FrameBufferFilter::FILTER_SMOOTH: {
// get smooth filter
SmoothFilter *__f = dynamic_cast<SmoothFilter *>(clonesrc->filter());
if (!__f->setMethod(target_method_))
Log::Info("Filter Smooth: unknown method '%s'", target_method_.c_str());
} break;
case FrameBufferFilter::FILTER_EDGE: {
// get edge filter
EdgeFilter *__f = dynamic_cast<EdgeFilter *>(clonesrc->filter());
if (!__f->setMethod(target_method_))
Log::Info("Filter Edge: unknown method '%s'", target_method_.c_str());
} break;
case FrameBufferFilter::FILTER_ALPHA: {
// get alpha filter
AlphaFilter *__f = dynamic_cast<AlphaFilter *>(clonesrc->filter());
if (!__f->setOperation(target_method_))
Log::Info("Filter Alpha: unknown operation '%s'", target_method_.c_str());
} break;
case FrameBufferFilter::FILTER_IMAGE: {
// Open the file
std::ifstream file(target_method_);
// Check if the file is opened successfully
if (file.is_open()) {
// Read the content of the file into an std::string
std::string fileContent((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
FilteringProgram prog;
prog.setName(target_method_);
prog.setCode({fileContent, ""});
// get alpha filter
ImageFilter *__f = dynamic_cast<ImageFilter *>(clonesrc->filter());
__f->setProgram(prog);
}
else
Log::Info("Filter Custom: can't read file '%s'", target_method_.c_str());
// Close the file
file.close();
} break;
default:
break;
}
}
// by default, consider it's over,
status_ = FINISHED;
// ...but if a target value is given,
if ( !std::isnan(target_value_) ){
imagefilter = dynamic_cast<ImageFilter *>(clonesrc->filter());
// ...and if there is a parameter to the filter
if (imagefilter && imagefilter->program().parameters().size() > 0) {
target_parameter_ = imagefilter->program().parameters().rbegin()->first;
start_value_ = imagefilter->program().parameters().rbegin()->second;
// then activate for value update
status_ = ACTIVE;
}
// or maybe its a delay filter?
else {
delayfilter = dynamic_cast<DelayFilter *>(clonesrc->filter());
if (delayfilter) {
start_value_ = delayfilter->delay();
// then activate for value update
status_ = ACTIVE;
}
}
}
}
///
/// Set Value
///
if (status_ == ACTIVE) {
// time passed since start
float progress = elapsed_ - delay_;
// update ImageFilter types of filters
if (imagefilter) {
// time-out or instantaneous
if (!(ABS(duration_) > 0.f) || progress > duration_) {
// apply target value
imagefilter->setProgramParameter(target_parameter_, target_value_);
// done
status_ = FINISHED;
}
else {
// apply calculated intermediate value
imagefilter->setProgramParameter(target_parameter_,
glm::mix(start_value_,
target_value_,
progress / duration_));
}
}
// update DelayFilter
else if (delayfilter) {
// time-out or instantaneous
if (!(ABS(duration_) > 0.f) || progress > duration_) {
// apply target value
delayfilter->setDelay(target_value_);
// done
status_ = FINISHED;
}
else {
// apply calculated intermediate value
delayfilter->setDelay(glm::mix(start_value_, target_value_, progress / duration_));
}
}
else
status_ = FINISHED;
}
}
void SetFilter::multiply (float factor)
{
target_value_ *= factor;
}
SourceCallback *SetFilter::clone() const
{
return new SetFilter(target_filter_,
target_method_,
target_value_,
duration_);
}
void SetFilter::accept(Visitor& v)
{
SourceCallback::accept(v);
v.visit(*this);
}

View File

@@ -1,6 +1,8 @@
#ifndef SOURCECALLBACK_H
#define SOURCECALLBACK_H
#include <cmath>
#include <string>
#include <glm/glm.hpp>
#include "Scene.h"
@@ -48,7 +50,8 @@ public:
CALLBACK_HUE,
CALLBACK_THRESHOLD,
CALLBACK_INVERT,
CALLBACK_POSTERIZE
CALLBACK_POSTERIZE,
CALLBACK_FILTER
} CallbackType;
static SourceCallback *create(CallbackType type);
@@ -471,4 +474,37 @@ public:
void accept (Visitor& v) override;
};
class SetFilter : public SourceCallback
{
std::string target_filter_;
std::string target_method_;
std::string target_parameter_;
float start_value_;
float target_value_;
float duration_;
class ImageFilter *imagefilter;
class DelayFilter *delayfilter;
public:
SetFilter(const std::string &filter = std::string(),
const std::string &method = std::string(),
float value = NAN,
float ms = 0.f);
std::string filter() const { return target_filter_; }
void setFilter(const std::string &f) { target_filter_ = f; }
std::string method() const { return target_method_; }
void setMethod(const std::string &m) { target_method_ = m; }
float value () const { return target_value_; }
void setValue (float g) { target_value_ = g; }
float duration () const { return duration_; }
void setDuration (float ms) { duration_ = ms; }
void update (Source *s, float) override;
void multiply (float factor) override;
SourceCallback *clone () const override;
CallbackType type () const override { return CALLBACK_FILTER; }
void accept (Visitor& v) override;
};
#endif // SOURCECALLBACK_H

View File

@@ -313,4 +313,41 @@ void drawMediaPlayer()
}
// // get second argument : can be string, float or nothing
// bool argloop = false;
// while (!argloop) {
// // work on copy of arguments
// osc::ReceivedMessageArgumentStream __args = arguments;
// // no argument
// if (__args.Eos()) {
// filter_arg_type = osc::NIL_TYPE_TAG;
// argloop = true;
// }
// // try with float (last try)
// if (filter_arg_type == osc::FLOAT_TYPE_TAG) {
// try {
// __args >> filter_value >> osc::EndMessage;
// } catch (osc::WrongArgumentTypeException &) {
// filter_arg_type = osc::NIL_TYPE_TAG;
// }
// // done!
// argloop = true;
// }
// // try with string (first try)
// if (filter_arg_type == osc::STRING_TYPE_TAG) {
// try {
// const char *m = nullptr;
// __args >> m >> osc::EndMessage;
// // done!
// filter_method = std::string(m);
// std::transform(filter_method.begin(),
// filter_method.end(),
// filter_method.begin(),
// ::tolower);
// argloop = true;
// } catch (osc::WrongArgumentTypeException &) {
// // next: try with float
// filter_arg_type = osc::FLOAT_TYPE_TAG;
// }
// }
// }