// generated by Fast Light User Interface Designer (fluid) version 1.0300

#include "OscilGenUI.h"
//Copyright (c) 2002-2005 Nasca Octavian Paul
//License: GNU GPL version 2 or later
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

OscilSpectrum::OscilSpectrum(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) {
  oscil=NULL;
}

void OscilSpectrum::init(OscilGen *oscil_,int oscbase_,Master *master_) {
  oscil=oscil_;
  oscbase=oscbase_;
  master=master_;
}

void OscilSpectrum::draw() {
  int ox=x(),oy=y(),lx=w(),ly=h(),i;
  const int maxdb=60;//must be multiple of 10
  int GX=2;
  int n=lx/GX-1;
  if (n>OSCIL_SIZE/2) n=OSCIL_SIZE/2;
  
  REALTYPE x;
  REALTYPE* spc=new REALTYPE[n];
  for (i=0;i<n;i++) spc[i]=0.0;
  
  pthread_mutex_lock(&master->mutex);
  if (oscbase==0) oscil->getspectrum(n,spc,0);
      else oscil->getspectrum(n,spc,1);
  pthread_mutex_unlock(&master->mutex);
  
  //normalize
  REALTYPE max=0;
  for (i=0;i<n;i++){
     x=fabs(spc[i]);
     if (max<x) max=x;
  }
  if (max<0.000001) max=1.0;
  max=max*1.05;
  
  //draw
  
  if (this->active_r()) fl_color(this->parent()->selection_color());
      else fl_color(this->parent()->color());
  fl_line_style(FL_DOT);
  
  for (i=1;i<maxdb/10;i++){
    int ky=(int)((REALTYPE)i*ly*10.0/maxdb)/2;
    ky*=2;
    fl_line(ox,oy+ky-1,ox+lx-2,oy+ky-1);
  };
  
  for (i=2;i<n;i++){
      int tmp=i*GX-2;
      if (i%10==1) fl_line_style(0);
         else fl_line_style(FL_DOT);
      fl_line(ox+tmp,oy+2,ox+tmp,oy+ly-2);
  }
  
  if (this->active_r()) fl_color(this->parent()->labelcolor());
      else fl_color(this->parent()->color());
  fl_line_style(0);
  
  //draws the spectrum
  for (i=0;i<n;i++){
     int tmp=i*GX+2;
     x=spc[i]/max;
     
     if (x>dB2rap(-maxdb)) x=rap2dB(x)/maxdb+1;
         else x=0;
  
     int val=(int) ((ly-2)*x);
     if (val>0) fl_line(ox+tmp,oy+ly-2-val,ox+tmp,oy+ly-2);
  }
  delete [] spc;
}

PSlider::PSlider(int x,int y, int w, int h, const char *label):Fl_Slider(x,y,w,h,label) {
  ;
}

int PSlider::handle(int event) {
  int X=x(),Y=y(),W=w(),H=h();
  
  if ((!Fl::event_buttons())|| (event==0)||(Fl::event_shift()==0)) return(Fl_Slider::handle(event));
  
  if (!Fl::event_inside(X,Y,W,H)) {
  	if (event==FL_DRAG){
  		Fl_Slider::handle(FL_RELEASE);
  		Fl_Slider::handle(FL_LEAVE);
  		deactivate();
  		activate();
  		return(1);	
  	}else{
  		return(Fl_Slider::handle(event));
  	};
  } else {
  	//Fl_Slider::handle(FL_FOCUS);
  	Fl_Slider::handle(FL_PUSH);
  };
  
  return(1);
}

Oscilloscope::Oscilloscope(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) {
  oscil=NULL;
  phase=64;
  oscbase=0;
}

void Oscilloscope::init(OscilGen *oscil_,Master *master_) {
  oscil=oscil_;
  master=master_;
}

void Oscilloscope::init(OscilGen *oscil_,int oscbase_,Master *master_) {
  oscil=oscil_;
  oscbase=oscbase_;
  master=master_;
}

void Oscilloscope::init(OscilGen *oscil_,int oscbase_,int phase_,Master *master_) {
  oscil=oscil_;
  oscbase=oscbase_;
  phase=phase_;
  master=master_;
}

void Oscilloscope::draw() {
  int ox=x(),oy=y(),lx=w(),ly=h()-1,i;
  REALTYPE smps[OSCIL_SIZE];
  pthread_mutex_lock(&master->mutex);
  if (oscbase==0) oscil->get(smps,-1.0);
      else oscil->getcurrentbasefunction(smps);
  pthread_mutex_unlock(&master->mutex);
  
  if (damage()!=1){
   fl_color(0,0,0);
   fl_rectf(ox,oy,lx,ly);
  };
  
  //normalize
  REALTYPE max=0;
  for (i=0;i<OSCIL_SIZE;i++)
     if (max<fabs(smps[i])) max=fabs(smps[i]);
  //fprintf(stderr,"%.4f\n",max);
  if (max<0.00001) max=1.0;
  max=-max*1.05;
  
  //draw
  fl_line_style(FL_DASH);
  if (this->active_r()) fl_color(this->parent()->labelcolor());
      else fl_color(this->parent()->color());
  int GX=16;if (lx<GX*3) GX=-1;
  for (i=1;i<GX;i++){
     int tmp=(int)(lx/(REALTYPE)GX*i);
     fl_line(ox+tmp,oy+2,ox+tmp,oy+ly-2);
  };
  int GY=8;if (ly<GY*3) GY=-1;
  for (i=1;i<GY;i++){
     int tmp=(int)(ly/(REALTYPE)GY*i);
     fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp);
  };
  
  //draw the function
  fl_line_style(0,1);
  fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2);
  if (this->active_r()) fl_color(this->parent()->selection_color());
      else fl_color(this->parent()->labelcolor());
  int lw=1;
  //if ((lx<135)||(ly<135)) lw=1;
  fl_line_style(0,lw);
  int ph=(int)((phase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE);
  for (i=1;i<lx;i++){
     int k1=(int)((REALTYPE)OSCIL_SIZE*(i-1)/lx)+ph;
     int k2=(int)((REALTYPE)OSCIL_SIZE*i/lx)+ph;
     REALTYPE y1=smps[k1%OSCIL_SIZE]/max;
     REALTYPE y2=smps[k2%OSCIL_SIZE]/max;
     fl_line(i-1+ox,(int)(y1*ly/2.0)+oy+ly/2,i+ox,(int)(y2*ly/2.0)+oy+ly/2);
  };
}

void Oscilharmonic::cb_mag_i(PSlider* o, void*) {
  int x=64;
if (Fl::event_button3()) o->value(x);
   else x=127-(int)o->value();
if (x==64) o->selection_color(0);
    else o->selection_color(222);

pthread_mutex_lock(&master->mutex);
 oscil->Phmag[n]=x;
 if (x==64) {
    oscil->Phphase[n]=64;
    phase->value(64);
 };
 oscil->prepare();
pthread_mutex_unlock(&master->mutex);

display->redraw();
oldosc->redraw();
if (cbwidget!=NULL) {
	cbwidget->do_callback();
	applybutton->color(FL_RED);
	applybutton->redraw();
};
}
void Oscilharmonic::cb_mag(PSlider* o, void* v) {
  ((Oscilharmonic*)(o->parent()->user_data()))->cb_mag_i(o,v);
}

void Oscilharmonic::cb_phase_i(PSlider* o, void*) {
  int x=64;
if (Fl::event_button3()) o->value(x);
   else x=(int)o->value();

pthread_mutex_lock(&master->mutex);
 oscil->Phphase[n]=x;
 oscil->prepare();
pthread_mutex_unlock(&master->mutex);

display->redraw();
oldosc->redraw();
if (cbwidget!=NULL) {
	cbwidget->do_callback();
	applybutton->color(FL_RED);
	applybutton->redraw();
};
}
void Oscilharmonic::cb_phase(PSlider* o, void* v) {
  ((Oscilharmonic*)(o->parent()->user_data()))->cb_phase_i(o,v);
}

Fl_Group* Oscilharmonic::make_window() {
  { harmonic = new Fl_Group(0, 0, 90, 225);
    harmonic->box(FL_FLAT_BOX);
    harmonic->color(FL_BACKGROUND_COLOR);
    harmonic->selection_color(FL_BACKGROUND_COLOR);
    harmonic->labeltype(FL_NO_LABEL);
    harmonic->labelfont(0);
    harmonic->labelsize(14);
    harmonic->labelcolor(FL_FOREGROUND_COLOR);
    harmonic->user_data((void*)(this));
    harmonic->align(Fl_Align(FL_ALIGN_TOP));
    harmonic->when(FL_WHEN_RELEASE);
    { PSlider* o = mag = new PSlider(0, 15, 15, 115);
      mag->type(4);
      mag->box(FL_FLAT_BOX);
      mag->color(FL_BACKGROUND_COLOR);
      mag->selection_color((Fl_Color)222);
      mag->labeltype(FL_NORMAL_LABEL);
      mag->labelfont(0);
      mag->labelsize(14);
      mag->labelcolor(FL_FOREGROUND_COLOR);
      mag->maximum(127);
      mag->step(1);
      mag->value(64);
      mag->callback((Fl_Callback*)cb_mag);
      mag->align(Fl_Align(FL_ALIGN_BOTTOM));
      mag->when(FL_WHEN_CHANGED);
      o->value(127-oscil->Phmag[n]);
      if (oscil->Phmag[n]==64) o->selection_color(0);
    } // PSlider* mag
    { PSlider* o = phase = new PSlider(0, 135, 15, 75);
      phase->type(4);
      phase->box(FL_FLAT_BOX);
      phase->color(FL_BACKGROUND_COLOR);
      phase->selection_color((Fl_Color)222);
      phase->labeltype(FL_NORMAL_LABEL);
      phase->labelfont(0);
      phase->labelsize(14);
      phase->labelcolor(FL_FOREGROUND_COLOR);
      phase->maximum(127);
      phase->step(1);
      phase->value(64);
      phase->callback((Fl_Callback*)cb_phase);
      phase->align(Fl_Align(FL_ALIGN_BOTTOM));
      phase->when(FL_WHEN_CHANGED);
      o->value(oscil->Phphase[n]);
    } // PSlider* phase
    { Fl_Box* o = new Fl_Box(15, 70, 5, 5);
      o->box(FL_FLAT_BOX);
      o->color(FL_DARK2);
    } // Fl_Box* o
    { Fl_Box* o = new Fl_Box(15, 170, 5, 5);
      o->box(FL_FLAT_BOX);
      o->color(FL_DARK2);
    } // Fl_Box* o
    { Fl_Box* o = new Fl_Box(0, 210, 20, 15, "01");
      o->labelfont(1);
      o->labelsize(9);
      o->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
      char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));
    } // Fl_Box* o
    { Fl_Box* o = new Fl_Box(0, 0, 20, 15, "01");
      o->labelfont(1);
      o->labelsize(9);
      o->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
      char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));
    } // Fl_Box* o
    harmonic->end();
  } // Fl_Group* harmonic
  return harmonic;
}

Oscilharmonic::Oscilharmonic(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) {
  n=0;
  oscil=NULL;
  display=NULL;
  applybutton=NULL;
  cbwidget=NULL;
}

void Oscilharmonic::init(OscilGen *oscil_,int n_,Fl_Group *display_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *applybutton_, Master *master_) {
  oscil=oscil_;
  n=n_;
  display=display_;
  master=master_;
  oldosc=oldosc_;
  cbwidget=cbwidget_;
  applybutton=applybutton_;
  make_window();
  end();
  harmonic->show();
}

void Oscilharmonic::refresh() {
  mag->value(127-oscil->Phmag[n]);
  phase->value(oscil->Phphase[n]);
  
  if (oscil->Phmag[n]==64) mag->selection_color(0);
      else mag->selection_color(222);
}

Oscilharmonic::~Oscilharmonic() {
  harmonic->hide();
  //delete(harmonic);
}

void OscilEditor::cb_applybutton_i(Fl_Button*, void*) {
  applybutton->color(FL_GRAY);
applybutton->redraw();
if (cbapplywidget!=NULL) {
	cbapplywidget->do_callback();
	cbapplywidget->color(FL_GRAY);
	cbapplywidget->redraw();
};
}
void OscilEditor::cb_applybutton(Fl_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->user_data()))->cb_applybutton_i(o,v);
}

void OscilEditor::cb_rndslider_i(Fl_Value_Slider* o, void*) {
  oscil->Prand=(int)o->value()+64;
oscildisplaygroup->redraw();
oldosc->redraw();
}
void OscilEditor::cb_rndslider(Fl_Value_Slider* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_rndslider_i(o,v);
}

void OscilEditor::cb_hrndtype_i(Fl_Choice* o, void*) {
  oscil->Pamprandtype=(int) o->value();
}
void OscilEditor::cb_hrndtype(Fl_Choice* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_hrndtype_i(o,v);
}

Fl_Menu_Item OscilEditor::menu_hrndtype[] = {
 {"None", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Pow", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Sin", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {0,0,0,0,0,0,0,0,0}
};

void OscilEditor::cb_hrnddial_i(WidgetPDial* o, void*) {
  oscil->Pamprandpower=(int) o->value();
}
void OscilEditor::cb_hrnddial(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_hrnddial_i(o,v);
}

void OscilEditor::cb_bfslider_i(WidgetPDial* o, void*) {
  oscil->Pbasefuncpar=(int)o->value()+64;
basefuncdisplaygroup->redraw();
bfparval->value(oscil->Pbasefuncpar-64);

redrawoscil();
}
void OscilEditor::cb_bfslider(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_bfslider_i(o,v);
}

void OscilEditor::cb_bftype_i(Fl_Choice* o, void*) {
  oscil->Pcurrentbasefunc=(int) o->value();

basefuncdisplaygroup->redraw();
redrawoscil();

if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodulation->deactivate();
      else basefuncmodulation->activate();
}
void OscilEditor::cb_bftype(Fl_Choice* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_bftype_i(o,v);
}

Fl_Menu_Item OscilEditor::menu_bftype[] = {
 {"Sine", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"Triangle", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"Pulse", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"Saw", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"Power", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"Gauss", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"Diode", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"AbsSine", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"PulseSine", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"StrchSine", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"Chirp", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"AbsStrSine", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"Chebyshev", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"Sqr", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {0,0,0,0,0,0,0,0,0}
};

void OscilEditor::cb_bfmodtype_i(Fl_Choice* o, void*) {
  oscil->Pbasefuncmodulation=(int) o->value();
basefuncdisplaygroup->redraw();
redrawoscil();
}
void OscilEditor::cb_bfmodtype(Fl_Choice* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_bfmodtype_i(o,v);
}

Fl_Menu_Item OscilEditor::menu_bfmodtype[] = {
 {"None", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Rev", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Sine", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Pow", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {0,0,0,0,0,0,0,0,0}
};

void OscilEditor::cb_bfmodpar1_i(WidgetPDial* o, void*) {
  oscil->Pbasefuncmodulationpar1=(int)o->value();
basefuncdisplaygroup->redraw();
redrawoscil();
}
void OscilEditor::cb_bfmodpar1(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_bfmodpar1_i(o,v);
}

void OscilEditor::cb_bfmodpar2_i(WidgetPDial* o, void*) {
  oscil->Pbasefuncmodulationpar2=(int)o->value();
basefuncdisplaygroup->redraw();
redrawoscil();
}
void OscilEditor::cb_bfmodpar2(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_bfmodpar2_i(o,v);
}

void OscilEditor::cb_bfmodpar3_i(WidgetPDial* o, void*) {
  oscil->Pbasefuncmodulationpar3=(int)o->value();
basefuncdisplaygroup->redraw();
redrawoscil();
}
void OscilEditor::cb_bfmodpar3(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_bfmodpar3_i(o,v);
}

void OscilEditor::cb_magtype_i(Fl_Choice* o, void*) {
  oscil->Phmagtype=(int) o->value();
basefuncdisplaygroup->redraw();

redrawoscil();
}
void OscilEditor::cb_magtype(Fl_Choice* o, void* v) {
  ((OscilEditor*)(o->parent()->user_data()))->cb_magtype_i(o,v);
}

Fl_Menu_Item OscilEditor::menu_magtype[] = {
 {"Linear", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"-40dB", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"-60dB", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"-80dB", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {"-100dB", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0},
 {0,0,0,0,0,0,0,0,0}
};

void OscilEditor::cb_Use_i(Fl_Button*, void*) {
  oscil->useasbase();
if (autoclearbutton->value()){
   for (int i=0;i<MAX_AD_HARMONICS;i++){
      h[i]->mag->value(64);
      oscil->Phmag[i]=64;
      h[i]->phase->value(64);
      oscil->Phphase[i]=64;
   };
   oscil->Phmag[0]=127;

   oscil->Pharmonicshift=0;
   harmonicshiftcounter->value(0);

   h[0]->mag->value(0);
   wshbutton->value(0);
   wshbutton->do_callback();
   fltbutton->value(0);
   fltbutton->do_callback();
   sabutton->value(0);
   sabutton->do_callback();
};

pthread_mutex_lock(&master->mutex);
 for (int i=0;i<MAX_AD_HARMONICS;i++){
   if (oscil->Phmag[i]==64) h[i]->mag->selection_color(0);
      else h[i]->mag->selection_color(222);
 };
 oscil->prepare();
pthread_mutex_unlock(&master->mutex);

basefuncdisplaygroup->redraw();
redrawoscil();
}
void OscilEditor::cb_Use(Fl_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->user_data()))->cb_Use_i(o,v);
}

void OscilEditor::cb_Close_i(Fl_Button*, void*) {
  osceditUI->hide();
}
void OscilEditor::cb_Close(Fl_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->user_data()))->cb_Close_i(o,v);
}

void OscilEditor::cb_Clear_i(Fl_Button*, void*) {
  if (!fl_choice("Clear the harmonics settings?","No","Yes",NULL)) return;

for (int i=0;i<MAX_AD_HARMONICS;i++){
    h[i]->mag->value(64);
    oscil->Phmag[i]=64;
    h[i]->phase->value(64);
    oscil->Phphase[i]=64;
};
oscil->Phmag[0]=127;
h[0]->mag->value(0);

for (int i=0;i<MAX_AD_HARMONICS;i++){
  if (oscil->Phmag[i]==64) h[i]->mag->selection_color(0);
     else h[i]->mag->selection_color(222);
};

//harmonics->redraw();

pthread_mutex_lock(&master->mutex);
 oscil->prepare();
pthread_mutex_unlock(&master->mutex);

redrawoscil();
}
void OscilEditor::cb_Clear(Fl_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->user_data()))->cb_Clear_i(o,v);
}

void OscilEditor::cb_wshbutton_i(Fl_Choice* o, void*) {
  oscil->Pwaveshapingfunction=(int) o->value();
basefuncdisplaygroup->redraw();
redrawoscil();
}
void OscilEditor::cb_wshbutton(Fl_Choice* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_wshbutton_i(o,v);
}

Fl_Menu_Item OscilEditor::menu_wshbutton[] = {
 {"None", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Atan", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Asym1", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Pow", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Sine", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Qnts", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Zigzg", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Lmt", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"LmtU", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"LmtL", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"ILmt", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Clip", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Asym2", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Pow2", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Sgm", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {0,0,0,0,0,0,0,0,0}
};

void OscilEditor::cb_wshpar_i(WidgetPDial* o, void*) {
  oscil->Pwaveshaping=(int)o->value()+64;
wsparval->value(oscil->Pwaveshaping-64);
redrawoscil();
}
void OscilEditor::cb_wshpar(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_wshpar_i(o,v);
}

void OscilEditor::cb_fltbutton_i(Fl_Choice* o, void*) {
  oscil->Pfiltertype=(int) o->value();

redrawoscil();
}
void OscilEditor::cb_fltbutton(Fl_Choice* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_fltbutton_i(o,v);
}

Fl_Menu_Item OscilEditor::menu_fltbutton[] = {
 {"None", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"LP1", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"HP1a", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"HP1b", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"BP1", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"BS1", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"LP2", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"HP2", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"BP2", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"BS2", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Cos", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Sin", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"LSh", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"S", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {0,0,0,0,0,0,0,0,0}
};

void OscilEditor::cb_filtervalue1_i(WidgetPDial* o, void*) {
  oscil->Pfilterpar1=(int)o->value();

redrawoscil();
}
void OscilEditor::cb_filtervalue1(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_filtervalue1_i(o,v);
}

void OscilEditor::cb_filterpref_i(Fl_Check_Button* o, void*) {
  oscil->Pfilterbeforews=(int)o->value();

redrawoscil();
}
void OscilEditor::cb_filterpref(Fl_Check_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_filterpref_i(o,v);
}

void OscilEditor::cb_filtervalue2_i(WidgetPDial* o, void*) {
  oscil->Pfilterpar2=(int)o->value();

redrawoscil();
}
void OscilEditor::cb_filtervalue2(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_filtervalue2_i(o,v);
}

void OscilEditor::cb_sabutton_i(Fl_Choice* o, void*) {
  oscil->Psatype=(int) o->value();
redrawoscil();
}
void OscilEditor::cb_sabutton(Fl_Choice* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_sabutton_i(o,v);
}

Fl_Menu_Item OscilEditor::menu_sabutton[] = {
 {"None", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Pow", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"ThrsD", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"ThrsU", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {0,0,0,0,0,0,0,0,0}
};

void OscilEditor::cb_sadjpar_i(WidgetPDial* o, void*) {
  oscil->Psapar=(int)o->value();
redrawoscil();
}
void OscilEditor::cb_sadjpar(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_sadjpar_i(o,v);
}

void OscilEditor::cb_harmonicshiftcounter_i(Fl_Counter* o, void*) {
  oscil->Pharmonicshift=(int)o->value();
redrawoscil();
}
void OscilEditor::cb_harmonicshiftcounter(Fl_Counter* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_harmonicshiftcounter_i(o,v);
}

void OscilEditor::cb_harmonicshiftpre_i(Fl_Check_Button* o, void*) {
  oscil->Pharmonicshiftfirst=(int)o->value();
redrawoscil();
}
void OscilEditor::cb_harmonicshiftpre(Fl_Check_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_harmonicshiftpre_i(o,v);
}

void OscilEditor::cb_R_i(Fl_Button*, void*) {
  oscil->Pharmonicshift=0;
harmonicshiftcounter->value(0);
redrawoscil();
}
void OscilEditor::cb_R(Fl_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_R_i(o,v);
}

void OscilEditor::cb_adhrtype_i(Fl_Choice* o, void*) {
  oscil->Padaptiveharmonics=(int) o->value();
redrawoscil();
}
void OscilEditor::cb_adhrtype(Fl_Choice* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_adhrtype_i(o,v);
}

Fl_Menu_Item OscilEditor::menu_adhrtype[] = {
 {"OFF", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"ON", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Square", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"2xSub", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"2xAdd", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"3xSub", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"3xAdd", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"4xSub", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"4xAdd", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {0,0,0,0,0,0,0,0,0}
};

void OscilEditor::cb_adhrpow_i(WidgetPDial* o, void*) {
  oscil->Padaptiveharmonicspower=(int)o->value();
redrawoscil();
}
void OscilEditor::cb_adhrpow(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_adhrpow_i(o,v);
}

void OscilEditor::cb_adhrbf_i(WidgetPDial* o, void*) {
  oscil->Padaptiveharmonicsbasefreq=(int)o->value();
redrawoscil();
}
void OscilEditor::cb_adhrbf(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_adhrbf_i(o,v);
}

void OscilEditor::cb_adhrpar_i(Fl_Slider* o, void*) {
  oscil->Padaptiveharmonicspar=(int)o->value();
redrawoscil();
}
void OscilEditor::cb_adhrpar(Fl_Slider* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_adhrpar_i(o,v);
}

void OscilEditor::cb_modtype_i(Fl_Choice* o, void*) {
  oscil->Pmodulation=(int) o->value();

redrawoscil();
}
void OscilEditor::cb_modtype(Fl_Choice* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_modtype_i(o,v);
}

Fl_Menu_Item OscilEditor::menu_modtype[] = {
 {"None", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Rev", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Sine", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {"Pow", 0,  0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0},
 {0,0,0,0,0,0,0,0,0}
};

void OscilEditor::cb_modpar1_i(WidgetPDial* o, void*) {
  oscil->Pmodulationpar1=(int)o->value();

redrawoscil();
}
void OscilEditor::cb_modpar1(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_modpar1_i(o,v);
}

void OscilEditor::cb_modpar2_i(WidgetPDial* o, void*) {
  oscil->Pmodulationpar2=(int)o->value();

redrawoscil();
}
void OscilEditor::cb_modpar2(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_modpar2_i(o,v);
}

void OscilEditor::cb_modpar3_i(WidgetPDial* o, void*) {
  oscil->Pmodulationpar3=(int)o->value();
redrawoscil();
}
void OscilEditor::cb_modpar3(WidgetPDial* o, void* v) {
  ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_modpar3_i(o,v);
}

void OscilEditor::cb_Sine_i(Fl_Button*, void*) {
  if (!fl_choice("Convert to SINE?","No","Yes",NULL)) return;

pthread_mutex_lock(&master->mutex);
 oscil->convert2sine(0);
pthread_mutex_unlock(&master->mutex);

redrawoscil();
refresh();
}
void OscilEditor::cb_Sine(Fl_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->user_data()))->cb_Sine_i(o,v);
}

void OscilEditor::cb_C_i(Fl_Button*, void*) {
  presetsui->copy(oscil);
}
void OscilEditor::cb_C(Fl_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->user_data()))->cb_C_i(o,v);
}

void OscilEditor::cb_P_i(Fl_Button*, void*) {
  presetsui->paste(oscil,this);
}
void OscilEditor::cb_P(Fl_Button* o, void* v) {
  ((OscilEditor*)(o->parent()->user_data()))->cb_P_i(o,v);
}

Fl_Double_Window* OscilEditor::make_window() {
  { Fl_Double_Window* o = osceditUI = new Fl_Double_Window(735, 595, "ADsynth Oscillator Editor");
    osceditUI->user_data((void*)(this));
    { Fl_Button* o = applybutton = new Fl_Button(300, 280, 60, 20, "Apply");
      applybutton->box(FL_THIN_UP_BOX);
      applybutton->labelfont(1);
      applybutton->callback((Fl_Callback*)cb_applybutton);
      if (!oscil->ADvsPAD) o->hide();
    } // Fl_Button* applybutton
    { oscildisplaygroup = new Fl_Group(5, 5, 360, 300);
      oscildisplaygroup->box(FL_ENGRAVED_FRAME);
      { Fl_Group* o = new Fl_Group(10, 85, 350, 190);
        o->box(FL_THIN_DOWN_BOX);
        o->color(FL_GRAY0);
        o->selection_color((Fl_Color)71);
        o->labelcolor((Fl_Color)179);
        Oscilloscope *osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");
        osc->init(oscil,master);
        o->end();
      } // Fl_Group* o
      { Fl_Box* o = new Fl_Box(120, 10, 110, 20, "Oscillator");
        o->box(FL_FLAT_BOX);
        o->labelfont(1);
      } // Fl_Box* o
      { Fl_Value_Slider* o = rndslider = new Fl_Value_Slider(140, 285, 100, 10, "rnd");
        rndslider->tooltip("Oscilator Phase Randomness: smaller than 0 is \"group\", larger than 0 is for\
 each harmonic");
        rndslider->type(5);
        rndslider->box(FL_FLAT_BOX);
        rndslider->labelsize(10);
        rndslider->minimum(-64);
        rndslider->maximum(63);
        rndslider->step(1);
        rndslider->callback((Fl_Callback*)cb_rndslider);
        rndslider->align(Fl_Align(FL_ALIGN_TOP_LEFT));
        if (oscil->ADvsPAD) o->hide();
      } // Fl_Value_Slider* rndslider
      { Fl_Group* o = new Fl_Group(10, 30, 350, 50);
        o->box(FL_THIN_DOWN_BOX);
        o->color(FL_GRAY0);
        o->selection_color((Fl_Color)218);
        o->labelcolor(FL_GREEN);
        OscilSpectrum *spc=new OscilSpectrum(o->x(),o->y(),o->w(),o->h(),"");
        spc->init(oscil,0,master);
        o->end();
      } // Fl_Group* o
      { Fl_Group* o = new Fl_Group(246, 277, 115, 25);
        o->box(FL_ENGRAVED_BOX);
        { hrndtype = new Fl_Choice(281, 282, 50, 15, "H.rnd");
          hrndtype->tooltip("Harmonic Amplitude Randomness");
          hrndtype->down_box(FL_BORDER_BOX);
          hrndtype->labelsize(10);
          hrndtype->textsize(10);
          hrndtype->callback((Fl_Callback*)cb_hrndtype);
          hrndtype->menu(menu_hrndtype);
        } // Fl_Choice* hrndtype
        { hrnddial = new WidgetPDial(338, 280, 18, 18);
          hrnddial->tooltip("Oscillator\'s spectrum adjust parameter");
          hrnddial->box(FL_OVAL_BOX);
          hrnddial->color(FL_BACKGROUND_COLOR);
          hrnddial->selection_color(FL_INACTIVE_COLOR);
          hrnddial->labeltype(FL_NORMAL_LABEL);
          hrnddial->labelfont(0);
          hrnddial->labelsize(14);
          hrnddial->labelcolor(FL_FOREGROUND_COLOR);
          hrnddial->maximum(127);
          hrnddial->step(1);
          hrnddial->callback((Fl_Callback*)cb_hrnddial);
          hrnddial->align(Fl_Align(FL_ALIGN_BOTTOM));
          hrnddial->when(FL_WHEN_CHANGED);
        } // WidgetPDial* hrnddial
        if (oscil->ADvsPAD) o->hide();
        o->end();
      } // Fl_Group* o
      oscildisplaygroup->end();
    } // Fl_Group* oscildisplaygroup
    { Fl_Box* o = new Fl_Box(495, 15, 110, 20, "Base Func.");
      o->box(FL_FLAT_BOX);
      o->labelfont(1);
    } // Fl_Box* o
    { basefuncdisplaygroup = new Fl_Group(365, 5, 360, 300);
      basefuncdisplaygroup->box(FL_ENGRAVED_FRAME);
      { Fl_Group* o = new Fl_Group(370, 85, 350, 190);
        o->box(FL_THIN_DOWN_BOX);
        o->color(FL_GRAY0);
        o->selection_color((Fl_Color)71);
        o->labelcolor((Fl_Color)179);
        Oscilloscope *osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");
        osc->init(oscil,1,master);
        o->end();
      } // Fl_Group* o
      { bfslider = new WidgetPDial(520, 280, 20, 20);
        bfslider->tooltip("Base Function Parameter");
        bfslider->box(FL_OVAL_BOX);
        bfslider->color(FL_BACKGROUND_COLOR);
        bfslider->selection_color(FL_INACTIVE_COLOR);
        bfslider->labeltype(FL_NORMAL_LABEL);
        bfslider->labelfont(0);
        bfslider->labelsize(14);
        bfslider->labelcolor(FL_FOREGROUND_COLOR);
        bfslider->minimum(-64);
        bfslider->maximum(63);
        bfslider->step(1);
        bfslider->callback((Fl_Callback*)cb_bfslider);
        bfslider->align(Fl_Align(FL_ALIGN_BOTTOM));
        bfslider->when(FL_WHEN_CHANGED);
      } // WidgetPDial* bfslider
      { bftype = new Fl_Choice(370, 285, 90, 15, "Base.F..");
        bftype->down_box(FL_BORDER_BOX);
        bftype->labelsize(10);
        bftype->textsize(11);
        bftype->callback((Fl_Callback*)cb_bftype);
        bftype->align(Fl_Align(FL_ALIGN_TOP_LEFT));
        bftype->menu(menu_bftype);
      } // Fl_Choice* bftype
      { Fl_Box* o = new Fl_Box(480, 10, 110, 20, "Base Func.");
        o->box(FL_FLAT_BOX);
        o->labelfont(1);
      } // Fl_Box* o
      { Fl_Group* o = new Fl_Group(370, 30, 350, 50);
        o->box(FL_THIN_DOWN_BOX);
        o->color(FL_GRAY0);
        o->selection_color((Fl_Color)218);
        o->labelcolor(FL_GREEN);
        OscilSpectrum *spc=new OscilSpectrum (o->x(),o->y(),o->w(),o->h(),"");
        spc->init(oscil,1,master);
        o->end();
      } // Fl_Group* o
      { bfparval = new Fl_Value_Output(490, 285, 25, 15, "Par.");
        bfparval->labelsize(12);
        bfparval->minimum(-63);
        bfparval->maximum(63);
        bfparval->step(1);
      } // Fl_Value_Output* bfparval
      { basefuncmodulation = new Fl_Group(550, 276, 169, 25);
        basefuncmodulation->box(FL_ENGRAVED_BOX);
        { bfmodtype = new Fl_Choice(599, 281, 50, 15, "B.F.Mod.");
          bfmodtype->tooltip("Base function modulation");
          bfmodtype->down_box(FL_BORDER_BOX);
          bfmodtype->labelsize(10);
          bfmodtype->textsize(10);
          bfmodtype->callback((Fl_Callback*)cb_bfmodtype);
          bfmodtype->menu(menu_bfmodtype);
        } // Fl_Choice* bfmodtype
        { bfmodpar1 = new WidgetPDial(659, 281, 15, 15);
          bfmodpar1->tooltip("Oscillator\'s modulation parameter 1");
          bfmodpar1->box(FL_OVAL_BOX);
          bfmodpar1->color(FL_BACKGROUND_COLOR);
          bfmodpar1->selection_color(FL_INACTIVE_COLOR);
          bfmodpar1->labeltype(FL_NORMAL_LABEL);
          bfmodpar1->labelfont(0);
          bfmodpar1->labelsize(14);
          bfmodpar1->labelcolor(FL_FOREGROUND_COLOR);
          bfmodpar1->maximum(127);
          bfmodpar1->step(1);
          bfmodpar1->callback((Fl_Callback*)cb_bfmodpar1);
          bfmodpar1->align(Fl_Align(FL_ALIGN_BOTTOM));
          bfmodpar1->when(FL_WHEN_CHANGED);
        } // WidgetPDial* bfmodpar1
        { bfmodpar2 = new WidgetPDial(679, 281, 15, 15);
          bfmodpar2->tooltip("Oscillator\'s modulation parameter 2");
          bfmodpar2->box(FL_OVAL_BOX);
          bfmodpar2->color(FL_BACKGROUND_COLOR);
          bfmodpar2->selection_color(FL_INACTIVE_COLOR);
          bfmodpar2->labeltype(FL_NORMAL_LABEL);
          bfmodpar2->labelfont(0);
          bfmodpar2->labelsize(14);
          bfmodpar2->labelcolor(FL_FOREGROUND_COLOR);
          bfmodpar2->maximum(127);
          bfmodpar2->step(1);
          bfmodpar2->callback((Fl_Callback*)cb_bfmodpar2);
          bfmodpar2->align(Fl_Align(FL_ALIGN_BOTTOM));
          bfmodpar2->when(FL_WHEN_CHANGED);
        } // WidgetPDial* bfmodpar2
        { bfmodpar3 = new WidgetPDial(699, 281, 15, 15);
          bfmodpar3->tooltip("Oscillator\'s modulation parameter 3");
          bfmodpar3->box(FL_OVAL_BOX);
          bfmodpar3->color(FL_BACKGROUND_COLOR);
          bfmodpar3->selection_color(FL_INACTIVE_COLOR);
          bfmodpar3->labeltype(FL_NORMAL_LABEL);
          bfmodpar3->labelfont(0);
          bfmodpar3->labelsize(14);
          bfmodpar3->labelcolor(FL_FOREGROUND_COLOR);
          bfmodpar3->maximum(127);
          bfmodpar3->step(1);
          bfmodpar3->callback((Fl_Callback*)cb_bfmodpar3);
          bfmodpar3->align(Fl_Align(FL_ALIGN_BOTTOM));
          bfmodpar3->when(FL_WHEN_CHANGED);
        } // WidgetPDial* bfmodpar3
        if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodulation->deactivate();
        basefuncmodulation->end();
      } // Fl_Group* basefuncmodulation
      basefuncdisplaygroup->end();
    } // Fl_Group* basefuncdisplaygroup
    { magtype = new Fl_Choice(70, 280, 65, 20, "Mag.Type");
      magtype->down_box(FL_BORDER_BOX);
      magtype->labelsize(11);
      magtype->textsize(11);
      magtype->callback((Fl_Callback*)cb_magtype);
      magtype->menu(menu_magtype);
    } // Fl_Choice* magtype
    { Fl_Button* o = new Fl_Button(5, 313, 85, 20, "Use as base");
      o->tooltip("Use this Oscillator as base function");
      o->box(FL_THIN_UP_BOX);
      o->labelfont(1);
      o->labelsize(11);
      o->callback((Fl_Callback*)cb_Use);
    } // Fl_Button* o
    { Fl_Button* o = new Fl_Button(668, 565, 62, 25, "Close");
      o->box(FL_THIN_UP_BOX);
      o->callback((Fl_Callback*)cb_Close);
    } // Fl_Button* o
    { Fl_Button* o = new Fl_Button(670, 505, 55, 15, "Clear");
      o->box(FL_THIN_UP_BOX);
      o->labelfont(1);
      o->labelsize(11);
      o->callback((Fl_Callback*)cb_Clear);
    } // Fl_Button* o
    { Fl_Group* o = new Fl_Group(135, 308, 150, 30);
      o->box(FL_ENGRAVED_BOX);
      { wshbutton = new Fl_Choice(165, 313, 55, 20, "Wsh.");
        wshbutton->tooltip("Waveshaping function");
        wshbutton->down_box(FL_BORDER_BOX);
        wshbutton->labelsize(10);
        wshbutton->textsize(10);
        wshbutton->callback((Fl_Callback*)cb_wshbutton);
        wshbutton->menu(menu_wshbutton);
      } // Fl_Choice* wshbutton
      { wshpar = new WidgetPDial(260, 313, 20, 20);
        wshpar->tooltip("Waveshaping Parameter");
        wshpar->box(FL_OVAL_BOX);
        wshpar->color(FL_BACKGROUND_COLOR);
        wshpar->selection_color(FL_INACTIVE_COLOR);
        wshpar->labeltype(FL_NORMAL_LABEL);
        wshpar->labelfont(0);
        wshpar->labelsize(14);
        wshpar->labelcolor(FL_FOREGROUND_COLOR);
        wshpar->minimum(-64);
        wshpar->maximum(63);
        wshpar->step(1);
        wshpar->callback((Fl_Callback*)cb_wshpar);
        wshpar->align(Fl_Align(FL_ALIGN_BOTTOM));
        wshpar->when(FL_WHEN_CHANGED);
      } // WidgetPDial* wshpar
      { wsparval = new Fl_Value_Output(228, 316, 25, 15);
        wsparval->labelsize(12);
        wsparval->minimum(-63);
        wsparval->maximum(63);
        wsparval->step(1);
      } // Fl_Value_Output* wsparval
      o->end();
    } // Fl_Group* o
    { autoclearbutton = new Fl_Light_Button(95, 313, 35, 20, "Clr.");
      autoclearbutton->tooltip("Auto clear when using the oscillator as base function");
      autoclearbutton->box(FL_THIN_UP_BOX);
      autoclearbutton->value(1);
      autoclearbutton->labelfont(1);
      autoclearbutton->labelsize(10);
    } // Fl_Light_Button* autoclearbutton
    { Fl_Group* o = new Fl_Group(285, 308, 155, 30);
      o->box(FL_ENGRAVED_BOX);
      { fltbutton = new Fl_Choice(315, 313, 50, 20, "Filter");
        fltbutton->tooltip("Oscillator\'s filter type");
        fltbutton->down_box(FL_BORDER_BOX);
        fltbutton->labelsize(10);
        fltbutton->textsize(10);
        fltbutton->callback((Fl_Callback*)cb_fltbutton);
        fltbutton->menu(menu_fltbutton);
      } // Fl_Choice* fltbutton
      { filtervalue1 = new WidgetPDial(367, 313, 20, 20);
        filtervalue1->tooltip("Oscillator\'s filter parameter1");
        filtervalue1->box(FL_OVAL_BOX);
        filtervalue1->color(FL_BACKGROUND_COLOR);
        filtervalue1->selection_color(FL_INACTIVE_COLOR);
        filtervalue1->labeltype(FL_NORMAL_LABEL);
        filtervalue1->labelfont(0);
        filtervalue1->labelsize(14);
        filtervalue1->labelcolor(FL_FOREGROUND_COLOR);
        filtervalue1->maximum(127);
        filtervalue1->step(1);
        filtervalue1->callback((Fl_Callback*)cb_filtervalue1);
        filtervalue1->align(Fl_Align(FL_ALIGN_BOTTOM));
        filtervalue1->when(FL_WHEN_CHANGED);
      } // WidgetPDial* filtervalue1
      { filterpref = new Fl_Check_Button(415, 313, 20, 20, "p");
        filterpref->tooltip("Apply the filter before the waveshaping");
        filterpref->down_box(FL_DOWN_BOX);
        filterpref->labelsize(10);
        filterpref->callback((Fl_Callback*)cb_filterpref);
        filterpref->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE));
      } // Fl_Check_Button* filterpref
      { filtervalue2 = new WidgetPDial(392, 313, 20, 20);
        filtervalue2->tooltip("Oscillator\'s filter parameter2");
        filtervalue2->box(FL_OVAL_BOX);
        filtervalue2->color(FL_BACKGROUND_COLOR);
        filtervalue2->selection_color(FL_INACTIVE_COLOR);
        filtervalue2->labeltype(FL_NORMAL_LABEL);
        filtervalue2->labelfont(0);
        filtervalue2->labelsize(14);
        filtervalue2->labelcolor(FL_FOREGROUND_COLOR);
        filtervalue2->maximum(127);
        filtervalue2->step(1);
        filtervalue2->callback((Fl_Callback*)cb_filtervalue2);
        filtervalue2->align(Fl_Align(FL_ALIGN_BOTTOM));
        filtervalue2->when(FL_WHEN_CHANGED);
      } // WidgetPDial* filtervalue2
      o->end();
    } // Fl_Group* o
    { Fl_Group* o = new Fl_Group(590, 308, 135, 30);
      o->box(FL_ENGRAVED_BOX);
      { sabutton = new Fl_Choice(630, 313, 60, 20, "Sp.adj.");
        sabutton->tooltip("Oscillator\'s spectrum adjust");
        sabutton->down_box(FL_BORDER_BOX);
        sabutton->labelsize(10);
        sabutton->textsize(10);
        sabutton->callback((Fl_Callback*)cb_sabutton);
        sabutton->menu(menu_sabutton);
      } // Fl_Choice* sabutton
      { sadjpar = new WidgetPDial(695, 313, 20, 20);
        sadjpar->tooltip("Oscillator\'s spectrum adjust parameter");
        sadjpar->box(FL_OVAL_BOX);
        sadjpar->color(FL_BACKGROUND_COLOR);
        sadjpar->selection_color(FL_INACTIVE_COLOR);
        sadjpar->labeltype(FL_NORMAL_LABEL);
        sadjpar->labelfont(0);
        sadjpar->labelsize(14);
        sadjpar->labelcolor(FL_FOREGROUND_COLOR);
        sadjpar->maximum(127);
        sadjpar->step(1);
        sadjpar->callback((Fl_Callback*)cb_sadjpar);
        sadjpar->align(Fl_Align(FL_ALIGN_BOTTOM));
        sadjpar->when(FL_WHEN_CHANGED);
      } // WidgetPDial* sadjpar
      o->end();
    } // Fl_Group* o
    { Fl_Group* o = new Fl_Group(665, 340, 65, 65);
      o->box(FL_ENGRAVED_BOX);
      { harmonicshiftcounter = new Fl_Counter(670, 365, 55, 15, "Harmonic Shift");
        harmonicshiftcounter->type(1);
        harmonicshiftcounter->labelsize(10);
        harmonicshiftcounter->minimum(-64);
        harmonicshiftcounter->maximum(64);
        harmonicshiftcounter->step(1);
        harmonicshiftcounter->textfont(1);
        harmonicshiftcounter->textsize(10);
        harmonicshiftcounter->callback((Fl_Callback*)cb_harmonicshiftcounter);
        harmonicshiftcounter->align(Fl_Align(129));
      } // Fl_Counter* harmonicshiftcounter
      { harmonicshiftpre = new Fl_Check_Button(690, 385, 34, 15, "preH");
        harmonicshiftpre->tooltip("Apply the harmonic shift before the waveshaping and filtering");
        harmonicshiftpre->down_box(FL_DOWN_BOX);
        harmonicshiftpre->labelsize(10);
        harmonicshiftpre->callback((Fl_Callback*)cb_harmonicshiftpre);
        harmonicshiftpre->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE));
      } // Fl_Check_Button* harmonicshiftpre
      { Fl_Button* o = new Fl_Button(670, 385, 20, 15, "R");
        o->box(FL_THIN_UP_BOX);
        o->labelfont(1);
        o->labelsize(10);
        o->callback((Fl_Callback*)cb_R);
      } // Fl_Button* o
      o->end();
    } // Fl_Group* o
    { Fl_Group* o = new Fl_Group(665, 410, 65, 90);
      o->box(FL_ENGRAVED_FRAME);
      { adhrtype = new Fl_Choice(670, 425, 55, 15, "Adpt.Harm.");
        adhrtype->tooltip("The type of the addaptive harmonics");
        adhrtype->down_box(FL_BORDER_BOX);
        adhrtype->labelsize(10);
        adhrtype->textsize(10);
        adhrtype->callback((Fl_Callback*)cb_adhrtype);
        adhrtype->align(Fl_Align(129));
        adhrtype->when(FL_WHEN_RELEASE_ALWAYS);
        adhrtype->menu(menu_adhrtype);
      } // Fl_Choice* adhrtype
      { adhrpow = new WidgetPDial(700, 460, 25, 25, "pow");
        adhrpow->tooltip("Adaptive harmonics power");
        adhrpow->box(FL_OVAL_BOX);
        adhrpow->color(FL_BACKGROUND_COLOR);
        adhrpow->selection_color(FL_INACTIVE_COLOR);
        adhrpow->labeltype(FL_NORMAL_LABEL);
        adhrpow->labelfont(0);
        adhrpow->labelsize(10);
        adhrpow->labelcolor(FL_FOREGROUND_COLOR);
        adhrpow->maximum(200);
        adhrpow->step(1);
        adhrpow->callback((Fl_Callback*)cb_adhrpow);
        adhrpow->align(Fl_Align(FL_ALIGN_BOTTOM));
        adhrpow->when(FL_WHEN_CHANGED);
      } // WidgetPDial* adhrpow
      { adhrbf = new WidgetPDial(670, 460, 25, 25, "baseF");
        adhrbf->tooltip("Adaptive harmonics base frequency");
        adhrbf->box(FL_OVAL_BOX);
        adhrbf->color(FL_BACKGROUND_COLOR);
        adhrbf->selection_color(FL_INACTIVE_COLOR);
        adhrbf->labeltype(FL_NORMAL_LABEL);
        adhrbf->labelfont(0);
        adhrbf->labelsize(10);
        adhrbf->labelcolor(FL_FOREGROUND_COLOR);
        adhrbf->maximum(255);
        adhrbf->step(1);
        adhrbf->callback((Fl_Callback*)cb_adhrbf);
        adhrbf->align(Fl_Align(FL_ALIGN_BOTTOM));
        adhrbf->when(FL_WHEN_CHANGED);
      } // WidgetPDial* adhrbf
      { adhrpar = new Fl_Slider(670, 445, 55, 10);
        adhrpar->type(5);
        adhrpar->box(FL_FLAT_BOX);
        adhrpar->maximum(100);
        adhrpar->step(1);
        adhrpar->value(50);
        adhrpar->callback((Fl_Callback*)cb_adhrpar);
      } // Fl_Slider* adhrpar
      o->end();
    } // Fl_Group* o
    { Fl_Group* o = new Fl_Group(440, 308, 150, 30);
      o->box(FL_ENGRAVED_BOX);
      { modtype = new Fl_Choice(470, 315, 50, 15, "Mod.");
        modtype->tooltip("modulation");
        modtype->down_box(FL_BORDER_BOX);
        modtype->labelsize(10);
        modtype->textsize(10);
        modtype->callback((Fl_Callback*)cb_modtype);
        modtype->menu(menu_modtype);
      } // Fl_Choice* modtype
      { modpar1 = new WidgetPDial(530, 315, 15, 15);
        modpar1->tooltip("Oscillator\'s modulation parameter 1");
        modpar1->box(FL_OVAL_BOX);
        modpar1->color(FL_BACKGROUND_COLOR);
        modpar1->selection_color(FL_INACTIVE_COLOR);
        modpar1->labeltype(FL_NORMAL_LABEL);
        modpar1->labelfont(0);
        modpar1->labelsize(14);
        modpar1->labelcolor(FL_FOREGROUND_COLOR);
        modpar1->maximum(127);
        modpar1->step(1);
        modpar1->callback((Fl_Callback*)cb_modpar1);
        modpar1->align(Fl_Align(FL_ALIGN_BOTTOM));
        modpar1->when(FL_WHEN_CHANGED);
      } // WidgetPDial* modpar1
      { modpar2 = new WidgetPDial(550, 315, 15, 15);
        modpar2->tooltip("Oscillator\'s modulation parameter 2");
        modpar2->box(FL_OVAL_BOX);
        modpar2->color(FL_BACKGROUND_COLOR);
        modpar2->selection_color(FL_INACTIVE_COLOR);
        modpar2->labeltype(FL_NORMAL_LABEL);
        modpar2->labelfont(0);
        modpar2->labelsize(14);
        modpar2->labelcolor(FL_FOREGROUND_COLOR);
        modpar2->maximum(127);
        modpar2->step(1);
        modpar2->callback((Fl_Callback*)cb_modpar2);
        modpar2->align(Fl_Align(FL_ALIGN_BOTTOM));
        modpar2->when(FL_WHEN_CHANGED);
      } // WidgetPDial* modpar2
      { modpar3 = new WidgetPDial(570, 315, 15, 15);
        modpar3->tooltip("Oscillator\'s modulation parameter 3");
        modpar3->box(FL_OVAL_BOX);
        modpar3->color(FL_BACKGROUND_COLOR);
        modpar3->selection_color(FL_INACTIVE_COLOR);
        modpar3->labeltype(FL_NORMAL_LABEL);
        modpar3->labelfont(0);
        modpar3->labelsize(14);
        modpar3->labelcolor(FL_FOREGROUND_COLOR);
        modpar3->maximum(127);
        modpar3->step(1);
        modpar3->callback((Fl_Callback*)cb_modpar3);
        modpar3->align(Fl_Align(FL_ALIGN_BOTTOM));
        modpar3->when(FL_WHEN_CHANGED);
      } // WidgetPDial* modpar3
      o->end();
    } // Fl_Group* o
    { Fl_Button* o = new Fl_Button(670, 525, 55, 15, "Sine");
      o->box(FL_THIN_UP_BOX);
      o->labelfont(1);
      o->labelsize(11);
      o->callback((Fl_Callback*)cb_Sine);
    } // Fl_Button* o
    { Fl_Button* o = new Fl_Button(670, 545, 25, 15, "C");
      o->box(FL_THIN_UP_BOX);
      o->color((Fl_Color)179);
      o->labelfont(1);
      o->labelsize(11);
      o->labelcolor(FL_BACKGROUND2_COLOR);
      o->callback((Fl_Callback*)cb_C);
    } // Fl_Button* o
    { Fl_Button* o = new Fl_Button(700, 545, 25, 15, "P");
      o->box(FL_THIN_UP_BOX);
      o->color((Fl_Color)179);
      o->labelfont(1);
      o->labelsize(11);
      o->labelcolor(FL_BACKGROUND2_COLOR);
      o->callback((Fl_Callback*)cb_P);
    } // Fl_Button* o
    { _this_has_to_be_the_last = new Fl_Scroll(5, 340, 660, 250);
      _this_has_to_be_the_last->type(1);
      _this_has_to_be_the_last->box(FL_ENGRAVED_BOX);
      { Fl_Pack* o = harmonics = new Fl_Pack(10, 345, 650, 225);
        harmonics->type(1);
        for (int i=0;i<MAX_AD_HARMONICS;i++){h[i]=new Oscilharmonic(0,0,20,o->h(),"");h[i]->init(oscil,i,oscildisplaygroup,oldosc,cbwidget,applybutton,master);}
        harmonics->end();
      } // Fl_Pack* harmonics
      _this_has_to_be_the_last->end();
    } // Fl_Scroll* _this_has_to_be_the_last
    if (oscil->ADvsPAD) o->label("PADsynth Harmonic Content Editor");
    osceditUI->end();
  } // Fl_Double_Window* osceditUI
  return osceditUI;
}

OscilEditor::OscilEditor(OscilGen *oscil_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *cbapplywidget_,Master *master_) {
  oscil=oscil_;
  oldosc=oldosc_;
  cbwidget=cbwidget_;
  cbapplywidget=cbapplywidget_;
  master=master_;
  
  make_window();
  
  refresh();
  osceditUI->show();
}

OscilEditor::~OscilEditor() {
  osceditUI->hide();
  //for (int i=0;i<MAX_AD_HARMONICS;i++) delete (h[i]);
  delete (osceditUI);
}

void OscilEditor::refresh() {
  magtype->value(oscil->Phmagtype);
  rndslider->value(oscil->Prand-64);
  
  hrndtype->value(oscil->Pamprandtype);
  hrnddial->value(oscil->Pamprandpower);
  
  bftype->value(oscil->Pcurrentbasefunc);
  bfparval->value(oscil->Pbasefuncpar-64);
  bfslider->value(oscil->Pbasefuncpar-64);
  
  bfmodtype->value(oscil->Pbasefuncmodulation);
  bfmodpar1->value(oscil->Pbasefuncmodulationpar1);
  bfmodpar2->value(oscil->Pbasefuncmodulationpar2);
  bfmodpar3->value(oscil->Pbasefuncmodulationpar3);
  
  wshbutton->value(oscil->Pwaveshapingfunction);
  wsparval->value(oscil->Pwaveshaping-64);
  wshpar->value(oscil->Pwaveshaping-64);
  
  fltbutton->value(oscil->Pfiltertype);
  filtervalue1->value(oscil->Pfilterpar1);
  filtervalue2->value(oscil->Pfilterpar2);
  filterpref->value(oscil->Pfilterbeforews);
  
  modtype->value(oscil->Pmodulation);
  modpar1->value(oscil->Pmodulationpar1);
  modpar2->value(oscil->Pmodulationpar2);
  modpar3->value(oscil->Pmodulationpar3);
  
  sabutton->value(oscil->Psatype);
  sadjpar->value(oscil->Psapar);
  
  harmonicshiftcounter->value(oscil->Pharmonicshift);
  harmonicshiftpre->value(oscil->Pharmonicshiftfirst);
  
  adhrtype->value(oscil->Padaptiveharmonics);
  adhrbf->value(oscil->Padaptiveharmonicsbasefreq);
  adhrpow->value(oscil->Padaptiveharmonicspower);
  adhrtype->value(oscil->Padaptiveharmonicspar);
  
  for (int i=0;i<MAX_AD_HARMONICS;i++) h[i]->refresh();
  
  pthread_mutex_lock(&master->mutex);
   oscil->prepare();
  pthread_mutex_unlock(&master->mutex);
  
  basefuncdisplaygroup->redraw();
  redrawoscil();
}

void OscilEditor::redrawoscil() {
  oscildisplaygroup->redraw();
  oldosc->redraw();
  if (cbwidget!=NULL) {
        cbwidget->do_callback();
        applybutton->color(FL_RED);
        applybutton->redraw();
  };
}
