Browse Source

Update zynaddsubfx

tags/1.9.8
falkTX 7 years ago
parent
commit
f9bd8e4f6f
19 changed files with 219 additions and 167 deletions
  1. +1
    -1
      source/native-plugins/zynaddsubfx/Misc/Bank.cpp
  2. +11
    -11
      source/native-plugins/zynaddsubfx/Misc/BankDb.cpp
  3. +1
    -1
      source/native-plugins/zynaddsubfx/Misc/Master.cpp
  4. +1
    -0
      source/native-plugins/zynaddsubfx/Misc/Microtonal.cpp
  5. +15
    -11
      source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp
  6. +2
    -0
      source/native-plugins/zynaddsubfx/Misc/Schema.cpp
  7. +1
    -1
      source/native-plugins/zynaddsubfx/Misc/XMLwrapper.cpp
  8. +2
    -2
      source/native-plugins/zynaddsubfx/Params/EnvelopeParams.h
  9. +0
    -1
      source/native-plugins/zynaddsubfx/Params/FilterParams.cpp
  10. +104
    -80
      source/native-plugins/zynaddsubfx/Params/PADnoteParameters.cpp
  11. +30
    -12
      source/native-plugins/zynaddsubfx/Params/PADnoteParameters.h
  12. +1
    -1
      source/native-plugins/zynaddsubfx/rtosc/automations.h
  13. +13
    -4
      source/native-plugins/zynaddsubfx/rtosc/cpp/automations.cpp
  14. +1
    -0
      source/native-plugins/zynaddsubfx/rtosc/cpp/ports.cpp
  15. +2
    -2
      source/native-plugins/zynaddsubfx/rtosc/port-sugar.h
  16. +17
    -22
      source/native-plugins/zynaddsubfx/rtosc/ports.h
  17. +10
    -10
      source/native-plugins/zynaddsubfx/rtosc/pretty-format.h
  18. +1
    -0
      source/native-plugins/zynaddsubfx/rtosc/rtosc-version.h
  19. +6
    -8
      source/native-plugins/zynaddsubfx/rtosc/rtosc.h

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

@@ -492,7 +492,7 @@ std::vector<std::string> Bank::search(std::string s) const
std::vector<std::string> Bank::blist(std::string s) std::vector<std::string> Bank::blist(std::string s)
{ {
std::vector<std::string> out; std::vector<std::string> out;
int result = loadbank(s);
loadbank(s);
for(int i=0; i<128; ++i) { for(int i=0; i<128; ++i) {
if(ins[i].filename.empty()) if(ins[i].filename.empty())
out.push_back("Empty Preset"); out.push_back("Empty Preset");


+ 11
- 11
source/native-plugins/zynaddsubfx/Misc/BankDb.cpp View File

@@ -80,17 +80,17 @@ static svec split(string s)
return vec; return vec;
} }


static string line(string s)
{
string ss;
for(char c:s) {
if(c != '\n')
ss.push_back(c);
else
return ss;
}
return ss;
}
//static string line(string s)
//{
// string ss;
// for(char c:s) {
// if(c != '\n')
// ss.push_back(c);
// else
// return ss;
// }
// return ss;
//}


bvec BankDb::search(std::string ss) const bvec BankDb::search(std::string ss) const
{ {


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

@@ -186,6 +186,7 @@ static const Ports auto_param_ports = {
rEnd}, rEnd},
{"mapping/", 0, &mapping_ports, {"mapping/", 0, &mapping_ports,
rBegin; rBegin;
(void) a;
SNIP; SNIP;
mapping_ports.dispatch(msg, d); mapping_ports.dispatch(msg, d);
rEnd}, rEnd},
@@ -664,7 +665,6 @@ void Master::loadAutomation(XMLwrapper &xml, rtosc::AutomationMgr &midi)
auto &slot = midi.slots[i]; auto &slot = midi.slots[i];
if(xml.enterbranch("slot", i)) { if(xml.enterbranch("slot", i)) {
for(int j=0; j<midi.per_slot; ++j) { for(int j=0; j<midi.per_slot; ++j) {
auto &au = slot.automations[j];
if(xml.enterbranch("automation", j)) { if(xml.enterbranch("automation", j)) {
float gain = 1.0; float gain = 1.0;
float offset = 0.0; float offset = 0.0;


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

@@ -870,6 +870,7 @@ void Microtonal::apply(void)
strncat(buf, tmpbuf, sizeof(buf)-1); strncat(buf, tmpbuf, sizeof(buf)-1);
} }
int err = texttotunings(buf); int err = texttotunings(buf);
(void) err;
} }
} }




+ 15
- 11
source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp View File

@@ -18,6 +18,7 @@
#include <iostream> #include <iostream>
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <mutex>


#include <rtosc/undo-history.h> #include <rtosc/undo-history.h>
#include <rtosc/thread-link.h> #include <rtosc/thread-link.h>
@@ -59,6 +60,7 @@
namespace zyncarla { namespace zyncarla {


using std::string; using std::string;
using std::mutex;
int Pexitprogram = 0; int Pexitprogram = 0;


/****************************************************************************** /******************************************************************************
@@ -207,17 +209,19 @@ void preparePadSynth(string path, PADnoteParameters *p, rtosc::RtData &d)
assert(!path.empty()); assert(!path.empty());
path += "sample"; path += "sample";


unsigned max = 0;
p->sampleGenerator([&max,&path,&d]
(unsigned N, PADnoteParameters::Sample &s)
{
max = max<N ? N : max;
//printf("sending info to '%s'\n", (path+to_s(N)).c_str());
d.chain((path+to_s(N)).c_str(), "ifb",
s.size, s.basefreq, sizeof(float*), &s.smp);
}, []{return false;});
std::mutex rtdata_mutex;
unsigned num = p->sampleGenerator([&rtdata_mutex,&path,&d]
(unsigned N, PADnoteParameters::Sample &s)
{
//printf("sending info to '%s'\n",
// (path+to_s(N)).c_str());
rtdata_mutex.lock();
d.chain((path+to_s(N)).c_str(), "ifb",
s.size, s.basefreq, sizeof(float*), &s.smp);
rtdata_mutex.unlock();
}, []{return false;});
//clear out unused samples //clear out unused samples
for(unsigned i = max+1; i < PAD_MAX_SAMPLES; ++i) {
for(unsigned i = num; i < PAD_MAX_SAMPLES; ++i) {
d.chain((path+to_s(i)).c_str(), "ifb", d.chain((path+to_s(i)).c_str(), "ifb",
0, 440.0f, sizeof(float*), NULL); 0, 440.0f, sizeof(float*), NULL);
} }
@@ -1617,7 +1621,7 @@ void MiddleWareImpl::heartBeat(Master *master)
//Last provided beat //Last provided beat
//Last acknowledged beat //Last acknowledged beat
//Current offline status //Current offline status
struct timespec time; struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time); clock_gettime(CLOCK_MONOTONIC, &time);
uint32_t now = (time.tv_sec-start_time_sec)*100 + uint32_t now = (time.tv_sec-start_time_sec)*100 +


+ 2
- 0
source/native-plugins/zynaddsubfx/Misc/Schema.cpp View File

@@ -68,6 +68,7 @@ static const char *escape_string(const char *msg)


using std::ostream; using std::ostream;
using std::string; using std::string;
#if 0
static int enum_min(Port::MetaContainer meta) static int enum_min(Port::MetaContainer meta)
{ {
int min = 0; int min = 0;
@@ -125,6 +126,7 @@ static ostream &add_options(ostream &o, Port::MetaContainer meta)


return o; return o;
} }
#endif


/* /*
* parameter : * parameter :


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

@@ -253,7 +253,7 @@ void XMLwrapper::addparreal(const string &name, float val)
union { float in; uint32_t out; } convert; union { float in; uint32_t out; } convert;
char buf[11]; char buf[11];
convert.in = val; convert.in = val;
sprintf(buf, "0x%0.8X", convert.out);
sprintf(buf, "0x%.8X", convert.out);
addparams("par_real", 3, "name", name.c_str(), "value", addparams("par_real", 3, "name", name.c_str(), "value",
stringFrom<float>(val).c_str(), "exact_value", buf); stringFrom<float>(val).c_str(), "exact_value", buf);
} }


+ 2
- 2
source/native-plugins/zynaddsubfx/Params/EnvelopeParams.h View File

@@ -55,8 +55,8 @@ class EnvelopeParams:public Presets
static float dt(char val); static float dt(char val);
static char inv_dt(float val); static char inv_dt(float val);


//! @brief defines where it is used and its default settings
//! corresponds to envelope_type_t
//! Defines where it is used and its default settings.
//! Corresponds to envelope_type_t
int envelope_type; int envelope_type;


/* MIDI Parameters */ /* MIDI Parameters */


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

@@ -172,7 +172,6 @@ const rtosc::Ports FilterParams::ports = {
0.0, cf.d[1]); 0.0, cf.d[1]);
} }
} else if(obj->Pcategory == 2) { } else if(obj->Pcategory == 2) {
int order = 0;
float gain = dB2rap(obj->getgain()); float gain = dB2rap(obj->getgain());
auto cf = SVFilter::computeResponse(obj->Ptype, auto cf = SVFilter::computeResponse(obj->Ptype,
Filter::getrealfreq(obj->getfreq()), Filter::getrealfreq(obj->getfreq()),


+ 104
- 80
source/native-plugins/zynaddsubfx/Params/PADnoteParameters.cpp View File

@@ -10,6 +10,7 @@
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
*/ */
#include <limits>
#include <cmath> #include <cmath>
#include "PADnoteParameters.h" #include "PADnoteParameters.h"
#include "FilterParams.h" #include "FilterParams.h"
@@ -20,6 +21,7 @@
#include "../Misc/WavFile.h" #include "../Misc/WavFile.h"
#include "../Misc/Time.h" #include "../Misc/Time.h"
#include <cstdio> #include <cstdio>
#include <thread>


#include <rtosc/ports.h> #include <rtosc/ports.h>
#include <rtosc/port-sugar.h> #include <rtosc/port-sugar.h>
@@ -304,8 +306,6 @@ PADnoteParameters::PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_,
{ {
setpresettype("Ppadsynth"); setpresettype("Ppadsynth");


fft = fft_;

resonance = new Resonance(); resonance = new Resonance();
oscilgen = new OscilGen(synth, fft_, resonance); oscilgen = new OscilGen(synth, fft_, resonance);
oscilgen->ADvsPAD = true; oscilgen->ADvsPAD = true;
@@ -596,7 +596,7 @@ float PADnoteParameters::setPbandwidth(int Pbandwidth)
/* /*
* Get the harmonic(overtone) position * Get the harmonic(overtone) position
*/ */
float PADnoteParameters::getNhr(int n)
float PADnoteParameters::getNhr(int n) const
{ {
float result = 1.0f; float result = 1.0f;
const float par1 = powf(10.0f, -(1.0f - Phrpos.par1 / 255.0f) * 3.0f); const float par1 = powf(10.0f, -(1.0f - Phrpos.par1 / 255.0f) * 3.0f);
@@ -696,9 +696,9 @@ static float Pbwscale_translate(char Pbwscale)
void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum, void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
int size, int size,
float basefreq, float basefreq,
float *profile,
const float *profile,
int profilesize, int profilesize,
float bwadjust)
float bwadjust) const
{ {
float harmonics[synth.oscilsize]; float harmonics[synth.oscilsize];
memset(spectrum, 0, sizeof(float) * size); memset(spectrum, 0, sizeof(float) * size);
@@ -712,7 +712,7 @@ void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,


//Constants across harmonics //Constants across harmonics
const float power = Pbwscale_translate(Pbwscale); const float power = Pbwscale_translate(Pbwscale);
const float bandwidthcents = setPbandwidth(Pbandwidth);
const float bandwidthcents = const_cast<PADnoteParameters*>(this)->setPbandwidth(Pbandwidth);


for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic
const float realfreq = getNhr(nh) * basefreq; const float realfreq = getNhr(nh) * basefreq;
@@ -773,7 +773,7 @@ void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
*/ */
void PADnoteParameters::generatespectrum_otherModes(float *spectrum, void PADnoteParameters::generatespectrum_otherModes(float *spectrum,
int size, int size,
float basefreq)
float basefreq) const
{ {
float harmonics[synth.oscilsize]; float harmonics[synth.oscilsize];
memset(spectrum, 0, sizeof(float) * size); memset(spectrum, 0, sizeof(float) * size);
@@ -830,21 +830,20 @@ void PADnoteParameters::applyparameters()
applyparameters([]{return false;}); applyparameters([]{return false;});
} }


void PADnoteParameters::applyparameters(std::function<bool()> do_abort)
void PADnoteParameters::applyparameters(std::function<bool()> do_abort,
unsigned max_threads)
{ {
if(do_abort()) if(do_abort())
return; return;
unsigned max = 0;
sampleGenerator([&max,this]
(unsigned N, PADnoteParameters::Sample &smp) {
delete[] sample[N].smp;
sample[N] = smp;
max = max < N ? N : max;
},
do_abort);
unsigned num = sampleGenerator([this]
(unsigned N, PADnoteParameters::Sample &smp) {
delete[] sample[N].smp;
sample[N] = smp;
},
do_abort, max_threads);


//Delete remaining unused samples //Delete remaining unused samples
for(unsigned i = max; i < PAD_MAX_SAMPLES; ++i)
for(unsigned i = num; i < PAD_MAX_SAMPLES; ++i)
deletesample(i); deletesample(i);
} }


@@ -854,13 +853,17 @@ void PADnoteParameters::applyparameters(std::function<bool()> do_abort)
// - Pquality.oct // - Pquality.oct
// - Pquality.smpoct // - Pquality.smpoct
// - spectrum at various frequencies (oodles of data) // - spectrum at various frequencies (oodles of data)
void PADnoteParameters::sampleGenerator(PADnoteParameters::callback cb,
std::function<bool()> do_abort)
int PADnoteParameters::sampleGenerator(PADnoteParameters::callback cb,
std::function<bool()> do_abort,
unsigned max_threads)
{ {
if(!max_threads)
max_threads = std::numeric_limits<unsigned>::max();

const int samplesize = (((int) 1) << (Pquality.samplesize + 14)); const int samplesize = (((int) 1) << (Pquality.samplesize + 14));
const int spectrumsize = samplesize / 2; const int spectrumsize = samplesize / 2;
float *spectrum = new float[spectrumsize];
const int profilesize = 512; const int profilesize = 512;

float profile[profilesize]; float profile[profilesize];




@@ -885,71 +888,92 @@ void PADnoteParameters::sampleGenerator(PADnoteParameters::callback cb,
if(samplemax > PAD_MAX_SAMPLES) if(samplemax > PAD_MAX_SAMPLES)
samplemax = PAD_MAX_SAMPLES; samplemax = PAD_MAX_SAMPLES;


//prepare a BIG FFT
FFTwrapper *fft = new FFTwrapper(samplesize);
fft_t *fftfreqs = new fft_t[samplesize / 2];

//this is used to compute frequency relation to the base frequency //this is used to compute frequency relation to the base frequency
float adj[samplemax]; float adj[samplemax];
for(int nsample = 0; nsample < samplemax; ++nsample) for(int nsample = 0; nsample < samplemax; ++nsample)
adj[nsample] = (Pquality.oct + 1.0f) * (float)nsample / samplemax; adj[nsample] = (Pquality.oct + 1.0f) * (float)nsample / samplemax;
for(int nsample = 0; nsample < samplemax; ++nsample) {
if(do_abort())
goto exit;
const float basefreqadjust =
powf(2.0f, adj[nsample] - adj[samplemax - 1] * 0.5f);

if(Pmode == 0)
generatespectrum_bandwidthMode(spectrum,
spectrumsize,
basefreq * basefreqadjust,
profile,
profilesize,
bwadjust);
else
generatespectrum_otherModes(spectrum, spectrumsize,
basefreq * basefreqadjust);

//the last samples contains the first samples
//(used for linear/cubic interpolation)
const int extra_samples = 5;
PADnoteParameters::Sample newsample;
newsample.smp = new float[samplesize + extra_samples];

newsample.smp[0] = 0.0f;
for(int i = 1; i < spectrumsize; ++i) //randomize the phases
fftfreqs[i] = FFTpolar(spectrum[i], (float)RND * 2 * PI);
//that's all; here is the only ifft for the whole sample;
//no windows are used ;-)
fft->freqs2smps(fftfreqs, newsample.smp);


//normalize(rms)
float rms = 0.0f;
for(int i = 0; i < samplesize; ++i)
rms += newsample.smp[i] * newsample.smp[i];
rms = sqrt(rms);
if(rms < 0.000001f)
rms = 1.0f;
rms *= sqrt(262144.0f / samplesize);//262144=2^18
for(int i = 0; i < samplesize; ++i)
newsample.smp[i] *= 1.0f / rms * 50.0f;

//prepare extra samples used by the linear or cubic interpolation
for(int i = 0; i < extra_samples; ++i)
newsample.smp[i + samplesize] = newsample.smp[i];

//yield new sample
newsample.size = samplesize;
newsample.basefreq = basefreq * basefreqadjust;
cb(nsample, newsample);
}
exit:


//Cleanup
delete (fft);
delete[] fftfreqs;
delete[] spectrum;
const PADnoteParameters* this_c = this;

auto thread_cb = [basefreq, bwadjust, &cb, do_abort,
samplesize, samplemax, spectrumsize,
&adj, &profile, this_c](
unsigned nthreads, unsigned threadno)
{
//prepare a BIG IFFT
FFTwrapper *fft = new FFTwrapper(samplesize);
fft_t *fftfreqs = new fft_t[samplesize / 2];
float *spectrum = new float[spectrumsize];

for(int nsample = 0; nsample < samplemax; ++nsample)
if(nsample % nthreads == threadno)
{
if(do_abort())
break;
const float basefreqadjust =
powf(2.0f, adj[nsample] - adj[samplemax - 1] * 0.5f);

if(this_c->Pmode == 0)
this_c->generatespectrum_bandwidthMode(spectrum,
spectrumsize,
basefreq*basefreqadjust,
profile,
profilesize,
bwadjust);
else
this_c->generatespectrum_otherModes(spectrum, spectrumsize,
basefreq * basefreqadjust);

//the last samples contains the first samples
//(used for linear/cubic interpolation)
const int extra_samples = 5;
PADnoteParameters::Sample newsample;
newsample.smp = new float[samplesize + extra_samples];

newsample.smp[0] = 0.0f;
for(int i = 1; i < spectrumsize; ++i) //randomize the phases
fftfreqs[i] = FFTpolar(spectrum[i], (float)RND * 2 * PI);
//that's all; here is the only ifft for the whole sample;
//no windows are used ;-)
fft->freqs2smps(fftfreqs, newsample.smp);


//normalize(rms)
float rms = 0.0f;
for(int i = 0; i < samplesize; ++i)
rms += newsample.smp[i] * newsample.smp[i];
rms = sqrt(rms);
if(rms < 0.000001f)
rms = 1.0f;
rms *= sqrt(262144.0f / samplesize);//262144=2^18
for(int i = 0; i < samplesize; ++i)
newsample.smp[i] *= 1.0f / rms * 50.0f;

//prepare extra samples used by the linear or cubic interpolation
for(int i = 0; i < extra_samples; ++i)
newsample.smp[i + samplesize] = newsample.smp[i];

//yield new sample
newsample.size = samplesize;
newsample.basefreq = basefreq * basefreqadjust;
cb(nsample, newsample);
}

//Cleanup
delete (fft);
delete[] fftfreqs;
delete[] spectrum;
};

unsigned nthreads = std::min(max_threads,
std::thread::hardware_concurrency());
std::vector<std::thread> threads(nthreads);
for(unsigned i = 0; i < nthreads; ++i)
threads[i] = std::thread(thread_cb, nthreads, i);
for(unsigned i = 0; i < nthreads; ++i)
threads[i].join();

return samplemax;
} }


void PADnoteParameters::export2wav(std::string basefilename) void PADnoteParameters::export2wav(std::string basefilename)


+ 30
- 12
source/native-plugins/zynaddsubfx/Params/PADnoteParameters.h View File

@@ -25,7 +25,7 @@ namespace zyncarla {
/** /**
* Parameters for PAD synthesis * Parameters for PAD synthesis
* *
* Note - unlike most other parameter objects significant portions of this
* @note unlike most other parameter objects significant portions of this
* object are `owned' by the non-realtime context. The realtime context only * object are `owned' by the non-realtime context. The realtime context only
* needs the samples generated by the PADsynth algorithm and modulators (ie * needs the samples generated by the PADsynth algorithm and modulators (ie
* envelopes/filters/LFOs) for amplitude, frequency, and filters. * envelopes/filters/LFOs) for amplitude, frequency, and filters.
@@ -146,26 +146,45 @@ class PADnoteParameters:public Presets






float setPbandwidth(int Pbandwidth); //returns the BandWidth in cents
float getNhr(int n); //gets the n-th overtone position relatively to N harmonic
float setPbandwidth(int Pbandwidth); //!< Return the BandWidth in cents
//! Get the n-th overtone position relatively to N harmonic
float getNhr(int n) const;


void applyparameters(void); void applyparameters(void);
void applyparameters(std::function<bool()> do_abort);
//! Compute the #sample array from the other parameters.
//! For the function's parameters, see sampleGenerator()
void applyparameters(std::function<bool()> do_abort,
unsigned max_threads = 0);
void export2wav(std::string basefilename); void export2wav(std::string basefilename);


OscilGen *oscilgen; OscilGen *oscilgen;
Resonance *resonance; Resonance *resonance;


//RT sample data
struct Sample { struct Sample {
int size; int size;
float basefreq; float basefreq;
float *smp; float *smp;
} sample[PAD_MAX_SAMPLES];
};

//! RT sample data
Sample sample[PAD_MAX_SAMPLES];


typedef std::function<void(int,PADnoteParameters::Sample&)> callback; typedef std::function<void(int,PADnoteParameters::Sample&)> callback;
void sampleGenerator(PADnoteParameters::callback cb,
std::function<bool()> do_abort);

//! PAD synth main function
//! Generate spectrum and run IFFTs on it
//! @param cb A callback that will be executed for each sample buffer
//! Note that this function can be executed by multiple
//! threads at the same time, so make sure you use mutexes
//! etc where required
//! @param do_abort Function that decides whether the calculation should
//! be aborted (probably because of interruptions by the
//! user)
//! @param max_threads Maximum number of threads for computation, or
//! zero if no maximum shall be set
int sampleGenerator(PADnoteParameters::callback cb,
std::function<bool()> do_abort,
unsigned max_threads = 0);


const AbsTime *time; const AbsTime *time;
int64_t last_update_timestamp; int64_t last_update_timestamp;
@@ -178,16 +197,15 @@ class PADnoteParameters:public Presets
void generatespectrum_bandwidthMode(float *spectrum, void generatespectrum_bandwidthMode(float *spectrum,
int size, int size,
float basefreq, float basefreq,
float *profile,
const float *profile,
int profilesize, int profilesize,
float bwadjust);
float bwadjust) const;
void generatespectrum_otherModes(float *spectrum, void generatespectrum_otherModes(float *spectrum,
int size, int size,
float basefreq);
float basefreq) const;
void deletesamples(); void deletesamples();
void deletesample(int n); void deletesample(int n);


FFTwrapper *fft;
public: public:
const SYNTH_T &synth; const SYNTH_T &synth;
}; };


+ 1
- 1
source/native-plugins/zynaddsubfx/rtosc/automations.h View File

@@ -1,7 +1,7 @@
#pragma once
#include <rtosc/ports.h> #include <rtosc/ports.h>
#include <rtosc/rtosc.h> #include <rtosc/rtosc.h>
#include <cassert> #include <cassert>
#pragma once
namespace rtosc { namespace rtosc {
struct AutomationMapping struct AutomationMapping
{ {


+ 13
- 4
source/native-plugins/zynaddsubfx/rtosc/cpp/automations.cpp View File

@@ -39,8 +39,10 @@ void AutomationMgr::createBinding(int slot, const char *path, bool start_midi_le
} }
auto meta = port->meta(); auto meta = port->meta();
if(!(meta.find("min") && meta.find("max"))) { if(!(meta.find("min") && meta.find("max"))) {
fprintf(stderr, "No bounds for '%s' known\n", path);
return;
if(!strstr(port->name, ":T")) {
fprintf(stderr, "No bounds for '%s' known\n", path);
return;
}
} }
if(meta.find("internal") || meta.find("no learn")) { if(meta.find("internal") || meta.find("no learn")) {
fprintf(stderr, "[Warning] port '%s' is unlearnable\n", path); fprintf(stderr, "[Warning] port '%s' is unlearnable\n", path);
@@ -63,11 +65,18 @@ void AutomationMgr::createBinding(int slot, const char *path, bool start_midi_le


au.used = true; au.used = true;
au.active = true; au.active = true;
au.param_min = atof(meta["min"]);
au.param_max = atof(meta["max"]);
au.param_type = 'i'; au.param_type = 'i';
if(strstr(port->name, ":f")) if(strstr(port->name, ":f"))
au.param_type = 'f'; au.param_type = 'f';
else if(strstr(port->name, ":T"))
au.param_type = 'T';
if(au.param_type == 'T') {
au.param_min = 0.0;
au.param_max = 1.0;
} else {
au.param_min = atof(meta["min"]);
au.param_max = atof(meta["max"]);
}
strncpy(au.param_path, path, sizeof(au.param_path)); strncpy(au.param_path, path, sizeof(au.param_path));


au.map.gain = 100.0; au.map.gain = 100.0;


+ 1
- 0
source/native-plugins/zynaddsubfx/rtosc/cpp/ports.cpp View File

@@ -688,6 +688,7 @@ class CapturePretty : public RtData
size_t wrt = rtosc_print_arg_vals(arg_vals, nargs, size_t wrt = rtosc_print_arg_vals(arg_vals, nargs,
buffer, buffersize, NULL, buffer, buffersize, NULL,
cols_used); cols_used);
(void) wrt;
va_end(va); va_end(va);
assert(wrt); assert(wrt);
} }


+ 2
- 2
source/native-plugins/zynaddsubfx/rtosc/port-sugar.h View File

@@ -294,9 +294,9 @@ template<class T> constexpr T spice(T*t) {return *t;}
#define rBOIL_END } #define rBOIL_END }


#define rLIMIT(var, convert) \ #define rLIMIT(var, convert) \
if(prop["min"] && var < convert(prop["min"])) \
if(prop["min"] && var < (decltype(var)) convert(prop["min"])) \
var = convert(prop["min"]);\ var = convert(prop["min"]);\
if(prop["max"] && var > convert(prop["max"])) \
if(prop["max"] && var > (decltype(var)) convert(prop["max"])) \
var = convert(prop["max"]); var = convert(prop["max"]);


#define rTYPE(n) decltype(obj->n) #define rTYPE(n) decltype(obj->n)


+ 17
- 22
source/native-plugins/zynaddsubfx/rtosc/ports.h View File

@@ -24,6 +24,8 @@


/** /**
* @file ports.h * @file ports.h
* Collection of functions for ports.
* This includes dispatchin, reading metadata etc.
*/ */


#ifndef RTOSC_PORTS #ifndef RTOSC_PORTS
@@ -54,8 +56,7 @@ struct RtData
RtData(void); RtData(void);


/** /**
* @brief location of where the dispatch routine is currently being called
*
* Location of where the dispatch routine is currently being called.
* If non-NULL, the dispatch routine will update the port name here while * If non-NULL, the dispatch routine will update the port name here while
* walking through the Ports tree * walking through the Ports tree
*/ */
@@ -253,7 +254,7 @@ struct MergePorts:public Ports
}; };


/** /**
* @brief Returns a port's default value
* Return a port's default value
* *
* Returns the default value of a given port, if any exists, as a string. * Returns the default value of a given port, if any exists, as a string.
* For the parameters, see the overloaded function. * For the parameters, see the overloaded function.
@@ -266,7 +267,7 @@ const char* get_default_value(const char* port_name, const Ports& ports,
int32_t idx = -1, int recursive = 1); int32_t idx = -1, int recursive = 1);


/** /**
* @brief Returns a port's default value
* Return a port's default value
* *
* Returns the default value of a given port, if any exists, as an array of * Returns the default value of a given port, if any exists, as an array of
* rtosc_arg_vals . The values in the resulting array are being canonicalized, * rtosc_arg_vals . The values in the resulting array are being canonicalized,
@@ -299,7 +300,7 @@ int get_default_value(const char* port_name, const char *port_args,




/** /**
* @brief Return a string list of all changed values
* Return a string list of all changed values
* *
* Return a human readable list of the value that changed * Return a human readable list of the value that changed
* corresponding to the rDefault macro * corresponding to the rDefault macro
@@ -309,9 +310,8 @@ int get_default_value(const char* port_name, const char *port_args,
*/ */
std::string get_changed_values(const Ports& ports, void* runtime); std::string get_changed_values(const Ports& ports, void* runtime);


//! @brief Class to modify messages loaded from savefiles
//!
//! Object of this class shall be passed to savefile loading routines. You can
//! Class to modify messages loaded from savefiles.
//! Objects of this class shall be passed to savefile loading routines. You can
//! inherit to change the behaviour, e.g. to modify or discard such messages. //! inherit to change the behaviour, e.g. to modify or discard such messages.
class savefile_dispatcher_t class savefile_dispatcher_t
{ {
@@ -362,8 +362,7 @@ private:
}; };


/** /**
* @brief Scan OSC messages from human readable format and dispatch them
*
* Scan OSC messages from human readable format and dispatch them.
* @param messages The OSC messages, whitespace-separated * @param messages The OSC messages, whitespace-separated
* @param ports The static ports structure * @param ports The static ports structure
* @param runtime The runtime object * @param runtime The runtime object
@@ -378,9 +377,7 @@ int dispatch_printed_messages(const char* messages,
savefile_dispatcher_t *dispatcher = NULL); savefile_dispatcher_t *dispatcher = NULL);


/** /**
* @brief Return a savefile containing all values that differ from the default
* values.
*
* Return a savefile containing all values that differ from the default values.
* @param ports The static ports structure * @param ports The static ports structure
* @param runtime The runtime object * @param runtime The runtime object
* @param appname Name of the application calling this function * @param appname Name of the application calling this function
@@ -391,8 +388,7 @@ std::string save_to_file(const Ports& ports, void* runtime,
const char* appname, rtosc_version appver); const char* appname, rtosc_version appver);


/** /**
* @brief Read save file and dispatch contained parameters
*
* Read save file and dispatch contained parameters.
* @param file_content The file as a C string * @param file_content The file as a C string
* @param ports The static ports structure * @param ports The static ports structure
* @param runtime The runtime object * @param runtime The runtime object
@@ -410,9 +406,9 @@ int load_from_file(const char* file_content,
savefile_dispatcher_t* dispatcher = NULL); savefile_dispatcher_t* dispatcher = NULL);


/** /**
* @brief Convert given argument values to their canonical representation, e.g.
* to the ports first (or-wise) argument types.
* Convert given argument values to their canonical representation.
* *
* The ports first (or-wise) argument types are defined as canonical.
* E.g. if passing two 'S' argument values, the * E.g. if passing two 'S' argument values, the
* port could be `portname::ii:cc:SS` or `portname::ii:t`. * port could be `portname::ii:cc:SS` or `portname::ii:t`.
* *
@@ -428,8 +424,7 @@ int canonicalize_arg_vals(rtosc_arg_val_t* av, size_t n,
const char* port_args, Port::MetaContainer meta); const char* port_args, Port::MetaContainer meta);


/** /**
* @brief Converts each of the given arguments to their mapped symbol, if
* possible
* Convert each of the given arguments to their mapped symbol, if possible.
* @param av The input and output argument values * @param av The input and output argument values
* @param n The size of @p av * @param n The size of @p av
* @param meta The port's metadata container * @param meta The port's metadata container
@@ -442,7 +437,7 @@ void map_arg_vals(rtosc_arg_val_t* av, size_t n,
*********************/ *********************/
//typedef std::function<void(const Port*,const char*)> port_walker_t; //typedef std::function<void(const Port*,const char*)> port_walker_t;
/** /**
* @brief function pointer type for port walking
* Function pointer type for port walking.
* *
* accepts: * accepts:
* - the currently walked port * - the currently walked port
@@ -458,7 +453,7 @@ typedef void(*port_walker_t)(const Port*,const char*,const char*,
const Ports&,void*,void*); const Ports&,void*,void*);


/** /**
* @brief Call a function on all ports and subports
* Call a function on all ports and subports.
* @param base The base port of traversing * @param base The base port of traversing
* @param name_buffer Buffer which will be filled with the port name; must be * @param name_buffer Buffer which will be filled with the port name; must be
* reset to zero over the full length! * reset to zero over the full length!
@@ -474,7 +469,7 @@ void walk_ports(const Ports *base,
void *runtime = NULL); void *runtime = NULL);


/** /**
* @brief Return the index with value @p value from the metadata's enumeration
* Return the index with value @p value from the metadata's enumeration.
* @param meta The metadata * @param meta The metadata
* @param value The value to search the key for * @param value The value to search the key for
* @return The first key holding value, or `std::numeric_limits<int>::min()` * @return The first key holding value, or `std::numeric_limits<int>::min()`


+ 10
- 10
source/native-plugins/zynaddsubfx/rtosc/pretty-format.h View File

@@ -44,7 +44,7 @@ typedef struct
} rtosc_print_options; } rtosc_print_options;


/** /**
* @brief Pretty-print rtosct_arg_val_t structure into buffer
* Pretty-print rtosct_arg_val_t structure into buffer
* *
* @param arg Pointer to the structure that shall be printed * @param arg Pointer to the structure that shall be printed
* @param buffer The buffer to write to * @param buffer The buffer to write to
@@ -59,7 +59,7 @@ size_t rtosc_print_arg_val(const rtosc_arg_val_t* arg, char* buffer,
int* cols_used); int* cols_used);


/** /**
* @brief Pretty-print rtosct_arg_val_t array into buffer
* Pretty-print rtosct_arg_val_t array into buffer
* *
* @see rtosc_print_message * @see rtosc_print_message
* @warning in case of possible line breaks (almost always), buffer[-1] must * @warning in case of possible line breaks (almost always), buffer[-1] must
@@ -71,7 +71,7 @@ size_t rtosc_print_arg_vals(const rtosc_arg_val_t *args, size_t n,
int cols_used); int cols_used);


/** /**
* @brief Pretty-print OSC message into string buffer
* Pretty-print OSC message into string buffer
* *
* A newline will be appended. * A newline will be appended.
* *
@@ -91,7 +91,7 @@ size_t rtosc_print_message(const char* address,
int cols_used); int cols_used);


/** /**
* @brief Skip characters from a string until one argument value
* Skip characters from a string until one argument value
* would have been scanned * would have been scanned
* @param src The string * @param src The string
* @return The first character after that argument value * @return The first character after that argument value
@@ -99,9 +99,9 @@ size_t rtosc_print_message(const char* address,
const char* rtosc_skip_next_printed_arg(const char* src); const char* rtosc_skip_next_printed_arg(const char* src);


/** /**
* @brief Count arguments that would be scanned and do a complete syntax check
* Count arguments that would be scanned and do a complete syntax check
* *
* This functions should be run before rtosc_scan_arg_vals() in order
* This function should be run before rtosc_scan_arg_vals() in order
* to know the number of argument values. Also, rtosc_scan_arg_vals() does * to know the number of argument values. Also, rtosc_scan_arg_vals() does
* no complete syntax check. * no complete syntax check.
* *
@@ -112,7 +112,7 @@ const char* rtosc_skip_next_printed_arg(const char* src);
int rtosc_count_printed_arg_vals(const char* src); int rtosc_count_printed_arg_vals(const char* src);


/** /**
* @brief Count arguments of a message that would be scanned and
* Count arguments of a message that would be scanned and
* do a complete syntax check * do a complete syntax check
* *
* @param msg The message to scan from * @param msg The message to scan from
@@ -123,7 +123,7 @@ int rtosc_count_printed_arg_vals(const char* src);
int rtosc_count_printed_arg_vals_of_msg(const char* msg); int rtosc_count_printed_arg_vals_of_msg(const char* msg);


/** /**
* @brief Scans one argument value from a string
* Scan one argument value from a string
* *
* This function does no complete syntaxcheck. Call * This function does no complete syntaxcheck. Call
* rtosc_count_printed_arg_vals() before. * rtosc_count_printed_arg_vals() before.
@@ -141,7 +141,7 @@ size_t rtosc_scan_arg_val(const char* src,
char* buffer_for_strings, size_t* bufsize); char* buffer_for_strings, size_t* bufsize);


/** /**
* @brief Scan a fixed number of argument values from a string.
* Scan a fixed number of argument values from a string
* *
* This function does no complete syntaxcheck. Call * This function does no complete syntaxcheck. Call
* rtosc_count_printed_arg_vals() before. This will also give you the @p n * rtosc_count_printed_arg_vals() before. This will also give you the @p n
@@ -154,7 +154,7 @@ size_t rtosc_scan_arg_vals(const char* src,
char* buffer_for_strings, size_t bufsize); char* buffer_for_strings, size_t bufsize);


/** /**
* @brief Scan an OSC message from a string.
* Scan an OSC message from a string
* *
* This function does no complete syntaxcheck. Call * This function does no complete syntaxcheck. Call
* rtosc_count_printed_arg_vals() before. This will also give you the @p n * rtosc_count_printed_arg_vals() before. This will also give you the @p n


+ 1
- 0
source/native-plugins/zynaddsubfx/rtosc/rtosc-version.h View File

@@ -24,6 +24,7 @@


/** /**
* @file rtosc-version.h * @file rtosc-version.h
* Definition of rtosc's version struct
* @note the implementation is in version.c.in * @note the implementation is in version.c.in
*/ */




+ 6
- 8
source/native-plugins/zynaddsubfx/rtosc/rtosc.h View File

@@ -24,6 +24,7 @@


/** /**
* @file rtosc.h * @file rtosc.h
* Functions handling messages and arguments
*/ */


#ifndef RTOSC_H #ifndef RTOSC_H
@@ -135,7 +136,7 @@ typedef struct
} rtosc_cmp_options; } rtosc_cmp_options;


/** /**
* @brief Check if two arrays of rtosc_arg_val_t are equal
* Check if two arrays of rtosc_arg_val_t are equal
* *
* @param opt Comparison options or NULL for default options * @param opt Comparison options or NULL for default options
* @return One if they are equal, zero if not * @return One if they are equal, zero if not
@@ -145,8 +146,7 @@ int rtosc_arg_vals_eq(rtosc_arg_val_t* lhs, rtosc_arg_val_t* rhs,
const rtosc_cmp_options* opt); const rtosc_cmp_options* opt);


/** /**
* @brief Compare two arrays of rtosc_arg_val_t.
*
* Compare two arrays of rtosc_arg_val_t.
* Whether an argument value is less or greater than another is computed * Whether an argument value is less or greater than another is computed
* - using memcmp for blobs * - using memcmp for blobs
* - using strcmp for strings and identifiers * - using strcmp for strings and identifiers
@@ -166,7 +166,7 @@ int rtosc_arg_vals_cmp(rtosc_arg_val_t* lhs, rtosc_arg_val_t* rhs,
typedef struct { va_list a; } rtosc_va_list_t; typedef struct { va_list a; } rtosc_va_list_t;


/** /**
* @brief Pack arguments into pre-allocated rtosc_arg_t array
* Pack arguments into pre-allocated rtosc_arg_t array
* *
* @param args Pre-allocated array; size must be greater or equal @p nargs * @param args Pre-allocated array; size must be greater or equal @p nargs
* @param nargs Size of elements to pack * @param nargs Size of elements to pack
@@ -177,16 +177,14 @@ void rtosc_v2args(rtosc_arg_t* args, size_t nargs,
const char* arg_str, rtosc_va_list_t* ap); const char* arg_str, rtosc_va_list_t* ap);


/** /**
* @brief Pack parameters into pre-allocated rtosc_arg_val-t array
*
* Pack parameters into pre-allocated rtosc_arg_val-t array
* @see rtosc_v2args * @see rtosc_v2args
*/ */
void rtosc_v2argvals(rtosc_arg_val_t* args, size_t nargs, void rtosc_v2argvals(rtosc_arg_val_t* args, size_t nargs,
const char* arg_str, va_list ap); const char* arg_str, va_list ap);


/** /**
* @brief Pack parameters into pre-allocated rtosc_arg_val-t array
*
* Pack parameters into pre-allocated rtosc_arg_val-t array
* @see rtosc_v2args * @see rtosc_v2args
*/ */
void rtosc_2argvals(rtosc_arg_val_t* args, size_t nargs, void rtosc_2argvals(rtosc_arg_val_t* args, size_t nargs,


Loading…
Cancel
Save