Browse Source

Update zynaddsubfx

tags/1.9.7
falkTX 8 years ago
parent
commit
cbd2dadb86
30 changed files with 750 additions and 400 deletions
  1. +7
    -0
      source/native-plugins/zynaddsubfx-src.cpp
  2. +1
    -1
      source/native-plugins/zynaddsubfx/Containers/NotePool.cpp
  3. +5
    -3
      source/native-plugins/zynaddsubfx/DSP/AnalogFilter.cpp
  4. +1
    -1
      source/native-plugins/zynaddsubfx/DSP/Filter.cpp
  5. +1
    -1
      source/native-plugins/zynaddsubfx/DSP/Filter.h
  6. +2
    -2
      source/native-plugins/zynaddsubfx/DSP/FormantFilter.cpp
  7. +1
    -2
      source/native-plugins/zynaddsubfx/DSP/FormantFilter.h
  8. +1
    -1
      source/native-plugins/zynaddsubfx/DSP/SVFilter.cpp
  9. +25
    -3
      source/native-plugins/zynaddsubfx/Misc/Bank.cpp
  10. +8
    -1
      source/native-plugins/zynaddsubfx/Misc/Bank.h
  11. +163
    -41
      source/native-plugins/zynaddsubfx/Misc/Microtonal.cpp
  12. +41
    -14
      source/native-plugins/zynaddsubfx/Misc/Microtonal.h
  13. +75
    -0
      source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp
  14. +1
    -4
      source/native-plugins/zynaddsubfx/Misc/Part.cpp
  15. +1
    -1
      source/native-plugins/zynaddsubfx/Misc/XMLwrapper.cpp
  16. +11
    -11
      source/native-plugins/zynaddsubfx/Params/FilterParams.cpp
  17. +11
    -11
      source/native-plugins/zynaddsubfx/Params/FilterParams.h
  18. +68
    -102
      source/native-plugins/zynaddsubfx/Synth/ADnote.cpp
  19. +6
    -18
      source/native-plugins/zynaddsubfx/Synth/ADnote.h
  20. +149
    -0
      source/native-plugins/zynaddsubfx/Synth/ModFilter.cpp
  21. +55
    -0
      source/native-plugins/zynaddsubfx/Synth/ModFilter.h
  22. +28
    -35
      source/native-plugins/zynaddsubfx/Synth/PADnote.cpp
  23. +3
    -9
      source/native-plugins/zynaddsubfx/Synth/PADnote.h
  24. +41
    -59
      source/native-plugins/zynaddsubfx/Synth/SUBnote.cpp
  25. +6
    -7
      source/native-plugins/zynaddsubfx/Synth/SUBnote.h
  26. +1
    -4
      source/native-plugins/zynaddsubfx/UI/BankUI.fl
  27. +2
    -6
      source/native-plugins/zynaddsubfx/UI/MasterUI.fl
  28. +29
    -62
      source/native-plugins/zynaddsubfx/UI/MicrotonalUI.fl
  29. +6
    -0
      source/native-plugins/zynaddsubfx/globals.h
  30. +1
    -1
      source/native-plugins/zynaddsubfx/main.cpp

+ 7
- 0
source/native-plugins/zynaddsubfx-src.cpp View File

@@ -402,6 +402,13 @@ extern "C" {
#undef rChangeCb
#define rChangeCb

#include "zynaddsubfx/Synth/ModFilter.cpp"
#undef rObject
#undef rStdString
#undef rStdStringCb
#undef rChangeCb
#define rChangeCb

#include "zynaddsubfx/Synth/OscilGen.cpp"
#undef PC
#undef DIFF


+ 1
- 1
source/native-plugins/zynaddsubfx/Containers/NotePool.cpp View File

@@ -279,7 +279,7 @@ void NotePool::enforceKeyLimit(int limit)
void NotePool::releasePlayingNotes(void)
{
for(auto &d:activeDesc()) {
if(d.playing()) {
if(d.playing() || d.sustained()) {
d.setStatus(KEY_RELEASED);
for(auto s:activeNotes(d))
s.note->releasekey();


+ 5
- 3
source/native-plugins/zynaddsubfx/DSP/AnalogFilter.cpp View File

@@ -323,9 +323,11 @@ void AnalogFilter::setstages(int stages_)
{
if(stages_ >= MAX_FILTER_STAGES)
stages_ = MAX_FILTER_STAGES - 1;
stages = stages_;
cleanup();
computefiltercoefs();
if(stages_ != stages) {
stages = stages_;
cleanup();
computefiltercoefs();
}
}

inline void AnalogBiquadFilterA(const float coeff[5], float &src, float work[4])


+ 1
- 1
source/native-plugins/zynaddsubfx/DSP/Filter.cpp View File

@@ -39,7 +39,7 @@ Filter::Filter(unsigned int srate, int bufsize)
alias();
}

Filter *Filter::generate(Allocator &memory, FilterParams *pars,
Filter *Filter::generate(Allocator &memory, const FilterParams *pars,
unsigned int srate, int bufsize)
{
assert(srate != 0);


+ 1
- 1
source/native-plugins/zynaddsubfx/DSP/Filter.h View File

@@ -29,7 +29,7 @@ class Filter
{
public:
static float getrealfreq(float freqpitch);
static Filter *generate(class Allocator &memory, class FilterParams *pars,
static Filter *generate(Allocator &memory, const FilterParams *pars,
unsigned int srate, int bufsize);

Filter(unsigned int srate, int bufsize);


+ 2
- 2
source/native-plugins/zynaddsubfx/DSP/FormantFilter.cpp View File

@@ -28,8 +28,8 @@
#include "AnalogFilter.h"
#include "../Params/FilterParams.h"

FormantFilter::FormantFilter(FilterParams *pars, Allocator *alloc, unsigned int srate, int bufsize)
: Filter(srate, bufsize), memory(*alloc)
FormantFilter::FormantFilter(const FilterParams *pars, Allocator *alloc, unsigned int srate, int bufsize)
:Filter(srate, bufsize), memory(*alloc)
{
numformants = pars->Pnumformants;
for(int i = 0; i < numformants; ++i)


+ 1
- 2
source/native-plugins/zynaddsubfx/DSP/FormantFilter.h View File

@@ -27,11 +27,10 @@
#include "Filter.h"


class Allocator;
class FormantFilter:public Filter
{
public:
FormantFilter(class FilterParams *pars, Allocator *alloc, unsigned int srate, int bufsize);
FormantFilter(const FilterParams *pars, Allocator *alloc, unsigned int srate, int bufsize);
~FormantFilter();
void filterout(float *smp);
void setfreq(float frequency);


+ 1
- 1
source/native-plugins/zynaddsubfx/DSP/SVFilter.cpp View File

@@ -85,7 +85,7 @@ void SVFilter::setfreq(float frequency)
bool nyquistthresh = (abovenq ^ oldabovenq);

//if the frequency is changed fast, it needs interpolation
if((rap > 3.0f) || nyquistthresh) { //(now, filter and coeficients backup)
if((rap > 3.0f) || nyquistthresh) { //(now, filter and coefficients backup)
if(!firsttime)
needsinterpolation = true;
ipar = par;


+ 25
- 3
source/native-plugins/zynaddsubfx/Misc/Bank.cpp View File

@@ -212,6 +212,7 @@ int Bank::loadfromslot(unsigned int ninstrument, Part *part)
*/
int Bank::loadbank(string bankdirname)
{
normalizedirsuffix(bankdirname);
DIR *dir = opendir(bankdirname.c_str());
clearbank();

@@ -285,9 +286,8 @@ int Bank::newbank(string newbankdirname)
string bankdir;
bankdir = config->cfg.bankRootDirList[0];

if(((bankdir[bankdir.size() - 1]) != '/')
&& ((bankdir[bankdir.size() - 1]) != '\\'))
bankdir += "/";
expanddirname(bankdir);
normalizedirsuffix(bankdir);

bankdir += newbankdirname;
#ifdef _WIN32
@@ -404,6 +404,8 @@ void Bank::setLsb(uint8_t lsb)

void Bank::scanrootdir(string rootdir)
{
expanddirname(rootdir);

DIR *dir = opendir(rootdir.c_str());
if(dir == NULL)
return;
@@ -498,3 +500,23 @@ void Bank::deletefrombank(int pos)
Bank::ins_t::ins_t()
:name(""), filename("")
{}

void Bank::expanddirname(std::string &dirname) {
if (dirname.empty())
return;

// if the directory name starts with a ~ and the $HOME variable is
// defined in the environment, replace ~ by the content of $HOME
if (dirname.at(0) == '~') {
char *home_dirname = getenv("HOME");
if (home_dirname != NULL) {
dirname = std::string(home_dirname) + dirname.substr(1);
}
}
}

void Bank::normalizedirsuffix(string &dirname) const {
if(((dirname[dirname.size() - 1]) != '/')
&& ((dirname[dirname.size() - 1]) != '\\'))
dirname += "/";
}

+ 8
- 1
source/native-plugins/zynaddsubfx/Misc/Bank.h View File

@@ -100,7 +100,14 @@ class Bank
std::string dirname;

void scanrootdir(std::string rootdir); //scans a root dir for banks

/** Expends ~ prefix in dirname, if any */
void expanddirname(std::string &dirname);

/** Ensure that the directory name is suffixed by a
* directory separator */
void normalizedirsuffix(std::string &dirname) const;

Config* const config;

public:


+ 163
- 41
source/native-plugins/zynaddsubfx/Misc/Microtonal.cpp View File

@@ -23,6 +23,7 @@
#include <cmath>
#include <cstring>
#include <cstdio>
#include <cassert>

#include <rtosc/ports.h>
#include <rtosc/port-sugar.h>
@@ -72,6 +73,118 @@ const rtosc::Ports Microtonal::ports = {
Microtonal &m = *(Microtonal*)d.obj;
d.reply(d.loc, "i", m.getoctavesize());
}},
{"mapping::s", rDoc("Get user editable tunings"), 0, [](const char *msg, RtData &d)
{
char buf[100*MAX_OCTAVE_SIZE] = {0};
char tmpbuf[100] = {0};
Microtonal &m = *(Microtonal*)d.obj;
if(rtosc_narguments(msg) == 1) {
m.texttomapping(rtosc_argument(msg,0).s);
} else {
for (int i=0;i<m.Pmapsize;i++){
if (i!=0)
strncat(buf, "\n", sizeof(buf)-1);
if (m.Pmapping[i]==-1)
snprintf(tmpbuf,100,"x");
else
snprintf(tmpbuf,100,"%d",m.Pmapping[i]);
strncat(buf, tmpbuf, sizeof(buf)-1);
};
d.reply(d.loc, "s", buf);
}
}},
{"tunings::s", rDoc("Get user editable tunings"), 0, [](const char *msg, RtData &d)
{
char buf[100*MAX_OCTAVE_SIZE] = {0};
char tmpbuf[100] = {0};
Microtonal &m = *(Microtonal*)d.obj;
if(rtosc_narguments(msg) == 1) {
int err = m.texttotunings(rtosc_argument(msg,0).s);
if (err>=0)
d.reply("/alert", "s",
"Parse Error: The input may contain only numbers (like 232.59)\n"
"or divisions (like 121/64).");
if (err==-2)
d.reply("/alert", "s", "Parse Error: The input is empty.");
} else {
for (int i=0;i<m.getoctavesize();i++){
if (i!=0)
strncat(buf, "\n", sizeof(buf)-1);
m.tuningtoline(i,tmpbuf,100);
strncat(buf, tmpbuf, sizeof(buf)-1);
};
d.reply(d.loc, "s", buf);
}
}},

#define COPY(x) self.x = other->x;
{"paste:b", rProp(internal) rDoc("Clone Input Microtonal Object"), 0,
[](const char *msg, RtData &d)
{
rtosc_blob_t b = rtosc_argument(msg, 0).b;
assert(b.len == sizeof(void*));
Microtonal *other = *(Microtonal**)b.len;
Microtonal &self = *(Microtonal*)d.obj;
//oh how I wish there was some darn reflection for this...

COPY(Pinvertupdown);
COPY(Pinvertupdowncenter);
COPY(Penabled);
COPY(PAnote);
COPY(PAfreq);
COPY(Pscaleshift);
COPY(Pfirstkey);
COPY(Plastkey);
COPY(Pmiddlenote);
COPY(Pmapsize);
COPY(Pmappingenabled);
for(int i=0; i<self.octavesize; ++i)
self.octave[i] = other->octave[i];
COPY(Pglobalfinedetune);

memcpy(self.Pname, other->Pname, sizeof(self.Pname));
memcpy(self.Pcomment, other->Pcomment, sizeof(self.Pcomment));
COPY(octavesize);

for(int i=0; i<self.octavesize; ++i)
self.octave[i] = other->octave[i];
d.reply("/free", "sb", "Microtonal", b.len, b.data);
}},
{"paste_scl:b", rProp(internal) rDoc("Clone Input scl Object"), 0,
[](const char *msg, RtData &d)
{
rtosc_blob_t b = rtosc_argument(msg, 0).b;
assert(b.len == sizeof(void*));
SclInfo *other = *(SclInfo**)b.data;
Microtonal &self = *(Microtonal*)d.obj;
memcpy(self.Pname, other->Pname, sizeof(self.Pname));
memcpy(self.Pcomment, other->Pcomment, sizeof(self.Pcomment));
COPY(octavesize);

for(int i=0; i<self.octavesize; ++i)
self.octave[i] = other->octave[i];
d.reply("/free", "sb", "SclInfo", b.len, b.data);
}},
{"paste_kbm:b", rProp(internal) rDoc("Clone Input kbm Object"), 0,
[](const char *msg, RtData &d)
{
rtosc_blob_t b = rtosc_argument(msg, 0).b;
assert(b.len == sizeof(void*));
KbmInfo *other = *(KbmInfo**)b.data;
Microtonal &self = *(Microtonal*)d.obj;
COPY(Pmapsize);
COPY(Pfirstkey);
COPY(Plastkey);
COPY(Pmiddlenote);
COPY(PAnote);
COPY(PAfreq);
COPY(Pmappingenabled);

for(int i=0; i<128; ++i)
self.Pmapping[i] = other->Pmapping[i];
d.reply("/free", "sb", "KbmInfo", b.len, b.data);
}},
#undef COPY
};


@@ -101,13 +214,10 @@ void Microtonal::defaults()
Pmapping[i] = i;

for(int i = 0; i < MAX_OCTAVE_SIZE; ++i) {
octave[i].tuning = tmpoctave[i].tuning = powf(
2,
(i % octavesize
+ 1) / 12.0f);
octave[i].type = tmpoctave[i].type = 1;
octave[i].x1 = tmpoctave[i].x1 = (i % octavesize + 1) * 100;
octave[i].x2 = tmpoctave[i].x2 = 0;
octave[i].tuning = powf(2, (i % octavesize + 1) / 12.0f);
octave[i].type = 1;
octave[i].x1 = (i % octavesize + 1) * 100;
octave[i].x2 = 0;
}
octave[11].type = 2;
octave[11].x1 = 2;
@@ -298,7 +408,7 @@ bool Microtonal::operator!=(const Microtonal &micro) const
/*
* Convert a line to tunings; returns -1 if it ok
*/
int Microtonal::linetotunings(unsigned int nline, const char *line)
int Microtonal::linetotunings(OctaveTuning &octave, const char *line)
{
int x1 = -1, x2 = -1, type = -1;
float x = -1.0f, tmp, tuning = 1.0f;
@@ -346,10 +456,10 @@ int Microtonal::linetotunings(unsigned int nline, const char *line)
break;
}

tmpoctave[nline].tuning = tuning;
tmpoctave[nline].type = type;
tmpoctave[nline].x1 = x1;
tmpoctave[nline].x2 = x2;
octave.tuning = tuning;
octave.type = type;
octave.x1 = x1;
octave.x2 = x2;

return -1; //ok
}
@@ -359,10 +469,11 @@ int Microtonal::linetotunings(unsigned int nline, const char *line)
*/
int Microtonal::texttotunings(const char *text)
{
unsigned int i, k = 0, nl = 0;
char *lin;
lin = new char[MAX_LINE_SIZE + 1];
unsigned int k = 0, nl = 0;
char *lin = new char[MAX_LINE_SIZE + 1];
OctaveTuning tmpoctave[MAX_OCTAVE_SIZE];
while(k < strlen(text)) {
int i;
for(i = 0; i < MAX_LINE_SIZE; ++i) {
lin[i] = text[k++];
if(lin[i] < 0x20)
@@ -371,7 +482,7 @@ int Microtonal::texttotunings(const char *text)
lin[i] = '\0';
if(strlen(lin) == 0)
continue;
int err = linetotunings(nl, lin);
int err = linetotunings(tmpoctave[nl], lin);
if(err != -1) {
delete [] lin;
return nl; //Parse error
@@ -384,7 +495,7 @@ int Microtonal::texttotunings(const char *text)
if(nl == 0)
return -2; //the input is empty
octavesize = nl;
for(i = 0; i < octavesize; ++i) {
for(int i = 0; i < octavesize; ++i) {
octave[i].tuning = tmpoctave[i].tuning;
octave[i].type = tmpoctave[i].type;
octave[i].x1 = tmpoctave[i].x1;
@@ -449,28 +560,37 @@ void Microtonal::tuningtoline(int n, char *line, int maxn)

int Microtonal::loadline(FILE *file, char *line)
{
memset(line, 0, 500);
do {
if(fgets(line, 500, file) == 0)
return 1;
} while(line[0] == '!');
return 0;
}


/*
* Loads the tunnings from a scl file
*/
int Microtonal::loadscl(const char *filename)
int Microtonal::loadscl(SclInfo &scl, const char *filename)
{
FILE *file = fopen(filename, "r");
char tmp[500];
OctaveTuning tmpoctave[MAX_OCTAVE_SIZE];

fseek(file, 0, SEEK_SET);

//loads the short description
if(loadline(file, &tmp[0]) != 0)
return 2;

for(int i = 0; i < 500; ++i)
if(tmp[i] < 32)
tmp[i] = 0;
snprintf((char *) Pname, MICROTONAL_MAX_NAME_LEN, "%s", tmp);
snprintf((char *) Pcomment, MICROTONAL_MAX_NAME_LEN, "%s", tmp);

snprintf(scl.Pname, MICROTONAL_MAX_NAME_LEN, "%s", tmp);
snprintf(scl.Pcomment, MICROTONAL_MAX_NAME_LEN, "%s", tmp);

//loads the number of the notes
if(loadline(file, &tmp[0]) != 0)
return 2;
@@ -478,29 +598,31 @@ int Microtonal::loadscl(const char *filename)
sscanf(&tmp[0], "%d", &nnotes);
if(nnotes > MAX_OCTAVE_SIZE)
return 2;

//load the tunnings
for(int nline = 0; nline < nnotes; ++nline) {
if(loadline(file, &tmp[0]) != 0)
return 2;
linetotunings(nline, &tmp[0]);
linetotunings(tmpoctave[nline], tmp);
}
fclose(file);

octavesize = nnotes;
for(int i = 0; i < octavesize; ++i) {
octave[i].tuning = tmpoctave[i].tuning;
octave[i].type = tmpoctave[i].type;
octave[i].x1 = tmpoctave[i].x1;
octave[i].x2 = tmpoctave[i].x2;
scl.octavesize = nnotes;
for(int i = 0; i < scl.octavesize; ++i) {
scl.octave[i].tuning = tmpoctave[i].tuning;
scl.octave[i].type = tmpoctave[i].type;
scl.octave[i].x1 = tmpoctave[i].x1;
scl.octave[i].x2 = tmpoctave[i].x2;
}

return 0;
}


/*
* Loads the mapping from a kbm file
*/
int Microtonal::loadkbm(const char *filename)
int Microtonal::loadkbm(KbmInfo &kbm, const char *filename)
{
FILE *file = fopen(filename, "r");
int x;
@@ -511,32 +633,32 @@ int Microtonal::loadkbm(const char *filename)
//loads the mapsize
if(loadline(file, tmp) != 0 || sscanf(tmp, "%d", &x) == 0)
return 2;
Pmapsize = limit(x, 0, 127);
kbm.Pmapsize = limit(x, 0, 127);

//loads first MIDI note to retune
if(loadline(file, tmp) != 0 || sscanf(tmp, "%d", &x) == 0)
return 2;
Pfirstkey = limit(x, 0, 127);
kbm.Pfirstkey = limit(x, 0, 127);

//loads last MIDI note to retune
if(loadline(file, tmp) != 0 || sscanf(tmp, "%d", &x) == 0)
return 2;
Plastkey = limit(x, 0, 127);
kbm.Plastkey = limit(x, 0, 127);

//loads last the middle note where scale fro scale degree=0
if(loadline(file, tmp) != 0 || sscanf(tmp, "%d", &x) == 0)
return 2;
Pmiddlenote = limit(x, 0, 127);
kbm.Pmiddlenote = limit(x, 0, 127);

//loads the reference note
if(loadline(file, tmp) != 0 || sscanf(tmp, "%d", &x) == 0)
return 2;
PAnote = limit(x,0,127);
kbm.PAnote = limit(x,0,127);

//loads the reference freq.
if(loadline(file, tmp) != 0 || sscanf(tmp, "%f", &tmpPAfreq) == 0)
return 2;
PAfreq = tmpPAfreq;
kbm.PAfreq = tmpPAfreq;

//the scale degree(which is the octave) is not loaded,
//it is obtained by the tunnings with getoctavesize() method
@@ -544,20 +666,20 @@ int Microtonal::loadkbm(const char *filename)
return 2;

//load the mappings
if(Pmapsize != 0) {
for(int nline = 0; nline < Pmapsize; ++nline) {
if(kbm.Pmapsize != 0) {
for(int nline = 0; nline < kbm.Pmapsize; ++nline) {
if(loadline(file, tmp) != 0)
return 2;
if(sscanf(tmp, "%d", &x) == 0)
x = -1;
Pmapping[nline] = x;
kbm.Pmapping[nline] = x;
}
Pmappingenabled = 1;
kbm.Pmappingenabled = 1;
}
else {
Pmappingenabled = 0;
Pmapping[0] = 0;
Pmapsize = 1;
kbm.Pmappingenabled = 0;
kbm.Pmapping[0] = 0;
kbm.Pmapsize = 1;
}
fclose(file);



+ 41
- 14
source/native-plugins/zynaddsubfx/Misc/Microtonal.h View File

@@ -24,12 +24,43 @@
#define MICROTONAL_H

#include <cstdio>
#include <stdint.h>
#include "../globals.h"

#define MAX_OCTAVE_SIZE 128
#define MICROTONAL_MAX_NAME_LEN 120
class XMLwrapper;

struct KbmInfo
{
uint8_t Pmapsize;
uint8_t Pfirstkey;
uint8_t Plastkey;
uint8_t Pmiddlenote;
uint8_t PAnote;
float PAfreq;
uint8_t Pmappingenabled;
short int Pmapping[128];
};

struct OctaveTuning {
unsigned char type; //1 for cents or 2 for division

// the real tuning (eg. +1.05946f for one halftone)
// or 2.0f for one octave
float tuning;

//the real tunning is x1/x2
unsigned int x1, x2;
};

struct SclInfo
{
char Pname[MICROTONAL_MAX_NAME_LEN];
char Pcomment[MICROTONAL_MAX_NAME_LEN];
unsigned char octavesize;
OctaveTuning octave[MAX_OCTAVE_SIZE];
};

/**Tuning settings and microtonal capabilities*/
class Microtonal
@@ -88,9 +119,9 @@ class Microtonal
/**Convert tunning to string*/
void tuningtoline(int n, char *line, int maxn);
/**load the tunnings from a .scl file*/
int loadscl(const char *filename);
static int loadscl(SclInfo &scl, const char *filename);
/**load the mapping from .kbm file*/
int loadkbm(const char *filename);
static int loadkbm(KbmInfo &kbm, const char *filename);
/**Load text into the internal tunings
*
*\todo better description*/
@@ -114,23 +145,19 @@ class Microtonal
bool operator==(const Microtonal &micro) const;
bool operator!=(const Microtonal &micro) const;

void clone(Microtonal &m);

static const rtosc::Ports ports;

//only paste handler should access there (quasi-private)
unsigned char octavesize;
OctaveTuning octave[MAX_OCTAVE_SIZE];
private:
int linetotunings(unsigned int nline, const char *line);
//loads a line from the text file, while ignoring the lines beggining with "!"
int loadline(FILE *file, char *line);
static int loadline(FILE *file, char *line);
//Grab a 0..127 integer from the provided descriptor
unsigned char octavesize;
struct {
unsigned char type; //1 for cents or 2 for division

// the real tuning (eg. +1.05946f for one halftone)
// or 2.0f for one octave
float tuning;

//the real tunning is x1/x2
unsigned int x1, x2;
} octave[MAX_OCTAVE_SIZE], tmpoctave[MAX_OCTAVE_SIZE];
static int linetotunings(struct OctaveTuning &tune, const char *line);

const int& gzip_compression;
};


+ 75
- 0
source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp View File

@@ -157,6 +157,12 @@ void deallocate(const char *str, void *v)
delete (Master*)v;
else if(!strcmp(str, "fft_t"))
delete[] (fft_t*)v;
else if(!strcmp(str, "KbmInfo"))
delete (KbmInfo*)v;
else if(!strcmp(str, "SclInfo"))
delete (SclInfo*)v;
else if(!strcmp(str, "Microtonal"))
delete (Microtonal*)v;
else
fprintf(stderr, "Unknown type '%s', leaking pointer %p!!\n", str, v);
}
@@ -556,6 +562,48 @@ public:
parent->transmitMsg("/load-master", "b", sizeof(Master*), &m);
}

void loadXsz(const char *filename, rtosc::RtData &d)
{
Microtonal *micro = new Microtonal(master->gzip_compression);
int err = micro->loadXML(filename);
if(err) {
d.reply("/alert", "s", "Error: Could not load the xsz file.");
delete micro;
} else
d.chain("/microtonal/paste", "b", sizeof(void*), &micro);
}

void saveXsz(const char *filename, rtosc::RtData &d)
{
int err = 0;
doReadOnlyOp([this,filename,&err](){
err = master->microtonal.saveXML(filename);});
if(err)
d.reply("/alert", "s", "Error: Could not save the xsz file.");
}

void loadScl(const char *filename, rtosc::RtData &d)
{
SclInfo *scl = new SclInfo;
int err=Microtonal::loadscl(*scl, filename);
if(err) {
d.reply("/alert", "s", "Error: Could not load the scl file.");
delete scl;
} else
d.chain("/microtonal/paste_scl", "b", sizeof(void*), &scl);
}

void loadKbm(const char *filename, rtosc::RtData &d)
{
KbmInfo *kbm = new KbmInfo;
int err=Microtonal::loadkbm(*kbm, filename);
if(err) {
d.reply("/alert", "s", "Error: Could not load the kbm file.");
delete kbm;
} else
d.chain("/microtonal/paste_kbm", "b", sizeof(void*), &kbm);
}

void updateResources(Master *m)
{
obj_store.clear();
@@ -861,6 +909,12 @@ rtosc::Ports bankPorts = {
rBegin;
impl.setLsb(rtosc_argument(msg, 0).i);
rEnd},
{"newbank:s", 0, 0,
rBegin;
int err = impl.newbank(rtosc_argument(msg, 0).s);
if(err)
d.reply("/alert", "s", "Error: Could not make a new bank (directory)..");
rEnd},
};

/******************************************************************************
@@ -959,6 +1013,27 @@ static rtosc::Ports middwareSnoopPorts = {
xml.loadXMLfile(file);
loadMidiLearn(xml, impl.midi_mapper);
rEnd},
//scale file stuff
{"load_xsz:s", 0, 0,
rBegin;
const char *file = rtosc_argument(msg, 0).s;
impl.loadXsz(file, d);
rEnd},
{"save_xsz:s", 0, 0,
rBegin;
const char *file = rtosc_argument(msg, 0).s;
impl.saveXsz(file, d);
rEnd},
{"load_scl:s", 0, 0,
rBegin;
const char *file = rtosc_argument(msg, 0).s;
impl.loadScl(file, d);
rEnd},
{"load_kbm:s", 0, 0,
rBegin;
const char *file = rtosc_argument(msg, 0).s;
impl.loadKbm(file, d);
rEnd},
{"save_xmz:s", 0, 0,
rBegin;
const char *file = rtosc_argument(msg, 0).s;


+ 1
- 4
source/native-plugins/zynaddsubfx/Misc/Part.cpp View File

@@ -312,7 +312,7 @@ void Part::defaultsinstrument()
Pdrummode = 0;

for(int n = 0; n < NUM_KIT_ITEMS; ++n) {
//kit[n].Penabled = false;
kit[n].Penabled = false;
kit[n].Pmuted = false;
kit[n].Pminkey = 0;
kit[n].Pmaxkey = 127;
@@ -847,9 +847,6 @@ void Part::setkititemstatus(unsigned kititem, bool Penabled_)
delete kkit.adpars;
delete kkit.subpars;
delete kkit.padpars;
kkit.adpars = nullptr;
kkit.subpars = nullptr;
kkit.padpars = nullptr;
kkit.Pname[0] = '\0';

notePool.killAllNotes();


+ 1
- 1
source/native-plugins/zynaddsubfx/Misc/XMLwrapper.cpp View File

@@ -98,7 +98,7 @@ XMLwrapper::XMLwrapper()
{
version.Major = 2;
version.Minor = 5;
version.Revision = 2;
version.Revision = 3;

minimal = true;



+ 11
- 11
source/native-plugins/zynaddsubfx/Params/FilterParams.cpp View File

@@ -237,21 +237,21 @@ void FilterParams::getfromFilterParams(FilterParams *pars)
/*
* Parameter control
*/
float FilterParams::getfreq()
float FilterParams::getfreq() const
{
return (Pfreq / 64.0f - 1.0f) * 5.0f;
}

float FilterParams::getq()
float FilterParams::getq() const
{
return expf(powf((float) Pq / 127.0f, 2) * logf(1000.0f)) - 0.9f;
}
float FilterParams::getfreqtracking(float notefreq)
float FilterParams::getfreqtracking(float notefreq) const
{
return logf(notefreq / 440.0f) * (Pfreqtrack - 64.0f) / (64.0f * LOG_2);
}

float FilterParams::getgain()
float FilterParams::getgain() const
{
return (Pgain / 64.0f - 1.0f) * 30.0f; //-30..30dB
}
@@ -259,7 +259,7 @@ float FilterParams::getgain()
/*
* Get the center frequency of the formant's graph
*/
float FilterParams::getcenterfreq()
float FilterParams::getcenterfreq() const
{
return 10000.0f * powf(10, -(1.0f - Pcenterfreq / 127.0f) * 2.0f);
}
@@ -267,7 +267,7 @@ float FilterParams::getcenterfreq()
/*
* Get the number of octave that the formant functions applies to
*/
float FilterParams::getoctavesfreq()
float FilterParams::getoctavesfreq() const
{
return 0.25f + 10.0f * Poctavesfreq / 127.0f;
}
@@ -275,7 +275,7 @@ float FilterParams::getoctavesfreq()
/*
* Get the frequency from x, where x is [0..1]
*/
float FilterParams::getfreqx(float x)
float FilterParams::getfreqx(float x) const
{
if(x > 1.0f)
x = 1.0f;
@@ -286,7 +286,7 @@ float FilterParams::getfreqx(float x)
/*
* Get the x coordinate from frequency (used by the UI)
*/
float FilterParams::getfreqpos(float freq)
float FilterParams::getfreqpos(float freq) const
{
return (logf(freq) - logf(getfreqx(0.0f))) / logf(2.0f) / getoctavesfreq();
}
@@ -294,19 +294,19 @@ float FilterParams::getfreqpos(float freq)
/*
* Transforms a parameter to the real value
*/
float FilterParams::getformantfreq(unsigned char freq)
float FilterParams::getformantfreq(unsigned char freq) const
{
float result = getfreqx(freq / 127.0f);
return result;
}

float FilterParams::getformantamp(unsigned char amp)
float FilterParams::getformantamp(unsigned char amp) const
{
float result = powf(0.1f, (1.0f - amp / 127.0f) * 4.0f);
return result;
}

float FilterParams::getformantq(unsigned char q)
float FilterParams::getformantq(unsigned char q) const
{
//temp
float result = powf(25.0f, (q - 32.0f) / 64.0f);


+ 11
- 11
source/native-plugins/zynaddsubfx/Params/FilterParams.h View File

@@ -48,10 +48,10 @@ class FilterParams:public PresetsArray

void getfromFilterParams(FilterParams *pars);

float getfreq();
float getq();
float getfreqtracking(float notefreq);
float getgain();
float getfreq() const ;
float getq() const ;
float getfreqtracking(float notefreq) const ;
float getgain() const ;

unsigned char Pcategory; //Filter category (Analog/Formant/StVar)
unsigned char Ptype; // Filter type (for analog lpf,hpf,bpf..)
@@ -80,14 +80,14 @@ class FilterParams:public PresetsArray
unsigned char nvowel; //the vowel from the position
} Psequence[FF_MAX_SEQUENCE];

float getcenterfreq();
float getoctavesfreq();
float getfreqpos(float freq);
float getfreqx(float x);
float getcenterfreq() const ;
float getoctavesfreq() const ;
float getfreqpos(float freq) const ;
float getfreqx(float x) const ;

float getformantfreq(unsigned char freq);
float getformantamp(unsigned char amp);
float getformantq(unsigned char q);
float getformantfreq(unsigned char freq) const ;
float getformantamp(unsigned char amp) const ;
float getformantq(unsigned char q) const ;

void defaults(int n);



+ 68
- 102
source/native-plugins/zynaddsubfx/Synth/ADnote.cpp View File

@@ -29,9 +29,8 @@
#include "../globals.h"
#include "../Misc/Util.h"
#include "../Misc/Allocator.h"
#include "../DSP/Filter.h"
#include "../Params/ADnoteParameters.h"
#include "../Params/FilterParams.h"
#include "ModFilter.h"
#include "OscilGen.h"
#include "ADnote.h"

@@ -63,13 +62,6 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars)
NoteGlobalPar.Panning = pars.GlobalPar.PPanning / 128.0f;


NoteGlobalPar.FilterCenterPitch = pars.GlobalPar.GlobalFilter->getfreq() //center freq
+ pars.GlobalPar.PFilterVelocityScale
/ 127.0f * 6.0f //velocity sensing
* (VelF(velocity,
pars.GlobalPar.
PFilterVelocityScaleFunction) - 1);

NoteGlobalPar.Fadein_adjustment =
pars.GlobalPar.Fadein_adjustment / (float)FADEIN_ADJUSTMENT_SCALE;
NoteGlobalPar.Fadein_adjustment *= NoteGlobalPar.Fadein_adjustment;
@@ -373,17 +365,10 @@ ADnote::ADnote(ADnoteParameters *pars_, SynthParams &spars)
NoteVoicePar[nvoice].AmpLfo = NULL;
NoteVoicePar[nvoice].AmpEnvelope = NULL;

NoteVoicePar[nvoice].VoiceFilterL = NULL;
NoteVoicePar[nvoice].VoiceFilterR = NULL;
NoteVoicePar[nvoice].Filter = NULL;
NoteVoicePar[nvoice].FilterEnvelope = NULL;
NoteVoicePar[nvoice].FilterLfo = NULL;

NoteVoicePar[nvoice].FilterCenterPitch =
pars.VoicePar[nvoice].VoiceFilter->getfreq()
+ pars.VoicePar[nvoice].PFilterVelocityScale
/ 127.0f * 6.0f //velocity sensing
* (VelF(velocity,
pars.VoicePar[nvoice].PFilterVelocityScaleFunction) - 1);
NoteVoicePar[nvoice].filterbypass =
pars.VoicePar[nvoice].Pfilterbypass;

@@ -514,13 +499,9 @@ void ADnote::legatonote(LegatoParams lpars)
else
NoteGlobalPar.Panning = pars.GlobalPar.PPanning / 128.0f;

//center freq
NoteGlobalPar.FilterCenterPitch = pars.GlobalPar.GlobalFilter->getfreq()
+ pars.GlobalPar.PFilterVelocityScale
/ 127.0f * 6.0f //velocity sensing
* (VelF(velocity,
pars.GlobalPar.
PFilterVelocityScaleFunction) - 1);
NoteGlobalPar.Filter->updateSense(velocity,
pars.GlobalPar.PFilterVelocityScale,
pars.GlobalPar.PFilterVelocityScaleFunction);


for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
@@ -580,13 +561,12 @@ void ADnote::legatonote(LegatoParams lpars)
+ i] =
NoteVoicePar[nvoice].OscilSmp[i];


NoteVoicePar[nvoice].FilterCenterPitch =
pars.VoicePar[nvoice].VoiceFilter->getfreq()
+ pars.VoicePar[nvoice].PFilterVelocityScale
/ 127.0f * 6.0f //velocity sensing
* (VelF(velocity,
pars.VoicePar[nvoice].PFilterVelocityScaleFunction) - 1);
auto &voiceFilter = NoteVoicePar[nvoice].Filter;
if(voiceFilter) {
const auto &vce = pars.VoicePar[nvoice];
voiceFilter->updateSense(velocity, vce.PFilterVelocityScale,
vce.PFilterVelocityScaleFunction);
}

NoteVoicePar[nvoice].filterbypass =
pars.VoicePar[nvoice].Pfilterbypass;
@@ -653,9 +633,12 @@ void ADnote::legatonote(LegatoParams lpars)
* NoteGlobalPar.AmpEnvelope->envout_dB()
* NoteGlobalPar.AmpLfo->amplfoout();

NoteGlobalPar.FilterQ = pars.GlobalPar.GlobalFilter->getq();
NoteGlobalPar.FilterFreqTracking =
pars.GlobalPar.GlobalFilter->getfreqtracking(basefreq);
{
auto *filter = NoteGlobalPar.Filter;
filter->updateSense(velocity, pars.GlobalPar.PFilterVelocityScale,
pars.GlobalPar.PFilterVelocityScaleFunction);
filter->updateNoteFreq(basefreq);
}

// Forbids the Modulation Voice to be greater or equal than voice
for(int i = 0; i < NUM_VOICES; ++i)
@@ -693,10 +676,12 @@ void ADnote::legatonote(LegatoParams lpars)
if(pars.VoicePar[nvoice].PAmpLfoEnabled && NoteVoicePar[nvoice].AmpLfo)
newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout();



NoteVoicePar[nvoice].FilterFreqTracking =
pars.VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq);
auto *voiceFilter = NoteVoicePar[nvoice].Filter;
if(voiceFilter) {
voiceFilter->updateSense(velocity, pars.VoicePar[nvoice].PFilterVelocityScale,
pars.VoicePar[nvoice].PFilterVelocityScaleFunction);
voiceFilter->updateNoteFreq(basefreq);
}

/* Voice Modulation Parameters Init */
if((NoteVoicePar[nvoice].FMEnabled != NONE)
@@ -857,21 +842,24 @@ void ADnote::initparameters()
vce.FreqLfo = memory.alloc<LFO>(*param.FreqLfo, basefreq, time);

/* Voice Filter Parameters Init */
if(param.PFilterEnabled != 0) {
vce.VoiceFilterL = Filter::generate(memory, param.VoiceFilter,
synth.samplerate, synth.buffersize);
vce.VoiceFilterR = Filter::generate(memory, param.VoiceFilter,
synth.samplerate, synth.buffersize);
}
if(param.PFilterEnabled) {
vce.Filter = memory.alloc<ModFilter>(*param.VoiceFilter, synth, time, memory, stereo,
basefreq);
vce.Filter->updateSense(velocity, param.PFilterVelocityScale,
param.PFilterVelocityScaleFunction);

if(param.PFilterEnvelopeEnabled)
vce.FilterEnvelope = memory.alloc<Envelope>(*param.FilterEnvelope, basefreq, synth.dt());

if(param.PFilterLfoEnabled)
vce.FilterLfo = memory.alloc<LFO>(*param.FilterLfo, basefreq, time);
if(param.PFilterEnvelopeEnabled) {
vce.FilterEnvelope =
memory.alloc<Envelope>(*param.FilterEnvelope, basefreq, synth.dt());
vce.Filter->addMod(*vce.FilterEnvelope);
}

vce.FilterFreqTracking =
param.VoiceFilter->getfreqtracking(basefreq);
if(param.PFilterLfoEnabled) {
vce.FilterLfo = memory.alloc<LFO>(*param.FilterLfo, basefreq, time);
vce.Filter->addMod(*vce.FilterLfo);
}
}

/* Voice Modulation Parameters Init */
if((vce.FMEnabled != NONE) && (vce.FMVoice < 0)) {
@@ -1050,8 +1038,8 @@ float ADnote::getFMvoicebasefreq(int nvoice) const
void ADnote::computecurrentparameters()
{
int nvoice;
float voicefreq, voicepitch, filterpitch, filterfreq, FMfreq,
FMrelativepitch, globalpitch, globalfilterpitch;
float voicefreq, voicepitch, FMfreq,
FMrelativepitch, globalpitch;
globalpitch = 0.01f * (NoteGlobalPar.FreqEnvelope->envout()
+ NoteGlobalPar.FreqLfo->lfoout()
* ctl.modwheel.relmod);
@@ -1060,19 +1048,9 @@ void ADnote::computecurrentparameters()
* NoteGlobalPar.AmpEnvelope->envout_dB()
* NoteGlobalPar.AmpLfo->amplfoout();

globalfilterpitch = NoteGlobalPar.FilterEnvelope->envout()
+ NoteGlobalPar.FilterLfo->lfoout()
+ NoteGlobalPar.FilterCenterPitch;

float tmpfilterfreq = globalfilterpitch + ctl.filtercutoff.relfreq
+ NoteGlobalPar.FilterFreqTracking;

tmpfilterfreq = Filter::getrealfreq(tmpfilterfreq);
NoteGlobalPar.Filter->update(ctl.filtercutoff.relfreq,
ctl.filterq.relq);

float globalfilterq = NoteGlobalPar.FilterQ * ctl.filterq.relq;
NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq, globalfilterq);
if(stereo != 0)
NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq, globalfilterq);

//compute the portamento, if it is used by this note
float portamentofreqrap = 1.0f;
@@ -1107,21 +1085,10 @@ void ADnote::computecurrentparameters()
/****************/
/* Voice Filter */
/****************/
if(NoteVoicePar[nvoice].VoiceFilterL) {
filterpitch = NoteVoicePar[nvoice].FilterCenterPitch;

if(NoteVoicePar[nvoice].FilterEnvelope)
filterpitch += NoteVoicePar[nvoice].FilterEnvelope->envout();

if(NoteVoicePar[nvoice].FilterLfo)
filterpitch += NoteVoicePar[nvoice].FilterLfo->lfoout();

filterfreq = filterpitch + NoteVoicePar[nvoice].FilterFreqTracking;
filterfreq = Filter::getrealfreq(filterfreq);

NoteVoicePar[nvoice].VoiceFilterL->setfreq(filterfreq);
if(stereo && NoteVoicePar[nvoice].VoiceFilterR)
NoteVoicePar[nvoice].VoiceFilterR->setfreq(filterfreq);
auto *voiceFilter = NoteVoicePar[nvoice].Filter;
if(voiceFilter) {
voiceFilter->update(ctl.filtercutoff.relfreq,
ctl.filterq.relq);
}

if(NoteVoicePar[nvoice].noisetype == 0) { //compute only if the voice isn't noise
@@ -1702,12 +1669,13 @@ int ADnote::noteout(float *outl, float *outr)
firsttick[nvoice] = 0;
}


// Filter
if(NoteVoicePar[nvoice].VoiceFilterL)
NoteVoicePar[nvoice].VoiceFilterL->filterout(&tmpwavel[0]);
if(stereo && NoteVoicePar[nvoice].VoiceFilterR)
NoteVoicePar[nvoice].VoiceFilterR->filterout(&tmpwaver[0]);
if(NoteVoicePar[nvoice].Filter) {
if(stereo)
NoteVoicePar[nvoice].Filter->filter(tmpwavel, tmpwaver);
else
NoteVoicePar[nvoice].Filter->filter(tmpwavel, 0);
}

//check if the amplitude envelope is finished, if yes, the voice will be fadeout
if(NoteVoicePar[nvoice].AmpEnvelope)
@@ -1767,14 +1735,13 @@ int ADnote::noteout(float *outl, float *outr)


//Processing Global parameters
NoteGlobalPar.GlobalFilterL->filterout(&outl[0]);

if(stereo == 0) { //set the right channel=left channel
if(stereo) {
NoteGlobalPar.Filter->filter(outl, outr);
} else { //set the right channel=left channel
NoteGlobalPar.Filter->filter(outl, 0);
memcpy(outr, outl, synth.bufferbytes);
memcpy(bypassr, bypassl, synth.bufferbytes);
}
else
NoteGlobalPar.GlobalFilterR->filterout(&outr[0]);

for(int i = 0; i < synth.buffersize; ++i) {
outl[i] += bypassl[i];
@@ -1881,8 +1848,7 @@ void ADnote::Voice::kill(Allocator &memory, const SYNTH_T &synth)
memory.dealloc(FreqLfo);
memory.dealloc(AmpEnvelope);
memory.dealloc(AmpLfo);
memory.dealloc(VoiceFilterL);
memory.dealloc(VoiceFilterR);
memory.dealloc(Filter);
memory.dealloc(FilterEnvelope);
memory.dealloc(FilterLfo);
memory.dealloc(FMFreqEnvelope);
@@ -1905,8 +1871,7 @@ void ADnote::Global::kill(Allocator &memory)
memory.dealloc(FreqLfo);
memory.dealloc(AmpEnvelope);
memory.dealloc(AmpLfo);
memory.dealloc(GlobalFilterL);
memory.dealloc(GlobalFilterR);
memory.dealloc(Filter);
memory.dealloc(FilterEnvelope);
memory.dealloc(FilterLfo);
}
@@ -1927,16 +1892,17 @@ void ADnote::Global::initparameters(const ADnoteGlobalParam &param,
Volume = 4.0f * powf(0.1f, 3.0f * (1.0f - param.PVolume / 96.0f)) //-60 dB .. 0 dB
* VelF(velocity, param.PAmpVelocityScaleFunction); //sensing

GlobalFilterL = Filter::generate(memory, param.GlobalFilter,
synth.samplerate, synth.buffersize);
if(stereo)
GlobalFilterR = Filter::generate(memory, param.GlobalFilter,
synth.samplerate, synth.buffersize);
else
GlobalFilterR = NULL;
Filter = memory.alloc<ModFilter>(*param.GlobalFilter, synth, time, memory,
stereo, basefreq);

FilterEnvelope = memory.alloc<Envelope>(*param.FilterEnvelope, basefreq, synth.dt());
FilterLfo = memory.alloc<LFO>(*param.FilterLfo, basefreq, time);
FilterQ = param.GlobalFilter->getq();
FilterFreqTracking = param.GlobalFilter->getfreqtracking(basefreq);

Filter->addMod(*FilterEnvelope);
Filter->addMod(*FilterLfo);
{
Filter->updateSense(velocity, param.PFilterVelocityScale,
param.PFilterVelocityScaleFunction);
}
}

+ 6
- 18
source/native-plugins/zynaddsubfx/Synth/ADnote.h View File

@@ -154,15 +154,9 @@ class ADnote:public SynthNote
/******************************************
* FILTER GLOBAL PARAMETERS *
******************************************/
class Filter * GlobalFilterL, *GlobalFilterR;

float FilterCenterPitch; //octaves
float FilterQ;
float FilterFreqTracking;

Envelope *FilterEnvelope;

LFO *FilterLfo;
ModFilter *Filter;
Envelope *FilterEnvelope;
LFO *FilterLfo;
} NoteGlobalPar;


@@ -226,15 +220,9 @@ class ADnote:public SynthNote
/*************************
* FILTER PARAMETERS *
*************************/

class Filter * VoiceFilterL;
class Filter * VoiceFilterR;

float FilterCenterPitch; /* Filter center Pitch*/
float FilterFreqTracking;

Envelope *FilterEnvelope;
LFO *FilterLfo;
ModFilter *Filter;
Envelope *FilterEnvelope;
LFO *FilterLfo;


/****************************


+ 149
- 0
source/native-plugins/zynaddsubfx/Synth/ModFilter.cpp View File

@@ -0,0 +1,149 @@
#include "ModFilter.h"
#include "Envelope.h"
#include "LFO.h"
#include "../Misc/Util.h"
#include "../Misc/Allocator.h"
#include "../Params/FilterParams.h"
#include "../DSP/Filter.h"
#include "../DSP/SVFilter.h"
#include "../DSP/AnalogFilter.h"
#include "../DSP/FormantFilter.h"
#include <cassert>

ModFilter::ModFilter(const FilterParams &pars_,
const SYNTH_T &synth_,
const AbsTime &time_,
Allocator &alloc_,
bool stereo,
float notefreq)
:pars(pars_), synth(synth_), time(time_), alloc(alloc_),
baseQ(pars.getq()), baseFreq(pars.getfreq()),
noteFreq(notefreq),
left(nullptr),
right(nullptr),
env(nullptr),
lfo(nullptr)
{
tracking = pars.getfreqtracking(notefreq);
baseQ = pars.getq();
baseFreq = pars.getfreq();

left = Filter::generate(alloc, &pars,
synth.samplerate, synth.buffersize);

if(stereo)
right = Filter::generate(alloc, &pars,
synth.samplerate, synth.buffersize);
}

ModFilter::~ModFilter(void)
{
alloc.dealloc(left);
alloc.dealloc(right);
}
void ModFilter::addMod(LFO &lfo_)
{
lfo = &lfo_;
}

void ModFilter::addMod(Envelope &env_)
{
env = &env_;
}

//Recompute Filter Parameters
void ModFilter::update(float relfreq, float relq)
{
if(pars.last_update_timestamp == time.time()) {
paramUpdate(left);
if(right)
paramUpdate(right);

baseFreq = pars.getfreq();
baseQ = pars.getq();
tracking = pars.getfreqtracking(noteFreq);
}

//Controller Free Center Frequency
const float Fc = baseFreq
+ sense
+ (env ? env->envout() : 0)
+ (lfo ? lfo->lfoout() : 0);

const float Fc_mod = Fc + relfreq + tracking;

//Convert into Hz
const float Fc_Hz = Filter::getrealfreq(Fc_mod);

const float q = baseQ * relq;

left->setfreq_and_q(Fc_Hz, q);
if(right)
right->setfreq_and_q(Fc_Hz, q);
}

void ModFilter::updateNoteFreq(float noteFreq_)
{
noteFreq = noteFreq_;
tracking = pars.getfreqtracking(noteFreq);
}

void ModFilter::updateSense(float velocity, uint8_t scale,
uint8_t func)
{
const float velScale = scale / 127.0f;
sense = velScale * 6.0f * (VelF(velocity, func) - 1);
}
void ModFilter::filter(float *l, float *r)
{
if(left && l)
left->filterout(l);
if(right && r)
right->filterout(r);
}

static int current_category(Filter *f)
{
if(dynamic_cast<AnalogFilter*>(f))
return 0;
else if(dynamic_cast<FormantFilter*>(f))
return 1;
else if(dynamic_cast<SVFilter*>(f))
return 2;

assert(false);
}

void ModFilter::paramUpdate(Filter *&f)
{
//Common parameters
baseQ = pars.getq();
baseFreq = pars.getfreq();
if(current_category(f) != pars.Pcategory) {
alloc.dealloc(f);
f = Filter::generate(alloc, &pars,
synth.samplerate, synth.buffersize);
return;
}

if(auto *sv = dynamic_cast<SVFilter*>(f))
svParamUpdate(*sv);
else if(auto *an = dynamic_cast<AnalogFilter*>(f))
anParamUpdate(*an);
}

void ModFilter::svParamUpdate(SVFilter &sv)
{
sv.settype(pars.Ptype);
sv.setstages(pars.Pstages);
}

void ModFilter::anParamUpdate(AnalogFilter &an)
{
an.settype(pars.Ptype);
an.setstages(pars.Pstages);
an.setgain(pars.getgain());
}

+ 55
- 0
source/native-plugins/zynaddsubfx/Synth/ModFilter.h View File

@@ -0,0 +1,55 @@
#pragma once
#include "../globals.h"
#include "../Misc/Time.h"

//Modulated instance of one of the filters in src/DSP/
//Supports stereo modes
class ModFilter
{
public:
ModFilter(const FilterParams &pars,
const SYNTH_T &synth,
const AbsTime &time,
Allocator &alloc,
bool stereo,
float notefreq_);
~ModFilter(void);

void addMod(LFO &lfo);
void addMod(Envelope &env);

//normal per tick update
void update(float relfreq, float relq);

//updates typically seen in note-init
void updateNoteFreq(float noteFreq_);
void updateSense(float velocity,
uint8_t scale, uint8_t func);

//filter stereo/mono signal(s) in-place
void filter(float *l, float *r);
private:
void paramUpdate(Filter *&f);
void svParamUpdate(SVFilter &sv);
void anParamUpdate(AnalogFilter &an);

const FilterParams &pars; //Parameters to Pull Updates From
const SYNTH_T &synth; //Synthesizer Buffer Parameters
const AbsTime &time; //Time for RT Updates
Allocator &alloc; //RT Memory Pool



float baseQ; //filter sharpness
float baseFreq; //base filter frequency
float noteFreq; //frequency note was initialized to
float tracking; //shift due to note frequency
float sense; //shift due to note velocity


Filter *left; //left channel filter
Filter *right;//right channel filter
Envelope *env; //center freq envelope
LFO *lfo; //center freq lfo
};

+ 28
- 35
source/native-plugins/zynaddsubfx/Synth/PADnote.cpp View File

@@ -18,11 +18,12 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <cassert>
#include <cmath>
#include "PADnote.h"
#include "ModFilter.h"
#include "../Misc/Config.h"
#include "../Misc/Allocator.h"
#include "../DSP/Filter.h"
#include "../Params/PADnoteParameters.h"
#include "../Params/Controller.h"
#include "../Params/FilterParams.h"
@@ -32,6 +33,10 @@ PADnote::PADnote(const PADnoteParameters *parameters,
SynthParams pars, const int& interpolation)
:SynthNote(pars), pars(*parameters), interpolation(interpolation)
{
NoteGlobalPar.GlobalFilter = nullptr;
NoteGlobalPar.FilterEnvelope = nullptr;
NoteGlobalPar.FilterLfo = nullptr;

firsttime = true;
setup(pars.frequency, pars.velocity, pars.portamento, pars.note);
}
@@ -112,13 +117,6 @@ void PADnote::setup(float freq,
else
NoteGlobalPar.Panning = pars.PPanning / 128.0f;

NoteGlobalPar.FilterCenterPitch = pars.GlobalFilter->getfreq() //center freq
+ pars.PFilterVelocityScale / 127.0f
* 6.0f //velocity sensing
* (VelF(velocity,
pars.
PFilterVelocityScaleFunction) - 1);

if(!legato) {
NoteGlobalPar.Fadein_adjustment =
pars.Fadein_adjustment / (float)FADEIN_ADJUSTMENT_SCALE;
@@ -157,17 +155,25 @@ void PADnote::setup(float freq,
* NoteGlobalPar.AmpLfo->amplfoout();

if(!legato) {
NoteGlobalPar.GlobalFilterL = Filter::generate(memory, pars.GlobalFilter,
synth.samplerate, synth.buffersize);
NoteGlobalPar.GlobalFilterR = Filter::generate(memory, pars.GlobalFilter,
synth.samplerate, synth.buffersize);
auto &flt = NoteGlobalPar.GlobalFilter;
auto &env = NoteGlobalPar.FilterEnvelope;
auto &lfo = NoteGlobalPar.FilterLfo;
assert(flt == nullptr);
flt = memory.alloc<ModFilter>(*pars.GlobalFilter, synth, time, memory, true, basefreq);

//setup mod
env = memory.alloc<Envelope>(*pars.FilterEnvelope, basefreq, synth.dt());
lfo = memory.alloc<LFO>(*pars.FilterLfo, basefreq, time);
flt->addMod(*env);
flt->addMod(*lfo);
}

NoteGlobalPar.FilterEnvelope = memory.alloc<Envelope>(*pars.FilterEnvelope, basefreq, synth.dt());
NoteGlobalPar.FilterLfo = memory.alloc<LFO>(*pars.FilterLfo, basefreq, time);
{
auto &flt = *NoteGlobalPar.GlobalFilter;
flt.updateSense(velocity, pars.PFilterVelocityScale,
pars.PFilterVelocityScaleFunction);
flt.updateNoteFreq(basefreq);
}
NoteGlobalPar.FilterQ = pars.GlobalFilter->getq();
NoteGlobalPar.FilterFreqTracking = pars.GlobalFilter->getfreqtracking(
basefreq);

if(!pars.sample[nsample].smp) {
finished_ = true;
@@ -198,8 +204,7 @@ PADnote::~PADnote()
memory.dealloc(NoteGlobalPar.FreqLfo);
memory.dealloc(NoteGlobalPar.AmpEnvelope);
memory.dealloc(NoteGlobalPar.AmpLfo);
memory.dealloc(NoteGlobalPar.GlobalFilterL);
memory.dealloc(NoteGlobalPar.GlobalFilterR);
memory.dealloc(NoteGlobalPar.GlobalFilter);
memory.dealloc(NoteGlobalPar.FilterEnvelope);
memory.dealloc(NoteGlobalPar.FilterLfo);
}
@@ -230,8 +235,7 @@ inline void PADnote::fadein(float *smps)

void PADnote::computecurrentparameters()
{
float globalpitch, globalfilterpitch;
globalpitch = 0.01f * (NoteGlobalPar.FreqEnvelope->envout()
const float globalpitch = 0.01f * (NoteGlobalPar.FreqEnvelope->envout()
+ NoteGlobalPar.FreqLfo->lfoout()
* ctl.modwheel.relmod + NoteGlobalPar.Detune);
globaloldamplitude = globalnewamplitude;
@@ -239,18 +243,8 @@ void PADnote::computecurrentparameters()
* NoteGlobalPar.AmpEnvelope->envout_dB()
* NoteGlobalPar.AmpLfo->amplfoout();

globalfilterpitch = NoteGlobalPar.FilterEnvelope->envout()
+ NoteGlobalPar.FilterLfo->lfoout()
+ NoteGlobalPar.FilterCenterPitch;

float tmpfilterfreq = globalfilterpitch + ctl.filtercutoff.relfreq
+ NoteGlobalPar.FilterFreqTracking;

tmpfilterfreq = Filter::getrealfreq(tmpfilterfreq);

float globalfilterq = NoteGlobalPar.FilterQ * ctl.filterq.relq;
NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq, globalfilterq);
NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq, globalfilterq);
NoteGlobalPar.GlobalFilter->update(ctl.filtercutoff.relfreq,
ctl.filterq.relq);

//compute the portamento, if it is used by this note
float portamentofreqrap = 1.0f;
@@ -377,8 +371,7 @@ int PADnote::noteout(float *outl, float *outr)
firsttime = false;
}

NoteGlobalPar.GlobalFilterL->filterout(outl);
NoteGlobalPar.GlobalFilterR->filterout(outr);
NoteGlobalPar.GlobalFilter->filter(outl, outr);

//Apply the punch
if(NoteGlobalPar.Punch.Enabled != 0)


+ 3
- 9
source/native-plugins/zynaddsubfx/Synth/PADnote.h View File

@@ -98,15 +98,9 @@ class PADnote:public SynthNote
/******************************************
* FILTER GLOBAL PARAMETERS *
******************************************/
class Filter * GlobalFilterL, *GlobalFilterR;

float FilterCenterPitch; //octaves
float FilterQ;
float FilterFreqTracking;

Envelope *FilterEnvelope;

LFO *FilterLfo;
ModFilter *GlobalFilter;
Envelope *FilterEnvelope;
LFO *FilterLfo;
} NoteGlobalPar;




+ 41
- 59
source/native-plugins/zynaddsubfx/Synth/SUBnote.cpp View File

@@ -28,16 +28,24 @@
#include "../globals.h"
#include "SUBnote.h"
#include "Envelope.h"
#include "ModFilter.h"
#include "../Params/Controller.h"
#include "../Params/SUBnoteParameters.h"
#include "../Params/FilterParams.h"
#include "../Misc/Time.h"
#include "../Misc/Util.h"
#include "../Misc/Allocator.h"

SUBnote::SUBnote(const SUBnoteParameters *parameters, SynthParams &spars)
:SynthNote(spars), pars(*parameters)
:SynthNote(spars), pars(*parameters),
AmpEnvelope(nullptr),
FreqEnvelope(nullptr),
BandWidthEnvelope(nullptr),
GlobalFilter(nullptr),
GlobalFilterEnvelope(nullptr),
NoteEnabled(ON),
lfilter(nullptr), rfilter(nullptr)
{
NoteEnabled = ON;
setup(spars.frequency, spars.velocity, spars.portamento, spars.note);
}

@@ -56,12 +64,14 @@ void SUBnote::setup(float freq,
panning = pars.PPanning / 127.0f;
else
panning = RND;
if(!legato) {

if(!legato) { //normal note
numstages = pars.Pnumstages;
stereo = pars.Pstereo;
start = pars.Pstart;
firsttick = 1;
}

int pos[MAX_SUB_HARMONICS];

if(pars.Pfixedfreq == 0)
@@ -91,20 +101,6 @@ void SUBnote::setup(float freq,
basefreq *= powf(2.0f, detune / 1200.0f); //detune
// basefreq*=ctl.pitchwheel.relfreq;//pitch wheel

//global filter
GlobalFilterCenterPitch = pars.GlobalFilter->getfreq() //center freq
+ (pars.PGlobalFilterVelocityScale / 127.0f
* 6.0f) //velocity sensing
* (VelF(velocity,
pars.PGlobalFilterVelocityScaleFunction)
- 1);

if(!legato) {
GlobalFilterL = NULL;
GlobalFilterR = NULL;
GlobalFilterEnvelope = NULL;
}

int harmonics = 0;

//select only harmonics that desire to compute
@@ -113,7 +109,7 @@ void SUBnote::setup(float freq,
continue;
pos[harmonics++] = n;
}
if(!legato)
if(!legato) //normal note
firstnumharmonics = numharmonics = harmonics;
else {
if(harmonics > firstnumharmonics)
@@ -129,7 +125,7 @@ void SUBnote::setup(float freq,
}


if(!legato) {
if(!legato) { //normal note
lfilter = memory.valloc<bpfilter>(numstages * numharmonics);
if(stereo)
rfilter = memory.valloc<bpfilter>(numstages * numharmonics);
@@ -199,7 +195,7 @@ void SUBnote::setup(float freq,

oldpitchwheel = 0;
oldbandwidth = 64;
if(!legato) {
if(!legato) { //normal note
if(pars.Pfixedfreq == 0)
initparameters(basefreq);
else
@@ -211,13 +207,14 @@ void SUBnote::setup(float freq,
else
freq *= basefreq / 440.0f;

if(pars.PGlobalFilterEnabled) {
globalfiltercenterq = pars.GlobalFilter->getq();
GlobalFilterFreqTracking = pars.GlobalFilter->getfreqtracking(
basefreq);
}
if(GlobalFilter)
GlobalFilter->updateNoteFreq(basefreq);
}

if(GlobalFilter)
GlobalFilter->updateSense(velocity, pars.PGlobalFilterVelocityScale,
pars.PGlobalFilterVelocityScaleFunction);

oldamplitude = newamplitude;
}

@@ -260,8 +257,7 @@ void SUBnote::KillNote()
memory.dealloc(AmpEnvelope);
memory.dealloc(FreqEnvelope);
memory.dealloc(BandWidthEnvelope);
memory.dealloc(GlobalFilterL);
memory.dealloc(GlobalFilterR);
memory.dealloc(GlobalFilter);
memory.dealloc(GlobalFilterEnvelope);
NoteEnabled = OFF;
}
@@ -383,23 +379,19 @@ void SUBnote::filter(bpfilter &filter, float *smps)
void SUBnote::initparameters(float freq)
{
AmpEnvelope = memory.alloc<Envelope>(*pars.AmpEnvelope, freq, synth.dt());

if(pars.PFreqEnvelopeEnabled)
FreqEnvelope = memory.alloc<Envelope>(*pars.FreqEnvelope, freq, synth.dt());
else
FreqEnvelope = NULL;

if(pars.PBandWidthEnvelopeEnabled)
BandWidthEnvelope = memory.alloc<Envelope>(*pars.BandWidthEnvelope, freq, synth.dt());
else
BandWidthEnvelope = NULL;

if(pars.PGlobalFilterEnabled) {
globalfiltercenterq = pars.GlobalFilter->getq();
GlobalFilterL = Filter::generate(memory, pars.GlobalFilter,
synth.samplerate, synth.buffersize);
if(stereo)
GlobalFilterR = Filter::generate(memory, pars.GlobalFilter,
synth.samplerate, synth.buffersize);
GlobalFilterEnvelope = memory.alloc<Envelope>(*pars.GlobalFilterEnvelope, freq, synth.dt());
GlobalFilterFreqTracking = pars.GlobalFilter->getfreqtracking(basefreq);

GlobalFilter = memory.alloc<ModFilter>(*pars.GlobalFilter, synth, time, memory, stereo, freq);

GlobalFilter->addMod(*GlobalFilterEnvelope);
}
computecurrentparameters();
}
@@ -492,21 +484,9 @@ void SUBnote::computecurrentparameters()
newamplitude = volume * AmpEnvelope->envout_dB() * 2.0f;

//Filter
if(GlobalFilterL != NULL) {
float globalfilterpitch = GlobalFilterCenterPitch
+ GlobalFilterEnvelope->envout();
float filterfreq = globalfilterpitch + ctl.filtercutoff.relfreq
+ GlobalFilterFreqTracking;
filterfreq = Filter::getrealfreq(filterfreq);

GlobalFilterL->setfreq_and_q(filterfreq,
globalfiltercenterq * ctl.filterq.relq);
if(GlobalFilterR != NULL)
GlobalFilterR->setfreq_and_q(
filterfreq,
globalfiltercenterq
* ctl.filterq.relq);
}
if(GlobalFilter)
GlobalFilter->update(ctl.filtercutoff.relfreq,
ctl.filterq.relq);
}

/*
@@ -534,8 +514,6 @@ int SUBnote::noteout(float *outl, float *outr)
outl[i] += tmpsmp[i] * rolloff;
}

if(GlobalFilterL != NULL)
GlobalFilterL->filterout(&outl[0]);

//right channel
if(stereo) {
@@ -549,11 +527,15 @@ int SUBnote::noteout(float *outl, float *outr)
for(int i = 0; i < synth.buffersize; ++i)
outr[i] += tmpsmp[i] * rolloff;
}
if(GlobalFilterR != NULL)
GlobalFilterR->filterout(&outr[0]);
}
else
if(GlobalFilter)
GlobalFilter->filter(outl, outr);

} else {
if(GlobalFilter)
GlobalFilter->filter(outl, 0);

memcpy(outr, outl, synth.bufferbytes);
}

if(firsttick != 0) {
int n = 10;


+ 6
- 7
source/native-plugins/zynaddsubfx/Synth/SUBnote.h View File

@@ -25,7 +25,6 @@

#include "SynthNote.h"
#include "../globals.h"
#include "../DSP/Filter.h"

class SUBnote:public SynthNote
{
@@ -48,6 +47,10 @@ class SUBnote:public SynthNote
int midinote,
bool legato = false);
void computecurrentparameters();
/*
* Initialize envelopes and global filter
* calls computercurrentparameters()
*/
void initparameters(float freq);
void KillNote();

@@ -67,18 +70,14 @@ class SUBnote:public SynthNote
Envelope *FreqEnvelope;
Envelope *BandWidthEnvelope;

Filter *GlobalFilterL, *GlobalFilterR;

Envelope *GlobalFilterEnvelope;
ModFilter *GlobalFilter;
Envelope *GlobalFilterEnvelope;

//internal values
ONOFFTYPE NoteEnabled;
int firsttick, portamento;
float volume, oldamplitude, newamplitude;

float GlobalFilterCenterPitch; //octaves
float GlobalFilterFreqTracking;

struct bpfilter {
float freq, bw, amp; //filter parameters
float a1, a2, b0, b2; //filter coefs. b1=0


+ 1
- 4
source/native-plugins/zynaddsubfx/UI/BankUI.fl View File

@@ -72,10 +72,7 @@ class BankUI {open
dirname=fl_input("New empty Bank:");
if (dirname==NULL) return;


osc->write("/newbank", "s", dirname);
/*if (result!=0) fl_alert("Error: Could not make a new bank (directory)..");*/

osc->write("/bank/newbank", "s", dirname);
refreshmainwindow();}
xywh {685 5 93 25} labelfont 1 labelsize 11 align 128
}


+ 2
- 6
source/native-plugins/zynaddsubfx/UI/MasterUI.fl View File

@@ -336,9 +336,7 @@ filename=fl_file_chooser("Open:","({*.xsz})",NULL,0);
if (filename==NULL) return;

osc->write("/load_xsz", "s", filename);
/*
if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not a scale file.");
else if (result<0) fl_alert("Error: Could not load the file.");*/}
}
xywh {40 40 100 20}
}
MenuItem {} {
@@ -358,9 +356,7 @@ if (result) {
};


osc->write("/save_xsz", "s", filename);

/*if (result<0) fl_alert("Error: Could not save the file.");*/}
osc->write("/save_xsz", "s", filename); }
xywh {30 30 100 20}
}
MenuItem {} {


+ 29
- 62
source/native-plugins/zynaddsubfx/UI/MicrotonalUI.fl View File

@@ -96,7 +96,8 @@ class MicrotonalUI {} {
Fl_Input tuningsinput {
label {Tunings:}
xywh {8 144 182 264} type Multiline labelfont 1 labelsize 11 align 5 when 2
code0 {updateTuningsInput();}
code0 {o->init("tunings");}
class Fl_Osc_Input
}
Fl_Input commentinput {
label {Comment:}
@@ -113,23 +114,18 @@ class MicrotonalUI {} {
}
Fl_Button {} {
label {Import .SCL file}
callback {/*const char *filename;
callback {const char *filename;
filename=fl_file_chooser("Open:","(*.scl)",NULL,0);
if (filename==NULL) return;
int result=microtonal->loadscl(filename);
if (result==0) {
osc->write("/load_scl", "s", filename);
if (true) {
updateTuningsInput();
nameinput->cut(0,nameinput->maximum_size());
nameinput->insert((char *)microtonal->Pname);
nameinput->position(0);
commentinput->cut(0,commentinput->maximum_size());
commentinput->insert((char *)microtonal->Pname);
commentinput->position(0);
nameinput->update();
commentinput->update();
tuningsinput->position(0);
octavesizeoutput->do_callback();
} else {
fl_alert("Error: Could not load the file.");
};*/}
octavesizeoutput->update();
}
}
tooltip {Inport Scala .scl file (tunnings)} xywh {243 411 84 15} box THIN_UP_BOX labelfont 1 labelsize 10
}
Fl_Group keymappinggroup {
@@ -138,7 +134,8 @@ if (result==0) {
} {
Fl_Input mappinginput {
xywh {250 147 146 258} type Multiline labelfont 1 labelsize 11 align 5 when 2
code0 {updateMappingInput();}
code0 {o->init("mapping");}
class Fl_Osc_Input
}
Fl_Counter firstnotecounter {
label {First note}
@@ -177,12 +174,11 @@ o->show();}
Fl_Button {} {
label {Import .kbm file}
callback {
//TODO Disabled until this can be moved into middleware
/*const char *filename;
const char *filename;
filename=fl_file_chooser("Open:","(*.kbm)",NULL,0);
if (filename==NULL) return;
int result=microtonal->loadkbm(filename);
if (result==0) {
osc->write("/load_kbm", "s", filename);
if (true) {
updateMappingInput();
mappinginput->position(0);
mapsizeoutput->update();
@@ -192,9 +188,7 @@ if (result==0) {
mappingenabledbutton->update();
afreqinput->update();
anotecounter->update();
} else {
fl_alert("Error: Could not load the file.");
};*/}
}}
tooltip {Inport Scala .kbm file (keyboard mapping)} xywh {243 428 84 16} box THIN_UP_BOX labelfont 1 labelsize 10
}
}
@@ -236,39 +230,13 @@ o->redraw();}
}
}
Function {updateTuningsInput()} {} {
code {char *tmpbuf=new char[100];

/*
tuningsinput->cut(0,tuningsinput->maximum_size());

for (int i=0;i<microtonal->getoctavesize();i++){
if (i!=0) tuningsinput->insert("\\n");
microtonal->tuningtoline(i,tmpbuf,100);
tuningsinput->insert(tmpbuf);
};
*/

delete []tmpbuf;} {}
code {tuningsinput->update();} {}
}
Function {updateMappingInput()} {} {
code {char *tmpbuf=new char[100];

/*
mappinginput->cut(0,tuningsinput->maximum_size());

for (int i=0;i<microtonal->Pmapsize;i++){
if (i!=0) mappinginput->insert("\\n");
if ((microtonal->Pmapping[i])==-1)
snprintf(tmpbuf,100,"x");
else snprintf(tmpbuf,100,"%d",microtonal->Pmapping[i]);
mappinginput->insert(tmpbuf);
};
*/

delete []tmpbuf;} {}
code { mappinginput->update(); } {}
}
Function {MicrotonalUI(Fl_Osc_Interface *osc, std::string base)} {} {
code {make_window(osc, base);} {}
Function {MicrotonalUI(Fl_Osc_Interface *osc_, std::string base)} {} {
code {osc=osc_;make_window(osc, base);} {}
}
Function {~MicrotonalUI()} {} {
code {microtonaluiwindow->hide();
@@ -278,15 +246,14 @@ delete(microtonaluiwindow);} {}
code {microtonaluiwindow->show();} {}
}
Function {apply()} {} {
code {/*int err=microtonal->texttotunings(tuningsinput->value());
if (err>=0) fl_alert("Parse Error: The input may contain only numbers (like 232.59)\\n or divisions (like 121/64).");
if (err==-2) fl_alert("Parse Error: The input is empty.");
octavesizeoutput->do_callback();

microtonal->texttomapping(mappinginput->value());
mapsizeoutput->do_callback();
anotecounter->do_callback();
*/
//applybutton->color(FL_GRAY);} {}
code {
osc->write("/microtonal/tunings", "s", tuningsinput->value());
osc->write("/microtonal/mapping", "s", mappinginput->value());
octavesizeoutput->update();
mapsizeoutput->update();
anotecounter->update();
} {}
}
decl {Fl_Osc_Interface *osc;} {private local
}
}

+ 6
- 0
source/native-plugins/zynaddsubfx/globals.h View File

@@ -62,6 +62,12 @@ class Controller;
class Master;
class Part;

class Filter;
class AnalogFilter;
class SVFilter;
class FormantFilter;
class ModFilter;

#if defined(__APPLE__) || defined(__FreeBSD__)
#include <complex>
#else


+ 1
- 1
source/native-plugins/zynaddsubfx/main.cpp View File

@@ -136,7 +136,7 @@ int main(int argc, char *argv[])
<< "\nZynAddSubFX - Copyright (c) 2002-2013 Nasca Octavian Paul and others"
<< endl;
cerr
<< " Copyright (c) 2009-2015 Mark McCurry [active maintainer]"
<< " Copyright (c) 2009-2016 Mark McCurry [active maintainer]"
<< endl;
cerr << "Compiled: " << __DATE__ << " " << __TIME__ << endl;
cerr << "This program is free software (GNU GPL v2 or later) and \n";


Loading…
Cancel
Save