@@ -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); | |||