@@ -144,6 +144,7 @@ bin/resources/*.py | |||||
source/native-plugins/resources/*.py | source/native-plugins/resources/*.py | ||||
# zynaddsubfx | # zynaddsubfx | ||||
source/native-plugins/zynaddsubfx/rtosc/version.c.in | |||||
source/native-plugins/zynaddsubfx/Output/ | source/native-plugins/zynaddsubfx/Output/ | ||||
source/native-plugins/zynaddsubfx/Tests/ | source/native-plugins/zynaddsubfx/Tests/ | ||||
source/native-plugins/zynaddsubfx/UI/ADnoteUI.cpp | source/native-plugins/zynaddsubfx/UI/ADnoteUI.cpp | ||||
@@ -14,6 +14,7 @@ rm -f $CARLA_ZYN_DIR/Misc/* | |||||
rm -f $CARLA_ZYN_DIR/Nio/* | rm -f $CARLA_ZYN_DIR/Nio/* | ||||
rm -f $CARLA_ZYN_DIR/Params/* | rm -f $CARLA_ZYN_DIR/Params/* | ||||
rm -f $CARLA_ZYN_DIR/Synth/* | rm -f $CARLA_ZYN_DIR/Synth/* | ||||
rm -f $CARLA_ZYN_DIR/Tests/* | |||||
rm -fr $CARLA_ZYN_DIR/UI/* | rm -fr $CARLA_ZYN_DIR/UI/* | ||||
rm -fr $CARLA_ZYN_DIR/rtosc/* | rm -fr $CARLA_ZYN_DIR/rtosc/* | ||||
rm -f $CARLA_ZYN_DIR/tlsf/* | rm -f $CARLA_ZYN_DIR/tlsf/* | ||||
@@ -39,7 +40,13 @@ rm $CARLA_ZYN_DIR/UI/zynaddsubfx.xpm | |||||
cp $ORIG_ZYN_DIR/src/zyn-version.h.in $CARLA_ZYN_DIR/zyn-version.h | cp $ORIG_ZYN_DIR/src/zyn-version.h.in $CARLA_ZYN_DIR/zyn-version.h | ||||
sed -i 's|${VERSION_MAJOR}|3|' $CARLA_ZYN_DIR/zyn-version.h | sed -i 's|${VERSION_MAJOR}|3|' $CARLA_ZYN_DIR/zyn-version.h | ||||
sed -i 's|${VERSION_MINOR}|0|' $CARLA_ZYN_DIR/zyn-version.h | sed -i 's|${VERSION_MINOR}|0|' $CARLA_ZYN_DIR/zyn-version.h | ||||
sed -i 's|${VERSION_REVISION}|1|' $CARLA_ZYN_DIR/zyn-version.h | |||||
sed -i 's|${VERSION_REVISION}|2|' $CARLA_ZYN_DIR/zyn-version.h | |||||
find $CARLA_ZYN_DIR -name "*.h" -type f | xargs sed -i "s|namespace zyn|namespace zyncarla|g" | |||||
find $CARLA_ZYN_DIR -name "*.fl" -type f | xargs sed -i "s|namespace zyn|namespace zyncarla|g" | |||||
find $CARLA_ZYN_DIR -name "*.cpp" -type f | xargs sed -i "s|namespace zyn|namespace zyncarla|g" | |||||
sed -i "s|zyn::|zyncarla::|g" $CARLA_ZYN_DIR/*/*.h | |||||
sed -i "s|zyn::|zyncarla::|g" $CARLA_ZYN_DIR/*/*.cpp | |||||
sed -i "s|emplace_uint32(|emplace_uint32_cpp(|" $CARLA_ZYN_DIR/rtosc/cpp/subtree-serialize.cpp | sed -i "s|emplace_uint32(|emplace_uint32_cpp(|" $CARLA_ZYN_DIR/rtosc/cpp/subtree-serialize.cpp | ||||
sed -i "s|../../include/rtosc/|../|" $CARLA_ZYN_DIR/rtosc/cpp/*.cpp | sed -i "s|../../include/rtosc/|../|" $CARLA_ZYN_DIR/rtosc/cpp/*.cpp | ||||
@@ -31,7 +31,7 @@ endif # EXPERIMENTAL_PLUGINS | |||||
ifeq ($(HAVE_ZYN_DEPS),true) | ifeq ($(HAVE_ZYN_DEPS),true) | ||||
ZYN_CXX_FLAGS = $(BUILD_CXX_FLAGS) -Izynaddsubfx -Izynaddsubfx/rtosc | ZYN_CXX_FLAGS = $(BUILD_CXX_FLAGS) -Izynaddsubfx -Izynaddsubfx/rtosc | ||||
ZYN_CXX_FLAGS += -Wno-misleading-indentation -Wno-shift-negative-value | |||||
ZYN_CXX_FLAGS += -Wno-misleading-indentation -Wno-shift-negative-value -fpermissive | |||||
ZYN_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml zlib) | ZYN_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml zlib) | ||||
ZYN_LD_FLAGS = $(LINK_FLAGS) | ZYN_LD_FLAGS = $(LINK_FLAGS) | ||||
ZYN_LD_FLAGS += $(shell pkg-config --libs liblo) | ZYN_LD_FLAGS += $(shell pkg-config --libs liblo) | ||||
@@ -34,6 +34,8 @@ using juce::roundToIntAccurate; | |||||
using juce::FloatVectorOperations; | using juce::FloatVectorOperations; | ||||
using juce::SharedResourcePointer; | using juce::SharedResourcePointer; | ||||
using namespace zyncarla; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
template<class ZynFX> | template<class ZynFX> | ||||
@@ -241,7 +241,9 @@ extern "C" { | |||||
#undef rChangeCb | #undef rChangeCb | ||||
#define rChangeCb | #define rChangeCb | ||||
#define INSTRUMENT_EXTENSION INSTRUMENT_EXTENSION_DB | |||||
#include "zynaddsubfx/Misc/BankDb.cpp" | #include "zynaddsubfx/Misc/BankDb.cpp" | ||||
#undef INSTRUMENT_EXTENSION | |||||
#undef rBegin | #undef rBegin | ||||
#undef rObject | #undef rObject | ||||
#undef rStdString | #undef rStdString | ||||
@@ -528,6 +530,7 @@ extern "C" { | |||||
#include "zynaddsubfx/globals.cpp" | #include "zynaddsubfx/globals.cpp" | ||||
// Dummy variables and functions for linking purposes | // Dummy variables and functions for linking purposes | ||||
namespace zyncarla { | |||||
class WavFile; | class WavFile; | ||||
namespace Nio { | namespace Nio { | ||||
void masterSwap(Master*){} | void masterSwap(Master*){} | ||||
@@ -541,3 +544,4 @@ namespace Nio { | |||||
void waveStart(){} | void waveStart(){} | ||||
void waveStop(){} | void waveStop(){} | ||||
} | } | ||||
} |
@@ -38,6 +38,8 @@ using juce::roundToIntAccurate; | |||||
using juce::FloatVectorOperations; | using juce::FloatVectorOperations; | ||||
using juce::ScopedPointer; | using juce::ScopedPointer; | ||||
using namespace zyncarla; | |||||
// #define ZYN_MSG_ANYWHERE | // #define ZYN_MSG_ANYWHERE | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -73,7 +75,7 @@ public: | |||||
std::vector<const ProgramInfo*> programs; | std::vector<const ProgramInfo*> programs; | ||||
programs.push_back(new ProgramInfo(0, 0, "default", "")); | programs.push_back(new ProgramInfo(0, 0, "default", "")); | ||||
CarlaConfig config; | |||||
Config config; | |||||
config.init(); | config.init(); | ||||
SYNTH_T synth; | SYNTH_T synth; | ||||
@@ -834,7 +836,7 @@ private: | |||||
MiddleWare* fMiddleWare; | MiddleWare* fMiddleWare; | ||||
Master* fMaster; | Master* fMaster; | ||||
SYNTH_T fSynth; | SYNTH_T fSynth; | ||||
CarlaConfig fConfig; | |||||
Config fConfig; | |||||
char* fDefaultState; | char* fDefaultState; | ||||
float fParameters[kParamCount]; | float fParameters[kParamCount]; | ||||
@@ -15,6 +15,9 @@ | |||||
#define INVALID ((int32_t)0xffffffff) | #define INVALID ((int32_t)0xffffffff) | ||||
#define MAX ((int32_t)0x7fffffff) | #define MAX ((int32_t)0x7fffffff) | ||||
namespace zyncarla { | |||||
QueueListItem::QueueListItem(void) | QueueListItem::QueueListItem(void) | ||||
:memory(0), size(0) | :memory(0), size(0) | ||||
{ | { | ||||
@@ -114,3 +117,5 @@ MultiQueue::~MultiQueue(void) | |||||
delete [] pool[i].memory; | delete [] pool[i].memory; | ||||
delete [] pool; | delete [] pool; | ||||
} | } | ||||
} |
@@ -13,6 +13,8 @@ | |||||
#include <atomic> | #include <atomic> | ||||
#include <cassert> | #include <cassert> | ||||
namespace zyncarla { | |||||
//XXX rename this thing | //XXX rename this thing | ||||
typedef struct QueueListItem qli_t; | typedef struct QueueListItem qli_t; | ||||
struct QueueListItem | struct QueueListItem | ||||
@@ -60,3 +62,5 @@ class MultiQueue | |||||
void write(qli_t *q) { m_msgs.write(q); } | void write(qli_t *q) { m_msgs.write(q); } | ||||
qli_t *read(void) { return m_msgs.read(); } | qli_t *read(void) { return m_msgs.read(); } | ||||
}; | }; | ||||
} |
@@ -19,6 +19,8 @@ | |||||
#define SUSTAIN_BIT 0x04 | #define SUSTAIN_BIT 0x04 | ||||
#define NOTE_MASK 0x03 | #define NOTE_MASK 0x03 | ||||
namespace zyncarla { | |||||
enum NoteStatus { | enum NoteStatus { | ||||
KEY_OFF = 0x00, | KEY_OFF = 0x00, | ||||
KEY_PLAYING = 0x01, | KEY_PLAYING = 0x01, | ||||
@@ -430,3 +432,5 @@ void NotePool::dump(void) | |||||
} | } | ||||
printf(">NotePool::dump\n"); | printf(">NotePool::dump\n"); | ||||
} | } | ||||
} |
@@ -17,6 +17,8 @@ | |||||
//Expected upper bound of synths given that max polyphony is hit | //Expected upper bound of synths given that max polyphony is hit | ||||
#define EXPECTED_USAGE 3 | #define EXPECTED_USAGE 3 | ||||
namespace zyncarla { | |||||
struct LegatoParams; | struct LegatoParams; | ||||
class NotePool | class NotePool | ||||
{ | { | ||||
@@ -145,3 +147,5 @@ class NotePool | |||||
void dump(void); | void dump(void); | ||||
}; | }; | ||||
} |
@@ -2,6 +2,8 @@ | |||||
#include <cstring> | #include <cstring> | ||||
#include <cstdio> | #include <cstdio> | ||||
namespace zyncarla { | |||||
ScratchString::ScratchString(void) | ScratchString::ScratchString(void) | ||||
{ | { | ||||
memset(c_str, 0, sizeof(c_str)); | memset(c_str, 0, sizeof(c_str)); | ||||
@@ -37,3 +39,5 @@ ScratchString ScratchString::operator+(const ScratchString s) | |||||
//{ | //{ | ||||
// return c_str; | // return c_str; | ||||
//} | //} | ||||
} |
@@ -1,6 +1,8 @@ | |||||
#pragma once | #pragma once | ||||
#define SCRATCH_SIZE 128 | #define SCRATCH_SIZE 128 | ||||
namespace zyncarla { | |||||
//Fixed Size String Substitute | //Fixed Size String Substitute | ||||
struct ScratchString | struct ScratchString | ||||
{ | { | ||||
@@ -15,3 +17,6 @@ struct ScratchString | |||||
char c_str[SCRATCH_SIZE]; | char c_str[SCRATCH_SIZE]; | ||||
}; | }; | ||||
} | |||||
@@ -20,6 +20,8 @@ | |||||
#include "../Misc/Util.h" | #include "../Misc/Util.h" | ||||
#include "AnalogFilter.h" | #include "AnalogFilter.h" | ||||
namespace zyncarla { | |||||
AnalogFilter::AnalogFilter(unsigned char Ftype, | AnalogFilter::AnalogFilter(unsigned char Ftype, | ||||
float Ffreq, | float Ffreq, | ||||
float Fq, | float Fq, | ||||
@@ -423,3 +425,5 @@ float AnalogFilter::H(float freq) | |||||
h = h / (x * x + y * y); | h = h / (x * x + y * y); | ||||
return powf(h, (stages + 1.0f) / 2.0f); | return powf(h, (stages + 1.0f) / 2.0f); | ||||
} | } | ||||
} |
@@ -19,6 +19,8 @@ | |||||
#include "../globals.h" | #include "../globals.h" | ||||
#include "Filter.h" | #include "Filter.h" | ||||
namespace zyncarla { | |||||
/**Implementation of Several analog filters (lowpass, highpass...) | /**Implementation of Several analog filters (lowpass, highpass...) | ||||
* Implemented with IIR filters | * Implemented with IIR filters | ||||
* Coefficients generated with "Cookbook formulae for audio EQ"*/ | * Coefficients generated with "Cookbook formulae for audio EQ"*/ | ||||
@@ -77,5 +79,6 @@ class AnalogFilter:public Filter | |||||
//(used to see if it needs interpolation) | //(used to see if it needs interpolation) | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -17,6 +17,8 @@ | |||||
#include <pthread.h> | #include <pthread.h> | ||||
#include "FFTwrapper.h" | #include "FFTwrapper.h" | ||||
namespace zyncarla { | |||||
static pthread_mutex_t *mutex = NULL; | static pthread_mutex_t *mutex = NULL; | ||||
FFTwrapper::FFTwrapper(int fftsize_) | FFTwrapper::FFTwrapper(int fftsize_) | ||||
@@ -91,3 +93,5 @@ void FFT_cleanup() | |||||
delete mutex; | delete mutex; | ||||
mutex = NULL; | mutex = NULL; | ||||
} | } | ||||
} |
@@ -17,6 +17,8 @@ | |||||
#include <complex> | #include <complex> | ||||
#include "../globals.h" | #include "../globals.h" | ||||
namespace zyncarla { | |||||
/**A wrapper for the FFTW library (Fast Fourier Transforms)*/ | /**A wrapper for the FFTW library (Fast Fourier Transforms)*/ | ||||
class FFTwrapper | class FFTwrapper | ||||
{ | { | ||||
@@ -58,4 +60,7 @@ FFTpolar(const _Tp& __rho, const _Tp& __theta = _Tp(0)) | |||||
} | } | ||||
void FFT_cleanup(); | void FFT_cleanup(); | ||||
} | |||||
#endif | #endif |
@@ -22,6 +22,8 @@ | |||||
#include "../Params/FilterParams.h" | #include "../Params/FilterParams.h" | ||||
#include "../Misc/Allocator.h" | #include "../Misc/Allocator.h" | ||||
namespace zyncarla { | |||||
Filter::Filter(unsigned int srate, int bufsize) | Filter::Filter(unsigned int srate, int bufsize) | ||||
: outgain(1.0f), | : outgain(1.0f), | ||||
samplerate(srate), | samplerate(srate), | ||||
@@ -65,3 +67,5 @@ float Filter::getrealfreq(float freqpitch) | |||||
{ | { | ||||
return powf(2.0f, freqpitch + 9.96578428f); //log2(1000)=9.95748f | return powf(2.0f, freqpitch + 9.96578428f); //log2(1000)=9.95748f | ||||
} | } | ||||
} |
@@ -16,6 +16,8 @@ | |||||
#include "../globals.h" | #include "../globals.h" | ||||
namespace zyncarla { | |||||
class Filter | class Filter | ||||
{ | { | ||||
public: | public: | ||||
@@ -53,4 +55,6 @@ class Filter | |||||
} | } | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -19,6 +19,8 @@ | |||||
#include "AnalogFilter.h" | #include "AnalogFilter.h" | ||||
#include "../Params/FilterParams.h" | #include "../Params/FilterParams.h" | ||||
namespace zyncarla { | |||||
FormantFilter::FormantFilter(const FilterParams *pars, Allocator *alloc, unsigned int srate, int bufsize) | FormantFilter::FormantFilter(const FilterParams *pars, Allocator *alloc, unsigned int srate, int bufsize) | ||||
:Filter(srate, bufsize), memory(*alloc) | :Filter(srate, bufsize), memory(*alloc) | ||||
{ | { | ||||
@@ -215,3 +217,5 @@ void FormantFilter::filterout(float *smp) | |||||
oldformantamp[j] = currentformants[j].amp; | oldformantamp[j] = currentformants[j].amp; | ||||
} | } | ||||
} | } | ||||
} |
@@ -17,6 +17,7 @@ | |||||
#include "../globals.h" | #include "../globals.h" | ||||
#include "Filter.h" | #include "Filter.h" | ||||
namespace zyncarla { | |||||
class FormantFilter:public Filter | class FormantFilter:public Filter | ||||
{ | { | ||||
@@ -55,4 +56,6 @@ class FormantFilter:public Filter | |||||
Allocator &memory; | Allocator &memory; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -24,6 +24,8 @@ | |||||
#include <err.h> | #include <err.h> | ||||
#endif | #endif | ||||
namespace zyncarla { | |||||
SVFilter::SVFilter(unsigned char Ftype, float Ffreq, float Fq, | SVFilter::SVFilter(unsigned char Ftype, float Ffreq, float Fq, | ||||
unsigned char Fstages, unsigned int srate, int bufsize) | unsigned char Fstages, unsigned int srate, int bufsize) | ||||
:Filter(srate, bufsize), | :Filter(srate, bufsize), | ||||
@@ -229,3 +231,5 @@ void SVFilter::filterout(float *smp) | |||||
for(int i = 0; i < buffersize; ++i) | for(int i = 0; i < buffersize; ++i) | ||||
smp[i] *= outgain; | smp[i] *= outgain; | ||||
} | } | ||||
} |
@@ -17,6 +17,8 @@ | |||||
#include "../globals.h" | #include "../globals.h" | ||||
#include "Filter.h" | #include "Filter.h" | ||||
namespace zyncarla { | |||||
class SVFilter:public Filter | class SVFilter:public Filter | ||||
{ | { | ||||
public: | public: | ||||
@@ -67,4 +69,6 @@ class SVFilter:public Filter | |||||
bool needsinterpolation, firsttime; | bool needsinterpolation, firsttime; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -24,6 +24,8 @@ | |||||
#include <err.h> | #include <err.h> | ||||
#endif | #endif | ||||
namespace zyncarla { | |||||
Unison::Unison(Allocator *alloc_, int update_period_samples_, float max_delay_sec_, float srate_f) | Unison::Unison(Allocator *alloc_, int update_period_samples_, float max_delay_sec_, float srate_f) | ||||
:unison_size(0), | :unison_size(0), | ||||
base_freq(1.0f), | base_freq(1.0f), | ||||
@@ -196,3 +198,5 @@ void Unison::updateUnisonData() | |||||
} | } | ||||
first_time = false; | first_time = false; | ||||
} | } | ||||
} |
@@ -18,6 +18,9 @@ | |||||
//how much the unison frequencies varies (always >= 1.0) | //how much the unison frequencies varies (always >= 1.0) | ||||
#define UNISON_FREQ_SPAN 2.0f | #define UNISON_FREQ_SPAN 2.0f | ||||
namespace zyncarla { | |||||
class Allocator; | class Allocator; | ||||
class Unison | class Unison | ||||
@@ -67,4 +70,7 @@ class Unison | |||||
float samplerate_f; | float samplerate_f; | ||||
Allocator &alloc; | Allocator &alloc; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -17,6 +17,8 @@ | |||||
#include "../Misc/Allocator.h" | #include "../Misc/Allocator.h" | ||||
#include "Alienwah.h" | #include "Alienwah.h" | ||||
namespace zyncarla { | |||||
using std::complex; | using std::complex; | ||||
#define rObject Alienwah | #define rObject Alienwah | ||||
@@ -34,17 +36,26 @@ rtosc::Ports Alienwah::ports = { | |||||
else | else | ||||
d.reply(d.loc, "i", o->Ppreset); | d.reply(d.loc, "i", o->Ppreset); | ||||
rEnd}, | rEnd}, | ||||
//Pvolume/Ppanning are common | |||||
rEffPar(Pfreq, 2, rShort("freq"), "Effect Frequency"), | |||||
rEffPar(Pfreqrnd, 3, rShort("rand"), "Frequency Randomness"), | |||||
rEffParVol(rDefault(127), rPresetsAt(3, 93)), | |||||
rEffParPan(), | |||||
rEffPar(Pfreq, 2, rShort("freq") rPresets(70, 73, 63, 25), | |||||
"Effect Frequency"), | |||||
rEffPar(Pfreqrnd, 3, rShort("rand"), rPreset(1, 106) rDefault(0), | |||||
"Frequency Randomness"), | |||||
rEffPar(PLFOtype, 4, rShort("shape"), | rEffPar(PLFOtype, 4, rShort("shape"), | ||||
rOptions(sine, triangle), "LFO Shape"), | |||||
rEffPar(PStereo, 5, rShort("stereo"), "Stereo Mode"), | |||||
rEffPar(Pdepth, 6, rShort("depth"), "LFO Depth"), | |||||
rEffPar(Pfeedback, 7, rShort("fb"), "Feedback"), | |||||
rEffPar(Pdelay, 8, rLinear(1,100), rShort("delay"), "Delay"), | |||||
rEffPar(Plrcross, 9, rShort("l/r"), "Left/Right Crossover"), | |||||
rEffPar(Pphase, 10, rShort("phase"), "Phase"), | |||||
rOptions(sine, triangle), rPresets(sine, sine, triangle, triangle), | |||||
"LFO Shape"), | |||||
rEffPar(PStereo, 5, rShort("stereo"), rPresets(62, 101, 100, 66), | |||||
"Stereo Mode"), | |||||
rEffPar(Pdepth, 6, rShort("depth"), rPresets(60, 60, 112, 101), | |||||
"LFO Depth"), | |||||
rEffPar(Pfeedback, 7, rShort("fb"), rPreset(3, 11), rDefault(105), | |||||
"Feedback"), | |||||
rEffPar(Pdelay, 8, rLinear(1,100), rPresets(25, 17, 31, 47), | |||||
rShort("delay"), "Delay"), | |||||
rEffPar(Plrcross, 9, rShort("l/r"), rDefault(0), "Left/Right Crossover"), | |||||
rEffPar(Pphase, 10, rShort("phase"), rDefault(64), rPreset(2, 42), | |||||
rPreset(3, 86), "Phase"), | |||||
}; | }; | ||||
#undef rBegin | #undef rBegin | ||||
#undef rEnd | #undef rEnd | ||||
@@ -257,3 +268,5 @@ unsigned char Alienwah::getpar(int npar) const | |||||
default: return 0; | default: return 0; | ||||
} | } | ||||
} | } | ||||
} |
@@ -20,6 +20,8 @@ | |||||
#define MAX_ALIENWAH_DELAY 100 | #define MAX_ALIENWAH_DELAY 100 | ||||
namespace zyncarla { | |||||
/**"AlienWah" Effect*/ | /**"AlienWah" Effect*/ | ||||
class Alienwah:public Effect | class Alienwah:public Effect | ||||
{ | { | ||||
@@ -58,4 +60,6 @@ class Alienwah:public Effect | |||||
int oldk; | int oldk; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -17,9 +17,10 @@ | |||||
#include "../Misc/Allocator.h" | #include "../Misc/Allocator.h" | ||||
#include "Chorus.h" | #include "Chorus.h" | ||||
#include <iostream> | #include <iostream> | ||||
using namespace std; | using namespace std; | ||||
namespace zyncarla { | |||||
#define rObject Chorus | #define rObject Chorus | ||||
#define rBegin [](const char *msg, rtosc::RtData &d) { | #define rBegin [](const char *msg, rtosc::RtData &d) { | ||||
#define rEnd } | #define rEnd } | ||||
@@ -38,17 +39,32 @@ rtosc::Ports Chorus::ports = { | |||||
rEnd}, | rEnd}, | ||||
//Pvolume/Ppanning are common | //Pvolume/Ppanning are common | ||||
rEffPar(Pfreq, 2, rShort("freq"), "Effect Frequency"), | |||||
rEffPar(Pfreqrnd, 3, rShort("rand"), "Frequency Randomness"), | |||||
rEffParVol(rDefault(64)), | |||||
rEffParPan(), | |||||
rEffPar(Pfreq, 2, rShort("freq"), | |||||
rPresets(50, 45, 29, 26, 29, 57, 33, 53, 40, 55), | |||||
"Effect Frequency"), | |||||
rEffPar(Pfreqrnd, 3, rShort("rand"), | |||||
rPreset(4, 117) rPreset(6, 34) rPreset(7, 34) rPreset(9, 105) | |||||
rDefault(0), "Frequency Randomness"), | |||||
rEffPar(PLFOtype, 4, rShort("shape"), | rEffPar(PLFOtype, 4, rShort("shape"), | ||||
rOptions(sine, tri), "LFO Shape"), | |||||
rEffPar(PStereo, 5, rShort("stereo"), "Stereo Mode"), | |||||
rEffPar(Pdepth, 6, rShort("depth"), "LFO Depth"), | |||||
rEffPar(Pdelay, 7, rShort("delay"), "Delay"), | |||||
rEffPar(Pfeedback,8, rShort("fb"), "Feedback"), | |||||
rEffPar(Plrcross, 9, rShort("l/r"), "Left/Right Crossover"), | |||||
rEffParTF(Pflangemode, 10, rShort("flange"), "Flange Mode"), | |||||
rEffParTF(Poutsub, 11, rShort("sub"), "Output Subtraction"), | |||||
rOptions(sine, tri), | |||||
rPresets(sine, sine, tri, sine, sine, sine, tri, tri, tri, sine) | |||||
"LFO Shape"), | |||||
rEffPar(PStereo, 5, rShort("stereo"), | |||||
rPresets(90, 98, 42, 42, 50, 60, 40, 94, 62), "Stereo Mode"), | |||||
rEffPar(Pdepth, 6, rShort("depth"), | |||||
rPresets(40, 56, 97, 115, 115, 23, 35, 35, 12), "LFO Depth"), | |||||
rEffPar(Pdelay, 7, rShort("delay"), | |||||
rPresets(85, 90, 95, 18, 9, 3, 3, 3, 19), "Delay"), | |||||
rEffPar(Pfeedback,8, rShort("fb"), | |||||
rPresets(64, 64, 90, 90, 31, 62, 109, 54, 97), "Feedback"), | |||||
rEffPar(Plrcross, 9, rShort("l/r"), rPresets(119, 19, 127, 127, 127), | |||||
rDefault(0), "Left/Right Crossover"), | |||||
rEffParTF(Pflangemode, 10, rShort("flange"), rDefault(false), | |||||
"Flange Mode"), | |||||
rEffParTF(Poutsub, 11, rShort("sub"), rPreset(4, true), rPreset(7, true), | |||||
rDefault(false), "Output Subtraction"), | |||||
}; | }; | ||||
#undef rBegin | #undef rBegin | ||||
#undef rEnd | #undef rEnd | ||||
@@ -294,3 +310,5 @@ unsigned char Chorus::getpar(int npar) const | |||||
default: return 0; | default: return 0; | ||||
} | } | ||||
} | } | ||||
} |
@@ -19,6 +19,8 @@ | |||||
#define MAX_CHORUS_DELAY 250.0f //ms | #define MAX_CHORUS_DELAY 250.0f //ms | ||||
namespace zyncarla { | |||||
/**Chorus and Flange effects*/ | /**Chorus and Flange effects*/ | ||||
class Chorus:public Effect | class Chorus:public Effect | ||||
{ | { | ||||
@@ -95,4 +97,6 @@ class Chorus:public Effect | |||||
float getdelay(float xlfo); | float getdelay(float xlfo); | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -19,6 +19,8 @@ | |||||
#include <rtosc/ports.h> | #include <rtosc/ports.h> | ||||
#include <rtosc/port-sugar.h> | #include <rtosc/port-sugar.h> | ||||
namespace zyncarla { | |||||
#define rObject Distorsion | #define rObject Distorsion | ||||
#define rBegin [](const char *msg, rtosc::RtData &d) { | #define rBegin [](const char *msg, rtosc::RtData &d) { | ||||
#define rEnd } | #define rEnd } | ||||
@@ -35,21 +37,29 @@ rtosc::Ports Distorsion::ports = { | |||||
else | else | ||||
d.reply(d.loc, "i", o->Ppreset); | d.reply(d.loc, "i", o->Ppreset); | ||||
rEnd}, | rEnd}, | ||||
//Pvolume/Ppanning are common | |||||
rEffPar(Plrcross, 2, rShort("l/r"), "Left/Right Crossover"), | |||||
rEffPar(Pdrive, 3, rShort("drive"), "Input amplification"), | |||||
rEffPar(Plevel, 4, rShort("output"), "Output amplification"), | |||||
rEffParVol(rDefault(127), rPresetsAt(2, 64, 64)), | |||||
rEffParPan(), | |||||
rEffPar(Plrcross, 2, rShort("l/r"), rDefault(35), "Left/Right Crossover"), | |||||
rEffPar(Pdrive, 3, rShort("drive"), rPresets(56, 29, 75, 85, 63, 88), | |||||
"Input amplification"), | |||||
rEffPar(Plevel, 4, rShort("output"), rPresets(70, 75, 80, 62, 75, 75), | |||||
"Output amplification"), | |||||
rEffPar(Ptype, 5, rShort("type"), | rEffPar(Ptype, 5, rShort("type"), | ||||
rOptions(Arctangent, Asymmetric, Pow, Sine, Quantisize, | rOptions(Arctangent, Asymmetric, Pow, Sine, Quantisize, | ||||
Zigzag, Limiter, Upper Limiter, Lower Limiter, | |||||
Inverse Limiter, Clip, Asym2, Pow2, sigmoid), | |||||
Zigzag, Limiter, Upper Limiter, Lower Limiter, | |||||
Inverse Limiter, Clip, Asym2, Pow2, sigmoid), | |||||
rPresets(Arctangent, Asymmetric, Zigzag, | |||||
Asymmetric, Pow, Quantisize), | |||||
"Distortion Shape"), | "Distortion Shape"), | ||||
rEffParTF(Pnegate, 6, rShort("neg"), "Negate Signal"), | |||||
rEffPar(Plpf, 7, rShort("lpf"), "Low Pass Cutoff"), | |||||
rEffPar(Phpf, 8, rShort("hpf"), "High Pass Cutoff"), | |||||
rEffParTF(Pstereo, 9, rShort("stereo"), "Stereo"), | |||||
rEffParTF(Pprefiltering, 10, rShort("p.filt"), | |||||
"Filtering before/after non-linearity"), | |||||
rEffParTF(Pnegate, 6, rShort("neg"), rDefault(false), "Negate Signal"), | |||||
rEffPar(Plpf, 7, rShort("lpf"), | |||||
rPreset(0, 96), rPreset(4, 55), rDefault(127), "Low Pass Cutoff"), | |||||
rEffPar(Phpf, 8, rShort("hpf"), | |||||
rPreset(2, 105), rPreset(3, 118), rDefault(0), "High Pass Cutoff"), | |||||
rEffParTF(Pstereo, 9, rShort("stereo"), | |||||
rPresets(false, false, true, true, false, true), "Stereo"), | |||||
rEffParTF(Pprefiltering, 10, rShort("p.filt"), rDefault(false), | |||||
"Filtering before/after non-linearity"), | |||||
{"waveform:", 0, 0, [](const char *, rtosc::RtData &d) | {"waveform:", 0, 0, [](const char *, rtosc::RtData &d) | ||||
{ | { | ||||
Distorsion &dd = *(Distorsion*)d.obj; | Distorsion &dd = *(Distorsion*)d.obj; | ||||
@@ -60,7 +70,8 @@ rtosc::Ports Distorsion::ports = { | |||||
for(int i=0; i<128; ++i) | for(int i=0; i<128; ++i) | ||||
buffer[i] = 2*(i/128.0)-1; | buffer[i] = 2*(i/128.0)-1; | ||||
waveShapeSmps(sizeof(buffer), buffer, dd.Ptype + 1, dd.Pdrive); | |||||
waveShapeSmps(sizeof(buffer)/sizeof(buffer[0]), buffer, | |||||
dd.Ptype + 1, dd.Pdrive); | |||||
for(int i=0; i<128; ++i) { | for(int i=0; i<128; ++i) { | ||||
arg_str[i] = 'f'; | arg_str[i] = 'f'; | ||||
@@ -292,3 +303,5 @@ unsigned char Distorsion::getpar(int npar) const | |||||
default: return 0; //in case of bogus parameter number | default: return 0; //in case of bogus parameter number | ||||
} | } | ||||
} | } | ||||
} |
@@ -16,6 +16,8 @@ | |||||
#include "Effect.h" | #include "Effect.h" | ||||
namespace zyncarla { | |||||
/**Distortion Effect*/ | /**Distortion Effect*/ | ||||
class Distorsion:public Effect | class Distorsion:public Effect | ||||
{ | { | ||||
@@ -50,4 +52,6 @@ class Distorsion:public Effect | |||||
class AnalogFilter * lpfl, *lpfr, *hpfl, *hpfr; | class AnalogFilter * lpfl, *lpfr, *hpfl, *hpfr; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -20,6 +20,8 @@ | |||||
#include <rtosc/ports.h> | #include <rtosc/ports.h> | ||||
#include <rtosc/port-sugar.h> | #include <rtosc/port-sugar.h> | ||||
namespace zyncarla { | |||||
#define rObject DynamicFilter | #define rObject DynamicFilter | ||||
#define rBegin [](const char *msg, rtosc::RtData &d) { | #define rBegin [](const char *msg, rtosc::RtData &d) { | ||||
#define rEnd } | #define rEnd } | ||||
@@ -34,16 +36,24 @@ rtosc::Ports DynamicFilter::ports = { | |||||
else | else | ||||
d.reply(d.loc, "i", o->Ppreset); | d.reply(d.loc, "i", o->Ppreset); | ||||
rEnd}, | rEnd}, | ||||
//Pvolume/Ppanning are common | |||||
rEffPar(Pfreq, 2, rShort("freq"), "Effect Frequency"), | |||||
rEffPar(Pfreqrnd, 3, rShort("rand"), "Frequency Randomness"), | |||||
rEffPar(PLFOtype, 4, rShort("shape"), | |||||
rOptions(sin, tri), "LFO Shape"), | |||||
rEffPar(PStereo, 5, rShort("stereo"), "Stereo Mode"), | |||||
rEffPar(Pdepth, 6, rShort("depth"), "LFO Depth"), | |||||
rEffPar(Pampsns, 7, rShort("sense"), "how the filter varies according to the input amplitude"), | |||||
rEffPar(Pampsnsinv, 8, rShort("sns.inv"), "Sense Inversion"), | |||||
rEffPar(Pampsmooth, 9, rShort("smooth"), "how smooth the input amplitude changes the filter"), | |||||
rEffParVol(rDefault(110), rPreset(2, 110), rPreset(4, 127)), | |||||
rEffParPan(), | |||||
rEffPar(Pfreq, 2, rShort("freq"), rPresets(80, 70, 30, 80, 50), | |||||
"Effect Frequency"), | |||||
rEffPar(Pfreqrnd, 3, rShort("rand"), rDefault(0), | |||||
"Frequency Randomness"), | |||||
rEffPar(PLFOtype, 4, rShort("shape"), rOptions(sin, tri), rDefault(sin), | |||||
"LFO Shape"), | |||||
rEffPar(PStereo, 5, rShort("stereo"), rPresets(64, 80, 50, 64, 96), | |||||
"Stereo Mode"), | |||||
rEffPar(Pdepth, 6, rShort("depth"), rPresets(0, 70, 80, 0, 64), | |||||
"LFO Depth"), | |||||
rEffPar(Pampsns, 7, rShort("sense"), | |||||
rPreset(0, 90) rPreset(3, 64) rDefault(0), | |||||
"how the filter varies according to the input amplitude"), | |||||
rEffPar(Pampsnsinv, 8, rShort("sns.inv"), rDefault(0), "Sense Inversion"), | |||||
rEffPar(Pampsmooth, 9, rShort("smooth"), rDefault(60), | |||||
"how smooth the input amplitude changes the filter"), | |||||
}; | }; | ||||
#undef rBegin | #undef rBegin | ||||
#undef rEnd | #undef rEnd | ||||
@@ -351,3 +361,5 @@ unsigned char DynamicFilter::getpar(int npar) const | |||||
default: return 0; | default: return 0; | ||||
} | } | ||||
} | } | ||||
} |
@@ -17,6 +17,8 @@ | |||||
#include "Effect.h" | #include "Effect.h" | ||||
#include "EffectLFO.h" | #include "EffectLFO.h" | ||||
namespace zyncarla { | |||||
/**DynamicFilter Effect*/ | /**DynamicFilter Effect*/ | ||||
class DynamicFilter:public Effect | class DynamicFilter:public Effect | ||||
{ | { | ||||
@@ -56,4 +58,6 @@ class DynamicFilter:public Effect | |||||
float ms1, ms2, ms3, ms4; //mean squares | float ms1, ms2, ms3, ms4; //mean squares | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -18,6 +18,8 @@ | |||||
#include "../DSP/AnalogFilter.h" | #include "../DSP/AnalogFilter.h" | ||||
#include "../Misc/Allocator.h" | #include "../Misc/Allocator.h" | ||||
namespace zyncarla { | |||||
using rtosc::RtData; | using rtosc::RtData; | ||||
#define rObject EQ | #define rObject EQ | ||||
#define rBegin [](const char *msg, RtData &d) {\ | #define rBegin [](const char *msg, RtData &d) {\ | ||||
@@ -78,8 +80,8 @@ rtosc::Ports EQ::ports = { | |||||
memset(b, 0, sizeof(b)); | memset(b, 0, sizeof(b)); | ||||
eq->getFilter(a,b); | eq->getFilter(a,b); | ||||
char type[MAX_EQ_BANDS*MAX_FILTER_STAGES*3*2+1] = {0}; | |||||
rtosc_arg_t val[MAX_EQ_BANDS*MAX_FILTER_STAGES*3*2] = {0}; | |||||
char type[MAX_EQ_BANDS*MAX_FILTER_STAGES*3*2+1] = {}; | |||||
rtosc_arg_t val[MAX_EQ_BANDS*MAX_FILTER_STAGES*3*2] = {}; | |||||
for(int i=0; i<MAX_EQ_BANDS*MAX_FILTER_STAGES*3; ++i) { | for(int i=0; i<MAX_EQ_BANDS*MAX_FILTER_STAGES*3; ++i) { | ||||
int stride = MAX_EQ_BANDS*MAX_FILTER_STAGES*3; | int stride = MAX_EQ_BANDS*MAX_FILTER_STAGES*3; | ||||
type[i] = type[i+stride] = 'f'; | type[i] = type[i+stride] = 'f'; | ||||
@@ -297,3 +299,5 @@ void EQ::getFilter(float *a, float *b) const | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} |
@@ -16,6 +16,8 @@ | |||||
#include "Effect.h" | #include "Effect.h" | ||||
namespace zyncarla { | |||||
/**EQ Effect*/ | /**EQ Effect*/ | ||||
class EQ:public Effect | class EQ:public Effect | ||||
{ | { | ||||
@@ -53,4 +55,6 @@ class EQ:public Effect | |||||
} filter[MAX_EQ_BANDS]; | } filter[MAX_EQ_BANDS]; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -21,6 +21,8 @@ | |||||
#define MAX_DELAY 2 | #define MAX_DELAY 2 | ||||
namespace zyncarla { | |||||
#define rObject Echo | #define rObject Echo | ||||
#define rBegin [](const char *msg, rtosc::RtData &d) { | #define rBegin [](const char *msg, rtosc::RtData &d) { | ||||
#define rEnd } | #define rEnd } | ||||
@@ -37,12 +39,23 @@ rtosc::Ports Echo::ports = { | |||||
else | else | ||||
d.reply(d.loc, "i", o->Ppreset); | d.reply(d.loc, "i", o->Ppreset); | ||||
rEnd}, | rEnd}, | ||||
//Pvolume/Ppanning are common | |||||
rEffPar(Pdelay, 2, rShort("delay"), "Length of Echo"), | |||||
rEffPar(Plrdelay, 3, rShort("lr delay"), "Difference In Left/Right Delay"), | |||||
rEffPar(Plrcross, 4, rShort("cross"), "Left/Right Crossover"), | |||||
rEffPar(Pfb, 5, rShort("feedback"), "Echo Feedback"), | |||||
rEffPar(Phidamp, 6, rShort("damp"), "Dampen High Frequencies"), | |||||
rEffParVol(rDefault(67), rPresetsAt(6, 81, 81, 62)), | |||||
rEffParPan(rPresetsAt(2, 75, 60, 60, 64, 60, 60, 64)), | |||||
rEffPar(Pdelay, 2, rShort("delay"), | |||||
rPresets(35, 21, 60, 44, 102, 44, 46, 26, 28), | |||||
"Length of Echo"), | |||||
rEffPar(Plrdelay, 3, rShort("lr delay"), | |||||
rPresetsAt(4, 50, 17, 118, 100, 64), rDefault(64), | |||||
"Difference In Left/Right Delay"), | |||||
rEffPar(Plrcross, 4, rShort("cross"), | |||||
rPresetsAt(5, 0, 100, 127, 100), rDefault(30), | |||||
"Left/Right Crossover"), | |||||
rEffPar(Pfb, 5, rShort("feedback"), | |||||
rPresets(59, 59, 59, 0, 82, 82, 68, 67, 90), | |||||
"Echo Feedback"), | |||||
rEffPar(Phidamp, 6, rShort("damp"), | |||||
rPresets(0, 0, 10, 0, 48, 24, 18, 36, 55), | |||||
"Dampen High Frequencies"), | |||||
}; | }; | ||||
#undef rBegin | #undef rBegin | ||||
#undef rEnd | #undef rEnd | ||||
@@ -145,7 +158,11 @@ void Echo::setvolume(unsigned char _Pvolume) | |||||
Pvolume = _Pvolume; | Pvolume = _Pvolume; | ||||
if(insertion == 0) { | if(insertion == 0) { | ||||
outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f; | |||||
if (Pvolume == 0) { | |||||
outvolume = 0.0f; | |||||
} else { | |||||
outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f; | |||||
} | |||||
volume = 1.0f; | volume = 1.0f; | ||||
} | } | ||||
else | else | ||||
@@ -251,3 +268,5 @@ unsigned char Echo::getpar(int npar) const | |||||
default: return 0; // in case of bogus parameter number | default: return 0; // in case of bogus parameter number | ||||
} | } | ||||
} | } | ||||
} |
@@ -17,6 +17,8 @@ | |||||
#include "Effect.h" | #include "Effect.h" | ||||
#include "../Misc/Stereo.h" | #include "../Misc/Stereo.h" | ||||
namespace zyncarla { | |||||
/**Echo Effect*/ | /**Echo Effect*/ | ||||
class Echo:public Effect | class Echo:public Effect | ||||
{ | { | ||||
@@ -94,4 +96,6 @@ class Echo:public Effect | |||||
Stereo<int> ndelta; | Stereo<int> ndelta; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -17,6 +17,8 @@ | |||||
#include "../Params/FilterParams.h" | #include "../Params/FilterParams.h" | ||||
#include <cmath> | #include <cmath> | ||||
namespace zyncarla { | |||||
EffectParams::EffectParams(Allocator &alloc_, bool insertion_, float *efxoutl_, float *efxoutr_, | EffectParams::EffectParams(Allocator &alloc_, bool insertion_, float *efxoutl_, float *efxoutr_, | ||||
unsigned char Ppreset_, unsigned int srate_, int bufsize_, FilterParams *filterpars_, | unsigned char Ppreset_, unsigned int srate_, int bufsize_, FilterParams *filterpars_, | ||||
bool filterprotect_) | bool filterprotect_) | ||||
@@ -63,3 +65,5 @@ void Effect::setlrcross(char Plrcross_) | |||||
Plrcross = Plrcross_; | Plrcross = Plrcross_; | ||||
lrcross = (float)Plrcross / 127.0f; | lrcross = (float)Plrcross / 127.0f; | ||||
} | } | ||||
} |
@@ -19,14 +19,15 @@ | |||||
#include "../Params/FilterParams.h" | #include "../Params/FilterParams.h" | ||||
#include "../Misc/Stereo.h" | #include "../Misc/Stereo.h" | ||||
class FilterParams; | |||||
class Allocator; | |||||
// bug: the effect parameters can currently be set, but such values | |||||
// will not be saved into XML files | |||||
#ifndef rEffPar | #ifndef rEffPar | ||||
#define rEffPar(name, idx, ...) \ | #define rEffPar(name, idx, ...) \ | ||||
{STRINGIFY(name) "::i", rProp(parameter) DOC(__VA_ARGS__), NULL, rEffParCb(idx)} | |||||
{STRINGIFY(name) "::i", rProp(parameter) rDefaultDepends(preset) \ | |||||
DOC(__VA_ARGS__), NULL, rEffParCb(idx)} | |||||
#define rEffParTF(name, idx, ...) \ | #define rEffParTF(name, idx, ...) \ | ||||
{STRINGIFY(name) "::T:F", rProp(parameter) DOC(__VA_ARGS__), NULL, rEffParTFCb(idx)} | |||||
{STRINGIFY(name) "::T:F", rProp(parameter) rDefaultDepends(preset) \ | |||||
DOC(__VA_ARGS__), NULL, rEffParTFCb(idx)} | |||||
#define rEffParCb(idx) \ | #define rEffParCb(idx) \ | ||||
[](const char *msg, rtosc::RtData &d) {\ | [](const char *msg, rtosc::RtData &d) {\ | ||||
rObject &obj = *(rObject*)d.obj; \ | rObject &obj = *(rObject*)d.obj; \ | ||||
@@ -43,6 +44,32 @@ class Allocator; | |||||
d.reply(d.loc, obj.getpar(idx)?"T":"F");} | d.reply(d.loc, obj.getpar(idx)?"T":"F");} | ||||
#endif | #endif | ||||
#define rEffParCommon(pname, rshort, rdoc, idx, ...) \ | |||||
{STRINGIFY(pname) "::i", rProp(parameter) rLinear(0,127) \ | |||||
rShort(rshort) rDoc(rdoc), \ | |||||
0, \ | |||||
[](const char *msg, rtosc::RtData &d) \ | |||||
{ \ | |||||
rObject& eff = *(rObject*)d.obj; \ | |||||
if(!rtosc_narguments(msg)) \ | |||||
d.reply(d.loc, "i", eff.getpar(idx)); \ | |||||
else { \ | |||||
eff.changepar(0, rtosc_argument(msg, 0).i); \ | |||||
d.broadcast(d.loc, "i", eff.getpar(idx)); \ | |||||
} \ | |||||
}} | |||||
#define rEffParVol(...) rEffParCommon(Pvolume, "amt", "amount of effect", 0, \ | |||||
__VA_ARGS__) | |||||
#define rEffParPan(...) rEffParCommon(Ppanning, "pan", "panning", 1, \ | |||||
__VA_ARGS__) | |||||
namespace zyncarla { | |||||
class FilterParams; | |||||
class Allocator; | |||||
struct EffectParams | struct EffectParams | ||||
{ | { | ||||
/** | /** | ||||
@@ -154,4 +181,6 @@ class Effect | |||||
} | } | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -17,6 +17,8 @@ | |||||
#include <cmath> | #include <cmath> | ||||
#include "globals.h" | #include "globals.h" | ||||
namespace zyncarla { | |||||
EffectLFO::EffectLFO(float srate_f, float bufsize_f) | EffectLFO::EffectLFO(float srate_f, float bufsize_f) | ||||
:Pfreq(40), | :Pfreq(40), | ||||
Prandomness(0), | Prandomness(0), | ||||
@@ -104,3 +106,5 @@ void EffectLFO::effectlfoout(float *outl, float *outr) | |||||
} | } | ||||
*outr = (out + 1.0f) * 0.5f; | *outr = (out + 1.0f) * 0.5f; | ||||
} | } | ||||
} |
@@ -14,6 +14,8 @@ | |||||
#ifndef EFFECT_LFO_H | #ifndef EFFECT_LFO_H | ||||
#define EFFECT_LFO_H | #define EFFECT_LFO_H | ||||
namespace zyncarla { | |||||
/**LFO for some of the Effect objects | /**LFO for some of the Effect objects | ||||
* \todo see if this should inherit LFO*/ | * \todo see if this should inherit LFO*/ | ||||
class EffectLFO | class EffectLFO | ||||
@@ -41,4 +43,6 @@ class EffectLFO | |||||
float buffersize_f; | float buffersize_f; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -16,7 +16,6 @@ | |||||
#include <iostream> | #include <iostream> | ||||
#include <cassert> | #include <cassert> | ||||
#include "EffectMgr.h" | #include "EffectMgr.h" | ||||
#include "Effect.h" | #include "Effect.h" | ||||
#include "Alienwah.h" | #include "Alienwah.h" | ||||
@@ -32,21 +31,23 @@ | |||||
#include "../Params/FilterParams.h" | #include "../Params/FilterParams.h" | ||||
#include "../Misc/Allocator.h" | #include "../Misc/Allocator.h" | ||||
namespace zyncarla { | |||||
#define rObject EffectMgr | #define rObject EffectMgr | ||||
#define rSubtype(name) \ | #define rSubtype(name) \ | ||||
{STRINGIFY(name)"/", NULL, &name::ports,\ | {STRINGIFY(name)"/", NULL, &name::ports,\ | ||||
[](const char *msg, rtosc::RtData &data){\ | [](const char *msg, rtosc::RtData &data){\ | ||||
rObject &o = *(rObject*)data.obj; \ | rObject &o = *(rObject*)data.obj; \ | ||||
data.obj = o.efx; \ | |||||
if(!dynamic_cast<name*>(o.efx)) \ | |||||
data.obj = dynamic_cast<name*>(o.efx); \ | |||||
if(!data.obj) \ | |||||
return; \ | return; \ | ||||
SNIP \ | SNIP \ | ||||
name::ports.dispatch(msg, data); \ | name::ports.dispatch(msg, data); \ | ||||
}} | }} | ||||
static const rtosc::Ports local_ports = { | static const rtosc::Ports local_ports = { | ||||
rSelf(EffectMgr), | |||||
rSelf(EffectMgr, rEnabledByCondition(self-enabled)), | |||||
rPaste, | rPaste, | ||||
rEnabledCondition(self-enabled, obj->geteffect()), | |||||
rRecurp(filterpars, "Filter Parameter for Dynamic Filter"), | rRecurp(filterpars, "Filter Parameter for Dynamic Filter"), | ||||
{"Pvolume::i", rProp(parameter) rLinear(0,127) rShort("amt") rDoc("amount of effect"), | {"Pvolume::i", rProp(parameter) rLinear(0,127) rShort("amt") rDoc("amount of effect"), | ||||
0, | 0, | ||||
@@ -93,7 +94,8 @@ static const rtosc::Ports local_ports = { | |||||
d.broadcast(d.loc, "i", eff->geteffectparrt(atoi(mm))); | d.broadcast(d.loc, "i", eff->geteffectparrt(atoi(mm))); | ||||
} | } | ||||
}}, | }}, | ||||
{"preset::i", rProp(parameter) rProp(alias) rDoc("Effect Preset Selector"), NULL, | |||||
{"preset::i", rProp(parameter) rProp(alias) rDoc("Effect Preset Selector") | |||||
rDefault(0), NULL, | |||||
[](const char *msg, rtosc::RtData &d) | [](const char *msg, rtosc::RtData &d) | ||||
{ | { | ||||
char loc[1024]; | char loc[1024]; | ||||
@@ -129,18 +131,10 @@ static const rtosc::Ports local_ports = { | |||||
eq->getFilter(a,b); | eq->getFilter(a,b); | ||||
d.reply(d.loc, "bb", sizeof(a), a, sizeof(b), b); | d.reply(d.loc, "bb", sizeof(a), a, sizeof(b), b); | ||||
}}, | }}, | ||||
{"efftype::i", rOptions(Disabled, Reverb, Echo, Chorus, | |||||
Phaser, Alienwah, Distorsion, EQ, DynFilter) | |||||
rProp(parameter) rDoc("Get Effect Type"), NULL, | |||||
[](const char *m, rtosc::RtData &d) | |||||
{ | |||||
EffectMgr *eff = (EffectMgr*)d.obj; | |||||
if(rtosc_narguments(m)) { | |||||
eff->changeeffectrt(rtosc_argument(m,0).i); | |||||
d.broadcast(d.loc, "i", eff->nefx); | |||||
} else | |||||
d.reply(d.loc, "i", eff->nefx); | |||||
}}, | |||||
{"efftype::i:c:S", rOptions(Disabled, Reverb, Echo, Chorus, | |||||
Phaser, Alienwah, Distortion, EQ, DynFilter) rDefault(Disabled) | |||||
rProp(parameter) rDoc("Get Effect Type"), NULL, | |||||
rCOptionCb(obj->nefx, obj->changeeffectrt(var))}, | |||||
{"efftype:b", rProp(internal) rDoc("Pointer swap EffectMgr"), NULL, | {"efftype:b", rProp(internal) rDoc("Pointer swap EffectMgr"), NULL, | ||||
[](const char *msg, rtosc::RtData &d) | [](const char *msg, rtosc::RtData &d) | ||||
{ | { | ||||
@@ -472,7 +466,12 @@ void EffectMgr::add2XML(XMLwrapper& xml) | |||||
xml.beginbranch("EFFECT_PARAMETERS"); | xml.beginbranch("EFFECT_PARAMETERS"); | ||||
for(int n = 0; n < 128; ++n) { | for(int n = 0; n < 128; ++n) { | ||||
int par = geteffectpar(n); | |||||
int par = 0; | |||||
if(efx) | |||||
par = efx->getpar(n); | |||||
else if(n<128) | |||||
par = settings[n]; | |||||
if(par == 0) | if(par == 0) | ||||
continue; | continue; | ||||
xml.beginbranch("par_no", n); | xml.beginbranch("par_no", n); | ||||
@@ -515,3 +514,5 @@ void EffectMgr::getfromXML(XMLwrapper& xml) | |||||
} | } | ||||
cleanup(); | cleanup(); | ||||
} | } | ||||
} |
@@ -16,14 +16,16 @@ | |||||
#include <pthread.h> | #include <pthread.h> | ||||
#include "../Params/FilterParams.h" | |||||
#include "../Params/Presets.h" | |||||
namespace zyncarla { | |||||
class Effect; | class Effect; | ||||
class FilterParams; | class FilterParams; | ||||
class XMLwrapper; | class XMLwrapper; | ||||
class Allocator; | class Allocator; | ||||
#include "../Params/FilterParams.h" | |||||
#include "../Params/Presets.h" | |||||
/** Effect manager, an interface between the program and effects */ | /** Effect manager, an interface between the program and effects */ | ||||
class EffectMgr:public Presets | class EffectMgr:public Presets | ||||
{ | { | ||||
@@ -75,6 +77,30 @@ class EffectMgr:public Presets | |||||
//Parameters Prior to initialization | //Parameters Prior to initialization | ||||
char preset; | char preset; | ||||
/** | |||||
* When loading an effect from XML the child effect cannot be loaded | |||||
* directly as it would require access to the realtime memory pool, | |||||
* which cannot be done outside of the realtime thread. | |||||
* Therefore, parameters are loaded to this array which can then be used | |||||
* to construct the full effect (via init()) once the object is in the | |||||
* realtime context. | |||||
* | |||||
* Additionally this structure is used in the case of pasting effects as | |||||
* pasted effect object are *not* fully initialized when they're put on | |||||
* the middleware -> backend ringbuffer, but settings has the values | |||||
* loaded from the XML serialization. | |||||
* The settings values can be pasted once they're on the realtime thread | |||||
* and then they can be applied. | |||||
* | |||||
* The requirement that the realtime memory pool is used to create the | |||||
* effect is in place as it is possible to change the effect type in the | |||||
* realtime thread and thus the new effect would draw from the realtime | |||||
* memory pool and the old object would be expected to be freed to the | |||||
* realtime memory pool. | |||||
* | |||||
* See also: PresetExtractor.cpp | |||||
*/ | |||||
char settings[128]; | char settings[128]; | ||||
bool dryonly; | bool dryonly; | ||||
@@ -82,4 +108,6 @@ class EffectMgr:public Presets | |||||
const SYNTH_T &synth; | const SYNTH_T &synth; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -21,9 +21,10 @@ | |||||
#include <rtosc/port-sugar.h> | #include <rtosc/port-sugar.h> | ||||
#include "../Misc/Allocator.h" | #include "../Misc/Allocator.h" | ||||
#include "Phaser.h" | #include "Phaser.h" | ||||
using namespace std; | using namespace std; | ||||
namespace zyncarla { | |||||
#define rObject Phaser | #define rObject Phaser | ||||
#define rBegin [](const char *msg, rtosc::RtData &d) { | #define rBegin [](const char *msg, rtosc::RtData &d) { | ||||
#define rEnd } | #define rEnd } | ||||
@@ -36,7 +37,8 @@ using namespace std; | |||||
d.reply(d.loc, "i", p.P##pname); \ | d.reply(d.loc, "i", p.P##pname); \ | ||||
rEnd | rEnd | ||||
#define rParamPhaser(name, ...) \ | #define rParamPhaser(name, ...) \ | ||||
{STRINGIFY(P##name) "::i", rProp(parameter) rMap(min, 0) rMap(max, 127) DOC(__VA_ARGS__), NULL, ucharParamCb(name)} | |||||
{STRINGIFY(P##name) "::i", rProp(parameter) rMap(min, 0) rMap(max, 127) \ | |||||
rDefaultDepends(preset) DOC(__VA_ARGS__), NULL, ucharParamCb(name)} | |||||
rtosc::Ports Phaser::ports = { | rtosc::Ports Phaser::ports = { | ||||
{"preset::i", rProp(parameter) | {"preset::i", rProp(parameter) | ||||
@@ -52,23 +54,52 @@ rtosc::Ports Phaser::ports = { | |||||
else | else | ||||
d.reply(d.loc, "i", o->Ppreset); | d.reply(d.loc, "i", o->Ppreset); | ||||
rEnd}, | rEnd}, | ||||
//Pvolume/Ppanning are common | |||||
rEffPar(lfo.Pfreq, 2, rShort("freq"), "LFO frequency"), | |||||
rEffPar(lfo.Prandomness, 3, rShort("rnd."), "LFO randomness"), | |||||
rEffParVol(rDefault(64), rPreset(3, 39), rPreset(10, 25)), | |||||
rEffParPan(), | |||||
rEffPar(lfo.Pfreq, 2, rShort("freq"), | |||||
rPresets(36, 35, 31, 22, 20, 53, 14, 14, 9, 14, 127, 1), | |||||
"LFO frequency"), | |||||
rEffPar(lfo.Prandomness, 3, rShort("rnd."), | |||||
rPreset(5, 100), rPreset(7, 5), rPresetsAt(9, 10, 10, 10), | |||||
rDefault(0), "LFO randomness"), | |||||
rEffPar(lfo.PLFOtype, 4, rShort("type"), | rEffPar(lfo.PLFOtype, 4, rShort("type"), | ||||
rOptions(sine, tri), "lfo shape"), | |||||
rEffPar(lfo.Pstereo, 5, rShort("stereo"), "Left/right channel phase shift"), | |||||
rEffPar(Pdepth, 6, rShort("depth"), "LFP depth"), | |||||
rEffPar(Pfb, 7, rShort("fb"), "Feedback"), | |||||
rEffPar(Pstages, 8, rLinear(1,12), rShort("stages"), ""), | |||||
rParamPhaser(lrcross, rShort("cross"), "Channel routing"), | |||||
rParamPhaser(offset, rShort("off"), "Offset"), | |||||
rEffParTF(Poutsub, 10, rShort("sub"), "Invert output"), | |||||
rParamPhaser(phase, rShort("phase"), ""), | |||||
rParamPhaser(width, rShort("width"), ""), | |||||
rEffParTF(Phyper, 12, rShort("hyp."), "Square the LFO"), | |||||
rEffPar(Pdistortion, 13, rShort("distort"), "Distortion"), | |||||
rEffParTF(Panalog, 14, rShort("analog"), "Use analog phaser"), | |||||
rPreset(4, tri), rPresetsAt(6, tri, tri), rPreset(11, tri), | |||||
rDefault(sine), | |||||
rOptions(sine, tri), "lfo shape"), | |||||
rEffPar(lfo.Pstereo, 5, rShort("stereo"), | |||||
rPresetsAt(1, 88, 66, 66, 110, 58), rDefault(64), | |||||
"Left/right channel phase shift"), | |||||
rEffPar(Pdepth, 6, rShort("depth"), | |||||
rPresets(110, 40, 68, 67, 67, 37, 64, 70, 60, 45, 25, 70), | |||||
"LFP depth"), | |||||
rEffPar(Pfb, 7, rShort("fb"), | |||||
rPresets(64, 64, 107, 10, 78, 78, 40, 40, 40, 80, 16, 40), | |||||
"Feedback"), | |||||
rEffPar(Pstages, 8, rLinear(1,12), rShort("stages"), | |||||
rPresets(1, 3, 2, 5, 10, 3, 4, 6, 8, 7, 8, 12), | |||||
""), | |||||
rParamPhaser(lrcross, rShort("cross"), | |||||
rPresetsAt(6, 10, 10, 10, 10, 100, 10) rDefault(0), | |||||
"Channel routing"), | |||||
rParamPhaser(offset, rShort("off"), | |||||
rPresetsAt(6, 10, 10, 10, 10, 100, 10) rDefault(0), | |||||
"Offset"), | |||||
rEffParTF(Poutsub, 10, rShort("sub"), | |||||
rPreset(3, true), rPreset(9, true), rDefault(false), | |||||
"Invert output"), | |||||
rParamPhaser(phase, rShort("phase"), | |||||
rPresets(20, 20, 20, 20, 20, 20, 110, 110, 40, 110, 25, 110), ""), | |||||
rParamPhaser(width, rShort("width"), | |||||
rPresets(20, 20, 20, 20, 20, 20, 110, 110, 40, 110, 25, 110), ""), | |||||
rEffParTF(Phyper, 12, rShort("hyp."), | |||||
rPresetsAt(6, true, true, false, true, false, true), | |||||
rDefault(false), "Square the LFO"), | |||||
rEffPar(Pdistortion, 13, rShort("distort"), | |||||
rPresetsAt(6, 20, 20, 20, 20, 20, 20), rDefault(0), | |||||
"Distortion"), | |||||
rEffParTF(Panalog, 14, rShort("analog"), | |||||
rPresetsAt(6, true, true, true, true, true, true), rDefault(false), | |||||
"Use analog phaser"), | |||||
}; | }; | ||||
#undef rBegin | #undef rBegin | ||||
#undef rEnd | #undef rEnd | ||||
@@ -496,3 +527,5 @@ unsigned char Phaser::getpar(int npar) const | |||||
default: return 0; | default: return 0; | ||||
} | } | ||||
} | } | ||||
} |
@@ -23,6 +23,8 @@ | |||||
#define MAX_PHASER_STAGES 12 | #define MAX_PHASER_STAGES 12 | ||||
namespace zyncarla { | |||||
class Phaser:public Effect | class Phaser:public Effect | ||||
{ | { | ||||
public: | public: | ||||
@@ -87,4 +89,6 @@ class Phaser:public Effect | |||||
float applyPhase(float x, float g, float *old); | float applyPhase(float x, float g, float *old); | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -20,6 +20,8 @@ | |||||
#include <rtosc/ports.h> | #include <rtosc/ports.h> | ||||
#include <rtosc/port-sugar.h> | #include <rtosc/port-sugar.h> | ||||
namespace zyncarla { | |||||
#define rObject Reverb | #define rObject Reverb | ||||
#define rBegin [](const char *msg, rtosc::RtData &d) { | #define rBegin [](const char *msg, rtosc::RtData &d) { | ||||
#define rEnd } | #define rEnd } | ||||
@@ -37,18 +39,38 @@ rtosc::Ports Reverb::ports = { | |||||
else | else | ||||
d.reply(d.loc, "i", o->Ppreset); | d.reply(d.loc, "i", o->Ppreset); | ||||
rEnd}, | rEnd}, | ||||
//Pvolume/Ppanning are common | |||||
rEffPar(Ptime, 2, rShort("time"), "Length of Reverb"), | |||||
rEffPar(Pidelay, 3, rShort("i.time"), "Delay for first impulse"), | |||||
rEffPar(Pidelayfb,4, rShort("i.fb"), "Feedback for first impulse"), | |||||
rEffPar(Plpf, 7, rShort("lpf"), "Low pass filter"), | |||||
rEffPar(Phpf, 8, rShort("hpf"), "High pass filter"), | |||||
rEffPar(Plohidamp,9, rShort("damp"), "Dampening"), | |||||
rEffParVol(rDefault(90), rPresets(80, 80, 80), | |||||
rPresetsAt(5, 100, 100, 110, 85, 95)), | |||||
rEffParPan(rPreset(8, 80)), | |||||
rEffPar(Ptime, 2, rShort("time"), | |||||
rPresets(63, 69, 69, 51, 53, 33, 21, 14, 84, 26, 40, 93, 111), | |||||
"Length of Reverb"), | |||||
rEffPar(Pidelay, 3, rShort("i.time"), | |||||
rPresets(24, 35, 24, 10, 20, 0, 26, 0, 20, 60, 88, 15, 30), | |||||
"Delay for first impulse"), | |||||
rEffPar(Pidelayfb,4, rShort("i.fb"), rPresetsAt(8, 42, 71, 71), rDefault(0), | |||||
"Feedback for first impulse"), | |||||
rEffPar(Plpf, 7, rShort("lpf"), | |||||
rPreset(1, 85), rPresetsAt(62, 127, 51, 114, 114, 114), | |||||
rDefault(127), "Low pass filter"), | |||||
rEffPar(Phpf, 8, rShort("hpf"), | |||||
rPresets(5), rPresetsAt(2, 75, 21, 75), rPreset(7, 50), | |||||
rPreset(12, 90), rDefault(0), "High pass filter"), | |||||
rEffPar(Plohidamp,9, rShort("damp"), rDefault(0), | |||||
rPresets(83, 71, 78, 78, 71, 106, 77, 71, 78, 64, 88, 77, 74) | |||||
"Dampening"), | |||||
//Todo make this a selector | //Todo make this a selector | ||||
rEffPar(Ptype, 10,rShort("type"), | |||||
rOptions(Random, Freeverb, Bandwidth), "Type"), | |||||
rEffPar(Proomsize,11,rShort("size"), "Room Size"), | |||||
rEffPar(Pbandwidth,12,rShort("bw"), "Bandwidth"), | |||||
rEffPar(Ptype, 10, rShort("type"), | |||||
rOptions(Random, Freeverb, Bandwidth), | |||||
rPresets(Freeverb, Random, Freeverb, Freeverb, Freeverb, Random, | |||||
Freeverb, Random, Freeverb, Freeverb, Freeverb, Random, | |||||
Freeverb) | |||||
rDefault(Random), "Type"), | |||||
rEffPar(Proomsize,11,rShort("size"), | |||||
rPreset(2, 85), rPresetsAt(5, 30, 45, 25, 105), | |||||
rPresetsAt(11, 95, 80), rDefault(64), | |||||
"Room Size"), | |||||
rEffPar(Pbandwidth,12,rShort("bw"), rDefault(20), "Bandwidth"), | |||||
}; | }; | ||||
#undef rBegin | #undef rBegin | ||||
#undef rEnd | #undef rEnd | ||||
@@ -215,7 +237,11 @@ void Reverb::setvolume(unsigned char _Pvolume) | |||||
{ | { | ||||
Pvolume = _Pvolume; | Pvolume = _Pvolume; | ||||
if(!insertion) { | if(!insertion) { | ||||
outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f; | |||||
if (Pvolume == 0) { | |||||
outvolume = 0.0f; | |||||
} else { | |||||
outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f; | |||||
} | |||||
volume = 1.0f; | volume = 1.0f; | ||||
} | } | ||||
else { | else { | ||||
@@ -512,3 +538,5 @@ unsigned char Reverb::getpar(int npar) const | |||||
default: return 0; | default: return 0; | ||||
} | } | ||||
} | } | ||||
} |
@@ -19,6 +19,8 @@ | |||||
#define REV_COMBS 8 | #define REV_COMBS 8 | ||||
#define REV_APS 4 | #define REV_APS 4 | ||||
namespace zyncarla { | |||||
/**Creates Reverberation Effects*/ | /**Creates Reverberation Effects*/ | ||||
class Reverb:public Effect | class Reverb:public Effect | ||||
{ | { | ||||
@@ -83,4 +85,6 @@ class Reverb:public Effect | |||||
class AnalogFilter * lpf, *hpf; //filters | class AnalogFilter * lpf, *hpf; //filters | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -17,6 +17,8 @@ | |||||
#include "tlsf/tlsf.h" | #include "tlsf/tlsf.h" | ||||
#include "Allocator.h" | #include "Allocator.h" | ||||
namespace zyncarla { | |||||
//Used for dummy allocations | //Used for dummy allocations | ||||
DummyAllocator DummyAlloc; | DummyAllocator DummyAlloc; | ||||
@@ -230,3 +232,5 @@ void Allocator::rollbackTransaction() { | |||||
* pool size and the next pool in the list as this information is not | * pool size and the next pool in the list as this information is not | ||||
* accessible in O(good) time | * accessible in O(good) time | ||||
*/ | */ | ||||
} |
@@ -14,6 +14,8 @@ | |||||
#include <utility> | #include <utility> | ||||
#include <new> | #include <new> | ||||
namespace zyncarla { | |||||
//! Allocator Base class | //! Allocator Base class | ||||
//! subclasses must specify allocation and deallocation | //! subclasses must specify allocation and deallocation | ||||
class Allocator | class Allocator | ||||
@@ -198,3 +200,5 @@ extern DummyAllocator DummyAlloc; | |||||
* * A new one is constructed with a deep copy | * * A new one is constructed with a deep copy | ||||
* * The old one is returned to middleware for deallocation | * * The old one is returned to middleware for deallocation | ||||
*/ | */ | ||||
} |
@@ -30,15 +30,20 @@ | |||||
#include "Util.h" | #include "Util.h" | ||||
#include "Part.h" | #include "Part.h" | ||||
#include "BankDb.h" | #include "BankDb.h" | ||||
#ifdef WIN32 | |||||
#include <windows.h> | |||||
#endif | |||||
#define INSTRUMENT_EXTENSION ".xiz" | |||||
using namespace std; | |||||
//if this file exists into a directory, this make the directory to be considered as a bank, even if it not contains a instrument file | |||||
#define FORCE_BANK_DIR_FILE ".bankdir" | |||||
namespace zyncarla { | |||||
using namespace std; | |||||
static const char* INSTRUMENT_EXTENSION = ".xiz"; | |||||
//if this file exists into a directory, this make the directory to be considered as a bank, even if it not contains a instrument file | |||||
const char* FORCE_BANK_DIR_FILE = ".bankdir"; | |||||
Bank::Bank(CarlaConfig *config) | |||||
Bank::Bank(Config *config) | |||||
:bankpos(0), defaultinsname(" "), config(config), | :bankpos(0), defaultinsname(" "), config(config), | ||||
db(new BankDb), bank_msb(0), bank_lsb(0) | db(new BankDb), bank_msb(0), bank_lsb(0) | ||||
{ | { | ||||
@@ -360,6 +365,18 @@ void Bank::rescanforbanks() | |||||
for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | ||||
if(!config->cfg.bankRootDirList[i].empty()) | if(!config->cfg.bankRootDirList[i].empty()) | ||||
scanrootdir(config->cfg.bankRootDirList[i]); | scanrootdir(config->cfg.bankRootDirList[i]); | ||||
#ifdef WIN32 | |||||
{ | |||||
//Search the VST Directory for banks/preset/etc | |||||
char path[1024]; | |||||
GetModuleFileName(GetModuleHandle("ZynAddSubFX.dll"), path, sizeof(path)); | |||||
if(strstr(path, "ZynAddSubFX.dll")) { | |||||
strstr(path, "ZynAddSubFX.dll")[0] = 0; | |||||
strcat(path, "banks"); | |||||
scanrootdir(path); | |||||
} | |||||
} | |||||
#endif | |||||
//sort the banks | //sort the banks | ||||
sort(banks.begin(), banks.end()); | sort(banks.begin(), banks.end()); | ||||
@@ -471,7 +488,7 @@ std::vector<std::string> Bank::search(std::string s) const | |||||
} | } | ||||
return out; | return out; | ||||
} | } | ||||
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; | ||||
@@ -544,3 +561,5 @@ void Bank::normalizedirsuffix(string &dirname) const { | |||||
&& ((dirname[dirname.size() - 1]) != '\\')) | && ((dirname[dirname.size() - 1]) != '\\')) | ||||
dirname += "/"; | dirname += "/"; | ||||
} | } | ||||
} |
@@ -22,12 +22,14 @@ | |||||
//entries in a bank | //entries in a bank | ||||
#define BANK_SIZE 160 | #define BANK_SIZE 160 | ||||
namespace zyncarla { | |||||
/**The instrument Bank*/ | /**The instrument Bank*/ | ||||
class Bank | class Bank | ||||
{ | { | ||||
public: | public: | ||||
/**Constructor*/ | /**Constructor*/ | ||||
Bank(CarlaConfig* config); | |||||
Bank(Config* config); | |||||
~Bank(); | ~Bank(); | ||||
std::string getname(unsigned int ninstrument); | std::string getname(unsigned int ninstrument); | ||||
std::string getnamenumbered(unsigned int ninstrument); | std::string getnamenumbered(unsigned int ninstrument); | ||||
@@ -102,7 +104,7 @@ class Bank | |||||
* directory separator */ | * directory separator */ | ||||
void normalizedirsuffix(std::string &dirname) const; | void normalizedirsuffix(std::string &dirname) const; | ||||
CarlaConfig* const config; | |||||
Config* const config; | |||||
class BankDb *db; | class BankDb *db; | ||||
public: | public: | ||||
@@ -110,4 +112,6 @@ class Bank | |||||
uint8_t bank_lsb; | uint8_t bank_lsb; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -6,7 +6,9 @@ | |||||
#include <dirent.h> | #include <dirent.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#define INSTRUMENT_EXTENSION ".xiz" | |||||
namespace zyncarla { | |||||
static const char* INSTRUMENT_EXTENSION = ".xiz"; | |||||
using std::string; | using std::string; | ||||
typedef BankDb::svec svec; | typedef BankDb::svec svec; | ||||
@@ -57,7 +59,7 @@ bool BankEntry::match(string s) const | |||||
bool BankEntry::operator<(const BankEntry &b) const | bool BankEntry::operator<(const BankEntry &b) const | ||||
{ | { | ||||
return this->file < b.file; | |||||
return (this->bank+this->file) < (b.bank+b.file); | |||||
} | } | ||||
static svec split(string s) | static svec split(string s) | ||||
@@ -227,16 +229,20 @@ BankEntry BankDb::processXiz(std::string filename, | |||||
{ | { | ||||
string fname = bank+filename; | string fname = bank+filename; | ||||
#ifdef WIN32 | |||||
int ret, time = 0; | |||||
#else | |||||
//Grab a timestamp | //Grab a timestamp | ||||
struct stat st; | struct stat st; | ||||
int ret = lstat(fname.c_str(), &st); | |||||
int time = 0; | int time = 0; | ||||
//gah windows, just implement the darn standard APIs | |||||
#ifndef WIN32 | |||||
int ret = lstat(fname.c_str(), &st); | |||||
if(ret != -1) | if(ret != -1) | ||||
time = st.st_mtim.tv_sec; | time = st.st_mtim.tv_sec; | ||||
#else | |||||
int ret = 0; | |||||
time = rand(); | |||||
#endif | #endif | ||||
//quickly check if the file exists in the cache and if it is up-to-date | //quickly check if the file exists in the cache and if it is up-to-date | ||||
if(cache.find(fname) != cache.end() && | if(cache.find(fname) != cache.end() && | ||||
@@ -343,3 +349,5 @@ BankEntry BankDb::processXiz(std::string filename, | |||||
return entry; | return entry; | ||||
} | } | ||||
} |
@@ -3,6 +3,8 @@ | |||||
#include <vector> | #include <vector> | ||||
#include <map> | #include <map> | ||||
namespace zyncarla { | |||||
struct BankEntry | struct BankEntry | ||||
{ | { | ||||
BankEntry(void); | BankEntry(void); | ||||
@@ -53,3 +55,5 @@ class BankDb | |||||
bvec fields; | bvec fields; | ||||
svec banks; | svec banks; | ||||
}; | }; | ||||
} |
@@ -10,6 +10,9 @@ | |||||
of the License, or (at your option) any later version. | of the License, or (at your option) any later version. | ||||
*/ | */ | ||||
#include "CallbackRepeater.h" | #include "CallbackRepeater.h" | ||||
namespace zyncarla { | |||||
CallbackRepeater::CallbackRepeater(int interval, cb_t cb_) | CallbackRepeater::CallbackRepeater(int interval, cb_t cb_) | ||||
:last(time(0)), dt(interval), cb(cb_) | :last(time(0)), dt(interval), cb(cb_) | ||||
{} | {} | ||||
@@ -22,3 +25,5 @@ void CallbackRepeater::tick(void) | |||||
last = now; | last = now; | ||||
} | } | ||||
} | } | ||||
} |
@@ -13,6 +13,8 @@ | |||||
#include <functional> | #include <functional> | ||||
#include <ctime> | #include <ctime> | ||||
namespace zyncarla { | |||||
struct CallbackRepeater | struct CallbackRepeater | ||||
{ | { | ||||
typedef std::function<void(void)> cb_t ; | typedef std::function<void(void)> cb_t ; | ||||
@@ -27,3 +29,5 @@ struct CallbackRepeater | |||||
std::time_t dt; | std::time_t dt; | ||||
cb_t cb; | cb_t cb; | ||||
}; | }; | ||||
} |
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
ZynAddSubFX - a software synthesizer | ZynAddSubFX - a software synthesizer | ||||
CarlaConfig.cpp - CarlaConfiguration file functions | |||||
Config.cpp - Configuration file functions | |||||
Copyright (C) 2003-2005 Nasca Octavian Paul | Copyright (C) 2003-2005 Nasca Octavian Paul | ||||
Author: Nasca Octavian Paul | Author: Nasca Octavian Paul | ||||
@@ -22,6 +22,8 @@ | |||||
#include "../globals.h" | #include "../globals.h" | ||||
#include "XMLwrapper.h" | #include "XMLwrapper.h" | ||||
namespace zyncarla { | |||||
#define rStdString(name, len, ...) \ | #define rStdString(name, len, ...) \ | ||||
{STRINGIFY(name) "::s", rMap(length, len) rProp(parameter) DOC(__VA_ARGS__), NULL, rStringCb(name,len)} | {STRINGIFY(name) "::s", rMap(length, len) rProp(parameter) DOC(__VA_ARGS__), NULL, rStringCb(name,len)} | ||||
#define rStdStringCb(name, length) rBOIL_BEGIN \ | #define rStdStringCb(name, length) rBOIL_BEGIN \ | ||||
@@ -37,7 +39,7 @@ | |||||
#if 1 | #if 1 | ||||
#define rObject CarlaConfig | |||||
#define rObject Config | |||||
static const rtosc::Ports ports = { | static const rtosc::Ports ports = { | ||||
//rString(cfg.LinuxOSSWaveOutDev), | //rString(cfg.LinuxOSSWaveOutDev), | ||||
//rString(cfg.LinuxOSSSeqInDev), | //rString(cfg.LinuxOSSSeqInDev), | ||||
@@ -51,7 +53,7 @@ static const rtosc::Ports ports = { | |||||
{"cfg.presetsDirList", rDoc("list of preset search directories"), 0, | {"cfg.presetsDirList", rDoc("list of preset search directories"), 0, | ||||
[](const char *msg, rtosc::RtData &d) | [](const char *msg, rtosc::RtData &d) | ||||
{ | { | ||||
CarlaConfig &c = *(CarlaConfig*)d.obj; | |||||
Config &c = *(Config*)d.obj; | |||||
if(rtosc_narguments(msg) != 0) { | if(rtosc_narguments(msg) != 0) { | ||||
std::string args = rtosc_argument_string(msg); | std::string args = rtosc_argument_string(msg); | ||||
@@ -84,7 +86,7 @@ static const rtosc::Ports ports = { | |||||
{"cfg.bankRootDirList", rDoc("list of bank search directories"), 0, | {"cfg.bankRootDirList", rDoc("list of bank search directories"), 0, | ||||
[](const char *msg, rtosc::RtData &d) | [](const char *msg, rtosc::RtData &d) | ||||
{ | { | ||||
CarlaConfig &c = *(CarlaConfig*)d.obj; | |||||
Config &c = *(Config*)d.obj; | |||||
if(rtosc_narguments(msg) != 0) { | if(rtosc_narguments(msg) != 0) { | ||||
std::string args = rtosc_argument_string(msg); | std::string args = rtosc_argument_string(msg); | ||||
@@ -120,14 +122,14 @@ static const rtosc::Ports ports = { | |||||
//rArrayS(cfg.presetsDirList,MAX_BANK_ROOT_DIRS), | //rArrayS(cfg.presetsDirList,MAX_BANK_ROOT_DIRS), | ||||
rToggle(cfg.CheckPADsynth, "Old Check For PADsynth functionality within a patch"), | rToggle(cfg.CheckPADsynth, "Old Check For PADsynth functionality within a patch"), | ||||
rToggle(cfg.IgnoreProgramChange, "Ignore MIDI Program Change Events"), | rToggle(cfg.IgnoreProgramChange, "Ignore MIDI Program Change Events"), | ||||
rParamI(cfg.UserInterfaceMode, "Beginner/Advanced Mode Select"), | |||||
rParamI(cfg.VirKeybLayout, "Keyboard Layout For Virtual Piano Keyboard"), | |||||
rParamI(cfg.UserInterfaceMode, "Beginner/Advanced Mode Select"), | |||||
rParamI(cfg.VirKeybLayout, "Keyboard Layout For Virtual Piano Keyboard"), | |||||
//rParamS(cfg.LinuxALSAaudioDev), | //rParamS(cfg.LinuxALSAaudioDev), | ||||
//rParamS(cfg.nameTag) | //rParamS(cfg.nameTag) | ||||
{"cfg.OscilPower::i", rProp(parameter) rDoc("Size Of Oscillator Wavetable"), 0, | {"cfg.OscilPower::i", rProp(parameter) rDoc("Size Of Oscillator Wavetable"), 0, | ||||
[](const char *msg, rtosc::RtData &d) | [](const char *msg, rtosc::RtData &d) | ||||
{ | { | ||||
CarlaConfig &c = *(CarlaConfig*)d.obj; | |||||
Config &c = *(Config*)d.obj; | |||||
if(rtosc_narguments(msg) == 0) { | if(rtosc_narguments(msg) == 0) { | ||||
d.reply(d.loc, "i", (int)(log(c.cfg.OscilSize*1.0)/log(2.0))); | d.reply(d.loc, "i", (int)(log(c.cfg.OscilSize*1.0)/log(2.0))); | ||||
return; | return; | ||||
@@ -136,22 +138,29 @@ static const rtosc::Ports ports = { | |||||
c.cfg.OscilSize = val; | c.cfg.OscilSize = val; | ||||
d.broadcast(d.loc, "i", (int)(log(c.cfg.OscilSize*1.0)/log(2.0))); | d.broadcast(d.loc, "i", (int)(log(c.cfg.OscilSize*1.0)/log(2.0))); | ||||
}}, | }}, | ||||
{"clear-favorites:", rDoc("Clear favorite directories"), 0, | |||||
[](const char *msg, rtosc::RtData &d) { | |||||
Config &c = *(Config*)d.obj; | |||||
for(int i=0; i<MAX_BANK_ROOT_DIRS; ++i) | |||||
c.cfg.favoriteList[i] = ""; | |||||
}}, | |||||
{"add-favorite:s", rDoc("Add favorite directory"), 0, | {"add-favorite:s", rDoc("Add favorite directory"), 0, | ||||
[](const char *msg, rtosc::RtData &d) | [](const char *msg, rtosc::RtData &d) | ||||
{ | { | ||||
CarlaConfig &c = *(CarlaConfig*)d.obj; | |||||
Config &c = *(Config*)d.obj; | |||||
const char *path = rtosc_argument(msg, 0).s; | |||||
for(int i=0; i<MAX_BANK_ROOT_DIRS; ++i) { | for(int i=0; i<MAX_BANK_ROOT_DIRS; ++i) { | ||||
if(c.cfg.favoriteList[i].empty()) { | |||||
c.cfg.favoriteList[i] = rtosc_argument(msg, 0).s; | |||||
if(c.cfg.favoriteList[i].empty() || c.cfg.favoriteList[i] == path) { | |||||
c.cfg.favoriteList[i] = path; | |||||
return; | return; | ||||
} | } | ||||
} | } | ||||
}}, | }}, | ||||
{"favorites:", rProp(parameter), 0, | |||||
{"favorites:", /*rProp(parameter)*/ 0, 0, | |||||
[](const char *msg, rtosc::RtData &d) | [](const char *msg, rtosc::RtData &d) | ||||
{ | { | ||||
CarlaConfig &c = *(CarlaConfig*)d.obj; | |||||
Config &c = *(Config*)d.obj; | |||||
char *argt = new char[MAX_BANK_ROOT_DIRS+1]; | char *argt = new char[MAX_BANK_ROOT_DIRS+1]; | ||||
rtosc_arg_t *args = new rtosc_arg_t[MAX_BANK_ROOT_DIRS]; | rtosc_arg_t *args = new rtosc_arg_t[MAX_BANK_ROOT_DIRS]; | ||||
memset(argt, 0, MAX_BANK_ROOT_DIRS+1); | memset(argt, 0, MAX_BANK_ROOT_DIRS+1); | ||||
@@ -168,13 +177,15 @@ static const rtosc::Ports ports = { | |||||
delete [] args; | delete [] args; | ||||
}}, | }}, | ||||
}; | }; | ||||
const rtosc::Ports &CarlaConfig::ports = ::ports; | |||||
const rtosc::Ports &Config::ports = zyncarla::ports; | |||||
#endif | #endif | ||||
CarlaConfig::CarlaConfig() | |||||
{} | |||||
Config::Config() | |||||
{ | |||||
init(); | |||||
} | |||||
void CarlaConfig::init() | |||||
void Config::init() | |||||
{ | { | ||||
maxstringsize = MAX_STRING_SIZE; //for ui | maxstringsize = MAX_STRING_SIZE; //for ui | ||||
//defaults | //defaults | ||||
@@ -223,14 +234,18 @@ void CarlaConfig::init() | |||||
//banks | //banks | ||||
cfg.bankRootDirList[0] = "~/banks"; | cfg.bankRootDirList[0] = "~/banks"; | ||||
cfg.bankRootDirList[1] = "./"; | cfg.bankRootDirList[1] = "./"; | ||||
cfg.bankRootDirList[2] = "/usr/share/zynaddsubfx/banks"; | |||||
cfg.bankRootDirList[3] = "/usr/local/share/zynaddsubfx/banks"; | |||||
#ifdef __APPLE__ | #ifdef __APPLE__ | ||||
cfg.bankRootDirList[4] = "../Resources/banks"; | |||||
cfg.bankRootDirList[2] = "../Resources/banks"; | |||||
#else | |||||
cfg.bankRootDirList[2] = "../banks"; | |||||
#endif | |||||
cfg.bankRootDirList[3] = "banks"; | |||||
#ifdef ZYN_DATADIR | |||||
cfg.bankRootDirList[4] = ZYN_DATADIR "/banks"; | |||||
#else | #else | ||||
cfg.bankRootDirList[4] = "../banks"; | |||||
cfg.bankRootDirList[4] = "/usr/share/zynaddsubfx/banks"; | |||||
cfg.bankRootDirList[5] = "/usr/local/share/zynaddsubfx/banks"; | |||||
#endif | #endif | ||||
cfg.bankRootDirList[5] = "banks"; | |||||
} | } | ||||
if(cfg.presetsDirList[0].empty()) { | if(cfg.presetsDirList[0].empty()) { | ||||
@@ -242,14 +257,18 @@ void CarlaConfig::init() | |||||
cfg.presetsDirList[1] = "../presets"; | cfg.presetsDirList[1] = "../presets"; | ||||
#endif | #endif | ||||
cfg.presetsDirList[2] = "presets"; | cfg.presetsDirList[2] = "presets"; | ||||
#ifdef ZYN_DATADIR | |||||
cfg.presetsDirList[3] = ZYN_DATADIR "/presets"; | |||||
#else | |||||
cfg.presetsDirList[3] = "/usr/share/zynaddsubfx/presets"; | cfg.presetsDirList[3] = "/usr/share/zynaddsubfx/presets"; | ||||
cfg.presetsDirList[4] = "/usr/local/share/zynaddsubfx/presets"; | cfg.presetsDirList[4] = "/usr/local/share/zynaddsubfx/presets"; | ||||
#endif | |||||
} | } | ||||
cfg.LinuxALSAaudioDev = "default"; | cfg.LinuxALSAaudioDev = "default"; | ||||
cfg.nameTag = ""; | cfg.nameTag = ""; | ||||
} | } | ||||
CarlaConfig::~CarlaConfig() | |||||
Config::~Config() | |||||
{ | { | ||||
delete [] cfg.oss_devs.linux_wave_out; | delete [] cfg.oss_devs.linux_wave_out; | ||||
delete [] cfg.oss_devs.linux_seq_in; | delete [] cfg.oss_devs.linux_seq_in; | ||||
@@ -260,26 +279,26 @@ CarlaConfig::~CarlaConfig() | |||||
} | } | ||||
void CarlaConfig::save() const | |||||
void Config::save() const | |||||
{ | { | ||||
char filename[MAX_STRING_SIZE]; | char filename[MAX_STRING_SIZE]; | ||||
getConfigFileName(filename, MAX_STRING_SIZE); | getConfigFileName(filename, MAX_STRING_SIZE); | ||||
saveConfig(filename); | saveConfig(filename); | ||||
} | } | ||||
void CarlaConfig::clearbankrootdirlist() | |||||
void Config::clearbankrootdirlist() | |||||
{ | { | ||||
for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | ||||
cfg.bankRootDirList[i].clear(); | cfg.bankRootDirList[i].clear(); | ||||
} | } | ||||
void CarlaConfig::clearpresetsdirlist() | |||||
void Config::clearpresetsdirlist() | |||||
{ | { | ||||
for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | ||||
cfg.presetsDirList[i].clear(); | cfg.presetsDirList[i].clear(); | ||||
} | } | ||||
void CarlaConfig::readConfig(const char *filename) | |||||
void Config::readConfig(const char *filename) | |||||
{ | { | ||||
XMLwrapper xmlcfg; | XMLwrapper xmlcfg; | ||||
if(xmlcfg.loadXMLfile(filename) < 0) | if(xmlcfg.loadXMLfile(filename) < 0) | ||||
@@ -350,7 +369,7 @@ void CarlaConfig::readConfig(const char *filename) | |||||
cfg.presetsDirList[i] = xmlcfg.getparstr("presets_root", ""); | cfg.presetsDirList[i] = xmlcfg.getparstr("presets_root", ""); | ||||
xmlcfg.exitbranch(); | xmlcfg.exitbranch(); | ||||
} | } | ||||
//Get favs | //Get favs | ||||
for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | ||||
if(xmlcfg.enterbranch("FAVSROOT", i)) { | if(xmlcfg.enterbranch("FAVSROOT", i)) { | ||||
@@ -382,7 +401,7 @@ void CarlaConfig::readConfig(const char *filename) | |||||
cfg.OscilSize = (int) powf(2, ceil(logf(cfg.OscilSize - 1.0f) / logf(2.0f))); | cfg.OscilSize = (int) powf(2, ceil(logf(cfg.OscilSize - 1.0f) / logf(2.0f))); | ||||
} | } | ||||
void CarlaConfig::saveConfig(const char *filename) const | |||||
void Config::saveConfig(const char *filename) const | |||||
{ | { | ||||
XMLwrapper *xmlcfg = new XMLwrapper(); | XMLwrapper *xmlcfg = new XMLwrapper(); | ||||
@@ -418,7 +437,7 @@ void CarlaConfig::saveConfig(const char *filename) const | |||||
xmlcfg->addparstr("presets_root", cfg.presetsDirList[i]); | xmlcfg->addparstr("presets_root", cfg.presetsDirList[i]); | ||||
xmlcfg->endbranch(); | xmlcfg->endbranch(); | ||||
} | } | ||||
for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | ||||
if(!cfg.favoriteList[i].empty()) { | if(!cfg.favoriteList[i].empty()) { | ||||
xmlcfg->beginbranch("FAVSROOT", i); | xmlcfg->beginbranch("FAVSROOT", i); | ||||
@@ -444,8 +463,10 @@ void CarlaConfig::saveConfig(const char *filename) const | |||||
delete (xmlcfg); | delete (xmlcfg); | ||||
} | } | ||||
void CarlaConfig::getConfigFileName(char *name, int namesize) const | |||||
void Config::getConfigFileName(char *name, int namesize) const | |||||
{ | { | ||||
name[0] = 0; | name[0] = 0; | ||||
snprintf(name, namesize, "%s%s", getenv("HOME"), "/.zynaddsubfxXML.cfg"); | snprintf(name, namesize, "%s%s", getenv("HOME"), "/.zynaddsubfxXML.cfg"); | ||||
} | } | ||||
} |
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
ZynAddSubFX - a software synthesizer | ZynAddSubFX - a software synthesizer | ||||
CarlaConfig.h - CarlaConfiguration file functions | |||||
Config.h - Configuration file functions | |||||
Copyright (C) 2003-2005 Nasca Octavian Paul | Copyright (C) 2003-2005 Nasca Octavian Paul | ||||
Author: Nasca Octavian Paul | Author: Nasca Octavian Paul | ||||
@@ -23,6 +23,8 @@ namespace rtosc | |||||
struct Ports; | struct Ports; | ||||
} | } | ||||
namespace zyncarla { | |||||
class oss_devs_t | class oss_devs_t | ||||
{ | { | ||||
public: | public: | ||||
@@ -30,13 +32,13 @@ class oss_devs_t | |||||
}; | }; | ||||
/**Configuration file functions*/ | /**Configuration file functions*/ | ||||
class CarlaConfig | |||||
class Config | |||||
{ | { | ||||
public: | public: | ||||
CarlaConfig(); | |||||
CarlaConfig(const CarlaConfig& ) = delete; | |||||
~CarlaConfig(); | |||||
Config(); | |||||
Config(const Config& ) = delete; | |||||
~Config(); | |||||
struct { | struct { | ||||
oss_devs_t oss_devs; | oss_devs_t oss_devs; | ||||
int SampleRate, SoundBufferSize, OscilSize, SwapStereo; | int SampleRate, SoundBufferSize, OscilSize, SwapStereo; | ||||
@@ -73,4 +75,7 @@ class CarlaConfig | |||||
void saveConfig(const char *filename) const; | void saveConfig(const char *filename) const; | ||||
void getConfigFileName(char *name, int namesize) const; | void getConfigFileName(char *name, int namesize) const; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -16,6 +16,7 @@ | |||||
#include "LASHClient.h" | #include "LASHClient.h" | ||||
namespace zyncarla { | |||||
LASHClient::LASHClient(int *argc, char ***argv) | LASHClient::LASHClient(int *argc, char ***argv) | ||||
{ | { | ||||
@@ -92,3 +93,5 @@ void LASHClient::confirmevent(Event event) | |||||
if(event == Restore) | if(event == Restore) | ||||
lash_send_event(client, lash_event_new_with_type(LASH_Restore_File)); | lash_send_event(client, lash_event_new_with_type(LASH_Restore_File)); | ||||
} | } | ||||
} |
@@ -17,6 +17,7 @@ | |||||
#include <pthread.h> | #include <pthread.h> | ||||
#include <lash/lash.h> | #include <lash/lash.h> | ||||
namespace zyncarla { | |||||
/** This class wraps up some functions for initialising and polling | /** This class wraps up some functions for initialising and polling | ||||
* the LASH daemon.*/ | * the LASH daemon.*/ | ||||
@@ -50,5 +51,6 @@ class LASHClient | |||||
lash_client_t *client; | lash_client_t *client; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -16,6 +16,7 @@ | |||||
#include "Part.h" | #include "Part.h" | ||||
#include "zyn-version.h" | |||||
#include "../Misc/Stereo.h" | #include "../Misc/Stereo.h" | ||||
#include "../Misc/Util.h" | #include "../Misc/Util.h" | ||||
#include "../Params/LFOParams.h" | #include "../Params/LFOParams.h" | ||||
@@ -32,15 +33,18 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <fstream> | |||||
#include <iostream> | #include <iostream> | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <cmath> | #include <cmath> | ||||
#include <atomic> | #include <atomic> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
using namespace std; | using namespace std; | ||||
using namespace rtosc; | using namespace rtosc; | ||||
namespace zyncarla { | |||||
#define rObject Master | #define rObject Master | ||||
static const Ports sysefxPort = | static const Ports sysefxPort = | ||||
@@ -49,12 +53,18 @@ static const Ports sysefxPort = | |||||
rDoc("gain on part to sysefx routing"), 0, | rDoc("gain on part to sysefx routing"), 0, | ||||
[](const char *m, RtData&d) | [](const char *m, RtData&d) | ||||
{ | { | ||||
//ok, this is going to be an ugly workaround | |||||
//we know that if we are here the message previously MUST have | |||||
//matched Psysefxvol#/ | |||||
//and the number is one or two digits at most | |||||
const char *index_1 = m; | |||||
index_1 -=2; | |||||
//we know that if we are here the location must | |||||
//be ...Psysefxvol#N/part#M | |||||
//and the number "N" is one or two digits at most | |||||
// go backto the '/' | |||||
const char* m_findslash = m + strlen(m), | |||||
* loc_findslash = d.loc + strlen(d.loc); | |||||
for(;*loc_findslash != '/'; --m_findslash, --loc_findslash) | |||||
assert(*loc_findslash == *m_findslash); | |||||
assert(m_findslash + 1 == m); | |||||
const char *index_1 = loc_findslash-1; | |||||
assert(isdigit(*index_1)); | assert(isdigit(*index_1)); | ||||
if(isdigit(index_1[-1])) | if(isdigit(index_1[-1])) | ||||
index_1--; | index_1--; | ||||
@@ -78,9 +88,15 @@ static const Ports sysefsendto = | |||||
{"to#" STRINGIFY(NUM_SYS_EFX) "::i", | {"to#" STRINGIFY(NUM_SYS_EFX) "::i", | ||||
rProp(parameter) rDoc("sysefx to sysefx routing gain"), 0, [](const char *m, RtData&d) | rProp(parameter) rDoc("sysefx to sysefx routing gain"), 0, [](const char *m, RtData&d) | ||||
{ | { | ||||
//same ugly workaround as before | |||||
const char *index_1 = m; | |||||
index_1 -=2; | |||||
//same workaround as before | |||||
//go backto the '/' | |||||
const char* m_findslash = m + strlen(m), | |||||
* loc_findslash = d.loc + strlen(d.loc); | |||||
for(;*loc_findslash != '/'; --m_findslash, --loc_findslash) | |||||
assert(*loc_findslash == *m_findslash); | |||||
assert(m_findslash + 1 == m); | |||||
const char *index_1 = loc_findslash-1; | |||||
assert(isdigit(*index_1)); | assert(isdigit(*index_1)); | ||||
if(isdigit(index_1[-1])) | if(isdigit(index_1[-1])) | ||||
index_1--; | index_1--; | ||||
@@ -98,6 +114,236 @@ static const Ports sysefsendto = | |||||
}} | }} | ||||
}; | }; | ||||
#define rBegin [](const char *msg, RtData &d) { rtosc::AutomationMgr &a = *(AutomationMgr*)d.obj | |||||
#define rEnd } | |||||
static int extract_num(const char *&msg) | |||||
{ | |||||
while(*msg && !isdigit(*msg)) msg++; | |||||
int num = atoi(msg); | |||||
while(isdigit(*msg)) msg++; | |||||
return num; | |||||
} | |||||
static int get_next_int(const char *msg) | |||||
{ | |||||
return extract_num(msg); | |||||
} | |||||
static const Ports mapping_ports = { | |||||
{"offset::f", rProp(parameter) rDefault(0) rShort("off") rLinear(-50, 50) rMap(unit, percent), 0, | |||||
rBegin; | |||||
int slot = d.idx[1]; | |||||
int param = d.idx[0]; | |||||
if(!strcmp("f",rtosc_argument_string(msg))) { | |||||
a.setSlotSubOffset(slot, param, rtosc_argument(msg, 0).f); | |||||
a.updateMapping(slot, param); | |||||
d.broadcast(d.loc, "f", a.getSlotSubOffset(slot, param)); | |||||
} else | |||||
d.reply(d.loc, "f", a.getSlotSubOffset(slot, param)); | |||||
rEnd}, | |||||
{"gain::f", rProp(parameter) rDefault(100) rShort("gain") rLinear(-200, 200) rMap(unit, percent), 0, | |||||
rBegin; | |||||
int slot = d.idx[1]; | |||||
int param = d.idx[0]; | |||||
if(!strcmp("f",rtosc_argument_string(msg))) { | |||||
a.setSlotSubGain(slot, param, rtosc_argument(msg, 0).f); | |||||
a.updateMapping(slot, param); | |||||
d.broadcast(d.loc, "f", a.getSlotSubGain(slot, param)); | |||||
} else | |||||
d.reply(d.loc, "f", a.getSlotSubGain(slot, param)); | |||||
rEnd}, | |||||
}; | |||||
static const Ports auto_param_ports = { | |||||
{"used::T:F", rProp(parameter) rProp(read-only) rDoc("If automation is assigned to anything"), 0, | |||||
rBegin; | |||||
int slot = d.idx[1]; | |||||
int param = d.idx[0]; | |||||
d.reply(d.loc, a.slots[slot].automations[param].used ? "T" : "F"); | |||||
rEnd}, | |||||
{"active::T:F", rProp(parameter) rDoc("If automation is being actively used"), 0, | |||||
rBegin; | |||||
int slot = d.idx[1]; | |||||
int param = d.idx[0]; | |||||
if(rtosc_narguments(msg)) | |||||
a.slots[slot].automations[param].active = rtosc_argument(msg, 0).T; | |||||
else | |||||
d.reply(d.loc, a.slots[slot].automations[param].active ? "T" : "F"); | |||||
rEnd}, | |||||
{"path::s", rProp(parameter) rProp(read-only) rDoc("Path of parameter"), 0, | |||||
rBegin; | |||||
int slot = d.idx[1]; | |||||
int param = d.idx[0]; | |||||
d.reply(d.loc, "s", a.slots[slot].automations[param].param_path); | |||||
rEnd}, | |||||
{"clear:", rDoc("Clear automation param"), 0, | |||||
rBegin; | |||||
int slot = d.idx[1]; | |||||
int param = d.idx[0]; | |||||
a.clearSlotSub(slot, param); | |||||
rEnd}, | |||||
{"mapping/", 0, &mapping_ports, | |||||
rBegin; | |||||
SNIP; | |||||
mapping_ports.dispatch(msg, d); | |||||
rEnd}, | |||||
//{"mapping", rDoc("Parameter mapping control"), 0, | |||||
// rBegin; | |||||
// int slot = d.idx[1]; | |||||
// int param = d.idx[0]; | |||||
// if(!strcmp("b", rtosc_argument_string(msg))) { | |||||
// int len = rtosc_argument(msg, 0).b.len / sizeof(float); | |||||
// float *data = (float*)rtosc_argument(msg, 0).b.data; | |||||
// } else { | |||||
// d.reply(d.loc, "b", | |||||
// a.slots[slot].automations[param].map.npoints*sizeof(float), | |||||
// a.slots[slot].automations[param].map.control_points); | |||||
// } | |||||
// rEnd}, | |||||
}; | |||||
static const Ports slot_ports = { | |||||
//{"learn-binding:s", rDoc("Create binding for automation path with midi-learn"), 0, | |||||
// rBegin; | |||||
// (void) m; | |||||
// //m->automate.createBinding(rtosc_argument(msg, 0).i, | |||||
// // rtosc_argument(msg, 1).s, | |||||
// // rtosc_argument(msg, 2).T); | |||||
// rEnd}, | |||||
//{"create-binding:s", rDoc("Create binding for automation path"), 0, | |||||
// rBegin; | |||||
// m->automate.createBinding(rtosc_argument(msg, 0).i, | |||||
// rtosc_argument(msg, 1).s, | |||||
// rtosc_argument(msg, 2).T); | |||||
// rEnd}, | |||||
{"value::f", rProp(no learn) rProp(parameter) rMap(default, 0.5) rLinear(0, 1) rDoc("Access current value in slot 'i' (0..1)"), 0, | |||||
rBegin; | |||||
int num = d.idx[0]; | |||||
if(!strcmp("f",rtosc_argument_string(msg))) { | |||||
a.setSlot(num, rtosc_argument(msg, 0).f); | |||||
d.broadcast(d.loc, "f", a.getSlot(num)); | |||||
} else | |||||
d.reply(d.loc, "f", a.getSlot(num)); | |||||
rEnd}, | |||||
{"name::s", rProp(parameter) rDoc("Access name of automation slot"), 0, | |||||
rBegin; | |||||
int num = d.idx[0]; | |||||
if(!strcmp("s",rtosc_argument_string(msg))) { | |||||
a.setName(num, rtosc_argument(msg, 0).s); | |||||
d.broadcast(d.loc, "s", a.getName(num)); | |||||
} else | |||||
d.reply(d.loc, "s", a.getName(num)); | |||||
rEnd}, | |||||
{"midi-cc::i", rProp(parameter) rMap(default, -1) rDoc("Access assigned midi CC slot") , 0, | |||||
rBegin; | |||||
int slot = d.idx[0]; | |||||
if(rtosc_narguments(msg)) | |||||
a.slots[slot].midi_cc = rtosc_argument(msg, 0).i; | |||||
else | |||||
d.reply(d.loc, "i", a.slots[slot].midi_cc); | |||||
rEnd}, | |||||
{"active::T:F", rProp(parameter) rMap(default, F) rDoc("If Slot is enabled"), 0, | |||||
rBegin; | |||||
int slot = d.idx[0]; | |||||
if(rtosc_narguments(msg)) | |||||
a.slots[slot].active = rtosc_argument(msg, 0).T; | |||||
else | |||||
d.reply(d.loc, a.slots[slot].active ? "T" : "F"); | |||||
rEnd}, | |||||
{"learning::i", rProp(parameter) rMap(default, -1) rDoc("If slot is trying to find a midi learn binding"), 0, | |||||
rBegin; | |||||
int slot = d.idx[0]; | |||||
d.reply(d.loc, "i", a.slots[slot].learning); | |||||
rEnd}, | |||||
{"clear:", rDoc("Clear automation slot"), 0, | |||||
rBegin; | |||||
int slot = d.idx[0]; | |||||
a.clearSlot(slot); | |||||
rEnd}, | |||||
{"param#4/", rDoc("Info on individual param mappings"), &auto_param_ports, | |||||
rBegin; | |||||
(void)a; | |||||
d.push_index(get_next_int(msg)); | |||||
SNIP; | |||||
auto_param_ports.dispatch(msg, d); | |||||
d.pop_index(); | |||||
rEnd}, | |||||
}; | |||||
static const Ports automate_ports = { | |||||
{"active-slot::i", rProp(parameter) rMap(min, -1) rMap(max, 16) rDoc("Active Slot for macro learning"), 0, | |||||
rBegin; | |||||
if(!strcmp("i",rtosc_argument_string(msg))) { | |||||
a.active_slot = rtosc_argument(msg, 0).i; | |||||
d.broadcast(d.loc, "i", a.active_slot); | |||||
} else | |||||
d.reply(d.loc, "i", a.active_slot); | |||||
rEnd}, | |||||
{"learn-binding-new-slot:s", rDoc("Learn a parameter assigned to a new slot"), 0, | |||||
rBegin; | |||||
int free_slot = a.free_slot(); | |||||
if(free_slot >= 0) { | |||||
a.createBinding(free_slot, rtosc_argument(msg, 0).s, true); | |||||
a.active_slot = free_slot; | |||||
} | |||||
rEnd}, | |||||
{"learn-binding-same-slot:s", rDoc("Learn a parameter appending to the active-slot"), 0, | |||||
rBegin; | |||||
if(a.active_slot >= 0) | |||||
a.createBinding(a.active_slot, rtosc_argument(msg, 0).s, true); | |||||
rEnd}, | |||||
// TODO: remove rNoWalk | |||||
{"slot#16/", rNoWalk rDoc("Parameters of individual automation slots"), &slot_ports, | |||||
rBegin; | |||||
(void)a; | |||||
d.push_index(get_next_int(msg)); | |||||
SNIP; | |||||
slot_ports.dispatch(msg, d); | |||||
d.pop_index(); | |||||
rEnd}, | |||||
{"clear", rDoc("Clear all automation slots"), 0, | |||||
rBegin; | |||||
for(int i=0; i<a.nslots; ++i) | |||||
a.clearSlot(i); | |||||
rEnd}, | |||||
{"load-blob:b", rProp(internal) rDoc("Load blob from middleware"), 0, | |||||
rBegin; | |||||
auto &b = **(rtosc::AutomationMgr **)rtosc_argument(msg, 0).b.data; | |||||
//XXX this code should likely be in rtosc | |||||
for(int i=0; i<a.nslots; ++i) { | |||||
auto &slota = a.slots[i]; | |||||
auto &slotb = b.slots[i]; | |||||
std::swap(slota.learning, slotb.learning); | |||||
std::swap(slota.midi_cc, slotb.midi_cc); | |||||
std::swap(slota.used, slotb.used); | |||||
std::swap(slota.active, slotb.active); | |||||
for(int j=0; j<a.per_slot; ++j) { | |||||
auto &aa = slota.automations[j]; | |||||
auto &ab = slotb.automations[j]; | |||||
std::swap(aa.used, ab.used); | |||||
std::swap(aa.active, ab.active); | |||||
std::swap(aa.param_path, ab.param_path); | |||||
std::swap(aa.param_min, ab.param_min); | |||||
std::swap(aa.param_max, ab.param_max); | |||||
std::swap(aa.param_step, ab.param_step); | |||||
std::swap(aa.param_type, ab.param_type); | |||||
std::swap(aa.map.offset, ab.map.offset); | |||||
std::swap(aa.map.gain, ab.map.gain); | |||||
std::swap(aa.map.upoints, ab.map.upoints); | |||||
for(int k=0; k<aa.map.npoints; ++k) | |||||
std::swap(aa.map.control_points[k], ab.map.control_points[k]); | |||||
} | |||||
} | |||||
rEnd}, | |||||
}; | |||||
#undef rBegin | |||||
#undef rEnd | |||||
#define rBegin [](const char *msg, RtData &d) { Master *m = (Master*)d.obj | #define rBegin [](const char *msg, RtData &d) { Master *m = (Master*)d.obj | ||||
#define rEnd } | #define rEnd } | ||||
@@ -108,20 +354,22 @@ static const Ports watchPorts = { | |||||
rEnd}, | rEnd}, | ||||
}; | }; | ||||
extern const Ports bankPorts; | extern const Ports bankPorts; | ||||
static const Ports master_ports = { | static const Ports master_ports = { | ||||
rString(last_xmz, XMZ_PATH_MAX, "File name for last name loaded if any."), | rString(last_xmz, XMZ_PATH_MAX, "File name for last name loaded if any."), | ||||
rRecursp(part, 16, "Part"),//NUM_MIDI_PARTS | rRecursp(part, 16, "Part"),//NUM_MIDI_PARTS | ||||
rRecursp(sysefx, 4, "System Effect"),//NUM_SYS_EFX | rRecursp(sysefx, 4, "System Effect"),//NUM_SYS_EFX | ||||
rRecursp(insefx, 8, "Insertion Effect"),//NUM_INS_EFX | rRecursp(insefx, 8, "Insertion Effect"),//NUM_INS_EFX | ||||
rRecur(microtonal, "Micrtonal Mapping Functionality"), | |||||
rRecur(microtonal, "Microtonal Mapping Functionality"), | |||||
rRecur(ctl, "Controller"), | rRecur(ctl, "Controller"), | ||||
rArrayI(Pinsparts, NUM_INS_EFX, rOpt(-2, Master), rOpt(-1, Off) | |||||
rOptions(Part1, Part2, Part3, Part4, Part5, Part6, | |||||
Part7, Part8, Part9, Part10, Part11, Part12, | |||||
Part13, Part14, Part15, Part16), | |||||
"Part to insert part onto"), | |||||
{"Pkeyshift::i", rShort("key shift") rProp(parameter) rLinear(0,127) rDoc("Global Key Shift"), 0, [](const char *m, RtData&d) { | |||||
rArrayOption(Pinsparts, NUM_INS_EFX, rOpt(-2, Master), rOpt(-1, Off), | |||||
rOptions(Part1, Part2, Part3, Part4, Part5, Part6, | |||||
Part7, Part8, Part9, Part10, Part11, Part12, | |||||
Part13, Part14, Part15, Part16) rDefault(Off), | |||||
"Part to insert part onto"), | |||||
{"Pkeyshift::i", rShort("key shift") rProp(parameter) rLinear(0,127) | |||||
rDefault(64) rDoc("Global Key Shift"), 0, [](const char *m, RtData&d) { | |||||
if(rtosc_narguments(m)==0) { | if(rtosc_narguments(m)==0) { | ||||
d.reply(d.loc, "i", ((Master*)d.obj)->Pkeyshift); | d.reply(d.loc, "i", ((Master*)d.obj)->Pkeyshift); | ||||
} else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') { | } else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') { | ||||
@@ -160,6 +408,8 @@ static const Ports master_ports = { | |||||
d.reply("/free", "sb", "Part", sizeof(void*), &m->part[i]); | d.reply("/free", "sb", "Part", sizeof(void*), &m->part[i]); | ||||
m->part[i] = p; | m->part[i] = p; | ||||
p->initialize_rt(); | p->initialize_rt(); | ||||
for(int i=0; i<128; ++i) | |||||
m->activeNotes[i] = 0; | |||||
}}, | }}, | ||||
{"active_keys:", rProp("Obtain a list of active notes"), 0, | {"active_keys:", rProp("Obtain a list of active notes"), 0, | ||||
rBegin; | rBegin; | ||||
@@ -168,14 +418,16 @@ static const Ports master_ports = { | |||||
keys[i] = m->activeNotes[i] ? 'T' : 'F'; | keys[i] = m->activeNotes[i] ? 'T' : 'F'; | ||||
d.broadcast(d.loc, keys); | d.broadcast(d.loc, keys); | ||||
rEnd}, | rEnd}, | ||||
{"Pvolume::i", rShort("volume") rProp(parameter) rLinear(0,127) rDoc("Master Volume"), 0, | |||||
{"Pvolume::i", rShort("volume") rProp(parameter) rLinear(0,127) | |||||
rDefault(80) rDoc("Master Volume"), 0, | |||||
[](const char *m, rtosc::RtData &d) { | [](const char *m, rtosc::RtData &d) { | ||||
if(rtosc_narguments(m)==0) { | if(rtosc_narguments(m)==0) { | ||||
d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume); | d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume); | ||||
} else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') { | } else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') { | ||||
((Master*)d.obj)->setPvolume(limit<char>(rtosc_argument(m,0).i,0,127)); | ((Master*)d.obj)->setPvolume(limit<char>(rtosc_argument(m,0).i,0,127)); | ||||
d.broadcast(d.loc, "i", ((Master*)d.obj)->Pvolume);}}}, | d.broadcast(d.loc, "i", ((Master*)d.obj)->Pvolume);}}}, | ||||
{"volume::i", rShort("volume") rProp(parameter) rLinear(0,127) rDoc("Master Volume"), 0, | |||||
{"volume::i", rShort("volume") rProp(parameter) rLinear(0,127) | |||||
rDefault(80) rDoc("Master Volume"), 0, | |||||
[](const char *m, rtosc::RtData &d) { | [](const char *m, rtosc::RtData &d) { | ||||
if(rtosc_narguments(m)==0) { | if(rtosc_narguments(m)==0) { | ||||
d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume); | d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume); | ||||
@@ -229,13 +481,12 @@ static const Ports master_ports = { | |||||
[](const char *,RtData &d) { | [](const char *,RtData &d) { | ||||
Master *M = (Master*)d.obj; | Master *M = (Master*)d.obj; | ||||
M->frozenState = false;}}, | M->frozenState = false;}}, | ||||
{"midi-learn/", 0, &rtosc::MidiMapperRT::ports, | |||||
{"automate/", rDoc("MIDI Learn/Plugin Automation support"), &automate_ports, | |||||
[](const char *msg, RtData &d) { | [](const char *msg, RtData &d) { | ||||
Master *M = (Master*)d.obj; | |||||
SNIP; | SNIP; | ||||
printf("residue message = <%s>\n", msg); | |||||
d.obj = &M->midi; | |||||
rtosc::MidiMapperRT::ports.dispatch(msg,d);}}, | |||||
d.obj = (void*)&((Master*)d.obj)->automate; | |||||
automate_ports.dispatch(msg, d); | |||||
}}, | |||||
{"close-ui:", rDoc("Request to close any connection named \"GUI\""), 0, | {"close-ui:", rDoc("Request to close any connection named \"GUI\""), 0, | ||||
[](const char *, RtData &d) { | [](const char *, RtData &d) { | ||||
d.reply("/close-ui", "");}}, | d.reply("/close-ui", "");}}, | ||||
@@ -261,8 +512,8 @@ static const Ports master_ports = { | |||||
[](const char *, rtosc::RtData &d) {d.reply("/undo_pause", "");}}, | [](const char *, rtosc::RtData &d) {d.reply("/undo_pause", "");}}, | ||||
{"undo_resume:",rProp(internal) rDoc("resume undo event recording"),0, | {"undo_resume:",rProp(internal) rDoc("resume undo event recording"),0, | ||||
[](const char *, rtosc::RtData &d) {d.reply("/undo_resume", "");}}, | [](const char *, rtosc::RtData &d) {d.reply("/undo_resume", "");}}, | ||||
{"config/", rDoc("Top Level Application CarlaConfiguration Parameters"), &CarlaConfig::ports, | |||||
[](const char *, rtosc::RtData &d){d.forward();}}, | |||||
{"config/", rNoWalk rDoc("Top Level Application Configuration Parameters"), | |||||
&Config::ports, [](const char *, rtosc::RtData &d){d.forward();}}, | |||||
{"presets/", rDoc("Parameter Presets"), &preset_ports, rBOIL_BEGIN | {"presets/", rDoc("Parameter Presets"), &preset_ports, rBOIL_BEGIN | ||||
SNIP | SNIP | ||||
preset_ports.dispatch(msg, data); | preset_ports.dispatch(msg, data); | ||||
@@ -286,6 +537,14 @@ static const Ports master_ports = { | |||||
rBOIL_END}, | rBOIL_END}, | ||||
{"bank/", rDoc("Controls for instrument banks"), &bankPorts, | {"bank/", rDoc("Controls for instrument banks"), &bankPorts, | ||||
[](const char*,RtData&) {}}, | [](const char*,RtData&) {}}, | ||||
{"learn:s", rProp(depricated) rDoc("MIDI Learn"), 0, | |||||
rBegin; | |||||
int free_slot = m->automate.free_slot(); | |||||
if(free_slot >= 0) { | |||||
m->automate.createBinding(free_slot, rtosc_argument(msg, 0).s, true); | |||||
m->automate.active_slot = free_slot; | |||||
} | |||||
rEnd}, | |||||
}; | }; | ||||
#undef rBegin | #undef rBegin | ||||
@@ -359,18 +618,97 @@ vuData::vuData(void) | |||||
rmspeakl(0.0f), rmspeakr(0.0f), clipped(0) | rmspeakl(0.0f), rmspeakr(0.0f), clipped(0) | ||||
{} | {} | ||||
Master::Master(const SYNTH_T &synth_, CarlaConfig* config) | |||||
void Master::saveAutomation(XMLwrapper &xml, const rtosc::AutomationMgr &midi) | |||||
{ | |||||
xml.beginbranch("automation"); | |||||
{ | |||||
XmlNode metadata("mgr-info"); | |||||
metadata["nslots"] = to_s(midi.nslots); | |||||
metadata["nautomations"] = to_s(midi.per_slot); | |||||
metadata["ncontrol"] = to_s(midi.slots[0].automations[0].map.npoints); | |||||
xml.add(metadata); | |||||
for(int i=0; i<midi.nslots; ++i) { | |||||
const auto &slot = midi.slots[i]; | |||||
if(!slot.used) | |||||
continue; | |||||
xml.beginbranch("slot", i); | |||||
XmlNode params("params"); | |||||
params["midi-cc"] = to_s(slot.midi_cc); | |||||
xml.add(params); | |||||
for(int j=0; j<midi.per_slot; ++j) { | |||||
const auto &au = slot.automations[j]; | |||||
if(!au.used) | |||||
continue; | |||||
xml.beginbranch("automation", j); | |||||
XmlNode automation("params"); | |||||
automation["path"] = au.param_path; | |||||
XmlNode mapping("mapping"); | |||||
mapping["gain"] = to_s(au.map.gain); | |||||
mapping["offset"] = to_s(au.map.offset); | |||||
xml.add(automation); | |||||
xml.add(mapping); | |||||
xml.endbranch(); | |||||
} | |||||
xml.endbranch(); | |||||
} | |||||
} | |||||
xml.endbranch(); | |||||
} | |||||
void Master::loadAutomation(XMLwrapper &xml, rtosc::AutomationMgr &midi) | |||||
{ | |||||
if(xml.enterbranch("automation")) { | |||||
for(int i=0; i<midi.nslots; ++i) { | |||||
auto &slot = midi.slots[i]; | |||||
if(xml.enterbranch("slot", i)) { | |||||
for(int j=0; j<midi.per_slot; ++j) { | |||||
auto &au = slot.automations[j]; | |||||
if(xml.enterbranch("automation", j)) { | |||||
float gain = 1.0; | |||||
float offset = 0.0; | |||||
std::string path = ""; | |||||
for(auto node:xml.getBranch()) { | |||||
if(node.name == "params") | |||||
path = node["path"]; | |||||
else if(node.name == "mapping") { | |||||
gain = atof(node["gain"].c_str()); | |||||
offset = atof(node["offset"].c_str()); | |||||
} | |||||
} | |||||
printf("createBinding(%d, %s, false)\n", i, path.c_str()); | |||||
midi.createBinding(i, path.c_str(), false); | |||||
midi.setSlotSubGain(i, j, gain); | |||||
midi.setSlotSubOffset(i, j, offset); | |||||
xml.exitbranch(); | |||||
} | |||||
} | |||||
for(auto node:xml.getBranch()) | |||||
if(node.name == "params") | |||||
slot.midi_cc = atoi(node["midi-cc"].c_str()); | |||||
xml.exitbranch(); | |||||
} | |||||
} | |||||
xml.exitbranch(); | |||||
} | |||||
} | |||||
Master::Master(const SYNTH_T &synth_, Config* config) | |||||
:HDDRecorder(synth_), time(synth_), ctl(synth_, &time), | :HDDRecorder(synth_), time(synth_), ctl(synth_, &time), | ||||
microtonal(config->cfg.GzipCompression), bank(config), | microtonal(config->cfg.GzipCompression), bank(config), | ||||
automate(16,4,8), | |||||
frozenState(false), pendingMemory(false), | frozenState(false), pendingMemory(false), | ||||
synth(synth_), gzip_compression(config->cfg.GzipCompression) | synth(synth_), gzip_compression(config->cfg.GzipCompression) | ||||
{ | { | ||||
bToU = NULL; | bToU = NULL; | ||||
uToB = NULL; | uToB = NULL; | ||||
//Setup MIDI | |||||
midi.frontend = [this](const char *msg) {bToU->raw_write(msg);}; | |||||
midi.backend = [this](const char *msg) {applyOscEvent(msg);}; | |||||
//Setup MIDI Learn | |||||
automate.set_ports(master_ports); | |||||
automate.set_instance(this); | |||||
//midi.frontend = [this](const char *msg) {bToU->raw_write(msg);}; | |||||
automate.backend = [this](const char *msg) {applyOscEvent(msg);}; | |||||
memory = new AllocatorClass(); | memory = new AllocatorClass(); | ||||
swaplr = 0; | swaplr = 0; | ||||
@@ -441,6 +779,7 @@ void Master::defaults() | |||||
for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) { | for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) { | ||||
part[npart]->defaults(); | part[npart]->defaults(); | ||||
part[npart]->partno = npart % NUM_MIDI_CHANNELS; | |||||
part[npart]->Prcvchn = npart % NUM_MIDI_CHANNELS; | part[npart]->Prcvchn = npart % NUM_MIDI_CHANNELS; | ||||
} | } | ||||
@@ -519,8 +858,7 @@ void Master::setController(char chan, int type, int par) | |||||
{ | { | ||||
if(frozenState) | if(frozenState) | ||||
return; | return; | ||||
//TODO add chan back | |||||
midi.handleCC(type,par); | |||||
automate.handleMidi(chan, type, par); | |||||
if((type == C_dataentryhi) || (type == C_dataentrylo) | if((type == C_dataentryhi) || (type == C_dataentrylo) | ||||
|| (type == C_nrpnhi) || (type == C_nrpnlo)) { //Process RPN and NRPN by the Master (ignore the chan) | || (type == C_nrpnhi) || (type == C_nrpnlo)) { //Process RPN and NRPN by the Master (ignore the chan) | ||||
ctl.setparameternumber(type, par); | ctl.setparameternumber(type, par); | ||||
@@ -724,13 +1062,19 @@ bool Master::runOSC(float *outl, float *outr, bool offline) | |||||
} | } | ||||
if(!d.matches) {// && !ports.apropos(msg)) { | if(!d.matches) {// && !ports.apropos(msg)) { | ||||
fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 1, 7 + 30, 0 + 40); | fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 1, 7 + 30, 0 + 40); | ||||
fprintf(stderr, "Unknown address<BACKEND:%s> '%s:%s'\n", | |||||
fprintf(stderr, "Unknown address<BACKEND:%s> '%s:%s'\n", | |||||
offline ? "offline" : "online", | offline ? "offline" : "online", | ||||
uToB->peak(), | uToB->peak(), | ||||
rtosc_argument_string(uToB->peak())); | rtosc_argument_string(uToB->peak())); | ||||
fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40); | fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40); | ||||
} | } | ||||
} | } | ||||
if(automate.damaged) { | |||||
d.broadcast("/damage", "s", "/automate/"); | |||||
automate.damaged = 0; | |||||
} | |||||
if(events>1 && false) | if(events>1 && false) | ||||
fprintf(stderr, "backend: %d events per cycle\n",events); | fprintf(stderr, "backend: %d events per cycle\n",events); | ||||
@@ -1074,6 +1418,8 @@ void Master::add2XML(XMLwrapper& xml) | |||||
microtonal.add2XML(xml); | microtonal.add2XML(xml); | ||||
xml.endbranch(); | xml.endbranch(); | ||||
saveAutomation(xml, automate); | |||||
for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) { | for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) { | ||||
xml.beginbranch("PART", npart); | xml.beginbranch("PART", npart); | ||||
part[npart]->add2XML(xml); | part[npart]->add2XML(xml); | ||||
@@ -1198,6 +1544,8 @@ void Master::getfromXML(XMLwrapper& xml) | |||||
xml.exitbranch(); | xml.exitbranch(); | ||||
} | } | ||||
loadAutomation(xml, automate); | |||||
sysefx[0]->changeeffect(0); | sysefx[0]->changeeffect(0); | ||||
if(xml.enterbranch("SYSTEM_EFFECTS")) { | if(xml.enterbranch("SYSTEM_EFFECTS")) { | ||||
for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) { | for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) { | ||||
@@ -1248,3 +1596,114 @@ void Master::getfromXML(XMLwrapper& xml) | |||||
xml.exitbranch(); | xml.exitbranch(); | ||||
} | } | ||||
} | } | ||||
static rtosc_version version_in_rtosc_fmt() | |||||
{ | |||||
return rtosc_version | |||||
{ | |||||
(unsigned char) version.get_major(), | |||||
(unsigned char) version.get_minor(), | |||||
(unsigned char) version.get_revision() | |||||
}; | |||||
} | |||||
char* Master::getXMLData() | |||||
{ | |||||
XMLwrapper xml; | |||||
xml.beginbranch("MASTER"); | |||||
add2XML(xml); | |||||
xml.endbranch(); | |||||
return xml.getXMLdata(); | |||||
} | |||||
int Master::saveOSC(const char *filename) | |||||
{ | |||||
std::string savefile = rtosc::save_to_file(ports, this, | |||||
"ZynAddSubFX", | |||||
version_in_rtosc_fmt()); | |||||
zyncarla::Config config; | |||||
zyncarla::SYNTH_T* synth = new zyncarla::SYNTH_T; | |||||
synth->buffersize = 256; | |||||
synth->samplerate = 48000; | |||||
synth->alias(); | |||||
zyncarla::Master master2(*synth, &config); | |||||
int rval = master2.loadOSCFromStr(savefile.c_str()); | |||||
if(rval < 0) | |||||
{ | |||||
std::cerr << "invalid savefile!" << std::endl; | |||||
std::cerr << "complete savefile:" << std::endl; | |||||
std::cerr << savefile << std::endl; | |||||
std::cerr << "first entry that could not be parsed:" << std::endl; | |||||
for(int i = -rval + 1; savefile[i]; ++i) | |||||
if(savefile[i] == '\n') | |||||
{ | |||||
savefile.resize(i); | |||||
break; | |||||
} | |||||
std::cerr << (savefile.c_str() - rval) << std::endl; | |||||
rval = -1; | |||||
} | |||||
else | |||||
{ | |||||
char* xml = getXMLData(), | |||||
* xml2 = master2.getXMLData(); | |||||
rval = strcmp(xml, xml2) ? -1 : 0; | |||||
if(rval == 0) | |||||
{ | |||||
if(filename) | |||||
{ | |||||
std::ofstream ofs(filename); | |||||
ofs << savefile; | |||||
} | |||||
else if(!filename) | |||||
std::cout << savefile << std::endl; | |||||
} | |||||
else | |||||
{ | |||||
std::cout << savefile << std::endl; | |||||
std::cerr << "Can not write OSC savefile!! (see tmp1.txt and tmp2.txt)" | |||||
<< std::endl; | |||||
std::ofstream tmp1("tmp1.txt"), tmp2("tmp2.txt"); | |||||
tmp1 << xml; | |||||
tmp2 << xml2; | |||||
} | |||||
free(xml); | |||||
free(xml2); | |||||
} | |||||
return rval; | |||||
} | |||||
int Master::loadOSCFromStr(const char *filename) | |||||
{ | |||||
return rtosc::load_from_file(filename, | |||||
ports, this, | |||||
"ZynAddSubFX", version_in_rtosc_fmt()); | |||||
} | |||||
string loadfile(string fname) | |||||
{ | |||||
std::ifstream t(fname.c_str()); | |||||
std::string str((std::istreambuf_iterator<char>(t)), | |||||
std::istreambuf_iterator<char>()); | |||||
return str; | |||||
} | |||||
int Master::loadOSC(const char *filename) | |||||
{ | |||||
int rval = loadOSCFromStr(loadfile(filename).c_str()); | |||||
return rval < 0 ? rval : 0; | |||||
} | |||||
} |
@@ -16,7 +16,7 @@ | |||||
#define MASTER_H | #define MASTER_H | ||||
#include "../globals.h" | #include "../globals.h" | ||||
#include "Microtonal.h" | #include "Microtonal.h" | ||||
#include <rtosc/miditable.h> | |||||
#include <rtosc/automations.h> | |||||
#include <rtosc/ports.h> | #include <rtosc/ports.h> | ||||
#include "Time.h" | #include "Time.h" | ||||
@@ -26,6 +26,8 @@ | |||||
#include "../Params/Controller.h" | #include "../Params/Controller.h" | ||||
#include "../Synth/WatchPoint.h" | #include "../Synth/WatchPoint.h" | ||||
namespace zyncarla { | |||||
class Allocator; | class Allocator; | ||||
struct vuData { | struct vuData { | ||||
@@ -42,7 +44,7 @@ class Master | |||||
{ | { | ||||
public: | public: | ||||
/** Constructor TODO make private*/ | /** Constructor TODO make private*/ | ||||
Master(const SYNTH_T &synth, class CarlaConfig *config); | |||||
Master(const SYNTH_T &synth, class Config *config); | |||||
/** Destructor*/ | /** Destructor*/ | ||||
~Master(); | ~Master(); | ||||
@@ -57,12 +59,23 @@ class Master | |||||
/**This adds the parameters to the XML data*/ | /**This adds the parameters to the XML data*/ | ||||
void add2XML(XMLwrapper& xml); | void add2XML(XMLwrapper& xml); | ||||
static void saveAutomation(XMLwrapper &xml, const rtosc::AutomationMgr &midi); | |||||
static void loadAutomation(XMLwrapper &xml, rtosc::AutomationMgr &midi); | |||||
void defaults(); | void defaults(); | ||||
/**loads all settings from a XML file | /**loads all settings from a XML file | ||||
* @return 0 for ok or -1 if there is an error*/ | * @return 0 for ok or -1 if there is an error*/ | ||||
int loadXML(const char *filename); | int loadXML(const char *filename); | ||||
/**Save all settings to an OSC file (as specified by RT OSC) | |||||
* @param filename File to save to or NULL (useful for testing) | |||||
* @return 0 for ok or <0 if there is an error*/ | |||||
int saveOSC(const char *filename); | |||||
/**loads all settings from an OSC file (as specified by RT OSC) | |||||
* @return 0 for ok or <0 if there is an error*/ | |||||
int loadOSC(const char *filename); | |||||
/**Regenerate PADsynth and other non-RT parameters | /**Regenerate PADsynth and other non-RT parameters | ||||
* It is NOT SAFE to call this from a RT context*/ | * It is NOT SAFE to call this from a RT context*/ | ||||
void applyparameters(void) NONREALTIME; | void applyparameters(void) NONREALTIME; | ||||
@@ -169,7 +182,7 @@ class Master | |||||
WatchManager watcher; | WatchManager watcher; | ||||
//Midi Learn | //Midi Learn | ||||
rtosc::MidiMapperRT midi; | |||||
rtosc::AutomationMgr automate; | |||||
bool frozenState;//read-only parameters for threadsafe actions | bool frozenState;//read-only parameters for threadsafe actions | ||||
Allocator *memory; | Allocator *memory; | ||||
@@ -181,8 +194,8 @@ class Master | |||||
//Heartbeat for identifying plugin offline modes | //Heartbeat for identifying plugin offline modes | ||||
//in units of 10 ms (done s.t. overflow is in 497 days) | //in units of 10 ms (done s.t. overflow is in 497 days) | ||||
uint32_t last_beat; | |||||
uint32_t last_ack; | |||||
uint32_t last_beat = 0; | |||||
uint32_t last_ack = 0; | |||||
private: | private: | ||||
float sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; | float sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; | ||||
float sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; | float sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; | ||||
@@ -197,6 +210,13 @@ class Master | |||||
//Callback When Master changes | //Callback When Master changes | ||||
void(*mastercb)(void*,Master*); | void(*mastercb)(void*,Master*); | ||||
void* mastercb_ptr; | void* mastercb_ptr; | ||||
//Return XML data as string. Must be freed. | |||||
char* getXMLData(); | |||||
//Used by loadOSC and saveOSC | |||||
int loadOSCFromStr(const char *filename); | |||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -25,11 +25,13 @@ | |||||
#include "Util.h" | #include "Util.h" | ||||
#include "Microtonal.h" | #include "Microtonal.h" | ||||
using namespace rtosc; | |||||
#define MAX_LINE_SIZE 80 | #define MAX_LINE_SIZE 80 | ||||
namespace zyncarla { | |||||
#define rObject Microtonal | #define rObject Microtonal | ||||
using namespace rtosc; | |||||
/** | /** | ||||
* TODO | * TODO | ||||
@@ -40,25 +42,37 @@ using namespace rtosc; | |||||
* A good lookup table should be a good finalization of this | * A good lookup table should be a good finalization of this | ||||
*/ | */ | ||||
const rtosc::Ports Microtonal::ports = { | const rtosc::Ports Microtonal::ports = { | ||||
rToggle(Pinvertupdown, rShort("inv."), "key mapping inverse"), | |||||
rParamZyn(Pinvertupdowncenter, rShort("center"), "center of the inversion"), | |||||
rToggle(Penabled, rShort("enable"), "Enable for microtonal mode"), | |||||
rParamZyn(PAnote, rShort("A note"), "The note for 'A'"), | |||||
rParamF(PAfreq, rShort("A freq"), "Frequency of the 'A' note"), | |||||
rParamZyn(Pscaleshift, rShort("shift"), "UNDOCUMENTED"), | |||||
rParamZyn(Pfirstkey, rShort("first key"), "First key to retune"), | |||||
rParamZyn(Plastkey, rShort("last key"), "Last key to retune"), | |||||
rParamZyn(Pmiddlenote, rShort("middle"), "Scale degree 0 note"), | |||||
rToggle(Pinvertupdown, rShort("inv."), rDefault(false), | |||||
"key mapping inverse"), | |||||
rParamZyn(Pinvertupdowncenter, rShort("center"), rDefault(60), | |||||
"center of the inversion"), | |||||
rToggle(Penabled, rShort("enable"), rDefault(false), | |||||
"Enable for microtonal mode"), | |||||
rParamZyn(PAnote, rShort("1/1 midi note"), rDefault(69), | |||||
"The note for 'A'"), | |||||
rParamF(PAfreq, rShort("ref freq"), rDefault(440.0f), | |||||
"Frequency of the 'A' note"), | |||||
rParamZyn(Pscaleshift, rShort("shift"), rDefault(64), | |||||
"UNDOCUMENTED"), | |||||
rParamZyn(Pfirstkey, rShort("first key"), rDefault(0), | |||||
"First key to retune"), | |||||
rParamZyn(Plastkey, rShort("last key"), rDefault(127), | |||||
"Last key to retune"), | |||||
rParamZyn(Pmiddlenote, rShort("middle"), rDefault(60), | |||||
"Scale degree 0 note"), | |||||
//TODO check to see if this should be exposed | //TODO check to see if this should be exposed | ||||
rParamZyn(Pmapsize, "Size of key map"), | |||||
rToggle(Pmappingenabled, "Mapping Enable"), | |||||
rParamZyn(Pmapsize, rDefault(12), "Size of key map"), | |||||
rToggle(Pmappingenabled, rDefault(false), "Mapping Enable"), | |||||
rParams(Pmapping, 128, "Mapping of keys"), | |||||
rParamZyn(Pglobalfinedetune, rShort("fine"), "Fine detune for all notes"), | |||||
rParams(Pmapping, 128, rDefaultMissing, "Mapping of keys"), | |||||
rParamZyn(Pglobalfinedetune, rShort("fine"), rDefault(64), | |||||
"Fine detune for all notes"), | |||||
rString(Pname, MICROTONAL_MAX_NAME_LEN, rShort("name"), "Microtonal Name"), | |||||
rString(Pcomment, MICROTONAL_MAX_NAME_LEN, rShort("comment"), "Microtonal comments"), | |||||
rString(Pname, MICROTONAL_MAX_NAME_LEN, rShort("name"), | |||||
rDefault("12tET"), "Microtonal Name"), | |||||
rString(Pcomment, MICROTONAL_MAX_NAME_LEN, rShort("comment"), | |||||
rDefault("Equal Temperament 12 notes per octave"), "Microtonal comments"), | |||||
{"octavesize:", rDoc("Get octave size"), 0, [](const char*, RtData &d) | {"octavesize:", rDoc("Get octave size"), 0, [](const char*, RtData &d) | ||||
{ | { | ||||
@@ -570,6 +584,9 @@ int Microtonal::loadscl(SclInfo &scl, const char *filename) | |||||
char tmp[500]; | char tmp[500]; | ||||
OctaveTuning tmpoctave[MAX_OCTAVE_SIZE]; | OctaveTuning tmpoctave[MAX_OCTAVE_SIZE]; | ||||
if(!file) | |||||
return 2; | |||||
fseek(file, 0, SEEK_SET); | fseek(file, 0, SEEK_SET); | ||||
//loads the short description | //loads the short description | ||||
@@ -621,6 +638,9 @@ int Microtonal::loadkbm(KbmInfo &kbm, const char *filename) | |||||
float tmpPAfreq = 440.0f; | float tmpPAfreq = 440.0f; | ||||
char tmp[500]; | char tmp[500]; | ||||
if(!file) | |||||
return 2; | |||||
fseek(file, 0, SEEK_SET); | fseek(file, 0, SEEK_SET); | ||||
//loads the mapsize | //loads the mapsize | ||||
if(loadline(file, tmp) != 0 || sscanf(tmp, "%d", &x) == 0) | if(loadline(file, tmp) != 0 || sscanf(tmp, "%d", &x) == 0) | ||||
@@ -843,7 +863,7 @@ void Microtonal::apply(void) | |||||
{ | { | ||||
char buf[100*MAX_OCTAVE_SIZE] = {0}; | char buf[100*MAX_OCTAVE_SIZE] = {0}; | ||||
char tmpbuf[100] = {0}; | char tmpbuf[100] = {0}; | ||||
for (int i=0;i<getoctavesize();i++){ | |||||
for (int i=0;i<octavesize;i++){ | |||||
if (i!=0) | if (i!=0) | ||||
strncat(buf, "\n", sizeof(buf)-1); | strncat(buf, "\n", sizeof(buf)-1); | ||||
tuningtoline(i,tmpbuf,100); | tuningtoline(i,tmpbuf,100); | ||||
@@ -852,3 +872,5 @@ void Microtonal::apply(void) | |||||
int err = texttotunings(buf); | int err = texttotunings(buf); | ||||
} | } | ||||
} | } | ||||
} |
@@ -20,6 +20,9 @@ | |||||
#define MAX_OCTAVE_SIZE 128 | #define MAX_OCTAVE_SIZE 128 | ||||
#define MICROTONAL_MAX_NAME_LEN 120 | #define MICROTONAL_MAX_NAME_LEN 120 | ||||
namespace zyncarla { | |||||
class XMLwrapper; | class XMLwrapper; | ||||
struct KbmInfo | struct KbmInfo | ||||
@@ -154,4 +157,6 @@ class Microtonal | |||||
const int& gzip_compression; | const int& gzip_compression; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -56,6 +56,8 @@ | |||||
#include <err.h> | #include <err.h> | ||||
#endif | #endif | ||||
namespace zyncarla { | |||||
using std::string; | using std::string; | ||||
int Pexitprogram = 0; | int Pexitprogram = 0; | ||||
@@ -221,55 +223,6 @@ void preparePadSynth(string path, PADnoteParameters *p, rtosc::RtData &d) | |||||
} | } | ||||
} | } | ||||
/****************************************************************************** | |||||
* MIDI Serialization * | |||||
* * | |||||
******************************************************************************/ | |||||
void saveMidiLearn(XMLwrapper &xml, const rtosc::MidiMappernRT &midi) | |||||
{ | |||||
xml.beginbranch("midi-learn"); | |||||
for(auto value:midi.inv_map) { | |||||
XmlNode binding("midi-binding"); | |||||
auto biject = std::get<3>(value.second); | |||||
binding["osc-path"] = value.first; | |||||
binding["coarse-CC"] = to_s(std::get<1>(value.second)); | |||||
binding["fine-CC"] = to_s(std::get<2>(value.second)); | |||||
binding["type"] = "i"; | |||||
binding["minimum"] = to_s(biject.min); | |||||
binding["maximum"] = to_s(biject.max); | |||||
xml.add(binding); | |||||
} | |||||
xml.endbranch(); | |||||
} | |||||
void loadMidiLearn(XMLwrapper &xml, rtosc::MidiMappernRT &midi) | |||||
{ | |||||
using rtosc::Port; | |||||
if(xml.enterbranch("midi-learn")) { | |||||
auto nodes = xml.getBranch(); | |||||
//TODO clear mapper | |||||
for(auto node:nodes) { | |||||
if(node.name != "midi-binding" || | |||||
!node.has("osc-path") || | |||||
!node.has("coarse-CC")) | |||||
continue; | |||||
const string path = node["osc-path"]; | |||||
const int CC = atoi(node["coarse-CC"].c_str()); | |||||
const Port *p = Master::ports.apropos(path.c_str()); | |||||
if(p) { | |||||
printf("loading midi port...\n"); | |||||
midi.addNewMapper(CC, *p, path); | |||||
} else { | |||||
printf("unknown midi bindable <%s>\n", path.c_str()); | |||||
} | |||||
} | |||||
xml.exitbranch(); | |||||
} else | |||||
printf("cannot find 'midi-learn' branch...\n"); | |||||
} | |||||
/****************************************************************************** | /****************************************************************************** | ||||
* Non-RealTime Object Store * | * Non-RealTime Object Store * | ||||
* * | * * | ||||
@@ -451,17 +404,17 @@ namespace Nio | |||||
/* Implementation */ | /* Implementation */ | ||||
class CarlaMiddleWareImpl | |||||
class MiddleWareImpl | |||||
{ | { | ||||
public: | public: | ||||
MiddleWare *parent; | MiddleWare *parent; | ||||
private: | private: | ||||
public: | public: | ||||
CarlaConfig* const config; | |||||
CarlaMiddleWareImpl(MiddleWare *mw, SYNTH_T synth, CarlaConfig* config, | |||||
Config* const config; | |||||
MiddleWareImpl(MiddleWare *mw, SYNTH_T synth, Config* config, | |||||
int preferred_port); | int preferred_port); | ||||
~CarlaMiddleWareImpl(void); | |||||
~MiddleWareImpl(void); | |||||
//Check offline vs online mode in plugins | //Check offline vs online mode in plugins | ||||
void heartBeat(Master *m); | void heartBeat(Master *m); | ||||
@@ -745,7 +698,7 @@ public: | |||||
rtosc::UndoHistory undo; | rtosc::UndoHistory undo; | ||||
//MIDI Learn | //MIDI Learn | ||||
rtosc::MidiMappernRT midi_mapper; | |||||
//rtosc::MidiMappernRT midi_mapper; | |||||
//Link To the Realtime | //Link To the Realtime | ||||
rtosc::ThreadLink *bToU; | rtosc::ThreadLink *bToU; | ||||
@@ -774,7 +727,7 @@ public: | |||||
class MwDataObj:public rtosc::RtData | class MwDataObj:public rtosc::RtData | ||||
{ | { | ||||
public: | public: | ||||
MwDataObj(CarlaMiddleWareImpl *mwi_) | |||||
MwDataObj(MiddleWareImpl *mwi_) | |||||
{ | { | ||||
loc_size = 1024; | loc_size = 1024; | ||||
loc = new char[loc_size]; | loc = new char[loc_size]; | ||||
@@ -797,7 +750,7 @@ class MwDataObj:public rtosc::RtData | |||||
//Chain calls repeat the call into handle() | //Chain calls repeat the call into handle() | ||||
//Forward calls send the message directly to the realtime | //Forward calls send the message directly to the realtime | ||||
virtual void reply(const char *path, const char *args, ...) | |||||
virtual void reply(const char *path, const char *args, ...) override | |||||
{ | { | ||||
//printf("reply building '%s'\n", path); | //printf("reply building '%s'\n", path); | ||||
va_list va; | va_list va; | ||||
@@ -823,7 +776,7 @@ class MwDataObj:public rtosc::RtData | |||||
reply(buffer); | reply(buffer); | ||||
} | } | ||||
} | } | ||||
virtual void reply(const char *msg){ | |||||
virtual void reply(const char *msg) override{ | |||||
mwi->sendToCurrentRemote(msg); | mwi->sendToCurrentRemote(msg); | ||||
}; | }; | ||||
//virtual void broadcast(const char *path, const char *args, ...){(void)path;(void)args;}; | //virtual void broadcast(const char *path, const char *args, ...){(void)path;(void)args;}; | ||||
@@ -854,7 +807,7 @@ class MwDataObj:public rtosc::RtData | |||||
bool forwarded; | bool forwarded; | ||||
private: | private: | ||||
char *buffer; | char *buffer; | ||||
CarlaMiddleWareImpl *mwi; | |||||
MiddleWareImpl *mwi; | |||||
}; | }; | ||||
static std::vector<std::string> getFiles(const char *folder, bool finddir) | static std::vector<std::string> getFiles(const char *folder, bool finddir) | ||||
@@ -885,11 +838,12 @@ static std::vector<std::string> getFiles(const char *folder, bool finddir) | |||||
} | } | ||||
#else | #else | ||||
std::string darn_windows = folder + std::string("/") + std::string(fn->d_name); | std::string darn_windows = folder + std::string("/") + std::string(fn->d_name); | ||||
printf("attr on <%s> => %x\n", darn_windows.c_str(), GetFileAttributes(darn_windows.c_str())); | |||||
printf("error = %x\n", INVALID_FILE_ATTRIBUTES); | |||||
//printf("attr on <%s> => %x\n", darn_windows.c_str(), GetFileAttributes(darn_windows.c_str())); | |||||
//printf("desired mask = %x\n", mask); | |||||
//printf("error = %x\n", INVALID_FILE_ATTRIBUTES); | |||||
bool is_dir = GetFileAttributes(darn_windows.c_str()) & FILE_ATTRIBUTE_DIRECTORY; | bool is_dir = GetFileAttributes(darn_windows.c_str()) & FILE_ATTRIBUTE_DIRECTORY; | ||||
#endif | #endif | ||||
if(finddir == is_dir) | |||||
if(finddir == is_dir && strcmp(".", fn->d_name)) | |||||
files.push_back(fn->d_name); | files.push_back(fn->d_name); | ||||
} | } | ||||
@@ -935,13 +889,28 @@ extern const rtosc::Ports bankPorts; | |||||
const rtosc::Ports bankPorts = { | const rtosc::Ports bankPorts = { | ||||
{"rescan:", 0, 0, | {"rescan:", 0, 0, | ||||
rBegin; | rBegin; | ||||
impl.bankpos = 0; | |||||
impl.rescanforbanks(); | impl.rescanforbanks(); | ||||
//Send updated banks | //Send updated banks | ||||
int i = 0; | int i = 0; | ||||
for(auto &elm : impl.banks) | for(auto &elm : impl.banks) | ||||
d.reply("/bank/bank_select", "iss", i++, elm.name.c_str(), elm.dir.c_str()); | d.reply("/bank/bank_select", "iss", i++, elm.name.c_str(), elm.dir.c_str()); | ||||
d.reply("/bank/bank_select", "i", impl.bankpos); | d.reply("/bank/bank_select", "i", impl.bankpos); | ||||
if (i > 0) { | |||||
impl.loadbank(impl.banks[0].dir); | |||||
//Reload bank slots | |||||
for(int i=0; i<BANK_SIZE; ++i) { | |||||
d.reply("/bankview", "iss", | |||||
i, impl.ins[i].name.c_str(), | |||||
impl.ins[i].filename.c_str()); | |||||
} | |||||
} else { | |||||
//Clear all bank slots | |||||
for(int i=0; i<BANK_SIZE; ++i) { | |||||
d.reply("/bankview", "iss", i, "", ""); | |||||
} | |||||
} | |||||
rEnd}, | rEnd}, | ||||
{"bank_list:", 0, 0, | {"bank_list:", 0, 0, | ||||
rBegin; | rBegin; | ||||
@@ -1089,8 +1058,8 @@ const rtosc::Ports bankPorts = { | |||||
rBegin; | rBegin; | ||||
auto res = impl.search(rtosc_argument(msg, 0).s); | auto res = impl.search(rtosc_argument(msg, 0).s); | ||||
#define MAX_SEARCH 300 | #define MAX_SEARCH 300 | ||||
char res_type[MAX_SEARCH+1] = {0}; | |||||
rtosc_arg_t res_dat[MAX_SEARCH] = {0}; | |||||
char res_type[MAX_SEARCH+1] = {}; | |||||
rtosc_arg_t res_dat[MAX_SEARCH] = {}; | |||||
for(unsigned i=0; i<res.size() && i<MAX_SEARCH; ++i) { | for(unsigned i=0; i<res.size() && i<MAX_SEARCH; ++i) { | ||||
res_type[i] = 's'; | res_type[i] = 's'; | ||||
res_dat[i].s = res[i].c_str(); | res_dat[i].s = res[i].c_str(); | ||||
@@ -1102,8 +1071,8 @@ const rtosc::Ports bankPorts = { | |||||
rBegin; | rBegin; | ||||
auto res = impl.blist(rtosc_argument(msg, 0).s); | auto res = impl.blist(rtosc_argument(msg, 0).s); | ||||
#define MAX_SEARCH 300 | #define MAX_SEARCH 300 | ||||
char res_type[MAX_SEARCH+1] = {0}; | |||||
rtosc_arg_t res_dat[MAX_SEARCH] = {0}; | |||||
char res_type[MAX_SEARCH+1] = {}; | |||||
rtosc_arg_t res_dat[MAX_SEARCH] = {}; | |||||
for(unsigned i=0; i<res.size() && i<MAX_SEARCH; ++i) { | for(unsigned i=0; i<res.size() && i<MAX_SEARCH; ++i) { | ||||
res_type[i] = 's'; | res_type[i] = 's'; | ||||
res_dat[i].s = res[i].c_str(); | res_dat[i].s = res[i].c_str(); | ||||
@@ -1128,7 +1097,7 @@ const rtosc::Ports bankPorts = { | |||||
******************************************************************************/ | ******************************************************************************/ | ||||
#undef rObject | #undef rObject | ||||
#define rObject CarlaMiddleWareImpl | |||||
#define rObject MiddleWareImpl | |||||
#ifndef STRINGIFY | #ifndef STRINGIFY | ||||
#define STRINGIFY2(a) #a | #define STRINGIFY2(a) #a | ||||
@@ -1180,13 +1149,13 @@ static rtosc::Ports middwareSnoopPorts = { | |||||
GUI::raiseUi(impl.ui, buffer); | GUI::raiseUi(impl.ui, buffer); | ||||
} | } | ||||
rEnd}, | rEnd}, | ||||
{"config/", 0, &CarlaConfig::ports, | |||||
{"config/", 0, &Config::ports, | |||||
rBegin; | rBegin; | ||||
d.obj = impl.config; | d.obj = impl.config; | ||||
CarlaConfig::ports.dispatch(chomp(msg), d); | |||||
Config::ports.dispatch(chomp(msg), d); | |||||
rEnd}, | rEnd}, | ||||
{"presets/", 0, &real_preset_ports, [](const char *msg, RtData &d) { | {"presets/", 0, &real_preset_ports, [](const char *msg, RtData &d) { | ||||
CarlaMiddleWareImpl *obj = (CarlaMiddleWareImpl*)d.obj; | |||||
MiddleWareImpl *obj = (MiddleWareImpl*)d.obj; | |||||
d.obj = (void*)obj->parent; | d.obj = (void*)obj->parent; | ||||
real_preset_ports.dispatch(chomp(msg), d); | real_preset_ports.dispatch(chomp(msg), d); | ||||
if(strstr(msg, "paste") && rtosc_argument_string(msg)[0] == 's') | if(strstr(msg, "paste") && rtosc_argument_string(msg)[0] == 's') | ||||
@@ -1201,21 +1170,26 @@ static rtosc::Ports middwareSnoopPorts = { | |||||
rEnd}, | rEnd}, | ||||
{"save_xlz:s", 0, 0, | {"save_xlz:s", 0, 0, | ||||
rBegin; | rBegin; | ||||
const char *file = rtosc_argument(msg, 0).s; | |||||
XMLwrapper xml; | |||||
saveMidiLearn(xml, impl.midi_mapper); | |||||
xml.saveXMLfile(file, impl.master->gzip_compression); | |||||
impl.doReadOnlyOp([&]() { | |||||
const char *file = rtosc_argument(msg, 0).s; | |||||
XMLwrapper xml; | |||||
Master::saveAutomation(xml, impl.master->automate); | |||||
xml.saveXMLfile(file, impl.master->gzip_compression); | |||||
}); | |||||
rEnd}, | rEnd}, | ||||
{"load_xlz:s", 0, 0, | {"load_xlz:s", 0, 0, | ||||
rBegin; | rBegin; | ||||
const char *file = rtosc_argument(msg, 0).s; | const char *file = rtosc_argument(msg, 0).s; | ||||
XMLwrapper xml; | XMLwrapper xml; | ||||
xml.loadXMLfile(file); | xml.loadXMLfile(file); | ||||
loadMidiLearn(xml, impl.midi_mapper); | |||||
rtosc::AutomationMgr *mgr = new rtosc::AutomationMgr(16,4,8); | |||||
mgr->set_ports(Master::ports); | |||||
Master::loadAutomation(xml, *mgr); | |||||
d.chain("/automate/load-blob", "b", sizeof(void*), &mgr); | |||||
rEnd}, | rEnd}, | ||||
{"clear_xlz:", 0, 0, | {"clear_xlz:", 0, 0, | ||||
rBegin; | rBegin; | ||||
impl.midi_mapper.clear(); | |||||
d.chain("/automate/clear", ""); | |||||
rEnd}, | rEnd}, | ||||
//scale file stuff | //scale file stuff | ||||
{"load_xsz:s", 0, 0, | {"load_xsz:s", 0, 0, | ||||
@@ -1388,51 +1362,51 @@ static rtosc::Ports middwareSnoopPorts = { | |||||
impl.undo.seekHistory(+1); | impl.undo.seekHistory(+1); | ||||
rEnd}, | rEnd}, | ||||
//port to observe the midi mappings | //port to observe the midi mappings | ||||
{"midi-learn-values:", 0, 0, | |||||
rBegin; | |||||
auto &midi = impl.midi_mapper; | |||||
auto key = keys(midi.inv_map); | |||||
//cc-id, path, min, max | |||||
#define MAX_MIDI 32 | |||||
rtosc_arg_t args[MAX_MIDI*4]; | |||||
char argt[MAX_MIDI*4+1] = {0}; | |||||
int j=0; | |||||
for(unsigned i=0; i<key.size() && i<MAX_MIDI; ++i) { | |||||
auto val = midi.inv_map[key[i]]; | |||||
if(std::get<1>(val) == -1) | |||||
continue; | |||||
argt[4*j+0] = 'i'; | |||||
args[4*j+0].i = std::get<1>(val); | |||||
argt[4*j+1] = 's'; | |||||
args[4*j+1].s = key[i].c_str(); | |||||
argt[4*j+2] = 'i'; | |||||
args[4*j+2].i = 0; | |||||
argt[4*j+3] = 'i'; | |||||
args[4*j+3].i = 127; | |||||
j++; | |||||
} | |||||
d.replyArray(d.loc, argt, args); | |||||
#undef MAX_MIDI | |||||
rEnd}, | |||||
{"learn:s", 0, 0, | |||||
rBegin; | |||||
string addr = rtosc_argument(msg, 0).s; | |||||
auto &midi = impl.midi_mapper; | |||||
auto map = midi.getMidiMappingStrings(); | |||||
if(map.find(addr) != map.end()) | |||||
midi.map(addr.c_str(), false); | |||||
else | |||||
midi.map(addr.c_str(), true); | |||||
rEnd}, | |||||
{"unlearn:s", 0, 0, | |||||
rBegin; | |||||
string addr = rtosc_argument(msg, 0).s; | |||||
auto &midi = impl.midi_mapper; | |||||
auto map = midi.getMidiMappingStrings(); | |||||
midi.unMap(addr.c_str(), false); | |||||
midi.unMap(addr.c_str(), true); | |||||
rEnd}, | |||||
//{"midi-learn-values:", 0, 0, | |||||
// rBegin; | |||||
// auto &midi = impl.midi_mapper; | |||||
// auto key = keys(midi.inv_map); | |||||
// //cc-id, path, min, max | |||||
//#define MAX_MIDI 32 | |||||
// rtosc_arg_t args[MAX_MIDI*4]; | |||||
// char argt[MAX_MIDI*4+1] = {}; | |||||
// int j=0; | |||||
// for(unsigned i=0; i<key.size() && i<MAX_MIDI; ++i) { | |||||
// auto val = midi.inv_map[key[i]]; | |||||
// if(std::get<1>(val) == -1) | |||||
// continue; | |||||
// argt[4*j+0] = 'i'; | |||||
// args[4*j+0].i = std::get<1>(val); | |||||
// argt[4*j+1] = 's'; | |||||
// args[4*j+1].s = key[i].c_str(); | |||||
// argt[4*j+2] = 'i'; | |||||
// args[4*j+2].i = 0; | |||||
// argt[4*j+3] = 'i'; | |||||
// args[4*j+3].i = 127; | |||||
// j++; | |||||
// } | |||||
// d.replyArray(d.loc, argt, args); | |||||
//#undef MAX_MIDI | |||||
// rEnd}, | |||||
//{"learn:s", 0, 0, | |||||
// rBegin; | |||||
// string addr = rtosc_argument(msg, 0).s; | |||||
// auto &midi = impl.midi_mapper; | |||||
// auto map = midi.getMidiMappingStrings(); | |||||
// if(map.find(addr) != map.end()) | |||||
// midi.map(addr.c_str(), false); | |||||
// else | |||||
// midi.map(addr.c_str(), true); | |||||
// rEnd}, | |||||
//{"unlearn:s", 0, 0, | |||||
// rBegin; | |||||
// string addr = rtosc_argument(msg, 0).s; | |||||
// auto &midi = impl.midi_mapper; | |||||
// auto map = midi.getMidiMappingStrings(); | |||||
// midi.unMap(addr.c_str(), false); | |||||
// midi.unMap(addr.c_str(), true); | |||||
// rEnd}, | |||||
//drop this message into the abyss | //drop this message into the abyss | ||||
{"ui/title:", 0, 0, [](const char *msg, RtData &d) {}}, | {"ui/title:", 0, 0, [](const char *msg, RtData &d) {}}, | ||||
{"quit:", 0, 0, [](const char *, RtData&) {Pexitprogram = 1;}}, | {"quit:", 0, 0, [](const char *, RtData&) {Pexitprogram = 1;}}, | ||||
@@ -1479,10 +1453,6 @@ static rtosc::Ports middlewareReplyPorts = { | |||||
if(impl.recording_undo) | if(impl.recording_undo) | ||||
impl.undo.recordEvent(msg); | impl.undo.recordEvent(msg); | ||||
rEnd}, | rEnd}, | ||||
{"midi-use-CC:i", 0, 0, | |||||
rBegin; | |||||
impl.midi_mapper.useFreeID(rtosc_argument(msg, 0).i); | |||||
rEnd}, | |||||
{"broadcast:", 0, 0, rBegin; impl.broadcast = true; rEnd}, | {"broadcast:", 0, 0, rBegin; impl.broadcast = true; rEnd}, | ||||
{"forward:", 0, 0, rBegin; impl.forward = true; rEnd}, | {"forward:", 0, 0, rBegin; impl.forward = true; rEnd}, | ||||
}; | }; | ||||
@@ -1493,8 +1463,8 @@ static rtosc::Ports middlewareReplyPorts = { | |||||
* MiddleWare Implementation * | * MiddleWare Implementation * | ||||
******************************************************************************/ | ******************************************************************************/ | ||||
CarlaMiddleWareImpl::CarlaMiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, | |||||
CarlaConfig* config, int preferrred_port) | |||||
MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, | |||||
Config* config, int preferrred_port) | |||||
:parent(mw), config(config), ui(nullptr), synth(std::move(synth_)), | :parent(mw), config(config), ui(nullptr), synth(std::move(synth_)), | ||||
presetsstore(*config), autoSave(-1, [this]() { | presetsstore(*config), autoSave(-1, [this]() { | ||||
auto master = this->master; | auto master = this->master; | ||||
@@ -1507,8 +1477,8 @@ CarlaMiddleWareImpl::CarlaMiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, | |||||
{ | { | ||||
bToU = new rtosc::ThreadLink(4096*2*16,1024/16); | bToU = new rtosc::ThreadLink(4096*2*16,1024/16); | ||||
uToB = new rtosc::ThreadLink(4096*2*16,1024/16); | uToB = new rtosc::ThreadLink(4096*2*16,1024/16); | ||||
midi_mapper.base_ports = &Master::ports; | |||||
midi_mapper.rt_cb = [this](const char *msg){handleMsg(msg);}; | |||||
//midi_mapper.base_ports = &Master::ports; | |||||
//midi_mapper.rt_cb = [this](const char *msg){handleMsg(msg);}; | |||||
if(preferrred_port != -1) | if(preferrred_port != -1) | ||||
server = lo_server_new_with_proto(to_s(preferrred_port).c_str(), | server = lo_server_new_with_proto(to_s(preferrred_port).c_str(), | ||||
LO_UDP, liblo_error_cb); | LO_UDP, liblo_error_cb); | ||||
@@ -1561,7 +1531,7 @@ CarlaMiddleWareImpl::CarlaMiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, | |||||
offline = false; | offline = false; | ||||
} | } | ||||
CarlaMiddleWareImpl::~CarlaMiddleWareImpl(void) | |||||
MiddleWareImpl::~MiddleWareImpl(void) | |||||
{ | { | ||||
if(server) | if(server) | ||||
@@ -1597,7 +1567,7 @@ CarlaMiddleWareImpl::~CarlaMiddleWareImpl(void) | |||||
* 4) Observe /thaw_state and resume normal processing | * 4) Observe /thaw_state and resume normal processing | ||||
*/ | */ | ||||
void CarlaMiddleWareImpl::doReadOnlyOp(std::function<void()> read_only_fn) | |||||
void MiddleWareImpl::doReadOnlyOp(std::function<void()> read_only_fn) | |||||
{ | { | ||||
assert(uToB); | assert(uToB); | ||||
uToB->write("/freeze_state",""); | uToB->write("/freeze_state",""); | ||||
@@ -1606,7 +1576,7 @@ void CarlaMiddleWareImpl::doReadOnlyOp(std::function<void()> read_only_fn) | |||||
int tries = 0; | int tries = 0; | ||||
while(tries++ < 10000) { | while(tries++ < 10000) { | ||||
if(!bToU->hasNext()) { | if(!bToU->hasNext()) { | ||||
usleep(500); | |||||
os_usleep(500); | |||||
continue; | continue; | ||||
} | } | ||||
const char *msg = bToU->read(); | const char *msg = bToU->read(); | ||||
@@ -1641,13 +1611,13 @@ void CarlaMiddleWareImpl::doReadOnlyOp(std::function<void()> read_only_fn) | |||||
// the last heartbeat then it must be offline | // the last heartbeat then it must be offline | ||||
// - When marked offline the backend doesn't receive another heartbeat until it | // - When marked offline the backend doesn't receive another heartbeat until it | ||||
// registers the current beat that it's behind on | // registers the current beat that it's behind on | ||||
void CarlaMiddleWareImpl::heartBeat(Master *master) | |||||
void MiddleWareImpl::heartBeat(Master *master) | |||||
{ | { | ||||
//Current time | //Current time | ||||
//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 + | ||||
@@ -1691,7 +1661,7 @@ void CarlaMiddleWareImpl::heartBeat(Master *master) | |||||
} | } | ||||
void CarlaMiddleWareImpl::doReadOnlyOpPlugin(std::function<void()> read_only_fn) | |||||
void MiddleWareImpl::doReadOnlyOpPlugin(std::function<void()> read_only_fn) | |||||
{ | { | ||||
assert(uToB); | assert(uToB); | ||||
int offline = 0; | int offline = 0; | ||||
@@ -1710,7 +1680,7 @@ void CarlaMiddleWareImpl::doReadOnlyOpPlugin(std::function<void()> read_only_fn) | |||||
} | } | ||||
} | } | ||||
bool CarlaMiddleWareImpl::doReadOnlyOpNormal(std::function<void()> read_only_fn, bool canfail) | |||||
bool MiddleWareImpl::doReadOnlyOpNormal(std::function<void()> read_only_fn, bool canfail) | |||||
{ | { | ||||
assert(uToB); | assert(uToB); | ||||
uToB->write("/freeze_state",""); | uToB->write("/freeze_state",""); | ||||
@@ -1719,7 +1689,7 @@ bool CarlaMiddleWareImpl::doReadOnlyOpNormal(std::function<void()> read_only_fn, | |||||
int tries = 0; | int tries = 0; | ||||
while(tries++ < 2000) { | while(tries++ < 2000) { | ||||
if(!bToU->hasNext()) { | if(!bToU->hasNext()) { | ||||
usleep(500); | |||||
os_usleep(500); | |||||
continue; | continue; | ||||
} | } | ||||
const char *msg = bToU->read(); | const char *msg = bToU->read(); | ||||
@@ -1757,7 +1727,7 @@ bool CarlaMiddleWareImpl::doReadOnlyOpNormal(std::function<void()> read_only_fn, | |||||
return true; | return true; | ||||
} | } | ||||
void CarlaMiddleWareImpl::broadcastToRemote(const char *rtmsg) | |||||
void MiddleWareImpl::broadcastToRemote(const char *rtmsg) | |||||
{ | { | ||||
//Always send to the local UI | //Always send to the local UI | ||||
sendToRemote(rtmsg, "GUI"); | sendToRemote(rtmsg, "GUI"); | ||||
@@ -1770,7 +1740,7 @@ void CarlaMiddleWareImpl::broadcastToRemote(const char *rtmsg) | |||||
broadcast = false; | broadcast = false; | ||||
} | } | ||||
void CarlaMiddleWareImpl::sendToRemote(const char *rtmsg, std::string dest) | |||||
void MiddleWareImpl::sendToRemote(const char *rtmsg, std::string dest) | |||||
{ | { | ||||
if(!rtmsg || rtmsg[0] != '/' || !rtosc_message_length(rtmsg, -1)) { | if(!rtmsg || rtmsg[0] != '/' || !rtosc_message_length(rtmsg, -1)) { | ||||
printf("[Warning] Invalid message in sendToRemote <%s>...\n", rtmsg); | printf("[Warning] Invalid message in sendToRemote <%s>...\n", rtmsg); | ||||
@@ -1804,7 +1774,7 @@ void CarlaMiddleWareImpl::sendToRemote(const char *rtmsg, std::string dest) | |||||
* This includes forwarded events which need to be retransmitted to the backend | * This includes forwarded events which need to be retransmitted to the backend | ||||
* after the snooping code inspects the message | * after the snooping code inspects the message | ||||
*/ | */ | ||||
void CarlaMiddleWareImpl::bToUhandle(const char *rtmsg) | |||||
void MiddleWareImpl::bToUhandle(const char *rtmsg) | |||||
{ | { | ||||
//Verify Message isn't a known corruption bug | //Verify Message isn't a known corruption bug | ||||
assert(strcmp(rtmsg, "/part0/kit0/Ppadenableda")); | assert(strcmp(rtmsg, "/part0/kit0/Ppadenableda")); | ||||
@@ -1845,7 +1815,7 @@ void CarlaMiddleWareImpl::bToUhandle(const char *rtmsg) | |||||
} | } | ||||
//Allocate kits on a as needed basis | //Allocate kits on a as needed basis | ||||
void CarlaMiddleWareImpl::kitEnable(const char *msg) | |||||
void MiddleWareImpl::kitEnable(const char *msg) | |||||
{ | { | ||||
const string argv = rtosc_argument_string(msg); | const string argv = rtosc_argument_string(msg); | ||||
if(argv != "T") | if(argv != "T") | ||||
@@ -1879,7 +1849,7 @@ void CarlaMiddleWareImpl::kitEnable(const char *msg) | |||||
kitEnable(part, kit, type); | kitEnable(part, kit, type); | ||||
} | } | ||||
void CarlaMiddleWareImpl::kitEnable(int part, int kit, int type) | |||||
void MiddleWareImpl::kitEnable(int part, int kit, int type) | |||||
{ | { | ||||
//printf("attempting a kit enable<%d,%d,%d>\n", part, kit, type); | //printf("attempting a kit enable<%d,%d,%d>\n", part, kit, type); | ||||
string url = "/part"+to_s(part)+"/kit"+to_s(kit)+"/"; | string url = "/part"+to_s(part)+"/kit"+to_s(kit)+"/"; | ||||
@@ -1908,7 +1878,7 @@ void CarlaMiddleWareImpl::kitEnable(int part, int kit, int type) | |||||
/* | /* | ||||
* Handle all messages traveling to the realtime side. | * Handle all messages traveling to the realtime side. | ||||
*/ | */ | ||||
void CarlaMiddleWareImpl::handleMsg(const char *msg) | |||||
void MiddleWareImpl::handleMsg(const char *msg) | |||||
{ | { | ||||
//Check for known bugs | //Check for known bugs | ||||
assert(msg && *msg && strrchr(msg, '/')[1]); | assert(msg && *msg && strrchr(msg, '/')[1]); | ||||
@@ -1947,7 +1917,7 @@ void CarlaMiddleWareImpl::handleMsg(const char *msg) | |||||
} | } | ||||
} | } | ||||
void CarlaMiddleWareImpl::write(const char *path, const char *args, ...) | |||||
void MiddleWareImpl::write(const char *path, const char *args, ...) | |||||
{ | { | ||||
//We have a free buffer in the threadlink, so use it | //We have a free buffer in the threadlink, so use it | ||||
va_list va; | va_list va; | ||||
@@ -1956,7 +1926,7 @@ void CarlaMiddleWareImpl::write(const char *path, const char *args, ...) | |||||
va_end(va); | va_end(va); | ||||
} | } | ||||
void CarlaMiddleWareImpl::write(const char *path, const char *args, va_list va) | |||||
void MiddleWareImpl::write(const char *path, const char *args, va_list va) | |||||
{ | { | ||||
//printf("is that a '%s' I see there?\n", path); | //printf("is that a '%s' I see there?\n", path); | ||||
char *buffer = uToB->buffer(); | char *buffer = uToB->buffer(); | ||||
@@ -1973,9 +1943,9 @@ void CarlaMiddleWareImpl::write(const char *path, const char *args, va_list va) | |||||
/****************************************************************************** | /****************************************************************************** | ||||
* MidleWare Forwarding Stubs * | * MidleWare Forwarding Stubs * | ||||
******************************************************************************/ | ******************************************************************************/ | ||||
MiddleWare::MiddleWare(SYNTH_T synth, CarlaConfig* config, | |||||
MiddleWare::MiddleWare(SYNTH_T synth, Config* config, | |||||
int preferred_port) | int preferred_port) | ||||
:impl(new CarlaMiddleWareImpl(this, std::move(synth), config, preferred_port)) | |||||
:impl(new MiddleWareImpl(this, std::move(synth), config, preferred_port)) | |||||
{} | {} | ||||
MiddleWare::~MiddleWare(void) | MiddleWare::~MiddleWare(void) | ||||
@@ -2164,3 +2134,5 @@ PresetsStore& MiddleWare::getPresetsStore() | |||||
{ | { | ||||
return impl->presetsstore; | return impl->presetsstore; | ||||
} | } | ||||
} |
@@ -14,6 +14,10 @@ | |||||
#include <cstdarg> | #include <cstdarg> | ||||
#include <string> | #include <string> | ||||
class Fl_Osc_Interface; | |||||
namespace zyncarla { | |||||
struct SYNTH_T; | struct SYNTH_T; | ||||
class Master; | class Master; | ||||
class PresetsStore; | class PresetsStore; | ||||
@@ -22,7 +26,7 @@ class PresetsStore; | |||||
class MiddleWare | class MiddleWare | ||||
{ | { | ||||
public: | public: | ||||
MiddleWare(SYNTH_T synth, class CarlaConfig *config, | |||||
MiddleWare(SYNTH_T synth, class Config *config, | |||||
int preferred_port = -1); | int preferred_port = -1); | ||||
~MiddleWare(void); | ~MiddleWare(void); | ||||
void updateResources(Master *m); | void updateResources(Master *m); | ||||
@@ -41,7 +45,7 @@ class MiddleWare | |||||
void removeAutoSave(void); | void removeAutoSave(void); | ||||
//return UI interface | //return UI interface | ||||
class Fl_Osc_Interface *spawnUiApi(void); | |||||
Fl_Osc_Interface *spawnUiApi(void); | |||||
//Set callback to push UI events to | //Set callback to push UI events to | ||||
void setUiCallback(void(*cb)(void*,const char *),void *ui); | void setUiCallback(void(*cb)(void*,const char *),void *ui); | ||||
//Set callback to run while busy | //Set callback to run while busy | ||||
@@ -79,5 +83,8 @@ class MiddleWare | |||||
const PresetsStore& getPresetsStore() const; | const PresetsStore& getPresetsStore() const; | ||||
PresetsStore& getPresetsStore(); | PresetsStore& getPresetsStore(); | ||||
private: | private: | ||||
class CarlaMiddleWareImpl *impl; | |||||
class MiddleWareImpl *impl; | |||||
}; | }; | ||||
} | |||||
@@ -37,6 +37,8 @@ | |||||
#include <rtosc/port-sugar.h> | #include <rtosc/port-sugar.h> | ||||
#include <iostream> | #include <iostream> | ||||
namespace zyncarla { | |||||
using rtosc::Ports; | using rtosc::Ports; | ||||
using rtosc::RtData; | using rtosc::RtData; | ||||
@@ -45,41 +47,55 @@ static const Ports partPorts = { | |||||
rRecurs(kit, 16, "Kit"),//NUM_KIT_ITEMS | rRecurs(kit, 16, "Kit"),//NUM_KIT_ITEMS | ||||
rRecursp(partefx, 3, "Part Effect"), | rRecursp(partefx, 3, "Part Effect"), | ||||
rRecur(ctl, "Controller"), | rRecur(ctl, "Controller"), | ||||
rToggle(Penabled, rShort("enable"), "Part enable"), | |||||
rParamZyn(partno, rProp(internal), | |||||
"How many parts are before this in the Master"), | |||||
#undef rChangeCb | |||||
#define rChangeCb if(obj->Penabled == false) obj->AllNotesOff(); | |||||
rToggle(Penabled, rShort("enable"), rDefaultDepends(partno), | |||||
rPresets(true), rDefault(false), "Part enable"), | |||||
#undef rChangeCb | |||||
#define rChangeCb | |||||
#undef rChangeCb | #undef rChangeCb | ||||
#define rChangeCb obj->setPvolume(obj->Pvolume); | #define rChangeCb obj->setPvolume(obj->Pvolume); | ||||
rParamZyn(Pvolume, rShort("Vol"), "Part Volume"), | |||||
rParamZyn(Pvolume, rShort("Vol"), rDefault(96),"Part Volume"), | |||||
#undef rChangeCb | #undef rChangeCb | ||||
#define rChangeCb obj->setPpanning(obj->Ppanning); | #define rChangeCb obj->setPpanning(obj->Ppanning); | ||||
rParamZyn(Ppanning, rShort("pan"), "Set Panning"), | |||||
rParamZyn(Ppanning, rShort("pan"), rDefault(64), "Set Panning"), | |||||
#undef rChangeCb | #undef rChangeCb | ||||
#define rChangeCb obj->setkeylimit(obj->Pkeylimit); | #define rChangeCb obj->setkeylimit(obj->Pkeylimit); | ||||
rParamI(Pkeylimit, rShort("limit"), rProp(parameter), rMap(min,0), rMap(max, POLYPHONY), "Key limit per part"), | |||||
rParamI(Pkeylimit, rShort("limit"), rProp(parameter), | |||||
rMap(min,0), rMap(max, POLYPHONY), rDefault(15), "Key limit per part"), | |||||
#undef rChangeCb | #undef rChangeCb | ||||
#define rChangeCb | #define rChangeCb | ||||
rParamZyn(Pminkey, rShort("min"), "Min Used Key"), | |||||
rParamZyn(Pmaxkey, rShort("max"), "Max Used Key"), | |||||
rParamZyn(Pkeyshift, rShort("shift"), "Part keyshift"), | |||||
rParamZyn(Pminkey, rShort("min"), rDefault(0), "Min Used Key"), | |||||
rParamZyn(Pmaxkey, rShort("max"), rDefault(127), "Max Used Key"), | |||||
rParamZyn(Pkeyshift, rShort("shift"), rDefault(64), "Part keyshift"), | |||||
rParamZyn(Prcvchn, rOptions(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16), | rParamZyn(Prcvchn, rOptions(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16), | ||||
"Active MIDI channel"), | |||||
rParamZyn(Pvelsns, rShort("sense"), "Velocity sensing"), | |||||
rParamZyn(Pveloffs, rShort("offset"), "Velocity offset"), | |||||
rToggle(Pnoteon, "If the channel accepts note on events"), | |||||
rOption(Pkitmode, rOptions(Off, Multi-Kit, Single-Kit), "Kit mode/enable\n" | |||||
rPresets(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16), | |||||
"Active MIDI channel"), | |||||
rParamZyn(Pvelsns, rShort("sense"), rDefault(64), "Velocity sensing"), | |||||
rParamZyn(Pveloffs, rShort("offset"), rDefault(64),"Velocity offset"), | |||||
rToggle(Pnoteon, rDefault(true), "If the channel accepts note on events"), | |||||
rOption(Pkitmode, rOptions(Off, Multi-Kit, Single-Kit), rDefault(Off), | |||||
"Kit mode/enable\n" | |||||
"Off - Only the first kit is ever utilized\n" | "Off - Only the first kit is ever utilized\n" | ||||
"Multi-kit - Every applicable kit is run for a note\n" | "Multi-kit - Every applicable kit is run for a note\n" | ||||
"Single-kit - The first applicable kit is run for a given note"), | "Single-kit - The first applicable kit is run for a given note"), | ||||
rToggle(Pdrummode, "Drum mode enable\n" | |||||
rToggle(Pdrummode, rDefault(false), "Drum mode enable\n" | |||||
"When drum mode is enabled all keys are mapped to 12tET and legato is disabled"), | "When drum mode is enabled all keys are mapped to 12tET and legato is disabled"), | ||||
rToggle(Ppolymode, "Polyphony mode"), | |||||
rToggle(Plegatomode, "Legato mode"), | |||||
rParamZyn(info.Ptype, "Class of Instrument"), | |||||
rString(info.Pauthor, MAX_INFO_TEXT_SIZE, "Instrument author"), | |||||
rString(info.Pcomments, MAX_INFO_TEXT_SIZE, "Instrument comments"), | |||||
rString(Pname, PART_MAX_NAME_LEN, "User specified label"), | |||||
rToggle(Ppolymode, rDefault(true), "Polyphony mode"), | |||||
rToggle(Plegatomode, rDefault(false), "Legato mode"), | |||||
rParamZyn(info.Ptype, rDefault(0), "Class of Instrument"), | |||||
rString(info.Pauthor, MAX_INFO_TEXT_SIZE, rDefault(""), | |||||
"Instrument author"), | |||||
rString(info.Pcomments, MAX_INFO_TEXT_SIZE, rDefault(""), | |||||
"Instrument comments"), | |||||
rString(Pname, PART_MAX_NAME_LEN, rDefault(""), "User specified label"), | |||||
rArrayI(Pefxroute, NUM_PART_EFX, | rArrayI(Pefxroute, NUM_PART_EFX, | ||||
rOptions(Next Effect,Part Out,Dry Out), "Effect Routing"), | |||||
rArrayT(Pefxbypass, NUM_PART_EFX, "If an effect is bypassed"), | |||||
rOptions(Next Effect,Part Out,Dry Out), rDefaultId(Next Effect), | |||||
"Effect Routing"), | |||||
rArrayT(Pefxbypass, NUM_PART_EFX, rDefault(false), | |||||
"If an effect is bypassed"), | |||||
{"captureMin:", rDoc("Capture minimum valid note"), NULL, | {"captureMin:", rDoc("Capture minimum valid note"), NULL, | ||||
[](const char *, RtData &r) | [](const char *, RtData &r) | ||||
{Part *p = (Part*)r.obj; p->Pminkey = p->lastnote;}}, | {Part *p = (Part*)r.obj; p->Pminkey = p->lastnote;}}, | ||||
@@ -156,20 +172,26 @@ static const Ports partPorts = { | |||||
#undef rObject | #undef rObject | ||||
#define rObject Part::Kit | #define rObject Part::Kit | ||||
static const Ports kitPorts = { | static const Ports kitPorts = { | ||||
rSelf(Part::Kit, rEnabledBy(Penabled)), | |||||
rRecurp(padpars, "Padnote parameters"), | rRecurp(padpars, "Padnote parameters"), | ||||
rRecurp(adpars, "Adnote parameters"), | rRecurp(adpars, "Adnote parameters"), | ||||
rRecurp(subpars, "Adnote parameters"), | rRecurp(subpars, "Adnote parameters"), | ||||
rToggle(Penabled, "Kit item enable"), | |||||
rToggle(Pmuted, "Kit item mute"), | |||||
rParamZyn(Pminkey, "Kit item min key"), | |||||
rParamZyn(Pmaxkey, "Kit item max key"), | |||||
rToggle(Padenabled, "ADsynth enable"), | |||||
rToggle(Psubenabled, "SUBsynth enable"), | |||||
rToggle(Ppadenabled, "PADsynth enable"), | |||||
rToggle(firstkit, rProp(internal), "If this is the part's first kit"), | |||||
rToggle(Penabled, rDefaultDepends(firstkit), | |||||
rPreset(true, true), rPreset(false, false), | |||||
"Kit item enable"), | |||||
rToggle(Pmuted, rDefault(false), "Kit item mute"), | |||||
rParamZyn(Pminkey, rDefault(0), "Kit item min key"), | |||||
rParamZyn(Pmaxkey, rDefault(127) "Kit item max key"), | |||||
rToggle(Padenabled, rDefaultDepends(firstkit), | |||||
rPreset(true, true), rPreset(false, false) | |||||
"ADsynth enable"), | |||||
rToggle(Psubenabled, rDefault(false), "SUBsynth enable"), | |||||
rToggle(Ppadenabled, rDefault(false), "PADsynth enable"), | |||||
rParamZyn(Psendtoparteffect, | rParamZyn(Psendtoparteffect, | ||||
rOptions(FX1, FX2, FX3, Off), | |||||
rOptions(FX1, FX2, FX3, Off), rDefault(FX1), | |||||
"Effect Levels"), | "Effect Levels"), | ||||
rString(Pname, PART_MAX_NAME_LEN, "Kit User Specified Label"), | |||||
rString(Pname, PART_MAX_NAME_LEN, rDefault(""), "Kit User Specified Label"), | |||||
{"captureMin:", rDoc("Capture minimum valid note"), NULL, | {"captureMin:", rDoc("Capture minimum valid note"), NULL, | ||||
[](const char *, RtData &r) | [](const char *, RtData &r) | ||||
{Part::Kit *p = (Part::Kit*)r.obj; p->Pminkey = p->parent->lastnote;}}, | {Part::Kit *p = (Part::Kit*)r.obj; p->Pminkey = p->parent->lastnote;}}, | ||||
@@ -326,6 +348,7 @@ void Part::defaultsinstrument() | |||||
for(int n = 0; n < NUM_KIT_ITEMS; ++n) { | for(int n = 0; n < NUM_KIT_ITEMS; ++n) { | ||||
//kit[n].Penabled = false; | //kit[n].Penabled = false; | ||||
kit[n].firstkit = false; | |||||
kit[n].Pmuted = false; | kit[n].Pmuted = false; | ||||
kit[n].Pminkey = 0; | kit[n].Pminkey = 0; | ||||
kit[n].Pmaxkey = 127; | kit[n].Pmaxkey = 127; | ||||
@@ -337,6 +360,7 @@ void Part::defaultsinstrument() | |||||
if(n != 0) | if(n != 0) | ||||
setkititemstatus(n, 0); | setkititemstatus(n, 0); | ||||
} | } | ||||
kit[0].firstkit = true; | |||||
kit[0].Penabled = 1; | kit[0].Penabled = 1; | ||||
kit[0].Padenabled = 1; | kit[0].Padenabled = 1; | ||||
kit[0].adpars->defaults(); | kit[0].adpars->defaults(); | ||||
@@ -1208,3 +1232,5 @@ bool Part::Kit::validNote(char note) const | |||||
{ | { | ||||
return !Pmuted && inRange((uint8_t)note, Pminkey, Pmaxkey); | return !Pmuted && inRange((uint8_t)note, Pminkey, Pmaxkey); | ||||
} | } | ||||
} |
@@ -22,6 +22,8 @@ | |||||
#include <functional> | #include <functional> | ||||
namespace zyncarla { | |||||
/** Part implementation*/ | /** Part implementation*/ | ||||
class Part | class Part | ||||
{ | { | ||||
@@ -83,6 +85,7 @@ class Part | |||||
struct Kit { | struct Kit { | ||||
Kit(void); | Kit(void); | ||||
Part *parent; | Part *parent; | ||||
bool firstkit; | |||||
bool Penabled, Pmuted; | bool Penabled, Pmuted; | ||||
unsigned char Pminkey, Pmaxkey; | unsigned char Pminkey, Pmaxkey; | ||||
char *Pname; | char *Pname; | ||||
@@ -104,13 +107,14 @@ class Part | |||||
void setkeylimit(unsigned char Pkeylimit); | void setkeylimit(unsigned char Pkeylimit); | ||||
void setkititemstatus(unsigned kititem, bool Penabled_); | void setkititemstatus(unsigned kititem, bool Penabled_); | ||||
unsigned char partno; /**<if it's the Master's first part*/ | |||||
bool Penabled; /**<if the part is enabled*/ | bool Penabled; /**<if the part is enabled*/ | ||||
unsigned char Pvolume; /**<part volume*/ | unsigned char Pvolume; /**<part volume*/ | ||||
unsigned char Pminkey; /**<the minimum key that the part receives noteon messages*/ | unsigned char Pminkey; /**<the minimum key that the part receives noteon messages*/ | ||||
unsigned char Pmaxkey; //the maximum key that the part receives noteon messages | unsigned char Pmaxkey; //the maximum key that the part receives noteon messages | ||||
void setPvolume(char Pvolume); | void setPvolume(char Pvolume); | ||||
unsigned char Pkeyshift; //Part keyshift | unsigned char Pkeyshift; //Part keyshift | ||||
unsigned char Prcvchn; //from what midi channel it receive commnads | |||||
unsigned char Prcvchn; //from what midi channel it receives commands | |||||
unsigned char Ppanning; //part panning | unsigned char Ppanning; //part panning | ||||
void setPpanning(char Ppanning); | void setPpanning(char Ppanning); | ||||
unsigned char Pvelsns; //velocity sensing (amplitude velocity scale) | unsigned char Pvelsns; //velocity sensing (amplitude velocity scale) | ||||
@@ -200,4 +204,6 @@ class Part | |||||
const int &gzip_compression, &interpolation; | const int &gzip_compression, &interpolation; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -31,8 +31,10 @@ | |||||
#include <rtosc/ports.h> | #include <rtosc/ports.h> | ||||
#include <rtosc/port-sugar.h> | #include <rtosc/port-sugar.h> | ||||
#include <string> | #include <string> | ||||
using std::string; | |||||
namespace zyncarla { | |||||
using std::string; | |||||
static void dummy(const char *, rtosc::RtData&) {} | static void dummy(const char *, rtosc::RtData&) {} | ||||
const rtosc::Ports real_preset_ports = | const rtosc::Ports real_preset_ports = | ||||
@@ -491,3 +493,5 @@ bool presetCheckClipboardType() | |||||
printf("PresetCheckClipboardType()<UNIMPLEMENTED>\n"); | printf("PresetCheckClipboardType()<UNIMPLEMENTED>\n"); | ||||
return true; | return true; | ||||
} | } | ||||
} |
@@ -13,8 +13,11 @@ | |||||
#include <string> | #include <string> | ||||
#include <rtosc/ports.h> | #include <rtosc/ports.h> | ||||
namespace zyncarla { | |||||
extern const rtosc::Ports real_preset_ports; | extern const rtosc::Ports real_preset_ports; | ||||
extern const rtosc::Ports preset_ports; | extern const rtosc::Ports preset_ports; | ||||
struct Clipboard { | struct Clipboard { | ||||
std::string data; | std::string data; | ||||
std::string type; | std::string type; | ||||
@@ -31,3 +34,5 @@ void presetDelete(int); | |||||
void presetRescan(); | void presetRescan(); | ||||
std::string presetClipboardType(); | std::string presetClipboardType(); | ||||
bool presetCheckClipboardType(); | bool presetCheckClipboardType(); | ||||
} |
@@ -17,6 +17,8 @@ | |||||
#include "../globals.h" | #include "../globals.h" | ||||
#include "../Nio/Nio.h" | #include "../Nio/Nio.h" | ||||
namespace zyncarla { | |||||
Recorder::Recorder(const SYNTH_T &synth_) | Recorder::Recorder(const SYNTH_T &synth_) | ||||
:status(0), notetrigger(0),synth(synth_) | :status(0), notetrigger(0),synth(synth_) | ||||
{} | {} | ||||
@@ -81,3 +83,4 @@ void Recorder::triggernow() | |||||
} | } | ||||
//TODO move recorder inside nio system | //TODO move recorder inside nio system | ||||
} |
@@ -15,6 +15,8 @@ | |||||
#define RECORDER_H | #define RECORDER_H | ||||
#include <string> | #include <string> | ||||
namespace zyncarla { | |||||
struct SYNTH_T; | struct SYNTH_T; | ||||
/**Records sound to a file*/ | /**Records sound to a file*/ | ||||
class Recorder | class Recorder | ||||
@@ -43,4 +45,6 @@ class Recorder | |||||
const SYNTH_T &synth; | const SYNTH_T &synth; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -1,6 +1,40 @@ | |||||
#include <ostream> | #include <ostream> | ||||
#include <rtosc/ports.h> | #include <rtosc/ports.h> | ||||
using namespace rtosc; | using namespace rtosc; | ||||
// forwards declaration from rtosc lib | |||||
void walk_ports2(const rtosc::Ports *base, | |||||
char *name_buffer, | |||||
size_t buffer_size, | |||||
void *data, | |||||
rtosc::port_walker_t walker); | |||||
namespace zyncarla { | |||||
static const char *escape_string(const char *msg) | |||||
{ | |||||
if(!msg) | |||||
return NULL; | |||||
char *out = (char*)malloc(strlen(msg)*2+1); | |||||
memset(out, 0, strlen(msg)*2+1); | |||||
char *itr = out; | |||||
while(*msg) { | |||||
if(*msg == '"') { | |||||
*itr++ = '\\'; | |||||
*itr++ = '\"'; | |||||
} else if(*msg == '\\') { | |||||
*itr++ = '\\'; | |||||
*itr++ = '\\'; | |||||
} else { | |||||
*itr++ = *msg; | |||||
} | |||||
msg++; | |||||
} | |||||
return out; | |||||
} | |||||
/* | /* | ||||
* root : | * root : | ||||
* - 'parameters' : [parameter...] | * - 'parameters' : [parameter...] | ||||
@@ -11,8 +45,12 @@ using namespace rtosc; | |||||
* - 'shortname' : string [OPTIONAL] | * - 'shortname' : string [OPTIONAL] | ||||
* - 'tooltip' : string [OPTIONAL] | * - 'tooltip' : string [OPTIONAL] | ||||
* - 'type' : type | * - 'type' : type | ||||
* - 'units' : unit-type | |||||
* - 'scale' : scale-type | |||||
* - 'domain' : range [OPTIONAL] | * - 'domain' : range [OPTIONAL] | ||||
* - 'options' : [option...] [OPTIONAL] | * - 'options' : [option...] [OPTIONAL] | ||||
* - 'default' : string | |||||
* - 'defaults' : defaults | |||||
* type : {'int', 'float', 'boolean'} | * type : {'int', 'float', 'boolean'} | ||||
* action : | * action : | ||||
* - 'path' : path-id | * - 'path' : path-id | ||||
@@ -23,15 +61,11 @@ using namespace rtosc; | |||||
* option : | * option : | ||||
* - 'id' : id-number | * - 'id' : id-number | ||||
* - 'value' : string-rep | * - 'value' : string-rep | ||||
* defaults : | |||||
* - 'id' : id-number | |||||
* - 'value' : string-rep | |||||
*/ | */ | ||||
void walk_ports2(const rtosc::Ports *base, | |||||
char *name_buffer, | |||||
size_t buffer_size, | |||||
void *data, | |||||
rtosc::port_walker_t walker); | |||||
using std::ostream; | using std::ostream; | ||||
using std::string; | using std::string; | ||||
static int enum_min(Port::MetaContainer meta) | static int enum_min(Port::MetaContainer meta) | ||||
@@ -102,7 +136,8 @@ static ostream &add_options(ostream &o, Port::MetaContainer meta) | |||||
* - 'domain' : range [OPTIONAL] | * - 'domain' : range [OPTIONAL] | ||||
*/ | */ | ||||
static bool first = true; | static bool first = true; | ||||
void dump_param_cb(const rtosc::Port *p, const char *full_name, void *v) | |||||
void dump_param_cb(const rtosc::Port *p, const char *full_name, const char*, | |||||
const Ports&,void *v, void*) | |||||
{ | { | ||||
typedef std::vector<std::pair<int,string>> opts; | typedef std::vector<std::pair<int,string>> opts; | ||||
std::ostream &o = *(std::ostream*)v; | std::ostream &o = *(std::ostream*)v; | ||||
@@ -111,6 +146,9 @@ void dump_param_cb(const rtosc::Port *p, const char *full_name, void *v) | |||||
auto mparameter = meta.find("parameter"); | auto mparameter = meta.find("parameter"); | ||||
auto mdoc = meta.find("documentation"); | auto mdoc = meta.find("documentation"); | ||||
auto msname = meta.find("shortname"); | auto msname = meta.find("shortname"); | ||||
auto units = meta.find("unit"); | |||||
auto scale = meta.find("scale"); | |||||
opts options; | opts options; | ||||
string doc; | string doc; | ||||
string name = p->name;; | string name = p->name;; | ||||
@@ -166,6 +204,8 @@ void dump_param_cb(const rtosc::Port *p, const char *full_name, void *v) | |||||
const char *min = meta["min"]; | const char *min = meta["min"]; | ||||
const char *max = meta["max"]; | const char *max = meta["max"]; | ||||
const char *def = meta["default"]; | |||||
def = escape_string(def); | |||||
for(auto m:meta) { | for(auto m:meta) { | ||||
if(strlen(m.title) >= 5 && !memcmp(m.title, "map ", 4)) { | if(strlen(m.title) >= 5 && !memcmp(m.title, "map ", 4)) { | ||||
@@ -186,9 +226,15 @@ void dump_param_cb(const rtosc::Port *p, const char *full_name, void *v) | |||||
o << " \"shortname\": \"" << msname.value << "\",\n"; | o << " \"shortname\": \"" << msname.value << "\",\n"; | ||||
o << " \"name\" : \"" << name << "\",\n"; | o << " \"name\" : \"" << name << "\",\n"; | ||||
o << " \"tooltip\" : \"" << doc << "\",\n"; | o << " \"tooltip\" : \"" << doc << "\",\n"; | ||||
if(units != meta.end()) | |||||
o << " \"units\" : \"" << units.value << "\",\n"; | |||||
if(scale != meta.end()) | |||||
o << " \"scale\" : \"" << scale.value << "\",\n"; | |||||
o << " \"type\" : \"" << type << "\""; | o << " \"type\" : \"" << type << "\""; | ||||
if(min && max) | if(min && max) | ||||
o << ",\n \"range\" : [" << min << "," << max << "]"; | o << ",\n \"range\" : [" << min << "," << max << "]"; | ||||
if(def) | |||||
o << ",\n \"default\" : \"" << def << "\"\n"; | |||||
if(!options.empty()) { | if(!options.empty()) { | ||||
o << ",\n \"options\" : [\n"; | o << ",\n \"options\" : [\n"; | ||||
int N = options.size(); | int N = options.size(); | ||||
@@ -221,4 +267,4 @@ void dump_json(std::ostream &o, const rtosc::Ports &p) | |||||
o << "}"; | o << "}"; | ||||
} | } | ||||
} |
@@ -11,6 +11,8 @@ | |||||
of the License, or (at your option) any later version. | of the License, or (at your option) any later version. | ||||
*/ | */ | ||||
namespace zyncarla { | |||||
template<class T> | template<class T> | ||||
Stereo<T>::Stereo(const T &left, const T &right) | Stereo<T>::Stereo(const T &left, const T &right) | ||||
:l(left), r(right) | :l(left), r(right) | ||||
@@ -28,3 +30,5 @@ Stereo<T> &Stereo<T>::operator=(const Stereo<T> &nstr) | |||||
r = nstr.r; | r = nstr.r; | ||||
return *this; | return *this; | ||||
} | } | ||||
} |
@@ -13,6 +13,8 @@ | |||||
#ifndef STEREO_H | #ifndef STEREO_H | ||||
#define STEREO_H | #define STEREO_H | ||||
namespace zyncarla { | |||||
template<class T> | template<class T> | ||||
struct Stereo { | struct Stereo { | ||||
public: | public: | ||||
@@ -28,5 +30,8 @@ struct Stereo { | |||||
//data | //data | ||||
T l, r; | T l, r; | ||||
}; | }; | ||||
} | |||||
#include "Stereo.cpp" | #include "Stereo.cpp" | ||||
#endif | #endif |
@@ -13,6 +13,8 @@ | |||||
#include <stdint.h> | #include <stdint.h> | ||||
#include "../globals.h" | #include "../globals.h" | ||||
namespace zyncarla { | |||||
class AbsTime | class AbsTime | ||||
{ | { | ||||
public: | public: | ||||
@@ -51,3 +53,5 @@ class RelTime | |||||
int32_t sample; | int32_t sample; | ||||
const AbsTime &t; | const AbsTime &t; | ||||
}; | }; | ||||
} |
@@ -36,6 +36,8 @@ | |||||
#include <rtosc/rtosc.h> | #include <rtosc/rtosc.h> | ||||
namespace zyncarla { | |||||
bool isPlugin = false; | bool isPlugin = false; | ||||
prng_t prng_state = 0x1234; | prng_t prng_state = 0x1234; | ||||
@@ -127,10 +129,31 @@ void set_realtime() | |||||
#endif | #endif | ||||
} | } | ||||
void os_sleep(long length) | |||||
#ifdef WIN32 | |||||
#include <windows.h> | |||||
//https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw | |||||
void os_usleep(long usec) | |||||
{ | |||||
HANDLE timer; | |||||
LARGE_INTEGER ft; | |||||
ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time | |||||
timer = CreateWaitableTimer(NULL, TRUE, NULL); | |||||
SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); | |||||
WaitForSingleObject(timer, INFINITE); | |||||
CloseHandle(timer); | |||||
} | |||||
#else | |||||
void os_usleep(long length) | |||||
{ | { | ||||
usleep(length); | usleep(length); | ||||
} | } | ||||
#endif | |||||
//!< maximum lenght a pid has on any POSIX system | //!< maximum lenght a pid has on any POSIX system | ||||
//!< this is an estimation, but more than 12 looks insane | //!< this is an estimation, but more than 12 looks insane | ||||
@@ -225,3 +248,5 @@ char *rtosc_splat(const char *path, std::set<std::string> v) | |||||
rtosc_amessage(buf, len, path, argT, arg); | rtosc_amessage(buf, len, path, argT, arg); | ||||
return buf; | return buf; | ||||
} | } | ||||
} |
@@ -23,16 +23,17 @@ | |||||
#include <rtosc/ports.h> | #include <rtosc/ports.h> | ||||
#include <rtosc/port-sugar.h> | #include <rtosc/port-sugar.h> | ||||
namespace zyncarla { | |||||
extern bool isPlugin; | |||||
bool fileexists(const char *filename); | |||||
using std::min; | using std::min; | ||||
using std::max; | using std::max; | ||||
//Velocity Sensing function | //Velocity Sensing function | ||||
extern float VelF(float velocity, unsigned char scaling); | extern float VelF(float velocity, unsigned char scaling); | ||||
extern bool isPlugin; | |||||
bool fileexists(const char *filename); | |||||
#define N_DETUNE_TYPES 4 //the number of detune types | #define N_DETUNE_TYPES 4 //the number of detune types | ||||
extern float getdetune(unsigned char type, | extern float getdetune(unsigned char type, | ||||
unsigned short int coarsedetune, | unsigned short int coarsedetune, | ||||
@@ -45,7 +46,7 @@ extern float getdetune(unsigned char type, | |||||
void set_realtime(); | void set_realtime(); | ||||
/**Os independent sleep in microsecond*/ | /**Os independent sleep in microsecond*/ | ||||
void os_sleep(long length); | |||||
void os_usleep(long length); | |||||
//! returns pid padded to maximum pid lenght, posix conform | //! returns pid padded to maximum pid lenght, posix conform | ||||
std::string os_pid_as_padded_string(); | std::string os_pid_as_padded_string(); | ||||
@@ -152,11 +153,6 @@ char *rtosc_splat(const char *path, std::set<std::string>); | |||||
#define rParamZyn(name, ...) \ | #define rParamZyn(name, ...) \ | ||||
{STRINGIFY(name) "::i", rProp(parameter) rMap(min, 0) rMap(max, 127) DOC(__VA_ARGS__), NULL, rParamICb(name)} | {STRINGIFY(name) "::i", rProp(parameter) rMap(min, 0) rMap(max, 127) DOC(__VA_ARGS__), NULL, rParamICb(name)} | ||||
#define rSelf(type) \ | |||||
{"self:", rProp(internal) rMap(class, type) rDoc("port metadata"), 0, \ | |||||
[](const char *, rtosc::RtData &d){ \ | |||||
d.reply(d.loc, "b", sizeof(d.obj), &d.obj);}}\ | |||||
#define rPresetType \ | #define rPresetType \ | ||||
{"preset-type:", rProp(internal) rDoc("clipboard type of object"), 0, \ | {"preset-type:", rProp(internal) rDoc("clipboard type of object"), 0, \ | ||||
[](const char *, rtosc::RtData &d){ \ | [](const char *, rtosc::RtData &d){ \ | ||||
@@ -181,4 +177,8 @@ rPresetType, \ | |||||
rObject &o = *(rObject*)d.obj;\ | rObject &o = *(rObject*)d.obj;\ | ||||
o.pasteArray(paste,field);}} | o.pasteArray(paste,field);}} | ||||
} | |||||
#define rUnit(x) rMap(unit, x) | |||||
#endif | #endif |
@@ -19,6 +19,8 @@ | |||||
#include "WavFile.h" | #include "WavFile.h" | ||||
using namespace std; | using namespace std; | ||||
namespace zyncarla { | |||||
WavFile::WavFile(string filename, int samplerate, int channels) | WavFile::WavFile(string filename, int samplerate, int channels) | ||||
:sampleswritten(0), samplerate(samplerate), channels(channels), | :sampleswritten(0), samplerate(samplerate), channels(channels), | ||||
file(fopen(filename.c_str(), "w")) | file(fopen(filename.c_str(), "w")) | ||||
@@ -90,3 +92,5 @@ void WavFile::writeMonoSamples(int nsmps, short int *smps) | |||||
sampleswritten += nsmps; | sampleswritten += nsmps; | ||||
} | } | ||||
} | } | ||||
} |
@@ -16,6 +16,8 @@ | |||||
#define WAVFILE_H | #define WAVFILE_H | ||||
#include <string> | #include <string> | ||||
namespace zyncarla { | |||||
class WavFile | class WavFile | ||||
{ | { | ||||
public: | public: | ||||
@@ -33,4 +35,7 @@ class WavFile | |||||
int channels; | int channels; | ||||
FILE *file; | FILE *file; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -14,6 +14,8 @@ | |||||
#include "WaveShapeSmps.h" | #include "WaveShapeSmps.h" | ||||
#include <cmath> | #include <cmath> | ||||
namespace zyncarla { | |||||
void waveShapeSmps(int n, | void waveShapeSmps(int n, | ||||
float *smps, | float *smps, | ||||
unsigned char type, | unsigned char type, | ||||
@@ -178,3 +180,5 @@ void waveShapeSmps(int n, | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} |
@@ -13,10 +13,14 @@ | |||||
#ifndef WAVESHAPESMPS_H | #ifndef WAVESHAPESMPS_H | ||||
#define WAVESHAPESMPS_H | #define WAVESHAPESMPS_H | ||||
namespace zyncarla { | |||||
//Waveshaping(called by Distorsion effect and waveshape from OscilGen) | //Waveshaping(called by Distorsion effect and waveshape from OscilGen) | ||||
void waveShapeSmps(int n, | void waveShapeSmps(int n, | ||||
float *smps, | float *smps, | ||||
unsigned char type, | unsigned char type, | ||||
unsigned char drive); | unsigned char drive); | ||||
} | |||||
#endif | #endif |
@@ -27,6 +27,8 @@ | |||||
using namespace std; | using namespace std; | ||||
namespace zyncarla { | |||||
int xml_k = 0; | int xml_k = 0; | ||||
bool verbose = false; | bool verbose = false; | ||||
@@ -251,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%8X", convert.out); | |||||
sprintf(buf, "0x%0.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); | ||||
} | } | ||||
@@ -395,6 +397,12 @@ bool XMLwrapper::putXMLdata(const char *xmldata) | |||||
if(root == NULL) | if(root == NULL) | ||||
return false; | return false; | ||||
//fetch version information | |||||
_fileversion.set_major(stringTo<int>(mxmlElementGetAttr(root, "version-major"))); | |||||
_fileversion.set_minor(stringTo<int>(mxmlElementGetAttr(root, "version-minor"))); | |||||
_fileversion.set_revision( | |||||
stringTo<int>(mxmlElementGetAttr(root, "version-revision"))); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -677,3 +685,5 @@ std::vector<XmlNode> XMLwrapper::getBranch(void) const | |||||
} | } | ||||
return res; | return res; | ||||
} | } | ||||
} |
@@ -21,6 +21,8 @@ | |||||
#ifndef XML_WRAPPER_H | #ifndef XML_WRAPPER_H | ||||
#define XML_WRAPPER_H | #define XML_WRAPPER_H | ||||
namespace zyncarla { | |||||
class XmlAttr | class XmlAttr | ||||
{ | { | ||||
public: | public: | ||||
@@ -285,4 +287,6 @@ public: | |||||
version_type _fileversion; | version_type _fileversion; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -15,8 +15,6 @@ | |||||
#include <iostream> | #include <iostream> | ||||
#include <cmath> | #include <cmath> | ||||
using namespace std; | |||||
#include "../Misc/Util.h" | #include "../Misc/Util.h" | ||||
#include "../Misc/Config.h" | #include "../Misc/Config.h" | ||||
#include "InMgr.h" | #include "InMgr.h" | ||||
@@ -24,6 +22,10 @@ using namespace std; | |||||
#include "Compressor.h" | #include "Compressor.h" | ||||
#include "Nio.h" | #include "Nio.h" | ||||
using namespace std; | |||||
namespace zyncarla { | |||||
AlsaEngine::AlsaEngine(const SYNTH_T &synth) | AlsaEngine::AlsaEngine(const SYNTH_T &synth) | ||||
:AudioOut(synth) | :AudioOut(synth) | ||||
{ | { | ||||
@@ -397,3 +399,5 @@ void *AlsaEngine::processAudio() | |||||
} | } | ||||
return NULL; | return NULL; | ||||
} | } | ||||
} |
@@ -24,6 +24,8 @@ | |||||
#include "OutMgr.h" | #include "OutMgr.h" | ||||
#include "../Misc/Stereo.h" | #include "../Misc/Stereo.h" | ||||
namespace zyncarla { | |||||
class AlsaEngine:public AudioOut, MidiIn | class AlsaEngine:public AudioOut, MidiIn | ||||
{ | { | ||||
public: | public: | ||||
@@ -74,4 +76,6 @@ class AlsaEngine:public AudioOut, MidiIn | |||||
void *processAudio(); | void *processAudio(); | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -15,12 +15,14 @@ | |||||
#include <cstring> | #include <cstring> | ||||
#include "SafeQueue.h" | #include "SafeQueue.h" | ||||
using namespace std; | |||||
#include "OutMgr.h" | #include "OutMgr.h" | ||||
#include "../Misc/Master.h" | #include "../Misc/Master.h" | ||||
#include "AudioOut.h" | #include "AudioOut.h" | ||||
using namespace std; | |||||
namespace zyncarla { | |||||
AudioOut::AudioOut(const SYNTH_T &synth_) | AudioOut::AudioOut(const SYNTH_T &synth_) | ||||
:synth(synth_), samplerate(synth.samplerate), bufferSize(synth.buffersize) | :synth(synth_), samplerate(synth.samplerate), bufferSize(synth.buffersize) | ||||
{} | {} | ||||
@@ -47,3 +49,5 @@ const Stereo<float *> AudioOut::getNext() | |||||
{ | { | ||||
return OutMgr::getInstance().tick(bufferSize); | return OutMgr::getInstance().tick(bufferSize); | ||||
} | } | ||||
} |
@@ -18,6 +18,8 @@ | |||||
#include "../globals.h" | #include "../globals.h" | ||||
#include "Engine.h" | #include "Engine.h" | ||||
namespace zyncarla { | |||||
class AudioOut:public virtual Engine | class AudioOut:public virtual Engine | ||||
{ | { | ||||
public: | public: | ||||
@@ -50,4 +52,6 @@ class AudioOut:public virtual Engine | |||||
int bufferSize; | int bufferSize; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -12,8 +12,12 @@ | |||||
*/ | */ | ||||
#include "Engine.h" | #include "Engine.h" | ||||
namespace zyncarla { | |||||
Engine::Engine() | Engine::Engine() | ||||
{} | {} | ||||
Engine::~Engine() | Engine::~Engine() | ||||
{} | {} | ||||
} |
@@ -14,6 +14,9 @@ | |||||
#ifndef ENGINE_H | #ifndef ENGINE_H | ||||
#define ENGINE_H | #define ENGINE_H | ||||
#include <string> | #include <string> | ||||
namespace zyncarla { | |||||
/**Marker for input/output driver*/ | /**Marker for input/output driver*/ | ||||
class Engine | class Engine | ||||
{ | { | ||||
@@ -29,4 +32,7 @@ class Engine | |||||
std::string name; | std::string name; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -19,6 +19,8 @@ | |||||
#include "AudioOut.h" | #include "AudioOut.h" | ||||
#include "MidiIn.h" | #include "MidiIn.h" | ||||
#include "NulEngine.h" | #include "NulEngine.h" | ||||
using namespace std; | |||||
#if OSS | #if OSS | ||||
#include "OssEngine.h" | #include "OssEngine.h" | ||||
#include "OssMultiEngine.h" | #include "OssMultiEngine.h" | ||||
@@ -34,7 +36,7 @@ | |||||
#include "PaEngine.h" | #include "PaEngine.h" | ||||
#endif | #endif | ||||
using namespace std; | |||||
namespace zyncarla { | |||||
EngineMgr &EngineMgr::getInstance(const SYNTH_T *synth, | EngineMgr &EngineMgr::getInstance(const SYNTH_T *synth, | ||||
const oss_devs_t *oss_devs) | const oss_devs_t *oss_devs) | ||||
@@ -172,3 +174,5 @@ bool EngineMgr::setOutDefault(string name) | |||||
cerr << " Defaulting to the NULL audio backend" << endl; | cerr << " Defaulting to the NULL audio backend" << endl; | ||||
return false; | return false; | ||||
} | } | ||||
} |
@@ -16,6 +16,7 @@ | |||||
#include <string> | #include <string> | ||||
#include "Engine.h" | #include "Engine.h" | ||||
namespace zyncarla { | |||||
class MidiIn; | class MidiIn; | ||||
class AudioOut; | class AudioOut; | ||||
@@ -54,4 +55,7 @@ class EngineMgr | |||||
private: | private: | ||||
EngineMgr(const SYNTH_T *synth, const oss_devs_t &oss_devs); | EngineMgr(const SYNTH_T *synth, const oss_devs_t &oss_devs); | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -17,10 +17,11 @@ | |||||
#include "../Misc/MiddleWare.h" | #include "../Misc/MiddleWare.h" | ||||
#include <rtosc/thread-link.h> | #include <rtosc/thread-link.h> | ||||
#include <iostream> | #include <iostream> | ||||
using namespace std; | using namespace std; | ||||
extern MiddleWare *middleware; | |||||
extern zyncarla::MiddleWare *middleware; | |||||
namespace zyncarla { | |||||
ostream &operator<<(ostream &out, const MidiEvent &ev) | ostream &operator<<(ostream &out, const MidiEvent &ev) | ||||
{ | { | ||||
@@ -172,3 +173,5 @@ void InMgr::setMaster(Master *master_) | |||||
{ | { | ||||
master = master_; | master = master_; | ||||
} | } | ||||
} |
@@ -16,6 +16,8 @@ | |||||
#include "ZynSema.h" | #include "ZynSema.h" | ||||
#include "SafeQueue.h" | #include "SafeQueue.h" | ||||
namespace zyncarla { | |||||
enum midi_type { | enum midi_type { | ||||
M_NOTE = 1, | M_NOTE = 1, | ||||
M_CONTROLLER = 2, | M_CONTROLLER = 2, | ||||
@@ -65,4 +67,6 @@ class InMgr | |||||
class Master *master; | class Master *master; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -32,10 +32,12 @@ | |||||
#include "JackEngine.h" | #include "JackEngine.h" | ||||
using namespace std; | |||||
extern char *instance_name; | extern char *instance_name; | ||||
namespace zyncarla { | |||||
using namespace std; | |||||
JackEngine::JackEngine(const SYNTH_T &synth) | JackEngine::JackEngine(const SYNTH_T &synth) | ||||
:AudioOut(synth), jackClient(NULL) | :AudioOut(synth), jackClient(NULL) | ||||
{ | { | ||||
@@ -438,3 +440,5 @@ void JackEngine::handleMidi(unsigned long frames) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} |
@@ -23,6 +23,8 @@ | |||||
#include "MidiIn.h" | #include "MidiIn.h" | ||||
#include "AudioOut.h" | #include "AudioOut.h" | ||||
namespace zyncarla { | |||||
typedef jack_default_audio_sample_t jsample_t; | typedef jack_default_audio_sample_t jsample_t; | ||||
class JackEngine:public AudioOut, MidiIn | class JackEngine:public AudioOut, MidiIn | ||||
@@ -83,4 +85,6 @@ class JackEngine:public AudioOut, MidiIn | |||||
void handleMidi(unsigned long frames); | void handleMidi(unsigned long frames); | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -26,7 +26,10 @@ | |||||
#include "JackMultiEngine.h" | #include "JackMultiEngine.h" | ||||
extern MiddleWare *middleware; | |||||
extern zyncarla::MiddleWare *middleware; | |||||
namespace zyncarla { | |||||
using std::string; | using std::string; | ||||
struct jack_multi | struct jack_multi | ||||
@@ -170,3 +173,5 @@ void JackMultiEngine::Stop() | |||||
impl->running = false; | impl->running = false; | ||||
} | } | ||||
} |
@@ -15,6 +15,8 @@ | |||||
#include "AudioOut.h" | #include "AudioOut.h" | ||||
namespace zyncarla { | |||||
class JackMultiEngine:public AudioOut | class JackMultiEngine:public AudioOut | ||||
{ | { | ||||
public: | public: | ||||
@@ -34,4 +36,6 @@ class JackMultiEngine:public AudioOut | |||||
struct jack_multi *impl; | struct jack_multi *impl; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -15,6 +15,8 @@ | |||||
#include "../globals.h" | #include "../globals.h" | ||||
#include "InMgr.h" | #include "InMgr.h" | ||||
namespace zyncarla { | |||||
void MidiIn::midiProcess(unsigned char head, | void MidiIn::midiProcess(unsigned char head, | ||||
unsigned char num, | unsigned char num, | ||||
unsigned char value) | unsigned char value) | ||||
@@ -66,3 +68,5 @@ void MidiIn::midiProcess(unsigned char head, | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} |
@@ -18,6 +18,8 @@ | |||||
#include "Engine.h" | #include "Engine.h" | ||||
namespace zyncarla { | |||||
/**This class is inherited by all the Midi input classes*/ | /**This class is inherited by all the Midi input classes*/ | ||||
class MidiIn:public virtual Engine | class MidiIn:public virtual Engine | ||||
{ | { | ||||
@@ -31,4 +33,6 @@ class MidiIn:public virtual Engine | |||||
unsigned char value); | unsigned char value); | ||||
}; | }; | ||||
} | |||||
#endif | #endif |
@@ -20,6 +20,9 @@ | |||||
#include <cstring> | #include <cstring> | ||||
#include <iostream> | #include <iostream> | ||||
#include <algorithm> | #include <algorithm> | ||||
namespace zyncarla { | |||||
using std::string; | using std::string; | ||||
using std::set; | using std::set; | ||||
using std::cerr; | using std::cerr; | ||||
@@ -183,3 +186,5 @@ void Nio::waveEnd(void) | |||||
{ | { | ||||
out->wave->destroyFile(); | out->wave->destroyFile(); | ||||
} | } | ||||
} |
@@ -14,6 +14,8 @@ | |||||
#include <string> | #include <string> | ||||
#include <set> | #include <set> | ||||
namespace zyncarla { | |||||
class WavFile; | class WavFile; | ||||
class Master; | class Master; | ||||
struct SYNTH_T; | struct SYNTH_T; | ||||
@@ -61,4 +63,6 @@ namespace Nio | |||||
extern std::string defaultSink; | extern std::string defaultSink; | ||||
}; | }; | ||||
} | |||||
#endif | #endif |