| @@ -136,8 +136,9 @@ static int handler_function(const char *path, const char *types, lo_arg **argv, | |||
| lo_message_serialise(msg, path, buffer, &size); | |||
| if(!strcmp(buffer, "/path-search") && !strcmp("ss", rtosc_argument_string(buffer))) { | |||
| path_search(buffer, mw->activeUrl().c_str()); | |||
| } else if(buffer[0]=='/' && rindex(buffer, '/')[1]) | |||
| mw->transmitMsg(buffer); | |||
| } else if(buffer[0]=='/' && rindex(buffer, '/')[1]) { | |||
| mw->transmitMsg(rtosc::Ports::collapsePath(buffer)); | |||
| } | |||
| return 0; | |||
| } | |||
| @@ -56,6 +56,7 @@ JackEngine::JackEngine(const SYNTH_T &synth) | |||
| } | |||
| midi.inport = NULL; | |||
| midi.jack_sync = false; | |||
| osc.oscport = NULL; | |||
| } | |||
| bool JackEngine::connectServer(string server) | |||
| @@ -169,7 +169,8 @@ void JackMultiEngine::Stop() | |||
| jack_port_unregister(impl->client, port); | |||
| } | |||
| jack_client_close(impl->client); | |||
| if(impl->client) | |||
| jack_client_close(impl->client); | |||
| impl->client = NULL; | |||
| impl->running = false; | |||
| @@ -52,7 +52,8 @@ bool Nio::start() | |||
| void Nio::stop() | |||
| { | |||
| eng->stop(); | |||
| if(eng) | |||
| eng->stop(); | |||
| } | |||
| void Nio::setDefaultSource(string name) | |||
| @@ -408,7 +408,6 @@ void OscilGen::convert2sine() | |||
| float mag[MAX_AD_HARMONICS], phase[MAX_AD_HARMONICS]; | |||
| float oscil[synth.oscilsize]; | |||
| fft_t *freqs = new fft_t[synth.oscilsize / 2]; | |||
| get(oscil, -1.0f); | |||
| FFTwrapper *fft = new FFTwrapper(synth.oscilsize); | |||
| fft->smps2freqs(oscil, freqs); | |||
| @@ -429,7 +428,7 @@ void OscilGen::convert2sine() | |||
| float newmag = mag[i]; | |||
| float newphase = phase[i]; | |||
| Phmag[i] = (int) ((newmag) * 64.0f) + 64; | |||
| Phmag[i] = (int) ((newmag) * 63.0f) + 64; | |||
| Phphase[i] = 64 - (int) (64.0f * newphase / PI); | |||
| if(Phphase[i] > 127) | |||
| @@ -232,6 +232,14 @@ else | |||
| voicelfofreq->deactivate(); | |||
| voiceoscil->deactivate(); | |||
| }; | |||
| ext_oscil = new Osc_IntModel(osc); | |||
| ext_oscil->callback = [this](int ext) { | |||
| if(ext == -1) | |||
| voiceoscil->reext("OscilSmp/"); | |||
| else | |||
| voiceoscil->reext("../VoicePar"+to_s(ext)+"/OscilSmp/"); | |||
| }; | |||
| nvoice=0;} {} | |||
| } | |||
| Function {init(int nvoice_, std::string loc_, Fl_Osc_Interface *osc_)} {open | |||
| @@ -240,6 +248,7 @@ else | |||
| assert(!loc_.empty()); | |||
| voice_phase->doUpdate(loc_ + "Poscilphase"); | |||
| sound_type->doUpdate(loc_ + "Type"); | |||
| ext_oscil->doUpdate(loc_ + "Pextoscil"); | |||
| nvoice=nvoice_; | |||
| loc = loc_; | |||
| @@ -256,8 +265,9 @@ ADnoteVoiceListItem->redraw();} {} | |||
| } | |||
| Function {~ADvoicelistitem()} {} { | |||
| code {ADnoteVoiceListItem->hide(); | |||
| osc->removeLink(voice_phase); | |||
| osc->removeLink(sound_type); | |||
| delete voice_phase; | |||
| delete sound_type; | |||
| delete ext_oscil; | |||
| } {} | |||
| } | |||
| decl {int nvoice;} {private local | |||
| @@ -266,6 +276,8 @@ ADnoteVoiceListItem->redraw();} {} | |||
| } | |||
| decl {class Osc_IntModel *sound_type;} {private local | |||
| } | |||
| decl {class Osc_IntModel *ext_oscil;} {private local | |||
| } | |||
| decl {Fl_Oscilloscope *oscil;} {private local | |||
| } | |||
| decl {std::string loc;} {private local | |||
| @@ -409,11 +421,10 @@ o->redraw();} | |||
| callback {if (oscedit!=NULL) | |||
| delete(oscedit); | |||
| //int nv=nvoice; | |||
| //if (extFMoscil->value()>=0) | |||
| // nv=extFMoscil->value(); | |||
| oscedit=new OscilEditor(true, loc+"FMSmp/", osc_i);} | |||
| if(extFMoscil->value() == 0) | |||
| oscedit=new OscilEditor(true,loc+"FMSmp/", osc_i); | |||
| else | |||
| oscedit=new OscilEditor(true,loc+"../VoicePar"+to_s(extFMoscil->value()-1)+"/FMSmp/", osc_i);} | |||
| xywh {700 380 55 15} box THIN_UP_BOX labelfont 1 labelsize 11 | |||
| code0 {(void)o;/*if (extFMoscil->value()>=0) o->labelcolor(FL_BLUE);*/} | |||
| } | |||
| @@ -434,6 +445,10 @@ fmoscil->redraw();} | |||
| oscFM->init(false); | |||
| changeFMoscilbutton->labelcolor(FL_BLACK); | |||
| }; | |||
| if(o->value() == 0) | |||
| fmoscil->rebase(loc); | |||
| else | |||
| fmoscil->rebase(loc+"../VoicePar"+to_s(o->value()-1)+"/"); | |||
| voiceFMparametersgroup->redraw();} open | |||
| xywh {560 410 75 20} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 | |||
| code0 {o->add("Internal");} | |||
| @@ -588,12 +603,11 @@ o->redraw();} | |||
| Fl_Button changevoiceoscilbutton { | |||
| label Change | |||
| callback {delete oscedit; | |||
| //if(extoscil->value()>=0) | |||
| // nv=extoscil->value(); | |||
| oscedit=new OscilEditor(true,loc+"OscilSmp/", osc_i);} | |||
| if(extoscil->value() == 0) | |||
| oscedit=new OscilEditor(true,loc+"OscilSmp/", osc_i); | |||
| else | |||
| oscedit=new OscilEditor(true,loc+"../VoicePar"+to_s(extoscil->value()-1)+"/OscilSmp/", osc_i);} | |||
| xywh {5 490 65 20} box THIN_UP_BOX labelfont 1 labelsize 11 | |||
| code0 {(void)o;/*if (extoscil->value()>=0) o->labelcolor(FL_BLUE);*/} | |||
| } | |||
| Fl_Box {} { | |||
| label {Voice Oscillator} | |||
| @@ -622,6 +636,10 @@ voiceoscil->redraw();} | |||
| osc->init(false); | |||
| changevoiceoscilbutton->labelcolor(FL_BLACK); | |||
| }; | |||
| if(o->value() == 0) | |||
| voiceoscil->rebase(loc); | |||
| else | |||
| voiceoscil->rebase(loc+"../VoicePar"+to_s(o->value()-1)+"/"); | |||
| voiceparametersgroup->redraw(); | |||
| voiceonbutton->redraw();} open | |||
| @@ -241,6 +241,9 @@ class UI_Interface:public Fl_Osc_Interface | |||
| { | |||
| assert(s!="/Psysefxvol-1/part0"); | |||
| //Fl_Osc_Interface::requestValue(s); | |||
| char *tmp = strdup(s.c_str()); | |||
| s = rtosc::Ports::collapsePath(tmp); | |||
| free(tmp); | |||
| if(impl->activeUrl() != "GUI") { | |||
| impl->transmitMsg("/echo", "ss", "OSC_URL", "GUI"); | |||
| impl->activeUrl("GUI"); | |||
| @@ -251,6 +254,9 @@ class UI_Interface:public Fl_Osc_Interface | |||
| void write(string s, const char *args, ...) override | |||
| { | |||
| char *tmp = strdup(s.c_str()); | |||
| s = rtosc::Ports::collapsePath(tmp); | |||
| free(tmp); | |||
| va_list va; | |||
| va_start(va, args); | |||
| //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40); | |||
| @@ -267,7 +273,7 @@ class UI_Interface:public Fl_Osc_Interface | |||
| ////fprintf(stderr, "."); | |||
| //fprintf(stderr, "rawWrite(%s:%s)\n", msg, rtosc_argument_string(msg)); | |||
| //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40); | |||
| impl->transmitMsg(msg); | |||
| impl->transmitMsg(rtosc::Ports::collapsePath((char*)msg)); | |||
| } | |||
| void writeValue(string s, string ss) override | |||
| @@ -275,7 +281,7 @@ class UI_Interface:public Fl_Osc_Interface | |||
| //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40); | |||
| //fprintf(stderr, "writevalue<string>(%s,%s)\n", s.c_str(),ss.c_str()); | |||
| //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40); | |||
| impl->transmitMsg(s.c_str(), "s", ss.c_str()); | |||
| write(s, "s", ss.c_str()); | |||
| } | |||
| void writeValue(string s, char c) override | |||
| @@ -283,7 +289,7 @@ class UI_Interface:public Fl_Osc_Interface | |||
| //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40); | |||
| //fprintf(stderr, "writevalue<char>(%s,%d)\n", s.c_str(),c); | |||
| //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40); | |||
| impl->transmitMsg(s.c_str(), "c", c); | |||
| write(s, "c", c); | |||
| } | |||
| void writeValue(string s, float f) override | |||
| @@ -291,11 +297,14 @@ class UI_Interface:public Fl_Osc_Interface | |||
| //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 4 + 30, 0 + 40); | |||
| //fprintf(stderr, "writevalue<float>(%s,%f)\n", s.c_str(),f); | |||
| //fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40); | |||
| impl->transmitMsg(s.c_str(), "f", f); | |||
| write(s, "f", f); | |||
| } | |||
| void createLink(string s, class Fl_Osc_Widget*w) override | |||
| { | |||
| char *tmp = strdup(s.c_str()); | |||
| s = rtosc::Ports::collapsePath(tmp); | |||
| free(tmp); | |||
| assert(s.length() != 0); | |||
| Fl_Osc_Interface::createLink(s,w); | |||
| assert(!strstr(s.c_str(), "/part0/kit-1")); | |||
| @@ -312,6 +321,9 @@ class UI_Interface:public Fl_Osc_Interface | |||
| void removeLink(string s, class Fl_Osc_Widget*w) override | |||
| { | |||
| char *tmp = strdup(s.c_str()); | |||
| s = rtosc::Ports::collapsePath(tmp); | |||
| free(tmp); | |||
| for(auto i = map.begin(); i != map.end(); ++i) { | |||
| if(i->first == s && i->second == w) { | |||
| map.erase(i); | |||
| @@ -91,7 +91,7 @@ delete (freemodeeditwindow);} {} | |||
| } { | |||
| Fl_Window freemodeeditwindow { | |||
| label Envelope open | |||
| xywh {702 801 575 180} type Double | |||
| xywh {702 801 575 180} type Double resizable | |||
| class Fl_Osc_Window visible | |||
| } { | |||
| Fl_Button {} { | |||
| @@ -106,7 +106,7 @@ delete (freemodeeditwindow);} {} | |||
| xywh {482 160 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 55 | |||
| } | |||
| Fl_Button addpoint { | |||
| label {Add point} | |||
| label {Add pt} | |||
| callback { | |||
| if(freeedit->lastpoint >= MAX_ENVELOPE_POINTS - 1) | |||
| return; | |||
| @@ -118,7 +118,7 @@ sustaincounter->update(); | |||
| //sustaincounter->value(Penvsustain); | |||
| //sustaincounter->maximum(Penvpoints-2);} | |||
| xywh {115 155 80 20} box THIN_UP_BOX labelsize 11 | |||
| xywh {90 155 80 20} box THIN_UP_BOX labelsize 11 | |||
| code0 {(void)o->init("addPoint");} | |||
| class PointButton | |||
| } | |||
| @@ -130,7 +130,7 @@ sustaincounter->update(); | |||
| class EnvelopeFreeEdit | |||
| } | |||
| Fl_Button deletepoint { | |||
| label {Delete point} | |||
| label {Delete pt} | |||
| callback {o->oscWrite("delPoint", "i", freeedit->lastpoint); | |||
| freeedit->lastpoint-=1; | |||
| freeedit->update(); | |||
| @@ -138,7 +138,7 @@ envfree->redraw(); | |||
| sustaincounter->update(); | |||
| //sustaincounter->value(Penvsustain); | |||
| //sustaincounter->maximum(Penvpoints-2);} | |||
| xywh {200 155 80 20} box THIN_UP_BOX labelsize 11 | |||
| xywh {175 155 85 20} box THIN_UP_BOX labelsize 11 | |||
| code0 {(void)o->init("delPoint");} | |||
| class PointButton | |||
| } | |||
| @@ -172,7 +172,7 @@ sustaincounter->update(); | |||
| label Sust | |||
| callback {freeedit->redraw(); | |||
| envfree->redraw();} | |||
| tooltip {Sustain (0 is disabled)} xywh {315 155 40 15} type Simple labelsize 11 align 4 minimum 0 maximum 127 step 1 | |||
| tooltip {Sustain (0 is disabled)} xywh {305 155 40 15} type Simple labelsize 11 align 4 minimum 0 maximum 127 step 1 | |||
| code3 {o->init("Penvsustain");} | |||
| class Fl_Osc_Counter | |||
| } | |||
| @@ -183,9 +183,10 @@ envfree->redraw();} | |||
| class Fl_Osc_Check | |||
| } | |||
| Fl_Button {} { | |||
| label {Cancel Freemode} | |||
| label {Cancel} | |||
| tooltip {Cancel freemode editing} | |||
| callback {disable_freemode();} | |||
| xywh {5 155 105 20} box THIN_UP_BOX labelsize 11 labelcolor 1 | |||
| xywh {5 155 80 20} box THIN_UP_BOX labelsize 11 labelcolor 1 | |||
| class Fl_Osc_Button | |||
| } | |||
| } | |||
| @@ -534,6 +535,7 @@ envfree->redraw();} | |||
| freeedit->update(); | |||
| freemodeeditwindow->show(); | |||
| freemodeeditwindow->position(Fl::event_x_root()-20, Fl::event_y_root()+20); | |||
| freemodeeditwindow->size_range(400,160); | |||
| } {} | |||
| } | |||
| Function {init(int env_type, Fl_Osc_Interface *osc_, std::string base_, std::string ext_)} {open | |||
| @@ -24,6 +24,7 @@ class Fl_EQGraph:public Fl_Box, public Fl_Osc_Widget | |||
| float getfreqpos(float freq) const; | |||
| float samplerate; | |||
| float gain; | |||
| float num[MAX_EQ_BANDS*MAX_FILTER_STAGES*3]; | |||
| float dem[MAX_EQ_BANDS*MAX_FILTER_STAGES*3]; | |||
| }; | |||
| @@ -11,7 +11,7 @@ | |||
| #define MAX_DB 30 | |||
| Fl_EQGraph::Fl_EQGraph(int x,int y, int w, int h, const char *label) | |||
| :Fl_Box(x,y,w,h,label), Fl_Osc_Widget(this), samplerate(48000) | |||
| :Fl_Box(x,y,w,h,label), Fl_Osc_Widget(this), samplerate(48000), gain(0.5f) | |||
| { | |||
| memset(num, 0, sizeof(num)); | |||
| memset(dem, 0, sizeof(dem)); | |||
| @@ -21,6 +21,7 @@ Fl_EQGraph::Fl_EQGraph(int x,int y, int w, int h, const char *label) | |||
| osc->createLink("/samplerate", this); | |||
| osc->requestValue("/samplerate"); | |||
| oscRegister("eq-coeffs"); | |||
| oscRegister("parameter0"); | |||
| } | |||
| Fl_EQGraph::~Fl_EQGraph(void) | |||
| @@ -30,6 +31,8 @@ void Fl_EQGraph::OSC_raw(const char *msg) | |||
| { | |||
| if(strstr(msg, "samplerate") && !strcmp("f", rtosc_argument_string(msg))) { | |||
| samplerate = rtosc_argument(msg, 0).f; | |||
| } else if(strstr(msg, "parameter0") && !strcmp("i", rtosc_argument_string(msg))) { | |||
| gain = powf(0.005f, (1.0f-rtosc_argument(msg, 0).i/127.0f)) * 10.0f; | |||
| } else { | |||
| memcpy(dem, rtosc_argument(msg, 0).b.data, sizeof(dem)); | |||
| memcpy(num, rtosc_argument(msg, 1).b.data, sizeof(num)); | |||
| @@ -158,7 +161,7 @@ double Fl_EQGraph::getresponse(int maxy,float freq) const | |||
| mag *= abs(num_res/dem_res); | |||
| } | |||
| float dbresp=20*log(mag)/log(10); | |||
| float dbresp=20*log(mag*gain)/log(10); | |||
| //rescale | |||
| return (int) ((dbresp/MAX_DB+1.0)*maxy/2.0); | |||
| @@ -20,6 +20,7 @@ void Fl_Osc_Button::OSC_value(bool v) | |||
| Fl_Button::value(v); | |||
| } | |||
| void Fl_Osc_Button::rebase(std::string) | |||
| void Fl_Osc_Button::rebase(std::string base) | |||
| { | |||
| loc = base; | |||
| } | |||
| @@ -19,7 +19,7 @@ decl {\#include <string.h>} {public local | |||
| decl {\#if ! defined(PLUGINVERSION) && HAS_X11 | |||
| \#include "zynaddsubfx.xpm" | |||
| \#endif} {public local | |||
| \#endif} {private local | |||
| } | |||
| decl {\#include "WidgetPDial.h"} {public local | |||
| @@ -1522,9 +1522,15 @@ last_xmz->callback = [this](std::string filestr) { | |||
| } else | |||
| last_loaded[0] = 0; | |||
| last_loaded[XMZ_PATH_MAX - 1] = 0; | |||
| char *label = last_loaded[0] == 0 ? NULL | |||
| : ((label = strrchr(last_loaded, '/'))) ? label+1 | |||
| : last_loaded; | |||
| char *label = NULL; | |||
| if(last_loaded[0] != 0) { | |||
| label = strrchr(last_loaded, '/'); | |||
| if(label && *label) | |||
| label = label+1; | |||
| else | |||
| label = last_loaded; | |||
| } | |||
| setfilelabel(label); | |||
| }; | |||
| last_xmz->doUpdate("/last_xmz"); | |||
| @@ -823,7 +823,7 @@ redrawoscil();} | |||
| class Fl_Osc_Dial | |||
| } | |||
| Fl_Slider adhrpar { | |||
| code0 {o->init("Padaptiveharmonicspar");o->reset_value=50;} | |||
| code0 {o->init("Padaptiveharmonicspar", 'i');o->reset_value=50;} | |||
| callback {redrawoscil();} | |||
| xywh {675 450 55 10} type {Horz Knob} box NO_BOX maximum 100 step 1 value 50 | |||
| class Fl_Osc_TSlider | |||
| @@ -880,6 +880,9 @@ redrawoscil();} | |||
| callback {if (!fl_choice("Convert to SINE?","No","Yes",NULL)) return; | |||
| osc->requestValue(loc+"convert2sine"); | |||
| bftype->update(); | |||
| bfslider->value(0); | |||
| bfslider->do_callback(); | |||
| redrawoscil(); | |||
| refresh();} | |||
| @@ -136,9 +136,9 @@ in ASCII collating sequence. (A minus sign at the end of the string has no speci | |||
| #define RTOSC_MATCH_OPTIONS 5 | |||
| #define RTOSC_MATCH_PARTIAL_OPTIONS 6 | |||
| #define RTOSC_MATCH_ENUMERATED 7 | |||
| static bool is_charwise(char c) | |||
| static bool is_charwise(uint8_t c) | |||
| { | |||
| return (c>=0 && c<=0x7f) && c != ' ' && c != '#' && | |||
| return c<=0x7f && c != ' ' && c != '#' && | |||
| c != '/' && c != '{' && c != '}'; | |||
| } | |||
| @@ -231,6 +231,7 @@ bool rtosc_match_partial(const char *a, const char *b) | |||
| const char *sub=NULL; | |||
| return strstr(a,sub); | |||
| } else if(type == RTOSC_MATCH_OPTIONS || type == 6) { | |||
| return false; | |||
| } else if(type == RTOSC_MATCH_ENUMERATED) { | |||
| while(rtosc_match_char(&a,&b)); | |||
| if(*a && *b=='#' && b[1] != '\0') | |||
| @@ -485,7 +485,7 @@ rtosc_arg_itr_t rtosc_itr_begin(const char *msg) | |||
| rtosc_arg_val_t rtosc_itr_next(rtosc_arg_itr_t *itr) | |||
| { | |||
| //current position provides the value | |||
| rtosc_arg_val_t result = {0}; | |||
| rtosc_arg_val_t result = {0,{0}}; | |||
| result.type = *itr->type_pos; | |||
| if(result.type) | |||
| result.val = extract_arg(itr->value_pos, result.type); | |||