| @@ -68,6 +68,7 @@ extern "C" { | |||||
| #include "zynaddsubfx/rtosc/cpp/undo-history.cpp" | #include "zynaddsubfx/rtosc/cpp/undo-history.cpp" | ||||
| // zynaddsubfx includes | // zynaddsubfx includes | ||||
| #include "zynaddsubfx/Containers/MultiPseudoStack.cpp" | |||||
| #include "zynaddsubfx/Containers/NotePool.cpp" | #include "zynaddsubfx/Containers/NotePool.cpp" | ||||
| #include "zynaddsubfx/DSP/AnalogFilter.cpp" | #include "zynaddsubfx/DSP/AnalogFilter.cpp" | ||||
| #include "zynaddsubfx/DSP/FFTwrapper.cpp" | #include "zynaddsubfx/DSP/FFTwrapper.cpp" | ||||
| @@ -47,7 +47,8 @@ | |||||
| using namespace std; | using namespace std; | ||||
| Bank::Bank(Config *config) | Bank::Bank(Config *config) | ||||
| :bankpos(0), defaultinsname(" "), config(config) | |||||
| :bankpos(0), defaultinsname(" "), config(config), | |||||
| bank_msb(0), bank_lsb(0) | |||||
| { | { | ||||
| clearbank(); | clearbank(); | ||||
| bankfiletitle = dirname; | bankfiletitle = dirname; | ||||
| @@ -222,6 +223,12 @@ int Bank::loadbank(string bankdirname) | |||||
| if(dir == NULL) | if(dir == NULL) | ||||
| return -1; | return -1; | ||||
| //set msb when possible | |||||
| bank_msb = 0; | |||||
| for(unsigned i=0; i<banks.size(); i++) | |||||
| if(banks[i].dir == bankdirname) | |||||
| bank_msb = i; | |||||
| dirname = bankdirname; | dirname = bankdirname; | ||||
| bankfiletitle = dirname; | bankfiletitle = dirname; | ||||
| @@ -385,6 +392,18 @@ void Bank::rescanforbanks() | |||||
| } | } | ||||
| } | } | ||||
| void Bank::setMsb(uint8_t msb) | |||||
| { | |||||
| if(msb < banks.size() && banks[msb].dir != bankfiletitle) | |||||
| loadbank(banks[msb].dir); | |||||
| } | |||||
| void Bank::setLsb(uint8_t lsb) | |||||
| { | |||||
| //should only involve values of 0/1 for the time being... | |||||
| bank_lsb = limit<uint8_t>(lsb,0,1); | |||||
| } | |||||
| // private stuff | // private stuff | ||||
| @@ -66,6 +66,9 @@ class Bank | |||||
| void rescanforbanks(); | void rescanforbanks(); | ||||
| void setMsb(uint8_t msb); | |||||
| void setLsb(uint8_t lsb); | |||||
| struct bankstruct { | struct bankstruct { | ||||
| bool operator<(const bankstruct &b) const; | bool operator<(const bankstruct &b) const; | ||||
| std::string dir; | std::string dir; | ||||
| @@ -99,6 +102,10 @@ class Bank | |||||
| void scanrootdir(std::string rootdir); //scans a root dir for banks | void scanrootdir(std::string rootdir); //scans a root dir for banks | ||||
| Config* const config; | Config* const config; | ||||
| public: | |||||
| uint8_t bank_msb; | |||||
| uint8_t bank_lsb; | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| @@ -453,7 +453,7 @@ void Master::setController(char chan, int type, int par) | |||||
| ctl.setparameternumber(type, par); | ctl.setparameternumber(type, par); | ||||
| int parhi = -1, parlo = -1, valhi = -1, vallo = -1; | 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) { | switch(parhi) { | ||||
| case 0x04: //System Effects | case 0x04: //System Effects | ||||
| if(parlo < NUM_SYS_EFX) | if(parlo < NUM_SYS_EFX) | ||||
| @@ -464,14 +464,8 @@ void Master::setController(char chan, int type, int par) | |||||
| insefx[parlo]->seteffectparrt(valhi, vallo); | insefx[parlo]->seteffectparrt(valhi, vallo); | ||||
| break; | 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 | 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)) | if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0)) | ||||
| part[npart]->SetController(type, par); | part[npart]->SetController(type, par); | ||||
| @@ -22,6 +22,7 @@ | |||||
| #include "Master.h" | #include "Master.h" | ||||
| #include "Part.h" | #include "Part.h" | ||||
| #include "PresetExtractor.h" | #include "PresetExtractor.h" | ||||
| #include "../Containers/MultiPseudoStack.h" | |||||
| #include "../Params/PresetsStore.h" | #include "../Params/PresetsStore.h" | ||||
| #include "../Params/ADnoteParameters.h" | #include "../Params/ADnoteParameters.h" | ||||
| #include "../Params/SUBnoteParameters.h" | #include "../Params/SUBnoteParameters.h" | ||||
| @@ -578,6 +579,10 @@ public: | |||||
| const char *rtmsg = bToU->read(); | const char *rtmsg = bToU->read(); | ||||
| bToUhandle(rtmsg); | 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 *bToU; | ||||
| rtosc::ThreadLink *uToB; | rtosc::ThreadLink *uToB; | ||||
| //Link to the unknown | |||||
| MultiQueue multi_thread_source; | |||||
| //LIBLO | //LIBLO | ||||
| lo_server server; | lo_server server; | ||||
| string last_url, curr_url; | 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 *path, const char *args, ...){(void)path;(void)args;}; | ||||
| //virtual void broadcast(const char *msg){(void)msg;}; | //virtual void broadcast(const char *msg){(void)msg;}; | ||||
| virtual void chain(const char *msg) override | virtual void chain(const char *msg) override | ||||
| { | { | ||||
| assert(msg); | assert(msg); | ||||
| @@ -835,6 +843,14 @@ rtosc::Ports bankPorts = { | |||||
| d.reply("/alert", "s", | d.reply("/alert", "s", | ||||
| "Failed To Clear Bank Slot, please check file permissions"); | "Failed To Clear Bank Slot, please check file permissions"); | ||||
| rEnd}, | 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}, | rEnd}, | ||||
| {"setprogram:i:c", 0, 0, | {"setprogram:i:c", 0, 0, | ||||
| rBegin; | 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}, | rEnd}, | ||||
| {"part#16/clear:", 0, 0, | {"part#16/clear:", 0, 0, | ||||
| rBegin; | 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"); | 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) | void MiddleWare::pendingSetBank(int bank) | ||||
| { | { | ||||
| impl->bToU->write("/setbank", "c", bank); | impl->bToU->write("/setbank", "c", bank); | ||||
| @@ -34,6 +34,9 @@ class MiddleWare | |||||
| //Handle a rtosc Message uToB | //Handle a rtosc Message uToB | ||||
| void transmitMsg_va(const char *, const char *args, va_list va); | 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 | //Indicate that a bank will be loaded | ||||
| //NOTE: Can only be called by realtime thread | //NOTE: Can only be called by realtime thread | ||||
| void pendingSetBank(int bank); | void pendingSetBank(int bank); | ||||
| @@ -88,7 +88,12 @@ void InMgr::flush(unsigned frameStart, unsigned frameStop) | |||||
| break; | break; | ||||
| case M_CONTROLLER: | 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; | break; | ||||
| case M_PGMCHANGE: | case M_PGMCHANGE: | ||||
| @@ -115,7 +115,7 @@ const rtosc::Ports OscilGen::non_realtime_ports = { | |||||
| d.reply(d.loc, "c", mag); | d.reply(d.loc, "c", mag); | ||||
| else { | else { | ||||
| mag = rtosc_argument(m,0).i; | mag = rtosc_argument(m,0).i; | ||||
| printf("setting magnitude\n\n"); | |||||
| //printf("setting magnitude\n\n"); | |||||
| //XXX hack hack | //XXX hack hack | ||||
| char *repath = strdup(d.loc); | char *repath = strdup(d.loc); | ||||
| char *edit = rindex(repath, '/')+1; | 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); | d.reply(d.loc, "b", n*sizeof(float), spc); | ||||
| delete[] 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"), | {"prepare:", rProp(non-realtime) rDoc("Performs setup operation to oscillator"), | ||||
| NULL, [](const char *, rtosc::RtData &d) { | NULL, [](const char *, rtosc::RtData &d) { | ||||
| //fprintf(stderr, "prepare: got a message from '%s'\n", m); | //fprintf(stderr, "prepare: got a message from '%s'\n", m); | ||||
| @@ -208,6 +196,18 @@ const rtosc::Ports OscilGen::realtime_ports{ | |||||
| "Adaptive Harmonic Strength"), | "Adaptive Harmonic Strength"), | ||||
| rParamZyn(Padaptiveharmonicspar, | rParamZyn(Padaptiveharmonicspar, | ||||
| "Adaptive Harmonics Postprocessing Power"), | "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"), | {"prepare:b", rProp(internal) rProp(realtime) rProp(pointer) rDoc("Sets prepared fft data"), | ||||
| NULL, [](const char *m, rtosc::RtData &d) { | NULL, [](const char *m, rtosc::RtData &d) { | ||||
| // fprintf(stderr, "prepare:b got a message from '%s'\n", m); | // 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]; | outoscilFFTfreqs = new fft_t[synth.oscilsize / 2]; | ||||
| oscilFFTfreqs = new fft_t[synth.oscilsize / 2]; | oscilFFTfreqs = new fft_t[synth.oscilsize / 2]; | ||||
| basefuncFFTfreqs = new fft_t[synth.oscilsize / 2]; | basefuncFFTfreqs = new fft_t[synth.oscilsize / 2]; | ||||
| cachedbasefunc = new float[synth.oscilsize]; | |||||
| cachedbasevalid = false; | |||||
| pendingfreqs = oscilFFTfreqs; | pendingfreqs = oscilFFTfreqs; | ||||
| randseed = 1; | randseed = 1; | ||||
| @@ -324,6 +326,7 @@ OscilGen::~OscilGen() | |||||
| delete[] outoscilFFTfreqs; | delete[] outoscilFFTfreqs; | ||||
| delete[] basefuncFFTfreqs; | delete[] basefuncFFTfreqs; | ||||
| delete[] oscilFFTfreqs; | delete[] oscilFFTfreqs; | ||||
| delete[] cachedbasefunc; | |||||
| } | } | ||||
| @@ -436,6 +439,17 @@ void OscilGen::convert2sine() | |||||
| prepare(); | 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 | * Get the base function | ||||
| */ | */ | ||||
| @@ -490,8 +504,10 @@ void OscilGen::getbasefunction(float *smps) | |||||
| if(func) | if(func) | ||||
| smps[i] = func(t, par); | smps[i] = func(t, par); | ||||
| else | |||||
| else if (Pcurrentbasefunc == 0) | |||||
| smps[i] = -sinf(2.0f * PI * i / synth.oscilsize); | smps[i] = -sinf(2.0f * PI * i / synth.oscilsize); | ||||
| else | |||||
| smps[i] = userfunc(t); | |||||
| } | } | ||||
| } | } | ||||
| @@ -1143,6 +1159,7 @@ void OscilGen::useasbase() | |||||
| oldbasefunc = Pcurrentbasefunc = 127; | oldbasefunc = Pcurrentbasefunc = 127; | ||||
| prepare(); | prepare(); | ||||
| cachedbasevalid = false; | |||||
| } | } | ||||
| @@ -1239,7 +1256,7 @@ void OscilGen::add2XML(XMLwrapper *xml) | |||||
| for(int i = 1; i < synth.oscilsize / 2; ++i) { | for(int i = 1; i < synth.oscilsize / 2; ++i) { | ||||
| float xc = basefuncFFTfreqs[i].real(); | float xc = basefuncFFTfreqs[i].real(); | ||||
| float xs = basefuncFFTfreqs[i].imag(); | 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->beginbranch("BF_HARMONIC", i); | ||||
| xml->addparreal("cos", xc); | xml->addparreal("cos", xc); | ||||
| xml->addparreal("sin", xs); | xml->addparreal("sin", xs); | ||||
| @@ -1326,10 +1343,6 @@ void OscilGen::getfromXML(XMLwrapper *xml) | |||||
| xml->exitbranch(); | xml->exitbranch(); | ||||
| } | } | ||||
| if(Pcurrentbasefunc != 0) | |||||
| changebasefunction(); | |||||
| if(xml->enterbranch("BASE_FUNCTION")) { | if(xml->enterbranch("BASE_FUNCTION")) { | ||||
| for(int i = 1; i < synth.oscilsize / 2; ++i) | for(int i = 1; i < synth.oscilsize / 2; ++i) | ||||
| if(xml->enterbranch("BF_HARMONIC", i)) { | if(xml->enterbranch("BF_HARMONIC", i)) { | ||||
| @@ -1340,9 +1353,13 @@ void OscilGen::getfromXML(XMLwrapper *xml) | |||||
| } | } | ||||
| xml->exitbranch(); | xml->exitbranch(); | ||||
| if(Pcurrentbasefunc != 0) | |||||
| changebasefunction(); | |||||
| clearDC(basefuncFFTfreqs); | clearDC(basefuncFFTfreqs); | ||||
| normalize(basefuncFFTfreqs, synth.oscilsize); | normalize(basefuncFFTfreqs, synth.oscilsize); | ||||
| } | |||||
| } else if(Pcurrentbasefunc != 0) | |||||
| changebasefunction(); | |||||
| } | } | ||||
| @@ -128,6 +128,8 @@ class OscilGen:public Presets | |||||
| //This array stores some termporary data and it has OSCIL_SIZE elements | //This array stores some termporary data and it has OSCIL_SIZE elements | ||||
| float *tmpsmps; | float *tmpsmps; | ||||
| fft_t *outoscilFFTfreqs; | 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 | 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 | //Do the oscil modulation stuff | ||||
| void modulation(fft_t *freqs); | void modulation(fft_t *freqs); | ||||
| float userfunc(float x); | |||||
| public: | public: | ||||
| //Check system for needed updates | //Check system for needed updates | ||||
| bool needPrepare(void); | bool needPrepare(void); | ||||
| @@ -91,18 +91,21 @@ class PhaseSlider {: {public Fl_Osc_TSlider} | |||||
| reset_value=0; | reset_value=0; | ||||
| setTransform(180.0/64, 0); | setTransform(180.0/64, 0); | ||||
| } {}} | } {}} | ||||
| Function {set_scope(Fl_Oscilloscope *newscope)} { | |||||
| } { code { oscope = newscope; } {} } | |||||
| Function {OSC_value(int i)} {open return_type void | Function {OSC_value(int i)} {open return_type void | ||||
| } { code { | } { code { | ||||
| value(64-i); | value(64-i); | ||||
| oscope->phase=i; | |||||
| oscope->parent()->redraw(); | |||||
| } {} } | } {} } | ||||
| Function {cb(void)} {open return_type void | 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 {} { | Fl_Slider {} { | ||||
| label Phase | 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 | 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 | class PhaseSlider | ||||
| } | } | ||||
| Fl_Choice extFMoscil { | Fl_Choice extFMoscil { | ||||
| @@ -615,10 +616,8 @@ o->redraw();} | |||||
| } | } | ||||
| Fl_Slider {} { | Fl_Slider {} { | ||||
| label Phase | 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 | 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 | class PhaseSlider | ||||
| } | } | ||||
| Fl_Check_Button {} { | Fl_Check_Button {} { | ||||
| @@ -303,7 +303,7 @@ void BankView::react(int event, int nslot) | |||||
| if(event==1 && mode==3) { | if(event==1 && mode==3) { | ||||
| if (!isempty && | if (!isempty && | ||||
| fl_choice("Clear the slot no. %d ?","No","Yes",NULL, nslot+1)) { | 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), ""); | osc->write("/bank/slot"+to_s(nslot), ""); | ||||
| } | } | ||||
| bvc->mode(1); | bvc->mode(1); | ||||
| @@ -21,8 +21,9 @@ class Fl_Osc_Choice:public Fl_Choice, public Fl_Osc_Widget | |||||
| void update(void); | void update(void); | ||||
| void callback(Fl_Callback *cb, void *p = NULL); | void callback(Fl_Callback *cb, void *p = NULL); | ||||
| void cb(void); | |||||
| virtual void cb(void); | |||||
| private: | private: | ||||
| int min; | int min; | ||||
| protected: | |||||
| std::pair<Fl_Callback*, void*> cb_data; | std::pair<Fl_Callback*, void*> cb_data; | ||||
| }; | }; | ||||
| @@ -95,6 +95,29 @@ class OGSlider {: {public Fl_Osc_TSlider} | |||||
| decl {bool phase;} {public local | 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} | class Oscilharmonic {: {public Fl_Group} | ||||
| } { | } { | ||||
| @@ -321,7 +344,7 @@ class OscilEditor {open : {public PresetsUI_} | |||||
| Fl_Group basefuncdisplaygroup {open | Fl_Group basefuncdisplaygroup {open | ||||
| xywh {370 10 360 300} box UP_FRAME | xywh {370 10 360 300} box UP_FRAME | ||||
| code0 {o->base = loc;} | code0 {o->base = loc;} | ||||
| code1 {o->osc = osc;} | |||||
| code1 {o->osc = osc; bftype->ogui = this;} | |||||
| code2 {assert(osc);} | code2 {assert(osc);} | ||||
| class Fl_Osc_Group | 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(),"");} | code0 {oscilo_base=new Fl_Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} | ||||
| code1 {oscilo_base->parent(o);oscilo_base->init(true);} | code1 {oscilo_base->parent(o);oscilo_base->init(true);} | ||||
| } {} | } {} | ||||
| Fl_Dial bfslider { | |||||
| Fl_Dial bfpar { | |||||
| callback {redrawoscil(); bfparval->value(o->value());} | callback {redrawoscil(); bfparval->value(o->value());} | ||||
| tooltip {Base Function Parameter} xywh {525 285 20 20} minimum -64 maximum 63 step 1 | tooltip {Base Function Parameter} xywh {525 285 20 20} minimum -64 maximum 63 step 1 | ||||
| code0 {o->init("Pbasefuncpar");} | code0 {o->init("Pbasefuncpar");} | ||||
| @@ -341,12 +364,11 @@ class OscilEditor {open : {public PresetsUI_} | |||||
| callback {basefuncdisplaygroup->redraw(); | callback {basefuncdisplaygroup->redraw(); | ||||
| redrawoscil(); | 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 | xywh {375 290 90 15} down_box BORDER_BOX labelsize 10 align 5 when 1 textsize 11 | ||||
| class Fl_Osc_Choice | |||||
| class OGWaveChoice | |||||
| } { | } { | ||||
| MenuItem {} { | MenuItem {} { | ||||
| label Sine | label Sine | ||||
| @@ -412,6 +434,10 @@ else basefuncmodulation->activate();} | |||||
| label Circle | label Circle | ||||
| xywh {127 127 100 20} labelfont 1 labelsize 11 | xywh {127 127 100 20} labelfont 1 labelsize 11 | ||||
| } | } | ||||
| MenuItem {} { | |||||
| label User | |||||
| xywh {127 127 100 20} labelfont 1 labelsize 11 hide | |||||
| } | |||||
| } | } | ||||
| Fl_Box {} { | Fl_Box {} { | ||||
| label {Base Func.} | label {Base Func.} | ||||
| @@ -502,9 +528,12 @@ if (autoclearbutton->value()){ | |||||
| fltbutton->do_callback(); | fltbutton->do_callback(); | ||||
| sabutton->value(0); | sabutton->value(0); | ||||
| sabutton->do_callback(); | sabutton->do_callback(); | ||||
| bfmodtype->value(0); | |||||
| bfmodtype->do_callback(); | |||||
| }; | }; | ||||
| osc->requestValue(loc+"prepare"); | osc->requestValue(loc+"prepare"); | ||||
| bftype->update(); | |||||
| basefuncdisplaygroup->redraw(); | basefuncdisplaygroup->redraw(); | ||||
| redrawoscil();} | redrawoscil();} | ||||
| @@ -885,8 +914,8 @@ redrawoscil();} | |||||
| osc->requestValue(loc+"convert2sine"); | osc->requestValue(loc+"convert2sine"); | ||||
| bftype->update(); | bftype->update(); | ||||
| bfslider->value(0); | |||||
| bfslider->do_callback(); | |||||
| bfpar->value(0); | |||||
| bfpar->do_callback(); | |||||
| redrawoscil(); | redrawoscil(); | ||||
| refresh();} | refresh();} | ||||
| @@ -937,7 +966,7 @@ rndslider = NULL; | |||||
| hrndtype = NULL; | hrndtype = NULL; | ||||
| magtype = NULL; | magtype = NULL; | ||||
| basefuncdisplaygroup = NULL; | basefuncdisplaygroup = NULL; | ||||
| bfslider = NULL; | |||||
| bfpar = NULL; | |||||
| bftype = NULL; | bftype = NULL; | ||||
| make_window(); | make_window(); | ||||
| bftype->init("Pcurrentbasefunc"); | bftype->init("Pcurrentbasefunc"); | ||||
| @@ -980,6 +1009,27 @@ oscils->update(); | |||||
| oscilo_base->update(); | oscilo_base->update(); | ||||
| oscils_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 {Oscilharmonic *h[(MAX_AD_HARMONICS - 1)];} {private local | ||||
| } | } | ||||
| decl {std::string loc;} {private local | decl {std::string loc;} {private local | ||||
| @@ -152,7 +152,7 @@ maxkcounter->do_callback();} | |||||
| xywh {490 0 40 15} box THIN_UP_BOX labelsize 11 | xywh {490 0 40 15} box THIN_UP_BOX labelsize 11 | ||||
| } | } | ||||
| Fl_Check_Button mutedcheck { | 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");} | code0 {o->init("Pmuted");} | ||||
| class Fl_Osc_Check | class Fl_Osc_Check | ||||
| } | } | ||||
| @@ -165,6 +165,7 @@ maxkcounter->do_callback();} | |||||
| label {Bass Drum} | label {Bass Drum} | ||||
| xywh {90 0 130 15} box THIN_DOWN_BOX labelfont 1 labelsize 10 align 20 | xywh {90 0 130 15} box THIN_DOWN_BOX labelfont 1 labelsize 10 align 20 | ||||
| code0 {o->init("Pname");} | code0 {o->init("Pname");} | ||||
| callback { o->oscWrite(o->ext, "s", o->value()); } | |||||
| class Fl_Osc_Input | class Fl_Osc_Input | ||||
| } | } | ||||
| Fl_Check_Button adcheck { | 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 | xywh {5 60 385 50} type Multiline color 124 labelsize 10 align 5 | ||||
| code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} | code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} | ||||
| code1 {o->init("info.Pauthor");} | code1 {o->init("info.Pauthor");} | ||||
| callback { o->oscWrite(o->ext, "s", o->value()); } | |||||
| class Fl_Osc_Input | class Fl_Osc_Input | ||||
| } | } | ||||
| Fl_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 | xywh {5 125 385 90} type Multiline color 124 labelsize 11 align 5 | ||||
| code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} | code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} | ||||
| code1 {o->init("info.Pcomments");} | code1 {o->init("info.Pcomments");} | ||||
| callback { o->oscWrite(o->ext, "s", o->value()); } | |||||
| class Fl_Osc_Input | class Fl_Osc_Input | ||||
| } | } | ||||
| Fl_Choice {} { | Fl_Choice {} { | ||||
| @@ -1118,7 +1121,7 @@ if (engine==2&&padnoteui) padnoteui->padnotewindow->show();} {} | |||||
| if (cleanuplastkit(kititem)) | if (cleanuplastkit(kititem)) | ||||
| return; | return; | ||||
| if(adnoteui || | if(adnoteui || | ||||
| (adnoteui=new ADnoteUI(loc+"kit"+to_s(kititem)+"/adpars/", osc))) | |||||
| (adnoteui=new ADnoteUI(loc+"kit"+to_s(kititem)+"/adpars/", osc))) { | |||||
| if(voicelist) | if(voicelist) | ||||
| adnoteui->ADnoteVoiceList->show(); | adnoteui->ADnoteVoiceList->show(); | ||||
| else { | else { | ||||
| @@ -1127,7 +1130,7 @@ if(adnoteui || | |||||
| else | else | ||||
| adnoteui->advoice->voiceFMparametersgroup->activate(); | adnoteui->advoice->voiceFMparametersgroup->activate(); | ||||
| adnoteui->ADnoteVoice->show(); | adnoteui->ADnoteVoice->show(); | ||||
| }} {}} | |||||
| }}} {}} | |||||
| Function {~PartUI()} {} { | Function {~PartUI()} {} { | ||||
| code {delete adnoteui; | code {delete adnoteui; | ||||