| @@ -131,25 +131,20 @@ static const Ports master_ports = { | |||
| d.reply("/free", "sb", "Part", sizeof(void*), &m->part[i]); | |||
| m->part[i] = p; | |||
| p->initialize_rt(); | |||
| //printf("part %d is now pointer %p\n", i, p); | |||
| }}, | |||
| {"Pvolume::i", rProp(parameter) rDoc("Master Volume"), 0, | |||
| }}, | |||
| {"Pvolume::i", rProp(parameter) rLinear(0,127) rDoc("Master Volume"), 0, | |||
| [](const char *m, rtosc::RtData &d) { | |||
| if(rtosc_narguments(m)==0) { | |||
| d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume); | |||
| } else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') { | |||
| ((Master*)d.obj)->setPvolume(limit<char>(rtosc_argument(m,0).i,0,127)); | |||
| d.broadcast(d.loc, "i", ((Master*)d.obj)->Pvolume);}}}, | |||
| {"volume::i", rProp(parameter) rDoc("Master Volume"), 0, | |||
| {"volume::i", rProp(parameter) rLinear(0,127) rDoc("Master Volume"), 0, | |||
| [](const char *m, rtosc::RtData &d) { | |||
| if(rtosc_narguments(m)==0) { | |||
| d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume); | |||
| } else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') { | |||
| //printf("looking at value %d\n", rtosc_argument(m,0).i); | |||
| //printf("limited value is %d\n", limit<char>( | |||
| // rtosc_argument(m,0).i, 0,127)); | |||
| ((Master*)d.obj)->setPvolume(limit<char>(rtosc_argument(m,0).i,0,127)); | |||
| //printf("sets volume to value %d\n", ((Master*)d.obj)->Pvolume); | |||
| d.broadcast(d.loc, "i", ((Master*)d.obj)->Pvolume);}}}, | |||
| {"Psysefxvol#" STRINGIFY(NUM_SYS_EFX) "/::i", 0, &sysefxPort, | |||
| [](const char *msg, rtosc::RtData &d) { | |||
| @@ -176,18 +171,21 @@ static const Ports master_ports = { | |||
| [](const char *m,RtData &d){ | |||
| Master *M = (Master*)d.obj; | |||
| M->setController(rtosc_argument(m,0).i,rtosc_argument(m,1).i,rtosc_argument(m,2).i);}}, | |||
| {"Panic:", rDoc("Stop All Sound"), 0, | |||
| {"Panic:", rDoc("Stop all sound"), 0, | |||
| [](const char *, RtData &d) { | |||
| Master &M = *(Master*)d.obj; | |||
| M.ShutUp(); | |||
| }}, | |||
| {"freeze_state:", rDoc("Internal Read-only Mode"), 0, | |||
| {"freeze_state:", rProp(internal) rDoc("Disable OSC event handling\n" | |||
| "This sets up a read-only mode from which it's safe for another" | |||
| " thread to save parameters"), 0, | |||
| [](const char *,RtData &d) { | |||
| Master *M = (Master*)d.obj; | |||
| std::atomic_thread_fence(std::memory_order_release); | |||
| M->frozenState = true; | |||
| d.reply("/state_frozen", "");}}, | |||
| {"thaw_state:", rDoc("Internal Read-only Mode"), 0, | |||
| {"thaw_state:", rProp(internal) rDoc("Resume handling OSC messages\n" | |||
| "See /freeze_state for more information"), 0, | |||
| [](const char *,RtData &d) { | |||
| Master *M = (Master*)d.obj; | |||
| M->frozenState = false;}}, | |||
| @@ -216,11 +214,11 @@ static const Ports master_ports = { | |||
| m.memory->addMemory(mem, i); | |||
| m.pendingMemory = false; | |||
| }}, | |||
| {"samplerate:", rMap(unit, Hz) rDoc("Synthesizer Global Sample Rate"), 0, [](const char *, RtData &d) { | |||
| {"samplerate:", rMap(unit, Hz) rDoc("Get synthesizer sample rate"), 0, [](const char *, RtData &d) { | |||
| Master &m = *(Master*)d.obj; | |||
| d.reply("/samplerate", "f", m.synth.samplerate_f); | |||
| }}, | |||
| {"oscilsize:", rDoc("Synthesizer Global Oscillator Size"), 0, [](const char *, RtData &d) { | |||
| {"oscilsize:", rDoc("Get synthesizer oscillator size"), 0, [](const char *, RtData &d) { | |||
| Master &m = *(Master*)d.obj; | |||
| d.reply("/oscilsize", "f", m.synth.oscilsize_f); | |||
| d.reply("/oscilsize", "i", m.synth.oscilsize); | |||
| @@ -639,7 +637,7 @@ void Master::AudioOut(float *outl, float *outr) | |||
| DataObj d{loc_buf, 1024, this, bToU}; | |||
| memset(loc_buf, 0, sizeof(loc_buf)); | |||
| int events = 0; | |||
| while(uToB && uToB->hasNext() && events < 10) { | |||
| while(uToB && uToB->hasNext() && events < 100) { | |||
| const char *msg = uToB->read(); | |||
| if(!strcmp(msg, "/load-master")) { | |||
| @@ -58,10 +58,10 @@ const rtosc::Ports Microtonal::ports = { | |||
| rParamZyn(Pmiddlenote, "Scale degree 0 note"), | |||
| //TODO check to see if this should be exposed | |||
| rParamZyn(Pmapsize, "UNDOCUMENTED"), | |||
| rParamZyn(Pmapsize, "Size of key map"), | |||
| rToggle(Pmappingenabled, "Mapping Enable"), | |||
| rParams(Pmapping, "UNDOCUMENTED"), | |||
| rParams(Pmapping, 128, "Mapping of keys"), | |||
| rParamZyn(Pglobalfinedetune, "Fine detune for all notes"), | |||
| rString(Pname, MICROTONAL_MAX_NAME_LEN, "Microtonal Name"), | |||
| @@ -71,16 +71,18 @@ static const Ports partPorts = { | |||
| rParamZyn(Pvelsns, "Velocity sensing"), | |||
| rParamZyn(Pveloffs, "Velocity offset"), | |||
| rToggle(Pnoteon, "If the channel accepts note on events"), | |||
| //TODO FIXME Change to 0=OFF 1=MULTI 2=SINGLE | |||
| rParamI(Pkitmode, "Kit mode enable"), | |||
| rOption(Pkitmode, rOptions(Off, Multi-Kit, Single-Kit), "Kit mode/enable\n" | |||
| "Off - Only the first kit is ever utilized\n" | |||
| "Multi-kit - Every applicable kit is run for a note\n" | |||
| "Single-kit - The first applicable kit is run for a given note"), | |||
| rToggle(Pdrummode, "Drum mode enable\n" | |||
| "When drum mode is enabled all keys are mapped to 12tET and legato is disabled"), | |||
| rToggle(Ppolymode, "Polyphoney mode"), | |||
| rToggle(Plegatomode, "Legato enable"), | |||
| rToggle(Ppolymode, "Polyphony mode"), | |||
| rToggle(Plegatomode, "Legato mode"), | |||
| rParamZyn(info.Ptype, "Class of Instrument"), | |||
| rString(info.Pauthor, MAX_INFO_TEXT_SIZE, "Instrument Author"), | |||
| rString(info.Pcomments, MAX_INFO_TEXT_SIZE, "Instrument Comments"), | |||
| rString(Pname, PART_MAX_NAME_LEN, "Kit User Specified Label"), | |||
| rString(info.Pauthor, MAX_INFO_TEXT_SIZE, "Instrument author"), | |||
| rString(info.Pcomments, MAX_INFO_TEXT_SIZE, "Instrument comments"), | |||
| rString(Pname, PART_MAX_NAME_LEN, "User specified label"), | |||
| rArray(Pefxroute, NUM_PART_EFX, "Effect Routing"), | |||
| rArrayT(Pefxbypass, NUM_PART_EFX, "If an effect is bypassed"), | |||
| {"captureMin:", rDoc("Capture minimum valid note"), NULL, | |||
| @@ -90,7 +92,13 @@ static const Ports partPorts = { | |||
| [](const char *, RtData &r) | |||
| {Part *p = (Part*)r.obj; p->Pmaxkey = p->lastnote;}}, | |||
| {"polyType::c:i", rProp(parameter) rOptions(Polyphonic, Monophonic, Legato) | |||
| rDoc("synthesis polyphony type"), NULL, | |||
| rDoc("Synthesis polyphony type\n" | |||
| "Polyphonic - Each note is played independently\n" | |||
| "Monophonic - A single note is played at a time with" | |||
| " envelopes resetting between notes\n" | |||
| "Legato - A single note is played at a time without" | |||
| " envelopes resetting between notes\n" | |||
| ), NULL, | |||
| [](const char *msg, RtData &d) | |||
| { | |||
| Part *p = (Part*)d.obj; | |||
| @@ -188,8 +196,6 @@ static const Ports kitPorts = { | |||
| assert(o.subpars == NULL); | |||
| o.subpars = *(decltype(o.subpars)*)rtosc_argument(msg, 0).b.data; | |||
| }}, | |||
| // []( | |||
| }; | |||
| const Ports &Part::Kit::ports = kitPorts; | |||
| @@ -95,7 +95,8 @@ static const Ports voicePorts = { | |||
| //Modulator Stuff | |||
| rParamZyn(PFMEnabled, "Modulator Enable/Type"), | |||
| rOption(PFMEnabled, rOptions(none, morph, ring modulation, phase modulation, | |||
| frequency modulation, pitch modulation), "Modulator mode"), | |||
| rParamI(PFMVoice, "Modulator Oscillator Selection"), | |||
| rParamZyn(PFMVolume, "Modulator Magnitude"), | |||
| rParamZyn(PFMVolumeDamp, "Modulator HF dampening"), | |||
| @@ -36,13 +36,17 @@ using namespace rtosc; | |||
| static const rtosc::Ports _ports = { | |||
| rSelf(LFOParams), | |||
| rPaste, | |||
| rParamF(Pfreq, "frequency of LFO"), | |||
| rParamF(Pfreq, rLinear(0.0,1.0), "frequency of LFO\n" | |||
| "lfo frequency = (2^(10*Pfreq)-1)/12 * stretch\n" | |||
| "true frequency is [0,85.33] Hz"), | |||
| rParamZyn(Pintensity, "Intensity of LFO"), | |||
| rParamZyn(Pstartphase, rSpecial(random), "Starting Phase"), | |||
| rOption(PLFOtype,"Shape of LFO"), | |||
| rParamZyn(Prandomness, rSpecial(disable), "Amplitude Randomness"), | |||
| rParamZyn(Pfreqrand, rSpecial(disable), "Frequency Randomness"), | |||
| rParamZyn(Pdelay, rSpecial(disable), "Delay before LFO start"), | |||
| rOption(PLFOtype, rOptions(sine, triangle, square, ramp-up, ramp-down, | |||
| exponential-down1, exponential-down2), "Shape of LFO"), | |||
| rParamZyn(Prandomness, rSpecial(disable), "Amplitude Randomness (calculated uniformly at each cycle)"), | |||
| rParamZyn(Pfreqrand, rSpecial(disable), "Frequency Randomness (calculated uniformly at each cycle)"), | |||
| rParamZyn(Pdelay, rSpecial(disable), "Delay before LFO start\n" | |||
| "0..4 second delay"), | |||
| rToggle(Pcontinous, "Enable for global operation"), | |||
| rParamZyn(Pstretch, rCentered, "Note frequency stretch"), | |||
| }; | |||
| @@ -90,7 +90,7 @@ class PhaseSlider {: {public Fl_Osc_TSlider} | |||
| setRounding(1); | |||
| reset_value=0; | |||
| setTransform(180.0/64, 0); | |||
| }} | |||
| } {}} | |||
| Function {OSC_value(int i)} {open return_type void | |||
| } { code { | |||
| value(64-i); | |||
| @@ -277,7 +277,7 @@ void BankView::react(int event, int nslot) | |||
| } | |||
| //Reads from slot | |||
| if ((event==1)&&(mode==1)&&(!slot.empty())){ | |||
| if ((event==1)&&(mode==1) && !isempty){ | |||
| printf("Loading a part #%d with file '%s'\n", nslot, slot.filename()); | |||
| osc->write("/load-part", "is", *npart, slot.filename()); | |||
| osc->writeValue("/part"+to_s(*npart)+"/name", slot.name()); | |||
| @@ -287,25 +287,23 @@ void BankView::react(int event, int nslot) | |||
| //save(write) to slot | |||
| if(event==1 && mode==2){ | |||
| if(!isempty && !fl_choice("Overwrite the slot no. %d ?","No","Yes",NULL,nslot+1)) | |||
| return; | |||
| osc->write("/save-bank-part", "ii", *npart, nslot); | |||
| osc->write("/refresh_bank", "i", nslot); | |||
| //pthread_mutex_lock(&master->part[*npart]->load_mutex); | |||
| //bank->savetoslot(slot,master->part[*npart]); | |||
| //pthread_mutex_unlock(&master->part[*npart]->load_mutex); | |||
| 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); | |||
| } | |||
| bvc->mode(1); | |||
| } | |||
| //Clears the slot | |||
| if(event==1 && mode==3 && !isempty) { | |||
| if (fl_choice("Clear the slot no. %d ?","No","Yes",NULL, nslot+1)) { | |||
| 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); | |||
| } | |||
| bvc->mode(1); | |||
| } | |||
| //Swap | |||
| @@ -314,7 +312,6 @@ void BankView::react(int event, int nslot) | |||
| osc->write("/swap-bank-slots", "ii", nselected, nslot); | |||
| osc->write("/refresh_bank", "i", nslot); | |||
| osc->write("/refresh_bank", "i", nselected); | |||
| //bank->swapslot(nselected,slot); | |||
| nselected=-1; | |||
| } else if(nselected<0 || event==2) { | |||
| nselected=nslot; | |||
| @@ -106,7 +106,7 @@ int Fl_Osc_Slider::handle(int ev, int X, int Y, int W, int H) | |||
| if (step < 1) | |||
| step = 1; | |||
| } | |||
| int dy = minimum() <= maximum() ? Fl::e_dy : -Fl::e_dy; | |||
| int dy = minimum() <= maximum() ? -Fl::e_dy : Fl::e_dy; | |||
| handle_drag(clamp(value() + step * dy)); | |||
| } | |||
| return 1; | |||
| @@ -136,18 +136,23 @@ maxkcounter->do_callback();} | |||
| } | |||
| Fl_Button adeditbutton { | |||
| label edit | |||
| callback {partui->showparameters(n,0);} | |||
| callback { | |||
| if (Fl::event_shift()) { | |||
| partui->showvoiceparams(n, true); | |||
| } else if (Fl::event_ctrl()) { | |||
| partui->showvoiceparams(n, false); | |||
| } else | |||
| partui->showparameters(n,0); | |||
| } | |||
| xywh {420 0 40 15} box THIN_UP_BOX labelsize 11 | |||
| code1 {if (n==0) o->hide();} | |||
| } | |||
| Fl_Button subeditbutton { | |||
| label edit | |||
| callback {partui->showparameters(n,1);} | |||
| xywh {490 0 40 15} box THIN_UP_BOX labelsize 11 | |||
| code1 {if (n==0) o->hide();} | |||
| } | |||
| Fl_Check_Button mutedcheck { | |||
| private xywh {60 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 | |||
| public xywh {60 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 | |||
| code0 {o->init("Pmuted");} | |||
| class Fl_Osc_Check | |||
| } | |||
| @@ -167,7 +172,6 @@ maxkcounter->do_callback();} | |||
| else adeditbutton->deactivate();} | |||
| private xywh {400 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 | |||
| code0 {o->init("Padenabled");} | |||
| code1 {if (n==0) o->hide();} | |||
| class Fl_Osc_Check | |||
| } | |||
| Fl_Check_Button subcheck { | |||
| @@ -175,7 +179,6 @@ maxkcounter->do_callback();} | |||
| else subeditbutton->deactivate();} | |||
| private xywh {470 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 | |||
| code0 {o->init("Psubenabled");} | |||
| code1 {if (n==0) o->hide();} | |||
| class Fl_Osc_Check | |||
| } | |||
| Fl_Choice sendtoeffect { | |||
| @@ -188,14 +191,12 @@ maxkcounter->do_callback();} | |||
| label edit | |||
| callback {partui->showparameters(n,2);} | |||
| xywh {560 0 40 15} box THIN_UP_BOX labelsize 11 | |||
| code1 {if (n==0) o->hide();} | |||
| } | |||
| Fl_Check_Button padcheck { | |||
| callback {if (o->value()!=0) padeditbutton->activate(); | |||
| else padeditbutton->deactivate();} | |||
| private xywh {540 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 | |||
| code0 {o->init("Ppadenabled");} | |||
| code1 {if (n==0) o->hide();} | |||
| class Fl_Osc_Check | |||
| } | |||
| } | |||
| @@ -231,6 +232,11 @@ partui->showparameters(n,-1);//use to delete the ui, if it is not to item 0} | |||
| ext = "kit"+to_s(n)+"/"; | |||
| partui=partui_; | |||
| make_window(); | |||
| if (n == 0) | |||
| mutedcheck->deactivate(); | |||
| else | |||
| deactivate(); | |||
| //partkititem->show(); | |||
| end();} {} | |||
| } | |||
| @@ -353,7 +359,12 @@ if (event==FL_RIGHT_MOUSE){ | |||
| } | |||
| Fl_Button {} { | |||
| label {Edit instrument} | |||
| callback {instrumenteditwindow->show();} | |||
| callback { | |||
| if (Fl::event_shift() || Fl::event_ctrl()) | |||
| instrumentkitlist->show(); | |||
| else | |||
| instrumenteditwindow->show(); | |||
| } | |||
| xywh {15 90 130 30} color 52 labelfont 1 labelsize 13 | |||
| } | |||
| Fl_Button {} { | |||
| @@ -745,7 +756,7 @@ if (x==2) part->partefx[ninseff]->setdryonly(true); | |||
| Fl_Button {} { | |||
| label {Close Window} | |||
| callback {instrumentkitlist->hide();} | |||
| xywh {375 350 160 20} box THIN_UP_BOX | |||
| xywh {255 350 160 20} box THIN_UP_BOX | |||
| } | |||
| Fl_Scroll kitlist {open | |||
| xywh {0 15 670 330} type VERTICAL box UP_FRAME | |||
| @@ -781,7 +792,14 @@ if (x==2) part->partefx[ninseff]->setdryonly(true); | |||
| } | |||
| Fl_Choice {} { | |||
| label Mode | |||
| callback {if (o->value()==0) { kitlist->deactivate(); } else { kitlist->activate(); };} | |||
| callback {if (o->value()==0) { | |||
| for (int i=1;i<NUM_KIT_ITEMS;i++) | |||
| partkititem[i]->deactivate(); | |||
| partkititem[0]->mutedcheck->deactivate(); | |||
| } else { | |||
| for (int i=1;i<NUM_KIT_ITEMS;i++) | |||
| partkititem[i]->activate(); | |||
| partkititem[0]->mutedcheck->activate(); };} | |||
| xywh {35 350 70 15} down_box BORDER_BOX labelsize 11 textfont 1 textsize 11 | |||
| code0 {o->init("Pkitmode");} | |||
| class Fl_Osc_Choice | |||
| @@ -801,10 +819,21 @@ if (x==2) part->partefx[ninseff]->setdryonly(true); | |||
| } | |||
| Fl_Check_Button {} { | |||
| label {Drum mode} | |||
| xywh {285 350 70 15} down_box DOWN_BOX labelsize 10 | |||
| xywh {125 350 80 15} down_box DOWN_BOX labelsize 10 | |||
| code0 {o->init("Pdrummode");} | |||
| class Fl_Osc_Check | |||
| } | |||
| Fl_Button {} { | |||
| label Comments | |||
| callback {instrumenteditwindow->show();} | |||
| xywh {481 350 106 20} box THIN_UP_BOX | |||
| } | |||
| Fl_Button {} { | |||
| label Effects | |||
| callback {partfx->show();} selected | |||
| xywh {600 350 70 20} box THIN_UP_BOX | |||
| } | |||
| Fl_Box {} { | |||
| label {FX.r.} | |||
| xywh {620 0 30 15} labelfont 1 labelsize 11 align 18 | |||
| @@ -863,7 +892,14 @@ if (x==2) part->partefx[ninseff]->setdryonly(true); | |||
| } | |||
| Fl_Button adeditbutton { | |||
| label Edit | |||
| callback {showparameters(0,0);} | |||
| callback { | |||
| if (Fl::event_shift()) { | |||
| showvoiceparams(0, true); | |||
| } else if (Fl::event_ctrl()) { | |||
| showvoiceparams(0, false); | |||
| } else | |||
| showparameters(0,0); | |||
| } | |||
| xywh {15 281 80 34} color 51 selection_color 51 labelfont 1 labelsize 13 align 128 | |||
| } | |||
| } | |||
| @@ -1030,6 +1066,23 @@ end(); | |||
| //if (config.ui.showinstrumentinfo!=0) instrumenteditwindow->show(); | |||
| } {} | |||
| } | |||
| Function {cleanuplastkit(int kititem)} {open return_type int | |||
| } { | |||
| code { | |||
| if (kititem==lastkititem) | |||
| return 0; | |||
| delete adnoteui; | |||
| delete subnoteui; | |||
| delete padnoteui; | |||
| adnoteui=NULL;subnoteui=NULL;padnoteui=NULL; | |||
| lastkititem=kititem; | |||
| if(kititem>=NUM_KIT_ITEMS) return 1;//bad kit item | |||
| if(kititem<0) return 1; | |||
| return 0; | |||
| } {}} | |||
| Function {showparameters(int kititem,int engine)} {open | |||
| } { | |||
| code { | |||
| @@ -1043,16 +1096,8 @@ if (engine==-1){//this is used if I want to clear the engine from the part | |||
| return; | |||
| } | |||
| if (kititem!=lastkititem){ | |||
| delete adnoteui; | |||
| delete subnoteui; | |||
| delete padnoteui; | |||
| adnoteui=NULL;subnoteui=NULL;padnoteui=NULL; | |||
| lastkititem=kititem; | |||
| if(kititem>=NUM_KIT_ITEMS) return;//bad kit item | |||
| if(kititem<0) return; | |||
| } | |||
| if (cleanuplastkit(kititem)) | |||
| return; | |||
| if(!adnoteui && engine==0)//adsynenabledcheck->value()) | |||
| adnoteui=new ADnoteUI(loc+"kit"+to_s(kititem)+"/adpars/", osc); | |||
| @@ -1067,6 +1112,23 @@ if (engine==0&&adnoteui) adnoteui->ADnoteGlobalParameters->show(); | |||
| if (engine==1&&subnoteui) subnoteui->SUBparameters->show(); | |||
| if (engine==2&&padnoteui) padnoteui->padnotewindow->show();} {} | |||
| } | |||
| Function {showvoiceparams(int kititem, bool voicelist)} {open | |||
| } { | |||
| code { | |||
| if (cleanuplastkit(kititem)) | |||
| return; | |||
| if(adnoteui || | |||
| (adnoteui=new ADnoteUI(loc+"kit"+to_s(kititem)+"/adpars/", osc))) | |||
| if(voicelist) | |||
| adnoteui->ADnoteVoiceList->show(); | |||
| else { | |||
| if (adnoteui->advoice->mod_type->value() == 0) | |||
| adnoteui->advoice->voiceFMparametersgroup->deactivate(); | |||
| else | |||
| adnoteui->advoice->voiceFMparametersgroup->activate(); | |||
| adnoteui->ADnoteVoice->show(); | |||
| }} {}} | |||
| Function {~PartUI()} {} { | |||
| code {delete adnoteui; | |||
| delete subnoteui; | |||
| @@ -48,7 +48,7 @@ class SUBSlider {: {public Fl_Osc_TSlider} | |||
| } { | |||
| Function {SUBSlider(int x,int y, int w, int h, const char *label=0) | |||
| :Fl_Osc_TSlider(x,y,w,h,label)} {open | |||
| } { code {}} | |||
| } { code {} {}} | |||
| Function {OSC_value(char c)} {open return_type void | |||
| } { code { | |||
| value(127-c); | |||
| @@ -41,6 +41,7 @@ int WidgetPDial::handle(int event) | |||
| if (event == FL_RELEASE && Fl::event_clicks() == 1) { | |||
| Fl::event_clicks(0); | |||
| value(reset_value); | |||
| tipwin->hide(); | |||
| value_damage(); | |||
| if (this->when() != 0) | |||
| do_callback(); | |||
| @@ -791,6 +791,63 @@ static void units(std::ostream &o, const char *u) | |||
| using std::ostream; | |||
| using std::string; | |||
| static int enum_min(Port::MetaContainer meta) | |||
| { | |||
| int min = 0; | |||
| for(auto m:meta) | |||
| if(strstr(m.title, "map ")) | |||
| min = atoi(m.title+4); | |||
| for(auto m:meta) | |||
| if(strstr(m.title, "map ")) | |||
| min = min>atoi(m.title+4) ? atoi(m.title+4) : min; | |||
| return min; | |||
| } | |||
| static int enum_max(Port::MetaContainer meta) | |||
| { | |||
| int max = 0; | |||
| for(auto m:meta) | |||
| if(strstr(m.title, "map ")) | |||
| max = atoi(m.title+4); | |||
| for(auto m:meta) | |||
| if(strstr(m.title, "map ")) | |||
| max = max<atoi(m.title+4) ? atoi(m.title+4) : max; | |||
| return max; | |||
| } | |||
| static ostream &add_options(ostream &o, Port::MetaContainer meta) | |||
| { | |||
| string sym_names = "xyzabcdefghijklmnopqrstuvw"; | |||
| int sym_idx = 0; | |||
| bool has_options = false; | |||
| for(auto m:meta) | |||
| if(strstr(m.title, "map ")) | |||
| has_options = true; | |||
| for(auto m:meta) | |||
| if(strcmp(m.title, "documentation") && | |||
| strcmp(m.title, "parameter") && | |||
| strcmp(m.title, "max") && | |||
| strcmp(m.title, "min")) | |||
| printf("m.title = <%s>\n", m.title); | |||
| if(!has_options) | |||
| return o; | |||
| o << " <hints>\n"; | |||
| for(auto m:meta) { | |||
| if(strstr(m.title, "map ")) { | |||
| o << " <point symbol=\"" << sym_names[sym_idx++] << "\" value=\""; | |||
| o << m.title+4 << "\">" << m.value << "</point>\n"; | |||
| } | |||
| } | |||
| o << " </hints>\n"; | |||
| return o; | |||
| } | |||
| static ostream &dump_t_f_port(ostream &o, string name, string doc) | |||
| { | |||
| o << " <message_in pattern=\"" << name << "\" typetag=\"T\">\n"; | |||
| @@ -899,6 +956,13 @@ void dump_ports_cb(const rtosc::Port *p, const char *name, void *v) | |||
| o << " <range_min_max " << (type == 'f' ? "lmin=\"[\" lmax=\"]\"" : ""); | |||
| o << " min=\"" << meta["min"] << "\" max=\"" << meta["max"] << "\"/>\n"; | |||
| o << " </param_" << type << ">"; | |||
| } else if(meta.find("enumerated") != meta.end()) { | |||
| o << " <param_" << type << " symbol=\"x\">\n"; | |||
| o << " <range_min_max min=\"" << enum_min(meta) << "\" max=\""; | |||
| o << enum_max(meta) << "\">\n"; | |||
| add_options(o, meta); | |||
| o << " </range_min_max>\n"; | |||
| o << " </param_" << type << ">\n"; | |||
| } else { | |||
| o << " <param_" << type << " symbol=\"x\""; | |||
| units(o, meta["unit"]); | |||
| @@ -917,6 +981,13 @@ void dump_ports_cb(const rtosc::Port *p, const char *name, void *v) | |||
| o << " <range_min_max " << (type == 'f' ? "lmin=\"[\" lmax=\"]\"" : ""); | |||
| o << " min=\"" << meta["min"] << "\" max=\"" << meta["max"] << "\"/>\n"; | |||
| o << " </param_" << type << ">\n"; | |||
| } else if(meta.find("enumerated") != meta.end()) { | |||
| o << " <param_" << type << " symbol=\"x\">\n"; | |||
| o << " <range_min_max min=\"" << enum_min(meta) << "\" max=\""; | |||
| o << enum_max(meta) << "\">\n"; | |||
| add_options(o, meta); | |||
| o << " </range_min_max>\n"; | |||
| o << " </param_" << type << ">\n"; | |||
| } else { | |||
| o << " <param_" << type << " symbol=\"x\""; | |||
| units(o, meta["unit"]); | |||
| @@ -138,7 +138,7 @@ struct rtosc_hack_decltype_t | |||
| #define rToggle(name, ...) \ | |||
| {STRINGIFY(name) "::T:F",rProp(parameter) DOC(__VA_ARGS__), NULL, rToggleCb(name)} | |||
| #define rOption(name, ...) \ | |||
| {STRINGIFY(name) "::i:c",rProp(parameter) DOC(__VA_ARGS__), NULL, rOptionCb(name)} | |||
| {STRINGIFY(name) "::i:c",rProp(parameter) rProp(enumerated) DOC(__VA_ARGS__), NULL, rOptionCb(name)} | |||
| //Array operators | |||
| #define rArrayF(name, length, ...) \ | |||