zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit ddd0fdfe062e07e688d9a55d7091a92d1b837abc
parent ddd10537c5e8cc32d1e239ad8861b0f75e9653ad
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Thu,  4 Jun 2015 11:23:20 -0400

NioUI: Restore Functionality

Diffstat:
Msrc/Misc/MiddleWare.cpp | 54+++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/Misc/Util.cpp | 20++++++++++++++++++++
Msrc/Misc/Util.h | 3+++
Msrc/UI/MasterUI.fl | 2+-
Msrc/UI/NioUI.cpp | 128++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/UI/NioUI.h | 8+++++---
Msrc/UI/Osc_DataModel.h | 4++--
7 files changed, 181 insertions(+), 38 deletions(-)

diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp @@ -8,6 +8,7 @@ #include <rtosc/undo-history.h> #include <rtosc/thread-link.h> #include <rtosc/ports.h> +#include <rtosc/typed-message.h> #include <lo/lo.h> #include <unistd.h> @@ -28,6 +29,7 @@ #include "../Params/PADnoteParameters.h" #include "../DSP/FFTwrapper.h" #include "../Synth/OscilGen.h" +#include "../Nio/Nio.h" #include <string> #include <future> @@ -427,6 +429,38 @@ struct ParamStore PADnoteParameters *pad[NUM_MIDI_PARTS][NUM_KIT_ITEMS]; }; +//XXX perhaps move this to Nio +//(there needs to be some standard Nio stub file for this sort of stuff) +namespace Nio +{ + using std::get; + using rtosc::rtMsg; + rtosc::Ports ports = { + {"sink-list:", 0, 0, [](const char *msg, rtosc::RtData &d) { + auto list = Nio::getSinks(); + char *ret = rtosc_splat(d.loc, list); + d.reply(ret); + delete [] ret; + }}, + {"source-list:", 0, 0, [](const char *msg, rtosc::RtData &d) { + auto list = Nio::getSources(); + char *ret = rtosc_splat(d.loc, list); + d.reply(ret); + delete [] ret; + }}, + {"source::s", 0, 0, [](const char *msg, rtosc::RtData &d) { + if(rtosc_narguments(msg) == 0) + d.reply(d.loc, "s", Nio::getSource().c_str()); + else if(rtMsg<const char*> m{msg}) + Nio::setSource(get<0>(m));}}, + {"sink::s", 0, 0, [](const char *msg, rtosc::RtData &d) { + if(rtosc_narguments(msg) == 0) + d.reply(d.loc, "s", Nio::getSink().c_str()); + else if(rtMsg<const char*> m{msg}) + Nio::setSink(get<0>(m));}}, + }; +} + /* Implementation */ class MiddleWareImpl { @@ -778,6 +812,22 @@ public: } } + void handleIo(const char *msg) + { + char buffer[1024]; + memset(buffer, 0, sizeof(buffer)); + DummyDataObj d(buffer, 1024, (void*)&config, this, uToB); + strcpy(buffer, "/io/"); + + Nio::ports.dispatch(msg+4, d); + if(!d.matches) { + fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 1, 7 + 30, 0 + 40); + fprintf(stderr, "Unknown location '%s'<%s>\n", + msg, rtosc_argument_string(msg)); + fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40); + } + } + void handleConfig(const char *msg) { char buffer[1024]; @@ -1243,6 +1293,8 @@ void MiddleWareImpl::handleMsg(const char *msg) handleConfig(msg); } else if(strstr(msg, "/presets/")) { handlePresets(msg); + } else if(strstr(msg, "/io/")) { + handleIo(msg); } else if(strstr(msg, "Padenabled") || strstr(msg, "Ppadenabled") || strstr(msg, "Psubenabled")) { kitEnable(msg); uToB->raw_write(msg); @@ -1367,7 +1419,7 @@ void MiddleWare::activeUrl(std::string u) { impl->last_url = u; } - + const SYNTH_T &MiddleWare::getSynth(void) const { return impl->synth; diff --git a/src/Misc/Util.cpp b/src/Misc/Util.cpp @@ -41,6 +41,8 @@ #include <err.h> #endif +#include <rtosc/rtosc.h> + prng_t prng_state = 0x1234; Config config; @@ -213,3 +215,21 @@ float cinterpolate(const float *data, size_t len, float pos) const float leftness = pos - l_pos; return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness); } + +char *rtosc_splat(const char *path, std::set<std::string> v) +{ + char argT[v.size()+1]; + rtosc_arg_t arg[v.size()]; + unsigned i=0; + for(auto vv : v) { + argT[i] = 's'; + arg[i].s = vv.c_str(); + i++; + } + argT[v.size()] = 0; + + size_t len = rtosc_amessage(0, 0, path, argT, arg); + char *buf = new char[len]; + rtosc_amessage(buf, len, path, argT, arg); + return buf; +} diff --git a/src/Misc/Util.h b/src/Misc/Util.h @@ -27,6 +27,7 @@ #include <sstream> #include <stdint.h> #include <algorithm> +#include <set> #include "Config.h" #include "../globals.h" @@ -152,6 +153,8 @@ static inline void nullify(T &t) {delete t; t = NULL; } template<class T> static inline void arrayNullify(T &t) {delete [] t; t = NULL; } +char *rtosc_splat(const char *path, std::set<std::string>); + /** * Port macros - these produce easy and regular port definitions for common * types diff --git a/src/UI/MasterUI.fl b/src/UI/MasterUI.fl @@ -1480,7 +1480,7 @@ masterwindowlabel[99]='\\0'; masterwindow->label(&masterwindowlabel[0]); simplemasterwindow->label(&masterwindowlabel[0]);} {} } - Function {MasterUI(int *exitprogram_, class Fl_Osc_Interface *osc_)} {open + Function {MasterUI(int *exitprogram_, class Fl_Osc_Interface *osc_):nioui(osc_)} {open } { code {exitprogram=exitprogram_; osc=osc_; diff --git a/src/UI/NioUI.cpp b/src/UI/NioUI.cpp @@ -10,49 +10,110 @@ #include <FL/Fl_Tabs.H> #include <FL/Fl_Group.H> #include <FL/Fl_Text_Display.H> +#include "Osc_SimpleListModel.h" using namespace std; -NioUI::NioUI() +static void callback_fn_choice(Fl_Widget *w, void *); +class Fl_Osc_StrChoice:public Fl_Choice, public Fl_Osc_Widget +{ + public: + Fl_Osc_StrChoice(int X, int Y, int W, int H, const char *label = NULL) + :Fl_Choice(X,Y,W,H, label), Fl_Osc_Widget(this), cb_data(NULL, NULL) + { + Fl_Choice::callback(callback_fn_choice, NULL); + } + + virtual ~Fl_Osc_StrChoice(void) {}; + void init(std::string path_) + { + ext = path_; + Fl_Osc_Pane *pane = fetch_osc_pane(this); + assert(pane); + assert(pane->osc); + osc = pane->osc; + oscRegister(path_.c_str()); + }; + + + void OSC_value(const char *S) override + { + for(int i=0; i<size()-1; ++i) { + printf("size = %d, i=%d, text='%s'\n", size(), i, text(i)); + if(!strcmp(S, text(i))) + value(i); + } + } + + //Refetch parameter information + void update(void) + { + assert(osc); + oscWrite(ext); + } + void callback(Fl_Callback *cb, void *p = NULL) + { + cb_data.first = cb; + cb_data.second = p; + } + + void cb(void) + { + assert(osc); + if(text(value())) + oscWrite(ext, "s", text(value())); + if(cb_data.first) + cb_data.first(this, cb_data.second); + } + private: + int min; + std::pair<Fl_Callback*, void*> cb_data; +}; +static void callback_fn_choice(Fl_Widget *w, void *) +{ + ((Fl_Osc_StrChoice*)w)->cb(); +} + +NioUI::NioUI(Fl_Osc_Interface *osc) :Fl_Window(200, 100, 400, 400, "New IO Controls") { //hm, I appear to be leaking memory - Fl_Group *settings = new Fl_Group(0, 20, 400, 400 - 35, "Settings"); + Fl_Osc_Group *settings = new Fl_Osc_Group(0, 20, 400, 400 - 35, "Settings"); { - audio = new Fl_Choice(60, 80, 100, 25, "Audio"); - audio->callback(audioCallback); - midi = new Fl_Choice(60, 100, 100, 25, "Midi"); - midi->callback(midiCallback); + settings->osc = osc; + audio = new Fl_Osc_StrChoice(60, 80, 100, 25, "Audio"); + //audio->callback(audioCallback); + audio->init("/io/sink"); + midi = new Fl_Osc_StrChoice(60, 100, 100, 25, "Midi"); + //midi->callback(midiCallback); + midi->init("/io/source"); } settings->end(); + //Get options + midi_opt = new Osc_SimpleListModel(osc); + audio_opt = new Osc_SimpleListModel(osc); + + using list_t = Osc_SimpleListModel::list_t; + //initialize midi list - { - //set<string> midiList = Nio::getSources(); - //string source = Nio::getSource(); - //int midival = 0; - //for(set<string>::iterator itr = midiList.begin(); - // itr != midiList.end(); ++itr) { - // midi->add(itr->c_str()); - // if(*itr == source) - // midival = midi->size() - 2; - //} - //midi->value(midival); - } + midi_opt->callback = [this](list_t list) { + printf("midi list updating...\n"); + midi->clear(); + for(auto io:list) + midi->add(io.c_str()); + }; //initialize audio list - { - //set<string> audioList = Nio::getSinks(); - //string sink = Nio::getSink(); - //int audioval = 0; - //for(set<string>::iterator itr = audioList.begin(); - // itr != audioList.end(); ++itr) { - // audio->add(itr->c_str()); - // if(*itr == sink) - // audioval = audio->size() - 2; - //} - //audio->value(audioval); - } + audio_opt->callback = [this](list_t list) { + audio->clear(); + for(auto io:list) + audio->add(io.c_str()); + }; + + midi_opt->update("/io/source-list"); + audio_opt->update("/io/sink-list"); + resizable(this); size_range(400, 300); } @@ -61,7 +122,12 @@ NioUI::~NioUI() {} void NioUI::refresh() -{} +{ + midi_opt->update("/io/source-list"); + audio_opt->update("/io/sink-list"); + midi->update(); + audio->update(); +} void NioUI::midiCallback(Fl_Widget *c) { diff --git a/src/UI/NioUI.h b/src/UI/NioUI.h @@ -7,12 +7,14 @@ class NioUI:public Fl_Window { public: - NioUI(); + NioUI(class Fl_Osc_Interface*); ~NioUI(); void refresh(); private: - class Fl_Choice * midi; - class Fl_Choice * audio; + class Fl_Osc_StrChoice * midi; + class Fl_Osc_StrChoice * audio; + class Osc_SimpleListModel * midi_opt; + class Osc_SimpleListModel * audio_opt; static void midiCallback(Fl_Widget *c); static void audioCallback(Fl_Widget *c); }; diff --git a/src/UI/Osc_DataModel.h b/src/UI/Osc_DataModel.h @@ -1,3 +1,4 @@ +#pragma once #include "Fl_Osc_Widget.H" #include <functional> #include <vector> @@ -7,7 +8,7 @@ class Osc_DataModel:public Fl_Osc_Widget { public: Osc_DataModel(Fl_Osc_Interface *osc_) - :Fl_Osc_Widget("", osc_), list_size(0) + :Fl_Osc_Widget("", osc_) { assert(osc); } @@ -15,7 +16,6 @@ class Osc_DataModel:public Fl_Osc_Widget typedef std::string value_t; value_t value; std::function<void(value_t)> callback; - unsigned list_size; void update(std::string url) {