zynaddsubfx

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

commit f3b20b975daca7c924d9951fb8b4f2676e72f1e2
parent 5c34e0a67e235d885c5d328c37e1374ea79d8aa4
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Sat, 31 Oct 2015 16:14:29 -0400

Fix Known Test Failures

- More OSC Message Rerouting

Diffstat:
Msrc/Misc/MiddleWare.cpp | 221++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/Params/PADnoteParameters.cpp | 193+++++++++++++++++++++++++++++--------------------------------------------------
Msrc/Params/PADnoteParameters.h | 4+++-
Msrc/Synth/OscilGen.cpp | 60+++++++++++++++++++++++++++---------------------------------
Msrc/Synth/OscilGen.h | 5+++--
Msrc/Tests/MessageTest.h | 9+++++++--
Msrc/UI/BankView.cpp | 27+++++++++++++--------------
Msrc/globals.h | 2+-
8 files changed, 242 insertions(+), 279 deletions(-)

diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp @@ -189,67 +189,6 @@ void preparePadSynth(string path, PADnoteParameters *p, rtosc::ThreadLink *uToB) } } - -/***************************************************************************** - * Data Object for Non-RT Class Dispatch * - *****************************************************************************/ - -class MwDataObj:public rtosc::RtData -{ - public: - MwDataObj(MiddleWareImpl *mwi_) - { - loc_size = 1024; - loc = new char[loc_size]; - memset(loc, 0, loc_size); - buffer = new char[4*4096]; - memset(buffer, 0, 4*4096); - obj = mwi_; - mwi = mwi_; - forwarded = false; - } - - ~MwDataObj(void) - { - delete[] buffer; - } - - //Replies and broadcasts go to the remote - - //Chain calls repeat the call into handle() - - //Forward calls send the message directly to the realtime - virtual void reply(const char *path, const char *args, ...) - { - //printf("reply building '%s'\n", path); - va_list va; - va_start(va,args); - if(!strcmp(path, "/forward")) { //forward the information to the backend - args++; - path = va_arg(va, const char *); - rtosc_vmessage(buffer,4*4096,path,args,va); - } else { - rtosc_vmessage(buffer,4*4096,path,args,va); - reply(buffer); - } - va_end(va); - } - virtual void reply(const char *msg){}; - //virtual void broadcast(const char *path, const char *args, ...){(void)path;(void)args;}; - //virtual void broadcast(const char *msg){(void)msg;}; - - virtual void forward(const char *) override - { - forwarded = true; - } - - bool forwarded; - private: - char *buffer; - MiddleWareImpl *mwi; -}; - - /****************************************************************************** * Non-RealTime Object Store * * * @@ -330,23 +269,22 @@ struct NonRtObjStore } void handleOscil(const char *msg, rtosc::RtData &d) { + string obj_rl(d.message, msg); + void *osc = get(obj_rl); + assert(osc); + strcpy(d.loc, obj_rl.c_str()); + d.obj = osc; + OscilGen::non_realtime_ports.dispatch(msg, d); } void handlePad(const char *msg, rtosc::RtData &d) { + string obj_rl(d.message, msg); + printf("object resource locator = <%s>\n", obj_rl.c_str()); + void *pad = get(obj_rl); + assert(pad); + strcpy(d.loc, obj_rl.c_str()); + d.obj = pad; + PADnoteParameters::non_realtime_ports.dispatch(msg, d); } -#if 0 - if(strstr(msg, "oscilgen/") || strstr(msg, "FMSmp/") || strstr(msg, "OscilSmp/")) { - if(!handleOscil(obj_rl, last_path+1, obj_store.get(obj_rl))) - uToB->raw_write(msg); - //else if(strstr(obj_rl.c_str(), "kititem")) - // handleKitItem(obj_rl, objmap[obj_rl],atoi(rindex(msg,'m')+1),rtosc_argument(msg,0).T); - } else if(strstr(msg, "padpars/prepare")) - preparePadSynth(obj_rl,(PADnoteParameters *) obj_store.get(obj_rl), uToB); - else if(strstr(msg, "padpars")) { - if(!handlePAD(obj_rl, last_path+1, obj_store.get(obj_rl))) - uToB->raw_write(msg); - } else //just forward the message - uToB->raw_write(msg); -#endif }; /****************************************************************************** @@ -438,9 +376,8 @@ class MiddleWareImpl : TmpFileMgr return true; } - Config* const config; - public: + Config* const config; MiddleWareImpl(MiddleWare *mw, SYNTH_T synth, Config* config, int preferred_port); ~MiddleWareImpl(void); @@ -521,7 +458,7 @@ public: //Give it to the backend and wait for the old part to return for //deallocation - uToB->write("/load-part", "ib", npart, sizeof(Part*), &p); + parent->transmitMsg("/load-part", "ib", npart, sizeof(Part*), &p); GUI::raiseUi(ui, "/damage", "s", ("/part"+to_s(npart)+"/").c_str()); } @@ -541,7 +478,7 @@ public: //Give it to the backend and wait for the old part to return for //deallocation - uToB->write("/load-part", "ib", npart, sizeof(Part*), &p); + parent->transmitMsg("/load-part", "ib", npart, sizeof(Part*), &p); GUI::raiseUi(ui, "/damage", "s", ("/part"+to_s(npart)+"/").c_str()); } @@ -567,7 +504,7 @@ public: //Give it to the backend and wait for the old part to return for //deallocation - uToB->write("/load-master", "b", sizeof(Master*), &m); + parent->transmitMsg("/load-master", "b", sizeof(Master*), &m); } void updateResources(Master *m) @@ -580,7 +517,10 @@ public: //If currently broadcasting messages bool broadcast = false; + //If message should be forwarded through snoop ports bool forward = false; + //if message is in order or out-of-order execution + bool in_order = false; //If accepting undo events as user driven bool recording_undo = true; void bToUhandle(const char *rtmsg); @@ -608,6 +548,11 @@ public: // Send a message to a remote client void sendToRemote(const char *msg, std::string dest); + // Send a message to the current remote client + void sendToCurrentRemote(const char *msg) + { + sendToRemote(msg, in_order ? curr_url : last_url); + } // Broadcast a message to all listening remote clients void broadcastToRemote(const char *msg); @@ -654,15 +599,78 @@ public: //Synthesis Rate Parameters const SYNTH_T synth; - + PresetsStore presetsstore; }; +/***************************************************************************** + * Data Object for Non-RT Class Dispatch * + *****************************************************************************/ + +class MwDataObj:public rtosc::RtData +{ + public: + MwDataObj(MiddleWareImpl *mwi_) + { + loc_size = 1024; + loc = new char[loc_size]; + memset(loc, 0, loc_size); + buffer = new char[4*4096]; + memset(buffer, 0, 4*4096); + obj = mwi_; + mwi = mwi_; + forwarded = false; + } + + ~MwDataObj(void) + { + delete[] buffer; + } + + //Replies and broadcasts go to the remote + + //Chain calls repeat the call into handle() + + //Forward calls send the message directly to the realtime + virtual void reply(const char *path, const char *args, ...) + { + //printf("reply building '%s'\n", path); + va_list va; + va_start(va,args); + if(!strcmp(path, "/forward")) { //forward the information to the backend + args++; + path = va_arg(va, const char *); + rtosc_vmessage(buffer,4*4096,path,args,va); + } else { + rtosc_vmessage(buffer,4*4096,path,args,va); + reply(buffer); + } + va_end(va); + } + virtual void reply(const char *msg){ + mwi->sendToCurrentRemote(msg); + }; + //virtual void broadcast(const char *path, const char *args, ...){(void)path;(void)args;}; + //virtual void broadcast(const char *msg){(void)msg;}; + + virtual void forward(const char *) override + { + forwarded = true; + } + + bool forwarded; + private: + char *buffer; + MiddleWareImpl *mwi; +}; + + + static int extractInt(const char *msg) { - const char *mm = msg; - while(*mm && !isdigit(*mm)) ++mm; + const char *mm = msg; + while(*mm && !isdigit(*mm)) ++mm; if(isdigit(*mm)) return atoi(mm); return -1; @@ -716,7 +724,7 @@ rtosc::Ports bankPorts = { for(auto &elm : impl.banks) d.reply("/bank-list", "iss", i++, elm.name.c_str(), elm.dir.c_str()); rEnd}, - {"bank_select::i", 0, 0, + {"bank_select::i", 0, 0, rBegin if(rtosc_narguments(msg)) { const int pos = rtosc_argument(msg, 0).i; @@ -739,7 +747,7 @@ rtosc::Ports bankPorts = { const int part_id = rtosc_argument(msg, 0).i; const int slot = rtosc_argument(msg, 1).i; //impl.saveBankSlot(part_id, slot, master); - + //int err = 0; //doReadOnlyOp([master,nslot,npart,&err](){ // err = master->bank.savetoslot(nslot, master->part[npart]);}); @@ -800,20 +808,20 @@ rtosc::Ports bankPorts = { * BASE/part#/kit#/padpars/oscil/\* */ static rtosc::Ports middwareSnoopPorts = { - {"part#16/kit#8/adpars/VoicePar#8/OscilSmp/", 0, 0, + {"part#16/kit#8/adpars/VoicePar#8/OscilSmp/", 0, &OscilGen::non_realtime_ports, rBegin; printf("snoop for oscilsmp\n"); - impl.obj_store.handleOscil(msg, d); + impl.obj_store.handleOscil(chomp(chomp(chomp(chomp(chomp(msg))))), d); rEnd}, - {"part#16/kit#8/adpars/VoicePar#8/FMSmp/", 0, 0, + {"part#16/kit#8/adpars/VoicePar#8/FMSmp/", 0, &OscilGen::non_realtime_ports, rBegin printf("snoop for fmsmp\n"); - impl.obj_store.handleOscil(msg, d); + impl.obj_store.handleOscil(chomp(chomp(chomp(chomp(chomp(msg))))), d); rEnd}, - {"part#16/kit#8/padpars/", 0, 0, + {"part#16/kit#8/padpars/", 0, &PADnoteParameters::non_realtime_ports, rBegin printf("snoop for padpars\n"); - impl.obj_store.handlePad(msg, d); + impl.obj_store.handlePad(chomp(chomp(chomp(msg))), d); rEnd}, {"bank/", 0, &bankPorts, rBegin; @@ -821,9 +829,12 @@ static rtosc::Ports middwareSnoopPorts = { d.obj = &impl.master->bank; bankPorts.dispatch(chomp(msg),d); rEnd}, - {"config/", 0, &Config::ports, [](const char *msg, RtData &d) { + {"config/", 0, &Config::ports, + rBegin; printf("config port\n"); - Config::ports.dispatch(chomp(msg), d);}}, + d.obj = impl.config; + Config::ports.dispatch(chomp(msg), d); + rEnd}, {"presets/", 0, &real_preset_ports, [](const char *msg, RtData &d) { printf("presets port\n"); MiddleWareImpl *obj = (MiddleWareImpl*)d.obj; @@ -898,11 +909,11 @@ static rtosc::Ports middwareSnoopPorts = { impl.undo.seekHistory(+1); rEnd}, //drop this message into the abyss - {"/ui/title:", 0, 0, [](const char *msg, RtData &d) {}} + {"ui/title:", 0, 0, [](const char *msg, RtData &d) {}} }; static rtosc::Ports middlewareReplyPorts = { - {"echo:ss", 0, 0, + {"echo:ss", 0, 0, rBegin; const char *type = rtosc_argument(msg, 0).s; const char *url = rtosc_argument(msg, 1).s; @@ -912,7 +923,7 @@ static rtosc::Ports middlewareReplyPorts = { {"free:sb", 0, 0, rBegin; const char *type = rtosc_argument(msg, 0).s; - void *ptr = rtosc_argument(msg, 1).b.data; + void *ptr = *(void**)rtosc_argument(msg, 1).b.data; deallocate(type, ptr); rEnd}, {"request_memory:", 0, 0, @@ -1095,6 +1106,8 @@ void MiddleWareImpl::broadcastToRemote(const char *rtmsg) void MiddleWareImpl::sendToRemote(const char *rtmsg, std::string dest) { + printf("sendToRemote(%s:%s,%s)\n", rtmsg, rtosc_argument_string(rtmsg), + dest.c_str()); if(dest == "GUI") { cb(ui, rtmsg); } else if(!dest.empty()) { @@ -1121,7 +1134,7 @@ void MiddleWareImpl::bToUhandle(const char *rtmsg) assert(strcmp(rtmsg, "/ze_state")); //Dump Incomming Events For Debugging - if(strcmp(rtmsg, "/vu-meter") && false) { + if(strcmp(rtmsg, "/vu-meter") && true) { fprintf(stdout, "%c[%d;%d;%dm", 0x1B, 0, 1 + 30, 0 + 40); fprintf(stdout, "frontend: '%s'<%s>\n", rtmsg, rtosc_argument_string(rtmsg)); @@ -1130,10 +1143,11 @@ void MiddleWareImpl::bToUhandle(const char *rtmsg) //Activity dot printf(".");fflush(stdout); - + MwDataObj d(this); middlewareReplyPorts.dispatch(rtmsg, d, true); + in_order = true; //Normal message not captured by the ports if(d.matches == 0) { if(forward) { @@ -1142,9 +1156,10 @@ void MiddleWareImpl::bToUhandle(const char *rtmsg) } if(broadcast) broadcastToRemote(rtmsg); else - sendToRemote(rtmsg, curr_url); + sendToCurrentRemote(rtmsg); } - + in_order = false; + } //Allocate kits on a as needed basis @@ -1224,7 +1239,7 @@ void MiddleWareImpl::handleMsg(const char *msg) fprintf(stdout, "%c[%d;%d;%dm", 0x1B, 0, 6 + 30, 0 + 40); fprintf(stdout, "middleware: '%s':%s\n", msg, rtosc_argument_string(msg)); fprintf(stdout, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40); - + const char *last_path = rindex(msg, '/'); if(!last_path) { printf("Bad message in handleMsg() <%s>\n", msg); @@ -1237,10 +1252,10 @@ void MiddleWareImpl::handleMsg(const char *msg) //A message unmodified by snooping if(d.matches == 0 || d.forwarded) { - printf("Message Continuing on...\n"); + printf("Message Continuing on<%s:%s>...\n", msg, rtosc_argument_string(msg)); uToB->raw_write(msg); } else - printf("Message Handled...\n"); + printf("Message Handled<%s:%s>...\n", msg, rtosc_argument_string(msg)); } void MiddleWareImpl::write(const char *path, const char *args, ...) diff --git a/src/Params/PADnoteParameters.cpp b/src/Params/PADnoteParameters.cpp @@ -35,7 +35,7 @@ using namespace rtosc; #define rObject PADnoteParameters -static const rtosc::Ports PADnotePorts = +const rtosc::Ports PADnoteParameters::realtime_ports = { rRecurp(FreqLfo, "Frequency LFO"), rRecurp(AmpLfo, "Amplitude LFO"), @@ -44,65 +44,6 @@ static const rtosc::Ports PADnotePorts = rRecurp(AmpEnvelope, "Amplitude Envelope"), rRecurp(FilterEnvelope, "Filter Envelope"), rRecurp(GlobalFilter, "Post Filter"), - - //Harmonic Source Distribution - rRecurp(oscilgen, "Oscillator"), - rRecurp(resonance, "Resonance"), - - //Harmonic Shape - rOption(Pmode, rMap(min, 0), rMap(max, 2), rOptions(bandwidth,discrete,continious), - "Harmonic Distribution Model"), - rOption(Php.base.type, rOptions(Gaussian, Rectanglar, Double Exponential), - "Harmonic profile shape"), - rParamZyn(Php.base.par1, "Harmonic shape distribution parameter"), - rParamZyn(Php.freqmult, "Frequency multiplier on distribution"), - rParamZyn(Php.modulator.par1, "Distribution modulator parameter"), - rParamZyn(Php.modulator.freq, "Frequency of modulator parameter"), - rParamZyn(Php.width, "Width of base harmonic"), - rOption(Php.amp.mode, rOptions(Sum, Mult, Div1, Div2), - "Amplitude harmonic multiplier type"), - - //Harmonic Modulation - rOption(Php.amp.type, rOptions(Off, Gauss, Sine, Flat), - "Type of amplitude multipler"), - rParamZyn(Php.amp.par1, "Amplitude multiplier parameter"), - rParamZyn(Php.amp.par2, "Amplitude multiplier parameter"), - rToggle(Php.autoscale, "Autoscaling Harmonics"), - rOption(Php.onehalf, - rOptions(Full, Upper Half, Lower Half), - "Harmonic cutoff model"), - - //Harmonic Bandwidth - rOption(Pbwscale, - rOptions(Normal, - EqualHz, Quater, - Half, 75%, 150%, - Double, Inv. Half), - "Bandwidth scaling"), - - //Harmonic Position Modulation - rOption(Phrpos.type, - rOptions(Harmonic, ShiftU, ShiftL, PowerU, PowerL, Sine, - Power, Shift), - "Harmonic Overtone shifting mode"), - rParamZyn(Phrpos.par1, "Harmonic position parameter"), - rParamZyn(Phrpos.par2, "Harmonic position parameter"), - rParamZyn(Phrpos.par3, "Harmonic position parameter"), - - //Quality - rOption(Pquality.samplesize, - rOptions(16k (Tiny), 32k, 64k (Small), 128k, - 256k (Normal), 512k, 1M (Big)), - "Size of each wavetable element"), - rOption(Pquality.basenote, - rOptions( C-2, G-2, C-3, G-3, C-4, - G-4, C-5, G-5, G-6,), - "Base note for wavetable"), - rOption(Pquality.smpoct, - rOptions(0.5, 1, 2, 3, 4, 6, 12), - "Samples per octave"), - rParamI(Pquality.oct, rLinear(0,7), - "Number of octaves to sample (above the first sample"), //Volume rToggle(PStereo, "Stereo/Mono Mode"), @@ -115,7 +56,7 @@ static const rtosc::Ports PADnotePorts = rParamZyn(PPunchTime, "UNKNOWN"), rParamZyn(PPunchStretch, "How Punch changes with note frequency"), rParamZyn(PPunchVelocitySensing, "Punch Velocity control"), - + //Filter rParamZyn(PFilterVelocityScale, "Filter Velocity Magnitude"), rParamZyn(PFilterVelocityScaleFunction, "Filter Velocity Function Shape"), @@ -128,43 +69,6 @@ static const rtosc::Ports PADnotePorts = rParamI(PCoarseDetune, "Coarse Detune"), rParamZyn(PDetuneType, "Magnitude of Detune"), - {"Pbandwidth::i", rProp(parameter) rLinear(0,1000) rDoc("Bandwith Of Harmonics"), NULL, - [](const char *msg, rtosc::RtData &d) { - PADnoteParameters *p = ((PADnoteParameters*)d.obj); - if(rtosc_narguments(msg)) { - p->setPbandwidth(rtosc_argument(msg, 0).i); - } else { - d.reply(d.loc, "i", p->Pbandwidth); - }}}, - - {"bandwidthvalue:", rMap(unit, cents) rDoc("Get Bandwidth"), NULL, - [](const char *, rtosc::RtData &d) { - PADnoteParameters *p = ((PADnoteParameters*)d.obj); - d.reply(d.loc, "f", p->setPbandwidth(p->Pbandwidth)); - }}, - - - {"nhr:", rProp(non-realtime) rDoc("Returns the harmonic shifts"), - NULL, [](const char *, rtosc::RtData &d) { - PADnoteParameters *p = ((PADnoteParameters*)d.obj); - const unsigned n = p->synth.oscilsize / 2; - float *tmp = new float[n]; - *tmp = 0; - for(unsigned i=1; i<n; ++i) - tmp[i] = p->getNhr(i); - d.reply(d.loc, "b", n*sizeof(float), tmp); - delete[] tmp;}}, - {"profile:i", rProp(non-realtime) rDoc("UI display of the harmonic profile"), - NULL, [](const char *m, rtosc::RtData &d) { - PADnoteParameters *p = ((PADnoteParameters*)d.obj); - const int n = rtosc_argument(m, 0).i; - if(n<=0) - return; - float *tmp = new float[n]; - float realbw = p->getprofile(tmp, n); - d.reply(d.loc, "b", n*sizeof(float), tmp); - d.reply(d.loc, "i", realbw); - delete[] tmp;}}, {"sample#64:ifb", rProp(internal) rDoc("Nothing to see here"), 0, [](const char *m, rtosc::RtData &d) { @@ -213,32 +117,34 @@ static const rtosc::Ports PADnotePorts = obj->PCoarseDetune = k + (obj->PCoarseDetune/1024)*1024; } }}, + }; -#if 0 -rtosc::ClonePort non_realtime{ - PADnotePorts, - { - //Recursions - {"oscilgen/", rRecurCb(oscilgen)}, - {"resonance/", rRecurCb(resonance)}, - //Harmonic Shape - {"Pmode::i", rParamICb} - - {Php.base.type::i, rOptionCb}, - {Php.base.par1::i, rParamZynCb}, - {Php.freqmult::i, rParamZynCb}, - {Php.modulator.par1::i, rParamZynCb}, - {Php.modulator.freq::i, rParamZynCb}, - {Php.width::i, rParamZynCb}, - {Php.amp.mode::i, rOptionCb}, +const rtosc::Ports PADnoteParameters::non_realtime_ports = +{ + //Harmonic Source Distribution + rRecurp(oscilgen, "Oscillator"), + rRecurp(resonance, "Resonance"), + + //Harmonic Shape + rOption(Pmode, rMap(min, 0), rMap(max, 2), rOptions(bandwidth,discrete,continious), + "Harmonic Distribution Model"), + rOption(Php.base.type, rOptions(Gaussian, Rectanglar, Double Exponential), + "Harmonic profile shape"), + rParamZyn(Php.base.par1, "Harmonic shape distribution parameter"), + rParamZyn(Php.freqmult, "Frequency multiplier on distribution"), + rParamZyn(Php.modulator.par1, "Distribution modulator parameter"), + rParamZyn(Php.modulator.freq, "Frequency of modulator parameter"), + rParamZyn(Php.width, "Width of base harmonic"), + rOption(Php.amp.mode, rOptions(Sum, Mult, Div1, Div2), + "Amplitude harmonic multiplier type"), //Harmonic Modulation - {Php.amp.type::i, rOptionCb}, - {Php.amp.par1::i, rParamZynCb}, - {Php.amp.par2::i, rParamZynCb}, - {Php.autoscale, rToggleCb}, - //... + rOption(Php.amp.type, rOptions(Off, Gauss, Sine, Flat), + "Type of amplitude multipler"), + rParamZyn(Php.amp.par1, "Amplitude multiplier parameter"), + rParamZyn(Php.amp.par2, "Amplitude multiplier parameter"), + rToggle(Php.autoscale, "Autoscaling Harmonics"), rOption(Php.onehalf, rOptions(Full, Upper Half, Lower Half), "Harmonic cutoff model"), @@ -272,13 +178,54 @@ rtosc::ClonePort non_realtime{ rOption(Pquality.smpoct, rOptions(0.5, 1, 2, 3, 4, 6, 12), "Samples per octave"), - rParamI(Pquality.oct, rLinear(0,7), + rParamI(Pquality.oct, rLinear(0,7), "Number of octaves to sample (above the first sample"), + {"Pbandwidth::i", rProp(parameter) rLinear(0,1000) rDoc("Bandwith Of Harmonics"), NULL, + [](const char *msg, rtosc::RtData &d) { + PADnoteParameters *p = ((PADnoteParameters*)d.obj); + if(rtosc_narguments(msg)) { + p->setPbandwidth(rtosc_argument(msg, 0).i); + } else { + d.reply(d.loc, "i", p->Pbandwidth); + }}}, + + {"bandwidthvalue:", rMap(unit, cents) rDoc("Get Bandwidth"), NULL, + [](const char *, rtosc::RtData &d) { + PADnoteParameters *p = ((PADnoteParameters*)d.obj); + d.reply(d.loc, "f", p->setPbandwidth(p->Pbandwidth)); + }}, + + + {"nhr:", rProp(non-realtime) rDoc("Returns the harmonic shifts"), + NULL, [](const char *, rtosc::RtData &d) { + PADnoteParameters *p = ((PADnoteParameters*)d.obj); + const unsigned n = p->synth.oscilsize / 2; + float *tmp = new float[n]; + *tmp = 0; + for(unsigned i=1; i<n; ++i) + tmp[i] = p->getNhr(i); + d.reply(d.loc, "b", n*sizeof(float), tmp); + delete[] tmp;}}, + {"profile:i", rProp(non-realtime) rDoc("UI display of the harmonic profile"), + NULL, [](const char *m, rtosc::RtData &d) { + PADnoteParameters *p = ((PADnoteParameters*)d.obj); + const int n = rtosc_argument(m, 0).i; + if(n<=0) + return; + float *tmp = new float[n]; + float realbw = p->getprofile(tmp, n); + d.reply(d.loc, "b", n*sizeof(float), tmp); + d.reply(d.loc, "i", realbw); + delete[] tmp;}}, +}; + +const rtosc::MergePorts PADnoteParameters::ports = +{ + &PADnoteParameters::non_realtime_ports, + &PADnoteParameters::realtime_ports }; -#endif -const rtosc::Ports &PADnoteParameters::ports = PADnotePorts; PADnoteParameters::PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_) :Presets(), synth(synth_) diff --git a/src/Params/PADnoteParameters.h b/src/Params/PADnoteParameters.h @@ -165,7 +165,9 @@ class PADnoteParameters:public Presets void sampleGenerator(PADnoteParameters::callback cb, std::function<bool()> do_abort); - static const rtosc::Ports &ports; + static const rtosc::MergePorts ports; + static const rtosc::Ports non_realtime_ports; + static const rtosc::Ports realtime_ports; private: void generatespectrum_bandwidthMode(float *spectrum, diff --git a/src/Synth/OscilGen.cpp b/src/Synth/OscilGen.cpp @@ -39,7 +39,7 @@ pthread_t main_thread; #define rObject OscilGen -const rtosc::Ports OscilGen::ports = { +const rtosc::Ports OscilGen::non_realtime_ports = { rSelf(OscilGen), rPaste, //TODO ensure min/max @@ -92,23 +92,6 @@ const rtosc::Ports OscilGen::ports = { rParamZyn(Pmodulationpar2, "modulation parameter"), rParamZyn(Pmodulationpar3, "modulation parameter"), - //XXX Start of realtime parameters - rParamZyn(Prand, "Oscilator Phase Randomness: smaller than 0 is \"" - "group\", larger than 0 is for each harmonic"), - rParamZyn(Pamprandpower, - "Variance of harmonic randomness"), - rOption(Pamprandtype, rOptions(None, Pow, Sin), - "Harmonic random distribution to select from"), - rOption(Padaptiveharmonics, - rOptions(OFF, ON, Square, 2xSub, 2xAdd, 3xSub, 3xAdd, 4xSub, 4xAdd), - "Adaptive Harmonics Mode"), - rParamI(Padaptiveharmonicsbasefreq, rLinear(0,255), - "Base frequency of adaptive harmonic (30..3000Hz)"), - rParamI(Padaptiveharmonicspower,rLinear(0,200), - "Adaptive Harmonic Strength"), - rParamZyn(Padaptiveharmonicspar, - "Adaptive Harmonics Postprocessing Power"), - //XXX End of realtime parameters //TODO update to rArray and test {"phase#128::c", rProp(parameter) rDoc("Sets harmonic phase"), @@ -165,6 +148,7 @@ const rtosc::Ports OscilGen::ports = { }}, {"waveform:", rProp(non-realtime) rDoc("Returns waveform points"), NULL, [](const char *, rtosc::RtData &d) { + printf("WAVEFORM PORT REPORTING IN\n"); OscilGen &o = *((OscilGen*)d.obj); const unsigned n = o.synth.oscilsize; float *smps = new float[n]; @@ -200,19 +184,25 @@ const rtosc::Ports OscilGen::ports = { #define rForwardCb [](const char *msg, rtosc::RtData &d) {\ printf("fowarding...\n"); d.forward();} - -const rtosc::ClonePorts OscilGen::realtime_ports{ - OscilGen::ports, { - {"self:", [](const char *, rtosc::RtData &d){ - d.reply(d.loc, "b", sizeof(d.obj), &d.obj);}}, - {"Prand::i", rParamICb(Prand)}, - {"Pamprandpower::i", rParamICb(Pamprandpower)}, - {"Pamprandtype::i:c", rOptionCb(Pamprandtype)}, - {"Padaptiveharmonics::i:c", rOptionCb(Padaptiveharmonics)}, - {"Padaptiveharmonicsbasefreq::i", rParamICb(Padaptiveharmonicsbasefreq)}, - {"Padaptiveharmonicspower::i", rParamICb(Padaptiveharmonicspower)}, - {"Padaptiveharmonicspar::i", rParamICb(Padaptiveharmonicspar)}, - {"prepare:b", [](const char *m, rtosc::RtData &d) { +const rtosc::Ports OscilGen::realtime_ports{ + rSelf(OscilGen), + rParamZyn(Prand, "Oscilator Phase Randomness: smaller than 0 is \"" + "group\", larger than 0 is for each harmonic"), + rParamZyn(Pamprandpower, + "Variance of harmonic randomness"), + rOption(Pamprandtype, rOptions(None, Pow, Sin), + "Harmonic random distribution to select from"), + rOption(Padaptiveharmonics, + rOptions(OFF, ON, Square, 2xSub, 2xAdd, 3xSub, 3xAdd, 4xSub, 4xAdd), + "Adaptive Harmonics Mode"), + rParamI(Padaptiveharmonicsbasefreq, rLinear(0,255), + "Base frequency of adaptive harmonic (30..3000Hz)"), + rParamI(Padaptiveharmonicspower,rLinear(0,200), + "Adaptive Harmonic Strength"), + rParamZyn(Padaptiveharmonicspar, + "Adaptive Harmonics Postprocessing Power"), + {"prepare:b", rProp(internal) rProp(realtime) rProp(pointer) rDoc("Sets prepared fft data"), + NULL, [](const char *m, rtosc::RtData &d) { //fprintf(stderr, "prepare:b got a message from '%s'\n", m); OscilGen &o = *(OscilGen*)d.obj; assert(rtosc_argument(m,0).b.len == sizeof(void*)); @@ -221,8 +211,12 @@ const rtosc::ClonePorts OscilGen::realtime_ports{ o.oscilFFTfreqs = *(fft_t**)rtosc_argument(m,0).b.data; }}, - {"*", rForwardCb} -}}; +}; + +const rtosc::MergePorts OscilGen::ports{ + &OscilGen::realtime_ports, + &OscilGen::non_realtime_ports +}; //operations on FFTfreqs diff --git a/src/Synth/OscilGen.h b/src/Synth/OscilGen.h @@ -114,8 +114,9 @@ class OscilGen:public Presets bool ADvsPAD; //if it is used by ADsynth or by PADsynth - static const rtosc::Ports ports; - static const rtosc::ClonePorts realtime_ports; + static const rtosc::MergePorts ports; + static const rtosc::Ports non_realtime_ports; + static const rtosc::Ports realtime_ports; /* Oscillator Frequencies - * this is different than the hamonics set-up by the user, diff --git a/src/Tests/MessageTest.h b/src/Tests/MessageTest.h @@ -30,6 +30,7 @@ #include <unistd.h> #include "../Misc/MiddleWare.h" #include "../Misc/Master.h" +#include "../Misc/Part.h" #include "../Misc/PresetExtractor.h" #include "../Misc/PresetExtractor.cpp" #include "../Misc/Util.h" @@ -59,7 +60,7 @@ class MessageTest:public CxxTest::TestSuite delete synth; } - void notestKitEnable(void) + void testKitEnable(void) { const char *msg = NULL; mw->transmitMsg("/part0/kit0/Psubenabled", "T"); @@ -71,7 +72,7 @@ class MessageTest:public CxxTest::TestSuite TS_ASSERT_EQUALS(string("/part0/kit0/Psubenabled"), msg); } - void notestBankCapture(void) + void testBankCapture(void) { mw->transmitMsg("/bank/slots", ""); TS_ASSERT(!ms->uToB->hasNext()); @@ -92,6 +93,8 @@ class MessageTest:public CxxTest::TestSuite ms->applyOscEvent(ms->uToB->read()); TS_ASSERT(!ms->uToB->hasNext()); + ms->part[0]->kit[0].adpars->VoicePar[0].FMSmp->Pbasefuncpar = 32; + int do_exit = 0; std::thread t([&do_exit,this](){ int tries = 0; @@ -109,11 +112,13 @@ class MessageTest:public CxxTest::TestSuite printf("====Copy From ADsynth modulator\n"); mw->transmitMsg("/presets/copy", "s", "/part0/kit0/adpars/VoicePar0/FMSmp/"); + TS_ASSERT(ms->part[0]->kit[0].padpars->oscilgen->Pbasefuncpar != 32); //Paste to PADsynth printf("====Paste to PADsynth\n"); mw->transmitMsg("/presets/paste", "s", "/part0/kit0/padpars/oscilgen/"); do_exit = 1; t.join(); + TS_ASSERT_EQUALS(ms->part[0]->kit[0].padpars->oscilgen->Pbasefuncpar, 32); } diff --git a/src/UI/BankView.cpp b/src/UI/BankView.cpp @@ -21,7 +21,7 @@ void BankList::init(std::string path) void BankList::OSC_raw(const char *msg) { - if(!strcmp(msg, "/bank-list") && !strcmp(rtosc_argument_string(msg),"iss")) { + if(!strcmp(msg, "/bank/bank_select") && !strcmp(rtosc_argument_string(msg),"iss")) { const int pos = rtosc_argument(msg, 0).i; const char *path = rtosc_argument(msg, 1).s; @@ -31,9 +31,8 @@ void BankList::OSC_raw(const char *msg) this->clear(); this->add(path); - osc->write("/loadbank"); } - if(!strcmp(msg, "/loadbank")&& !strcmp(rtosc_argument_string(msg),"i")) { + if(!strcmp(msg, "/bank/bank_select")&& !strcmp(rtosc_argument_string(msg),"i")) { value(rtosc_argument(msg, 0).i); } } @@ -248,7 +247,7 @@ void BankView::init(Fl_Osc_Interface *osc_, BankViewControls *bvc_, int *npart_) //Request Values for(int i=0; i<160; ++i) - osc->write("/refresh_bank", "i", i); + osc->write("/bank/slot"+to_s(i), ""); } /* @@ -271,8 +270,8 @@ void BankView::react(int event, int nslot) //Rename slot if (event==2 && !isempty && mode!=4) { if(const char *name=fl_input("Slot (instrument) name:", slot.name())) { - osc->write("/bank-rename", "is", nslot, name); - osc->write("/refresh_bank", "i", nslot); + osc->write("/bank/rename_slot", "is", nslot, name); + osc->write("/bank/slot"+to_s(nslot), ""); } } @@ -289,8 +288,8 @@ void BankView::react(int event, int nslot) if(event==1 && mode==2){ if(isempty || fl_choice("Overwrite the slot no. %d ?","No","Yes",NULL,nslot+1)) { - osc->write("/save-bank-part", "ii", *npart, nslot); - osc->write("/refresh_bank", "i", nslot); + osc->write("/bank/save_to_slot", "ii", *npart, nslot); + osc->write("/bank/slot"+to_s(nslot), ""); } bvc->mode(1); } @@ -300,8 +299,8 @@ void BankView::react(int event, int nslot) if(event==1 && mode==3) { if (!isempty && fl_choice("Clear the slot no. %d ?","No","Yes",NULL, nslot+1)) { - osc->write("/clear-bank-slot", "i", nslot); - osc->write("/refresh_bank", "i", nslot); + osc->write("/bank/clear-slot", "i", nslot); + osc->write("/bank/slot"+to_s(nslot), ""); } bvc->mode(1); } @@ -309,9 +308,9 @@ void BankView::react(int event, int nslot) //Swap if(mode==4) { if(event==1 && nselected>=0){ - osc->write("/swap-bank-slots", "ii", nselected, nslot); - osc->write("/refresh_bank", "i", nslot); - osc->write("/refresh_bank", "i", nselected); + osc->write("/bank/swap_slots", "ii", nselected, nslot); + osc->write("/bank/slot"+to_s(nslot), ""); + osc->write("/bank/slot"+to_s(nselected), ""); nselected=-1; } else if(nselected<0 || event==2) { nselected=nslot; @@ -345,6 +344,6 @@ void BankView::refresh(void) return; for(int i=0; i<160; ++i) - osc->write("/refresh_bank", "i", i); + osc->write("/bank/slot"+to_s(i), ""); } diff --git a/src/globals.h b/src/globals.h @@ -34,7 +34,7 @@ #endif //Forward Declarations -namespace rtosc{struct Ports; class ThreadLink;}; +namespace rtosc{struct Ports; struct ClonePorts; struct MergePorts; class ThreadLink;}; class EffectMgr; class ADnoteParameters; struct ADnoteGlobalParam;