diff --git a/source/native-plugins/zynaddsubfx-src.cpp b/source/native-plugins/zynaddsubfx-src.cpp index c255c2601..9dd6da091 100644 --- a/source/native-plugins/zynaddsubfx-src.cpp +++ b/source/native-plugins/zynaddsubfx-src.cpp @@ -68,6 +68,7 @@ extern "C" { #include "zynaddsubfx/rtosc/cpp/undo-history.cpp" // zynaddsubfx includes +#include "zynaddsubfx/Containers/MultiPseudoStack.cpp" #include "zynaddsubfx/Containers/NotePool.cpp" #include "zynaddsubfx/DSP/AnalogFilter.cpp" #include "zynaddsubfx/DSP/FFTwrapper.cpp" diff --git a/source/native-plugins/zynaddsubfx/Misc/Bank.cpp b/source/native-plugins/zynaddsubfx/Misc/Bank.cpp index a04f6d4f5..e936d9d57 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Bank.cpp +++ b/source/native-plugins/zynaddsubfx/Misc/Bank.cpp @@ -47,7 +47,8 @@ using namespace std; Bank::Bank(Config *config) - :bankpos(0), defaultinsname(" "), config(config) + :bankpos(0), defaultinsname(" "), config(config), + bank_msb(0), bank_lsb(0) { clearbank(); bankfiletitle = dirname; @@ -222,6 +223,12 @@ int Bank::loadbank(string bankdirname) if(dir == NULL) return -1; + //set msb when possible + bank_msb = 0; + for(unsigned i=0; i(lsb,0,1); +} + // private stuff diff --git a/source/native-plugins/zynaddsubfx/Misc/Bank.h b/source/native-plugins/zynaddsubfx/Misc/Bank.h index d958251df..a41fea627 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Bank.h +++ b/source/native-plugins/zynaddsubfx/Misc/Bank.h @@ -66,6 +66,9 @@ class Bank void rescanforbanks(); + void setMsb(uint8_t msb); + void setLsb(uint8_t lsb); + struct bankstruct { bool operator<(const bankstruct &b) const; std::string dir; @@ -99,6 +102,10 @@ class Bank void scanrootdir(std::string rootdir); //scans a root dir for banks Config* const config; + + public: + uint8_t bank_msb; + uint8_t bank_lsb; }; #endif diff --git a/source/native-plugins/zynaddsubfx/Misc/Master.cpp b/source/native-plugins/zynaddsubfx/Misc/Master.cpp index 39b0f93bf..4af648620 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Master.cpp +++ b/source/native-plugins/zynaddsubfx/Misc/Master.cpp @@ -453,7 +453,7 @@ void Master::setController(char chan, int type, int par) ctl.setparameternumber(type, par); int parhi = -1, parlo = -1, valhi = -1, vallo = -1; - if(ctl.getnrpn(&parhi, &parlo, &valhi, &vallo) == 0) //this is NRPN + if(ctl.getnrpn(&parhi, &parlo, &valhi, &vallo) == 0) { //this is NRPN switch(parhi) { case 0x04: //System Effects if(parlo < NUM_SYS_EFX) @@ -464,14 +464,8 @@ void Master::setController(char chan, int type, int par) insefx[parlo]->seteffectparrt(valhi, vallo); break; } - } - else - if(type == C_bankselectmsb) { // Change current bank - //if(((unsigned int)par < bank.banks.size()) - // && (bank.banks[par].dir != bank.bankfiletitle)) - // bank.loadbank(bank.banks[par].dir); - } - else { //other controllers + } + } else { //other controllers for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) //Send the controller to all part assigned to the channel if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0)) part[npart]->SetController(type, par); diff --git a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp index b29254ebc..27bcca64f 100644 --- a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp +++ b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp @@ -22,6 +22,7 @@ #include "Master.h" #include "Part.h" #include "PresetExtractor.h" +#include "../Containers/MultiPseudoStack.h" #include "../Params/PresetsStore.h" #include "../Params/ADnoteParameters.h" #include "../Params/SUBnoteParameters.h" @@ -578,6 +579,10 @@ public: const char *rtmsg = bToU->read(); bToUhandle(rtmsg); } + while(auto *m = multi_thread_source.read()) { + handleMsg(m->memory); + multi_thread_source.free(m); + } } @@ -642,6 +647,9 @@ public: rtosc::ThreadLink *bToU; rtosc::ThreadLink *uToB; + //Link to the unknown + MultiQueue multi_thread_source; + //LIBLO lo_server server; string last_url, curr_url; @@ -701,7 +709,7 @@ class MwDataObj:public rtosc::RtData }; //virtual void broadcast(const char *path, const char *args, ...){(void)path;(void)args;}; //virtual void broadcast(const char *msg){(void)msg;}; - + virtual void chain(const char *msg) override { assert(msg); @@ -835,6 +843,14 @@ rtosc::Ports bankPorts = { d.reply("/alert", "s", "Failed To Clear Bank Slot, please check file permissions"); rEnd}, + {"msb:i", 0, 0, + rBegin; + impl.setMsb(rtosc_argument(msg, 0).i); + rEnd}, + {"lsb:i", 0, 0, + rBegin; + impl.setLsb(rtosc_argument(msg, 0).i); + rEnd}, }; /****************************************************************************** @@ -961,9 +977,12 @@ static rtosc::Ports middwareSnoopPorts = { rEnd}, {"setprogram:i:c", 0, 0, rBegin; - const int slot = rtosc_argument(msg, 0).i; - impl.pending_load[0]++; - impl.loadPart(0, impl.master->bank.ins[slot].filename.c_str(), impl.master); + Bank &bank = impl.master->bank; + const int slot = rtosc_argument(msg, 0).i + 128*bank.bank_lsb; + if(slot < BANK_SIZE) { + impl.pending_load[0]++; + impl.loadPart(0, impl.master->bank.ins[slot].filename.c_str(), impl.master); + } rEnd}, {"part#16/clear:", 0, 0, rBegin; @@ -1432,6 +1451,23 @@ void MiddleWare::transmitMsg_va(const char *path, const char *args, va_list va) fprintf(stderr, "Error in transmitMsg(va)n"); } +void MiddleWare::messageAnywhere(const char *path, const char *args, ...) +{ + auto *mem = impl->multi_thread_source.alloc(); + if(!mem) + fprintf(stderr, "Middleware::messageAnywhere memory pool out of memory...\n"); + + va_list va; + va_start(va,args); + if(rtosc_vmessage(mem->memory,mem->size,path,args,va)) + impl->multi_thread_source.write(mem); + else { + fprintf(stderr, "Middleware::messageAnywhere message too big...\n"); + impl->multi_thread_source.free(mem); + } +} + + void MiddleWare::pendingSetBank(int bank) { impl->bToU->write("/setbank", "c", bank); diff --git a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.h b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.h index c8ec5079d..1fc1491c8 100644 --- a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.h +++ b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.h @@ -34,6 +34,9 @@ class MiddleWare //Handle a rtosc Message uToB void transmitMsg_va(const char *, const char *args, va_list va); + //Send a message to middleware from an arbitrary thread + void messageAnywhere(const char *msg, const char *args, ...); + //Indicate that a bank will be loaded //NOTE: Can only be called by realtime thread void pendingSetBank(int bank); diff --git a/source/native-plugins/zynaddsubfx/Nio/InMgr.cpp b/source/native-plugins/zynaddsubfx/Nio/InMgr.cpp index 08333bbac..45b08f705 100644 --- a/source/native-plugins/zynaddsubfx/Nio/InMgr.cpp +++ b/source/native-plugins/zynaddsubfx/Nio/InMgr.cpp @@ -88,7 +88,12 @@ void InMgr::flush(unsigned frameStart, unsigned frameStop) break; case M_CONTROLLER: - master->setController(ev.channel, ev.num, ev.value); + if(ev.num == C_bankselectmsb) // Change current bank + middleware->spawnMaster()->bToU->write("/bank/msb", "i", ev.value); + else if(ev.num == C_bankselectlsb) // Change current bank (LSB) + middleware->spawnMaster()->bToU->write("/bank/lsb", "i", ev.value); + else + master->setController(ev.channel, ev.num, ev.value); break; case M_PGMCHANGE: diff --git a/source/native-plugins/zynaddsubfx/Synth/OscilGen.cpp b/source/native-plugins/zynaddsubfx/Synth/OscilGen.cpp index 9bcc9e674..c6a49c196 100644 --- a/source/native-plugins/zynaddsubfx/Synth/OscilGen.cpp +++ b/source/native-plugins/zynaddsubfx/Synth/OscilGen.cpp @@ -115,7 +115,7 @@ const rtosc::Ports OscilGen::non_realtime_ports = { d.reply(d.loc, "c", mag); else { mag = rtosc_argument(m,0).i; - printf("setting magnitude\n\n"); + //printf("setting magnitude\n\n"); //XXX hack hack char *repath = strdup(d.loc); char *edit = rindex(repath, '/')+1; @@ -158,18 +158,6 @@ const rtosc::Ports OscilGen::non_realtime_ports = { d.reply(d.loc, "b", n*sizeof(float), spc); delete[] spc; }}, - {"waveform:", rProp(non-realtime) rDoc("Returns waveform points"), - NULL, [](const char *, rtosc::RtData &d) { - OscilGen &o = *((OscilGen*)d.obj); - const unsigned n = o.synth.oscilsize; - float *smps = new float[n]; - memset(smps, 0, 4*n); - //printf("%d\n", o->needPrepare()); - o.get(smps,-1.0); - //printf("wave: %f %f %f %f\n", smps[0], smps[1], smps[2], smps[3]); - d.reply(d.loc, "b", n*sizeof(float), smps); - delete[] smps; - }}, {"prepare:", rProp(non-realtime) rDoc("Performs setup operation to oscillator"), NULL, [](const char *, rtosc::RtData &d) { //fprintf(stderr, "prepare: got a message from '%s'\n", m); @@ -208,6 +196,18 @@ const rtosc::Ports OscilGen::realtime_ports{ "Adaptive Harmonic Strength"), rParamZyn(Padaptiveharmonicspar, "Adaptive Harmonics Postprocessing Power"), + {"waveform:", rDoc("Returns waveform points"), + NULL, [](const char *, rtosc::RtData &d) { + OscilGen &o = *((OscilGen*)d.obj); + const unsigned n = o.synth.oscilsize; + float *smps = new float[n]; + memset(smps, 0, 4*n); + //printf("%d\n", o->needPrepare()); + o.get(smps,-1.0); + //printf("wave: %f %f %f %f\n", smps[0], smps[1], smps[2], smps[3]); + d.reply(d.loc, "b", n*sizeof(float), smps); + delete[] smps; + }}, {"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); @@ -310,6 +310,8 @@ OscilGen::OscilGen(const SYNTH_T &synth_, FFTwrapper *fft_, Resonance *res_) outoscilFFTfreqs = new fft_t[synth.oscilsize / 2]; oscilFFTfreqs = new fft_t[synth.oscilsize / 2]; basefuncFFTfreqs = new fft_t[synth.oscilsize / 2]; + cachedbasefunc = new float[synth.oscilsize]; + cachedbasevalid = false; pendingfreqs = oscilFFTfreqs; randseed = 1; @@ -324,6 +326,7 @@ OscilGen::~OscilGen() delete[] outoscilFFTfreqs; delete[] basefuncFFTfreqs; delete[] oscilFFTfreqs; + delete[] cachedbasefunc; } @@ -436,6 +439,17 @@ void OscilGen::convert2sine() prepare(); } +float OscilGen::userfunc(float x) +{ + if (!fft) + return 0; + if (!cachedbasevalid) { + fft->freqs2smps(basefuncFFTfreqs, cachedbasefunc); + cachedbasevalid = true; + } + return cinterpolate(cachedbasefunc, synth.oscilsize, synth.oscilsize * x); +} + /* * Get the base function */ @@ -490,8 +504,10 @@ void OscilGen::getbasefunction(float *smps) if(func) smps[i] = func(t, par); - else + else if (Pcurrentbasefunc == 0) smps[i] = -sinf(2.0f * PI * i / synth.oscilsize); + else + smps[i] = userfunc(t); } } @@ -1143,6 +1159,7 @@ void OscilGen::useasbase() oldbasefunc = Pcurrentbasefunc = 127; prepare(); + cachedbasevalid = false; } @@ -1239,7 +1256,7 @@ void OscilGen::add2XML(XMLwrapper *xml) for(int i = 1; i < synth.oscilsize / 2; ++i) { float xc = basefuncFFTfreqs[i].real(); float xs = basefuncFFTfreqs[i].imag(); - if((fabs(xs) > 1e-6f) && (fabs(xc) > 1e-6f)) { + if((fabs(xs) > 1e-6f) || (fabs(xc) > 1e-6f)) { xml->beginbranch("BF_HARMONIC", i); xml->addparreal("cos", xc); xml->addparreal("sin", xs); @@ -1326,10 +1343,6 @@ void OscilGen::getfromXML(XMLwrapper *xml) xml->exitbranch(); } - if(Pcurrentbasefunc != 0) - changebasefunction(); - - if(xml->enterbranch("BASE_FUNCTION")) { for(int i = 1; i < synth.oscilsize / 2; ++i) if(xml->enterbranch("BF_HARMONIC", i)) { @@ -1340,9 +1353,13 @@ void OscilGen::getfromXML(XMLwrapper *xml) } xml->exitbranch(); + if(Pcurrentbasefunc != 0) + changebasefunction(); + clearDC(basefuncFFTfreqs); normalize(basefuncFFTfreqs, synth.oscilsize); - } + } else if(Pcurrentbasefunc != 0) + changebasefunction(); } diff --git a/source/native-plugins/zynaddsubfx/Synth/OscilGen.h b/source/native-plugins/zynaddsubfx/Synth/OscilGen.h index d7dfbaab5..1157b4551 100644 --- a/source/native-plugins/zynaddsubfx/Synth/OscilGen.h +++ b/source/native-plugins/zynaddsubfx/Synth/OscilGen.h @@ -128,6 +128,8 @@ class OscilGen:public Presets //This array stores some termporary data and it has OSCIL_SIZE elements float *tmpsmps; fft_t *outoscilFFTfreqs; + float *cachedbasefunc; + bool cachedbasevalid; float hmag[MAX_AD_HARMONICS], hphase[MAX_AD_HARMONICS]; //the magnituides and the phases of the sine/nonsine harmonics @@ -149,6 +151,8 @@ class OscilGen:public Presets //Do the oscil modulation stuff void modulation(fft_t *freqs); + float userfunc(float x); + public: //Check system for needed updates bool needPrepare(void); diff --git a/source/native-plugins/zynaddsubfx/UI/ADnoteUI.fl b/source/native-plugins/zynaddsubfx/UI/ADnoteUI.fl index f830c5498..650851b95 100644 --- a/source/native-plugins/zynaddsubfx/UI/ADnoteUI.fl +++ b/source/native-plugins/zynaddsubfx/UI/ADnoteUI.fl @@ -91,18 +91,21 @@ class PhaseSlider {: {public Fl_Osc_TSlider} reset_value=0; setTransform(180.0/64, 0); } {}} + Function {set_scope(Fl_Oscilloscope *newscope)} { + } { code { oscope = newscope; } {} } Function {OSC_value(int i)} {open return_type void } { code { value(64-i); + oscope->phase=i; + oscope->parent()->redraw(); } {} } Function {cb(void)} {open return_type void - } { - code { - oscWrite(ext, "i", (int)(64-Fl_Slider::value())); - if(cb_data.first) - cb_data.first(this, cb_data.second); -} {} - } + } { code { + oscWrite(ext, "i", (int)(64-Fl_Slider::value())); + if(cb_data.first) + cb_data.first(this, cb_data.second); +} {} } + decl {Fl_Oscilloscope *oscope = NULL; } {private local} } @@ -430,10 +433,8 @@ o->redraw();} } Fl_Slider {} { label Phase - callback {oscFM->phase=64-(int)o->value(); -fmoscil->redraw();} xywh {645 415 105 15} type {Horz Knob} box NO_BOX labelsize 10 align 5 minimum -63 maximum 64 step 1 - code0 { o->init("PFMoscilphase", 'i'); } + code0 { o->init("PFMoscilphase", 'i'); o->set_scope(oscFM); } class PhaseSlider } Fl_Choice extFMoscil { @@ -615,10 +616,8 @@ o->redraw();} } Fl_Slider {} { label Phase - callback {osc->phase=64-(int)o->value(); -voiceoscil->redraw();} xywh {10 435 65 10} type {Horz Knob} box NO_BOX labelsize 10 align 5 minimum -63 maximum 64 step 1 - code0 { o->init("Poscilphase", 'i'); } + code0 { o->init("Poscilphase", 'i'); o->set_scope(osc); } class PhaseSlider } Fl_Check_Button {} { diff --git a/source/native-plugins/zynaddsubfx/UI/BankView.cpp b/source/native-plugins/zynaddsubfx/UI/BankView.cpp index e0abb69e1..b6d45ccbe 100644 --- a/source/native-plugins/zynaddsubfx/UI/BankView.cpp +++ b/source/native-plugins/zynaddsubfx/UI/BankView.cpp @@ -303,7 +303,7 @@ 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("/bank/clear-slot", "i", nslot); + osc->write("/bank/clear_slot", "i", nslot); osc->write("/bank/slot"+to_s(nslot), ""); } bvc->mode(1); diff --git a/source/native-plugins/zynaddsubfx/UI/Fl_Osc_Choice.H b/source/native-plugins/zynaddsubfx/UI/Fl_Osc_Choice.H index 3a13c7851..a8b097749 100644 --- a/source/native-plugins/zynaddsubfx/UI/Fl_Osc_Choice.H +++ b/source/native-plugins/zynaddsubfx/UI/Fl_Osc_Choice.H @@ -21,8 +21,9 @@ class Fl_Osc_Choice:public Fl_Choice, public Fl_Osc_Widget void update(void); void callback(Fl_Callback *cb, void *p = NULL); - void cb(void); + virtual void cb(void); private: int min; + protected: std::pair cb_data; }; diff --git a/source/native-plugins/zynaddsubfx/UI/OscilGenUI.fl b/source/native-plugins/zynaddsubfx/UI/OscilGenUI.fl index 8cd386a03..bb7291f0a 100644 --- a/source/native-plugins/zynaddsubfx/UI/OscilGenUI.fl +++ b/source/native-plugins/zynaddsubfx/UI/OscilGenUI.fl @@ -95,6 +95,29 @@ class OGSlider {: {public Fl_Osc_TSlider} decl {bool phase;} {public local } } +class OGWaveChoice {: {public Fl_Osc_Choice} +} { + Function {OGWaveChoice(int x,int y, int w, int h, const char *label=0) + :Fl_Osc_Choice(x,y,w,h,label)} {open + } { code {} {}} + Function {OSC_value(int i)} {open return_type void + } { code { value(i == 127 ? size()-2 : i); + ogui->setbfmodstatus(i); } {} } + Function {cb(void)} {open return_type void + } { + code { + int v = Fl_Osc_Choice::value(); + if (value() < size()-2) + oscWrite(ext, "i", v); + else + oscWrite(ext); + if(cb_data.first) + cb_data.first(this, cb_data.second); +} {}} + + decl { class OscilEditor *ogui;} { public } + +} class Oscilharmonic {: {public Fl_Group} } { @@ -321,7 +344,7 @@ class OscilEditor {open : {public PresetsUI_} Fl_Group basefuncdisplaygroup {open xywh {370 10 360 300} box UP_FRAME code0 {o->base = loc;} - code1 {o->osc = osc;} + code1 {o->osc = osc; bftype->ogui = this;} code2 {assert(osc);} class Fl_Osc_Group } { @@ -330,7 +353,7 @@ class OscilEditor {open : {public PresetsUI_} code0 {oscilo_base=new Fl_Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} code1 {oscilo_base->parent(o);oscilo_base->init(true);} } {} - Fl_Dial bfslider { + Fl_Dial bfpar { callback {redrawoscil(); bfparval->value(o->value());} tooltip {Base Function Parameter} xywh {525 285 20 20} minimum -64 maximum 63 step 1 code0 {o->init("Pbasefuncpar");} @@ -341,12 +364,11 @@ class OscilEditor {open : {public PresetsUI_} callback {basefuncdisplaygroup->redraw(); redrawoscil(); -if(!basefuncmodulation) -return; -if(o->value()==0||o->value()==127) basefuncmodulation->deactivate(); -else basefuncmodulation->activate();} +if(!basefuncmodulation) return; +setbfmodstatus(o->value()); +} xywh {375 290 90 15} down_box BORDER_BOX labelsize 10 align 5 when 1 textsize 11 - class Fl_Osc_Choice + class OGWaveChoice } { MenuItem {} { label Sine @@ -412,6 +434,10 @@ else basefuncmodulation->activate();} label Circle xywh {127 127 100 20} labelfont 1 labelsize 11 } + MenuItem {} { + label User + xywh {127 127 100 20} labelfont 1 labelsize 11 hide + } } Fl_Box {} { label {Base Func.} @@ -502,9 +528,12 @@ if (autoclearbutton->value()){ fltbutton->do_callback(); sabutton->value(0); sabutton->do_callback(); + bfmodtype->value(0); + bfmodtype->do_callback(); }; osc->requestValue(loc+"prepare"); + bftype->update(); basefuncdisplaygroup->redraw(); redrawoscil();} @@ -885,8 +914,8 @@ redrawoscil();} osc->requestValue(loc+"convert2sine"); bftype->update(); -bfslider->value(0); -bfslider->do_callback(); +bfpar->value(0); +bfpar->do_callback(); redrawoscil(); refresh();} @@ -937,7 +966,7 @@ rndslider = NULL; hrndtype = NULL; magtype = NULL; basefuncdisplaygroup = NULL; -bfslider = NULL; +bfpar = NULL; bftype = NULL; make_window(); bftype->init("Pcurrentbasefunc"); @@ -980,6 +1009,27 @@ oscils->update(); oscilo_base->update(); oscils_base->update();} {} } + Function {setbfmodstatus(int menuentry)} {open public + } { + code { + switch (menuentry){ + case 0: + bfpar->deactivate(); + bfparval->deactivate(); + basefuncmodulation->deactivate(); + break; + case 127: + bfpar->deactivate(); + bfparval->deactivate(); + basefuncmodulation->activate(); + break; + default: + bfpar->activate(); + bfparval->activate(); + basefuncmodulation->activate(); + } + } {} } + decl {Oscilharmonic *h[(MAX_AD_HARMONICS - 1)];} {private local } decl {std::string loc;} {private local diff --git a/source/native-plugins/zynaddsubfx/UI/PartUI.fl b/source/native-plugins/zynaddsubfx/UI/PartUI.fl index 6aef31ef1..25867bfc1 100644 --- a/source/native-plugins/zynaddsubfx/UI/PartUI.fl +++ b/source/native-plugins/zynaddsubfx/UI/PartUI.fl @@ -152,7 +152,7 @@ maxkcounter->do_callback();} xywh {490 0 40 15} box THIN_UP_BOX labelsize 11 } Fl_Check_Button mutedcheck { - public xywh {60 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 + xywh {60 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 code0 {o->init("Pmuted");} class Fl_Osc_Check } @@ -165,6 +165,7 @@ maxkcounter->do_callback();} label {Bass Drum} xywh {90 0 130 15} box THIN_DOWN_BOX labelfont 1 labelsize 10 align 20 code0 {o->init("Pname");} + callback { o->oscWrite(o->ext, "s", o->value()); } class Fl_Osc_Input } Fl_Check_Button adcheck { @@ -940,6 +941,7 @@ if (x==2) part->partefx[ninseff]->setdryonly(true); xywh {5 60 385 50} type Multiline color 124 labelsize 10 align 5 code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} code1 {o->init("info.Pauthor");} + callback { o->oscWrite(o->ext, "s", o->value()); } class Fl_Osc_Input } Fl_Input {} { @@ -947,6 +949,7 @@ if (x==2) part->partefx[ninseff]->setdryonly(true); xywh {5 125 385 90} type Multiline color 124 labelsize 11 align 5 code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} code1 {o->init("info.Pcomments");} + callback { o->oscWrite(o->ext, "s", o->value()); } class Fl_Osc_Input } Fl_Choice {} { @@ -1118,7 +1121,7 @@ if (engine==2&&padnoteui) padnoteui->padnotewindow->show();} {} if (cleanuplastkit(kititem)) return; if(adnoteui || - (adnoteui=new ADnoteUI(loc+"kit"+to_s(kititem)+"/adpars/", osc))) + (adnoteui=new ADnoteUI(loc+"kit"+to_s(kititem)+"/adpars/", osc))) { if(voicelist) adnoteui->ADnoteVoiceList->show(); else { @@ -1127,7 +1130,7 @@ if(adnoteui || else adnoteui->advoice->voiceFMparametersgroup->activate(); adnoteui->ADnoteVoice->show(); - }} {}} + }}} {}} Function {~PartUI()} {} { code {delete adnoteui;