| @@ -144,6 +144,7 @@ bin/resources/*.py | |||
| source/native-plugins/resources/*.py | |||
| # zynaddsubfx | |||
| source/native-plugins/zynaddsubfx/rtosc/version.c.in | |||
| source/native-plugins/zynaddsubfx/Output/ | |||
| source/native-plugins/zynaddsubfx/Tests/ | |||
| 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/Params/* | |||
| rm -f $CARLA_ZYN_DIR/Synth/* | |||
| rm -f $CARLA_ZYN_DIR/Tests/* | |||
| rm -fr $CARLA_ZYN_DIR/UI/* | |||
| rm -fr $CARLA_ZYN_DIR/rtosc/* | |||
| 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 | |||
| 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_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|../../include/rtosc/|../|" $CARLA_ZYN_DIR/rtosc/cpp/*.cpp | |||
| @@ -31,7 +31,7 @@ endif # EXPERIMENTAL_PLUGINS | |||
| ifeq ($(HAVE_ZYN_DEPS),true) | |||
| 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_LD_FLAGS = $(LINK_FLAGS) | |||
| ZYN_LD_FLAGS += $(shell pkg-config --libs liblo) | |||
| @@ -34,6 +34,8 @@ using juce::roundToIntAccurate; | |||
| using juce::FloatVectorOperations; | |||
| using juce::SharedResourcePointer; | |||
| using namespace zyncarla; | |||
| // ----------------------------------------------------------------------- | |||
| template<class ZynFX> | |||
| @@ -241,7 +241,9 @@ extern "C" { | |||
| #undef rChangeCb | |||
| #define rChangeCb | |||
| #define INSTRUMENT_EXTENSION INSTRUMENT_EXTENSION_DB | |||
| #include "zynaddsubfx/Misc/BankDb.cpp" | |||
| #undef INSTRUMENT_EXTENSION | |||
| #undef rBegin | |||
| #undef rObject | |||
| #undef rStdString | |||
| @@ -528,6 +530,7 @@ extern "C" { | |||
| #include "zynaddsubfx/globals.cpp" | |||
| // Dummy variables and functions for linking purposes | |||
| namespace zyncarla { | |||
| class WavFile; | |||
| namespace Nio { | |||
| void masterSwap(Master*){} | |||
| @@ -541,3 +544,4 @@ namespace Nio { | |||
| void waveStart(){} | |||
| void waveStop(){} | |||
| } | |||
| } | |||
| @@ -38,6 +38,8 @@ using juce::roundToIntAccurate; | |||
| using juce::FloatVectorOperations; | |||
| using juce::ScopedPointer; | |||
| using namespace zyncarla; | |||
| // #define ZYN_MSG_ANYWHERE | |||
| // ----------------------------------------------------------------------- | |||
| @@ -73,7 +75,7 @@ public: | |||
| std::vector<const ProgramInfo*> programs; | |||
| programs.push_back(new ProgramInfo(0, 0, "default", "")); | |||
| CarlaConfig config; | |||
| Config config; | |||
| config.init(); | |||
| SYNTH_T synth; | |||
| @@ -834,7 +836,7 @@ private: | |||
| MiddleWare* fMiddleWare; | |||
| Master* fMaster; | |||
| SYNTH_T fSynth; | |||
| CarlaConfig fConfig; | |||
| Config fConfig; | |||
| char* fDefaultState; | |||
| float fParameters[kParamCount]; | |||
| @@ -15,6 +15,9 @@ | |||
| #define INVALID ((int32_t)0xffffffff) | |||
| #define MAX ((int32_t)0x7fffffff) | |||
| namespace zyncarla { | |||
| QueueListItem::QueueListItem(void) | |||
| :memory(0), size(0) | |||
| { | |||
| @@ -114,3 +117,5 @@ MultiQueue::~MultiQueue(void) | |||
| delete [] pool[i].memory; | |||
| delete [] pool; | |||
| } | |||
| } | |||
| @@ -13,6 +13,8 @@ | |||
| #include <atomic> | |||
| #include <cassert> | |||
| namespace zyncarla { | |||
| //XXX rename this thing | |||
| typedef struct QueueListItem qli_t; | |||
| struct QueueListItem | |||
| @@ -60,3 +62,5 @@ class MultiQueue | |||
| void write(qli_t *q) { m_msgs.write(q); } | |||
| qli_t *read(void) { return m_msgs.read(); } | |||
| }; | |||
| } | |||
| @@ -19,6 +19,8 @@ | |||
| #define SUSTAIN_BIT 0x04 | |||
| #define NOTE_MASK 0x03 | |||
| namespace zyncarla { | |||
| enum NoteStatus { | |||
| KEY_OFF = 0x00, | |||
| KEY_PLAYING = 0x01, | |||
| @@ -430,3 +432,5 @@ void NotePool::dump(void) | |||
| } | |||
| printf(">NotePool::dump\n"); | |||
| } | |||
| } | |||
| @@ -17,6 +17,8 @@ | |||
| //Expected upper bound of synths given that max polyphony is hit | |||
| #define EXPECTED_USAGE 3 | |||
| namespace zyncarla { | |||
| struct LegatoParams; | |||
| class NotePool | |||
| { | |||
| @@ -145,3 +147,5 @@ class NotePool | |||
| void dump(void); | |||
| }; | |||
| } | |||
| @@ -2,6 +2,8 @@ | |||
| #include <cstring> | |||
| #include <cstdio> | |||
| namespace zyncarla { | |||
| ScratchString::ScratchString(void) | |||
| { | |||
| memset(c_str, 0, sizeof(c_str)); | |||
| @@ -37,3 +39,5 @@ ScratchString ScratchString::operator+(const ScratchString s) | |||
| //{ | |||
| // return c_str; | |||
| //} | |||
| } | |||
| @@ -1,6 +1,8 @@ | |||
| #pragma once | |||
| #define SCRATCH_SIZE 128 | |||
| namespace zyncarla { | |||
| //Fixed Size String Substitute | |||
| struct ScratchString | |||
| { | |||
| @@ -15,3 +17,6 @@ struct ScratchString | |||
| char c_str[SCRATCH_SIZE]; | |||
| }; | |||
| } | |||
| @@ -20,6 +20,8 @@ | |||
| #include "../Misc/Util.h" | |||
| #include "AnalogFilter.h" | |||
| namespace zyncarla { | |||
| AnalogFilter::AnalogFilter(unsigned char Ftype, | |||
| float Ffreq, | |||
| float Fq, | |||
| @@ -423,3 +425,5 @@ float AnalogFilter::H(float freq) | |||
| h = h / (x * x + y * y); | |||
| return powf(h, (stages + 1.0f) / 2.0f); | |||
| } | |||
| } | |||
| @@ -19,6 +19,8 @@ | |||
| #include "../globals.h" | |||
| #include "Filter.h" | |||
| namespace zyncarla { | |||
| /**Implementation of Several analog filters (lowpass, highpass...) | |||
| * Implemented with IIR filters | |||
| * Coefficients generated with "Cookbook formulae for audio EQ"*/ | |||
| @@ -77,5 +79,6 @@ class AnalogFilter:public Filter | |||
| //(used to see if it needs interpolation) | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -17,6 +17,8 @@ | |||
| #include <pthread.h> | |||
| #include "FFTwrapper.h" | |||
| namespace zyncarla { | |||
| static pthread_mutex_t *mutex = NULL; | |||
| FFTwrapper::FFTwrapper(int fftsize_) | |||
| @@ -91,3 +93,5 @@ void FFT_cleanup() | |||
| delete mutex; | |||
| mutex = NULL; | |||
| } | |||
| } | |||
| @@ -17,6 +17,8 @@ | |||
| #include <complex> | |||
| #include "../globals.h" | |||
| namespace zyncarla { | |||
| /**A wrapper for the FFTW library (Fast Fourier Transforms)*/ | |||
| class FFTwrapper | |||
| { | |||
| @@ -58,4 +60,7 @@ FFTpolar(const _Tp& __rho, const _Tp& __theta = _Tp(0)) | |||
| } | |||
| void FFT_cleanup(); | |||
| } | |||
| #endif | |||
| @@ -22,6 +22,8 @@ | |||
| #include "../Params/FilterParams.h" | |||
| #include "../Misc/Allocator.h" | |||
| namespace zyncarla { | |||
| Filter::Filter(unsigned int srate, int bufsize) | |||
| : outgain(1.0f), | |||
| samplerate(srate), | |||
| @@ -65,3 +67,5 @@ float Filter::getrealfreq(float freqpitch) | |||
| { | |||
| return powf(2.0f, freqpitch + 9.96578428f); //log2(1000)=9.95748f | |||
| } | |||
| } | |||
| @@ -16,6 +16,8 @@ | |||
| #include "../globals.h" | |||
| namespace zyncarla { | |||
| class Filter | |||
| { | |||
| public: | |||
| @@ -53,4 +55,6 @@ class Filter | |||
| } | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -19,6 +19,8 @@ | |||
| #include "AnalogFilter.h" | |||
| #include "../Params/FilterParams.h" | |||
| namespace zyncarla { | |||
| FormantFilter::FormantFilter(const FilterParams *pars, Allocator *alloc, unsigned int srate, int bufsize) | |||
| :Filter(srate, bufsize), memory(*alloc) | |||
| { | |||
| @@ -215,3 +217,5 @@ void FormantFilter::filterout(float *smp) | |||
| oldformantamp[j] = currentformants[j].amp; | |||
| } | |||
| } | |||
| } | |||
| @@ -17,6 +17,7 @@ | |||
| #include "../globals.h" | |||
| #include "Filter.h" | |||
| namespace zyncarla { | |||
| class FormantFilter:public Filter | |||
| { | |||
| @@ -55,4 +56,6 @@ class FormantFilter:public Filter | |||
| Allocator &memory; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -24,6 +24,8 @@ | |||
| #include <err.h> | |||
| #endif | |||
| namespace zyncarla { | |||
| SVFilter::SVFilter(unsigned char Ftype, float Ffreq, float Fq, | |||
| unsigned char Fstages, unsigned int srate, int bufsize) | |||
| :Filter(srate, bufsize), | |||
| @@ -229,3 +231,5 @@ void SVFilter::filterout(float *smp) | |||
| for(int i = 0; i < buffersize; ++i) | |||
| smp[i] *= outgain; | |||
| } | |||
| } | |||
| @@ -17,6 +17,8 @@ | |||
| #include "../globals.h" | |||
| #include "Filter.h" | |||
| namespace zyncarla { | |||
| class SVFilter:public Filter | |||
| { | |||
| public: | |||
| @@ -67,4 +69,6 @@ class SVFilter:public Filter | |||
| bool needsinterpolation, firsttime; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -24,6 +24,8 @@ | |||
| #include <err.h> | |||
| #endif | |||
| namespace zyncarla { | |||
| Unison::Unison(Allocator *alloc_, int update_period_samples_, float max_delay_sec_, float srate_f) | |||
| :unison_size(0), | |||
| base_freq(1.0f), | |||
| @@ -196,3 +198,5 @@ void Unison::updateUnisonData() | |||
| } | |||
| first_time = false; | |||
| } | |||
| } | |||
| @@ -18,6 +18,9 @@ | |||
| //how much the unison frequencies varies (always >= 1.0) | |||
| #define UNISON_FREQ_SPAN 2.0f | |||
| namespace zyncarla { | |||
| class Allocator; | |||
| class Unison | |||
| @@ -67,4 +70,7 @@ class Unison | |||
| float samplerate_f; | |||
| Allocator &alloc; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -17,6 +17,8 @@ | |||
| #include "../Misc/Allocator.h" | |||
| #include "Alienwah.h" | |||
| namespace zyncarla { | |||
| using std::complex; | |||
| #define rObject Alienwah | |||
| @@ -34,17 +36,26 @@ rtosc::Ports Alienwah::ports = { | |||
| else | |||
| d.reply(d.loc, "i", o->Ppreset); | |||
| 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"), | |||
| 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 rEnd | |||
| @@ -257,3 +268,5 @@ unsigned char Alienwah::getpar(int npar) const | |||
| default: return 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -20,6 +20,8 @@ | |||
| #define MAX_ALIENWAH_DELAY 100 | |||
| namespace zyncarla { | |||
| /**"AlienWah" Effect*/ | |||
| class Alienwah:public Effect | |||
| { | |||
| @@ -58,4 +60,6 @@ class Alienwah:public Effect | |||
| int oldk; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -17,9 +17,10 @@ | |||
| #include "../Misc/Allocator.h" | |||
| #include "Chorus.h" | |||
| #include <iostream> | |||
| using namespace std; | |||
| namespace zyncarla { | |||
| #define rObject Chorus | |||
| #define rBegin [](const char *msg, rtosc::RtData &d) { | |||
| #define rEnd } | |||
| @@ -38,17 +39,32 @@ rtosc::Ports Chorus::ports = { | |||
| rEnd}, | |||
| //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"), | |||
| 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 rEnd | |||
| @@ -294,3 +310,5 @@ unsigned char Chorus::getpar(int npar) const | |||
| default: return 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -19,6 +19,8 @@ | |||
| #define MAX_CHORUS_DELAY 250.0f //ms | |||
| namespace zyncarla { | |||
| /**Chorus and Flange effects*/ | |||
| class Chorus:public Effect | |||
| { | |||
| @@ -95,4 +97,6 @@ class Chorus:public Effect | |||
| float getdelay(float xlfo); | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -19,6 +19,8 @@ | |||
| #include <rtosc/ports.h> | |||
| #include <rtosc/port-sugar.h> | |||
| namespace zyncarla { | |||
| #define rObject Distorsion | |||
| #define rBegin [](const char *msg, rtosc::RtData &d) { | |||
| #define rEnd } | |||
| @@ -35,21 +37,29 @@ rtosc::Ports Distorsion::ports = { | |||
| else | |||
| d.reply(d.loc, "i", o->Ppreset); | |||
| 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"), | |||
| 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"), | |||
| 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) | |||
| { | |||
| Distorsion &dd = *(Distorsion*)d.obj; | |||
| @@ -60,7 +70,8 @@ rtosc::Ports Distorsion::ports = { | |||
| for(int i=0; i<128; ++i) | |||
| 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) { | |||
| arg_str[i] = 'f'; | |||
| @@ -292,3 +303,5 @@ unsigned char Distorsion::getpar(int npar) const | |||
| default: return 0; //in case of bogus parameter number | |||
| } | |||
| } | |||
| } | |||
| @@ -16,6 +16,8 @@ | |||
| #include "Effect.h" | |||
| namespace zyncarla { | |||
| /**Distortion Effect*/ | |||
| class Distorsion:public Effect | |||
| { | |||
| @@ -50,4 +52,6 @@ class Distorsion:public Effect | |||
| class AnalogFilter * lpfl, *lpfr, *hpfl, *hpfr; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -20,6 +20,8 @@ | |||
| #include <rtosc/ports.h> | |||
| #include <rtosc/port-sugar.h> | |||
| namespace zyncarla { | |||
| #define rObject DynamicFilter | |||
| #define rBegin [](const char *msg, rtosc::RtData &d) { | |||
| #define rEnd } | |||
| @@ -34,16 +36,24 @@ rtosc::Ports DynamicFilter::ports = { | |||
| else | |||
| d.reply(d.loc, "i", o->Ppreset); | |||
| 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 rEnd | |||
| @@ -351,3 +361,5 @@ unsigned char DynamicFilter::getpar(int npar) const | |||
| default: return 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -17,6 +17,8 @@ | |||
| #include "Effect.h" | |||
| #include "EffectLFO.h" | |||
| namespace zyncarla { | |||
| /**DynamicFilter Effect*/ | |||
| class DynamicFilter:public Effect | |||
| { | |||
| @@ -56,4 +58,6 @@ class DynamicFilter:public Effect | |||
| float ms1, ms2, ms3, ms4; //mean squares | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -18,6 +18,8 @@ | |||
| #include "../DSP/AnalogFilter.h" | |||
| #include "../Misc/Allocator.h" | |||
| namespace zyncarla { | |||
| using rtosc::RtData; | |||
| #define rObject EQ | |||
| #define rBegin [](const char *msg, RtData &d) {\ | |||
| @@ -78,8 +80,8 @@ rtosc::Ports EQ::ports = { | |||
| memset(b, 0, sizeof(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) { | |||
| int stride = MAX_EQ_BANDS*MAX_FILTER_STAGES*3; | |||
| 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" | |||
| namespace zyncarla { | |||
| /**EQ Effect*/ | |||
| class EQ:public Effect | |||
| { | |||
| @@ -53,4 +55,6 @@ class EQ:public Effect | |||
| } filter[MAX_EQ_BANDS]; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -21,6 +21,8 @@ | |||
| #define MAX_DELAY 2 | |||
| namespace zyncarla { | |||
| #define rObject Echo | |||
| #define rBegin [](const char *msg, rtosc::RtData &d) { | |||
| #define rEnd } | |||
| @@ -37,12 +39,23 @@ rtosc::Ports Echo::ports = { | |||
| else | |||
| d.reply(d.loc, "i", o->Ppreset); | |||
| 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 rEnd | |||
| @@ -145,7 +158,11 @@ void Echo::setvolume(unsigned char _Pvolume) | |||
| Pvolume = _Pvolume; | |||
| 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; | |||
| } | |||
| else | |||
| @@ -251,3 +268,5 @@ unsigned char Echo::getpar(int npar) const | |||
| default: return 0; // in case of bogus parameter number | |||
| } | |||
| } | |||
| } | |||
| @@ -17,6 +17,8 @@ | |||
| #include "Effect.h" | |||
| #include "../Misc/Stereo.h" | |||
| namespace zyncarla { | |||
| /**Echo Effect*/ | |||
| class Echo:public Effect | |||
| { | |||
| @@ -94,4 +96,6 @@ class Echo:public Effect | |||
| Stereo<int> ndelta; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -17,6 +17,8 @@ | |||
| #include "../Params/FilterParams.h" | |||
| #include <cmath> | |||
| namespace zyncarla { | |||
| EffectParams::EffectParams(Allocator &alloc_, bool insertion_, float *efxoutl_, float *efxoutr_, | |||
| unsigned char Ppreset_, unsigned int srate_, int bufsize_, FilterParams *filterpars_, | |||
| bool filterprotect_) | |||
| @@ -63,3 +65,5 @@ void Effect::setlrcross(char Plrcross_) | |||
| Plrcross = Plrcross_; | |||
| lrcross = (float)Plrcross / 127.0f; | |||
| } | |||
| } | |||
| @@ -19,14 +19,15 @@ | |||
| #include "../Params/FilterParams.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 | |||
| #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, ...) \ | |||
| {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) \ | |||
| [](const char *msg, rtosc::RtData &d) {\ | |||
| rObject &obj = *(rObject*)d.obj; \ | |||
| @@ -43,6 +44,32 @@ class Allocator; | |||
| d.reply(d.loc, obj.getpar(idx)?"T":"F");} | |||
| #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 | |||
| { | |||
| /** | |||
| @@ -154,4 +181,6 @@ class Effect | |||
| } | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -17,6 +17,8 @@ | |||
| #include <cmath> | |||
| #include "globals.h" | |||
| namespace zyncarla { | |||
| EffectLFO::EffectLFO(float srate_f, float bufsize_f) | |||
| :Pfreq(40), | |||
| Prandomness(0), | |||
| @@ -104,3 +106,5 @@ void EffectLFO::effectlfoout(float *outl, float *outr) | |||
| } | |||
| *outr = (out + 1.0f) * 0.5f; | |||
| } | |||
| } | |||
| @@ -14,6 +14,8 @@ | |||
| #ifndef EFFECT_LFO_H | |||
| #define EFFECT_LFO_H | |||
| namespace zyncarla { | |||
| /**LFO for some of the Effect objects | |||
| * \todo see if this should inherit LFO*/ | |||
| class EffectLFO | |||
| @@ -41,4 +43,6 @@ class EffectLFO | |||
| float buffersize_f; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -16,7 +16,6 @@ | |||
| #include <iostream> | |||
| #include <cassert> | |||
| #include "EffectMgr.h" | |||
| #include "Effect.h" | |||
| #include "Alienwah.h" | |||
| @@ -32,21 +31,23 @@ | |||
| #include "../Params/FilterParams.h" | |||
| #include "../Misc/Allocator.h" | |||
| namespace zyncarla { | |||
| #define rObject EffectMgr | |||
| #define rSubtype(name) \ | |||
| {STRINGIFY(name)"/", NULL, &name::ports,\ | |||
| [](const char *msg, rtosc::RtData &data){\ | |||
| 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; \ | |||
| SNIP \ | |||
| name::ports.dispatch(msg, data); \ | |||
| }} | |||
| static const rtosc::Ports local_ports = { | |||
| rSelf(EffectMgr), | |||
| rSelf(EffectMgr, rEnabledByCondition(self-enabled)), | |||
| rPaste, | |||
| rEnabledCondition(self-enabled, obj->geteffect()), | |||
| rRecurp(filterpars, "Filter Parameter for Dynamic Filter"), | |||
| {"Pvolume::i", rProp(parameter) rLinear(0,127) rShort("amt") rDoc("amount of effect"), | |||
| 0, | |||
| @@ -93,7 +94,8 @@ static const rtosc::Ports local_ports = { | |||
| 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) | |||
| { | |||
| char loc[1024]; | |||
| @@ -129,18 +131,10 @@ static const rtosc::Ports local_ports = { | |||
| eq->getFilter(a,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, | |||
| [](const char *msg, rtosc::RtData &d) | |||
| { | |||
| @@ -472,7 +466,12 @@ void EffectMgr::add2XML(XMLwrapper& xml) | |||
| xml.beginbranch("EFFECT_PARAMETERS"); | |||
| 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) | |||
| continue; | |||
| xml.beginbranch("par_no", n); | |||
| @@ -515,3 +514,5 @@ void EffectMgr::getfromXML(XMLwrapper& xml) | |||
| } | |||
| cleanup(); | |||
| } | |||
| } | |||
| @@ -16,14 +16,16 @@ | |||
| #include <pthread.h> | |||
| #include "../Params/FilterParams.h" | |||
| #include "../Params/Presets.h" | |||
| namespace zyncarla { | |||
| class Effect; | |||
| class FilterParams; | |||
| class XMLwrapper; | |||
| class Allocator; | |||
| #include "../Params/FilterParams.h" | |||
| #include "../Params/Presets.h" | |||
| /** Effect manager, an interface between the program and effects */ | |||
| class EffectMgr:public Presets | |||
| { | |||
| @@ -75,6 +77,30 @@ class EffectMgr:public Presets | |||
| //Parameters Prior to initialization | |||
| 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]; | |||
| bool dryonly; | |||
| @@ -82,4 +108,6 @@ class EffectMgr:public Presets | |||
| const SYNTH_T &synth; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -21,9 +21,10 @@ | |||
| #include <rtosc/port-sugar.h> | |||
| #include "../Misc/Allocator.h" | |||
| #include "Phaser.h" | |||
| using namespace std; | |||
| namespace zyncarla { | |||
| #define rObject Phaser | |||
| #define rBegin [](const char *msg, rtosc::RtData &d) { | |||
| #define rEnd } | |||
| @@ -36,7 +37,8 @@ using namespace std; | |||
| d.reply(d.loc, "i", p.P##pname); \ | |||
| rEnd | |||
| #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 = { | |||
| {"preset::i", rProp(parameter) | |||
| @@ -52,23 +54,52 @@ rtosc::Ports Phaser::ports = { | |||
| else | |||
| d.reply(d.loc, "i", o->Ppreset); | |||
| 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"), | |||
| 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 rEnd | |||
| @@ -496,3 +527,5 @@ unsigned char Phaser::getpar(int npar) const | |||
| default: return 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -23,6 +23,8 @@ | |||
| #define MAX_PHASER_STAGES 12 | |||
| namespace zyncarla { | |||
| class Phaser:public Effect | |||
| { | |||
| public: | |||
| @@ -87,4 +89,6 @@ class Phaser:public Effect | |||
| float applyPhase(float x, float g, float *old); | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -20,6 +20,8 @@ | |||
| #include <rtosc/ports.h> | |||
| #include <rtosc/port-sugar.h> | |||
| namespace zyncarla { | |||
| #define rObject Reverb | |||
| #define rBegin [](const char *msg, rtosc::RtData &d) { | |||
| #define rEnd } | |||
| @@ -37,18 +39,38 @@ rtosc::Ports Reverb::ports = { | |||
| else | |||
| d.reply(d.loc, "i", o->Ppreset); | |||
| 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 | |||
| 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 rEnd | |||
| @@ -215,7 +237,11 @@ void Reverb::setvolume(unsigned char _Pvolume) | |||
| { | |||
| Pvolume = _Pvolume; | |||
| 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; | |||
| } | |||
| else { | |||
| @@ -512,3 +538,5 @@ unsigned char Reverb::getpar(int npar) const | |||
| default: return 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -19,6 +19,8 @@ | |||
| #define REV_COMBS 8 | |||
| #define REV_APS 4 | |||
| namespace zyncarla { | |||
| /**Creates Reverberation Effects*/ | |||
| class Reverb:public Effect | |||
| { | |||
| @@ -83,4 +85,6 @@ class Reverb:public Effect | |||
| class AnalogFilter * lpf, *hpf; //filters | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -17,6 +17,8 @@ | |||
| #include "tlsf/tlsf.h" | |||
| #include "Allocator.h" | |||
| namespace zyncarla { | |||
| //Used for dummy allocations | |||
| DummyAllocator DummyAlloc; | |||
| @@ -230,3 +232,5 @@ void Allocator::rollbackTransaction() { | |||
| * pool size and the next pool in the list as this information is not | |||
| * accessible in O(good) time | |||
| */ | |||
| } | |||
| @@ -14,6 +14,8 @@ | |||
| #include <utility> | |||
| #include <new> | |||
| namespace zyncarla { | |||
| //! Allocator Base class | |||
| //! subclasses must specify allocation and deallocation | |||
| class Allocator | |||
| @@ -198,3 +200,5 @@ extern DummyAllocator DummyAlloc; | |||
| * * A new one is constructed with a deep copy | |||
| * * The old one is returned to middleware for deallocation | |||
| */ | |||
| } | |||
| @@ -30,15 +30,20 @@ | |||
| #include "Util.h" | |||
| #include "Part.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), | |||
| 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) | |||
| if(!config->cfg.bankRootDirList[i].empty()) | |||
| 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(banks.begin(), banks.end()); | |||
| @@ -471,7 +488,7 @@ std::vector<std::string> Bank::search(std::string s) const | |||
| } | |||
| return out; | |||
| } | |||
| std::vector<std::string> Bank::blist(std::string s) | |||
| { | |||
| std::vector<std::string> out; | |||
| @@ -544,3 +561,5 @@ void Bank::normalizedirsuffix(string &dirname) const { | |||
| && ((dirname[dirname.size() - 1]) != '\\')) | |||
| dirname += "/"; | |||
| } | |||
| } | |||
| @@ -22,12 +22,14 @@ | |||
| //entries in a bank | |||
| #define BANK_SIZE 160 | |||
| namespace zyncarla { | |||
| /**The instrument Bank*/ | |||
| class Bank | |||
| { | |||
| public: | |||
| /**Constructor*/ | |||
| Bank(CarlaConfig* config); | |||
| Bank(Config* config); | |||
| ~Bank(); | |||
| std::string getname(unsigned int ninstrument); | |||
| std::string getnamenumbered(unsigned int ninstrument); | |||
| @@ -102,7 +104,7 @@ class Bank | |||
| * directory separator */ | |||
| void normalizedirsuffix(std::string &dirname) const; | |||
| CarlaConfig* const config; | |||
| Config* const config; | |||
| class BankDb *db; | |||
| public: | |||
| @@ -110,4 +112,6 @@ class Bank | |||
| uint8_t bank_lsb; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -6,7 +6,9 @@ | |||
| #include <dirent.h> | |||
| #include <sys/stat.h> | |||
| #define INSTRUMENT_EXTENSION ".xiz" | |||
| namespace zyncarla { | |||
| static const char* INSTRUMENT_EXTENSION = ".xiz"; | |||
| using std::string; | |||
| typedef BankDb::svec svec; | |||
| @@ -57,7 +59,7 @@ bool BankEntry::match(string s) 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) | |||
| @@ -227,16 +229,20 @@ BankEntry BankDb::processXiz(std::string filename, | |||
| { | |||
| string fname = bank+filename; | |||
| #ifdef WIN32 | |||
| int ret, time = 0; | |||
| #else | |||
| //Grab a timestamp | |||
| struct stat st; | |||
| int ret = lstat(fname.c_str(), &st); | |||
| int time = 0; | |||
| //gah windows, just implement the darn standard APIs | |||
| #ifndef WIN32 | |||
| int ret = lstat(fname.c_str(), &st); | |||
| if(ret != -1) | |||
| time = st.st_mtim.tv_sec; | |||
| #else | |||
| int ret = 0; | |||
| time = rand(); | |||
| #endif | |||
| //quickly check if the file exists in the cache and if it is up-to-date | |||
| if(cache.find(fname) != cache.end() && | |||
| @@ -343,3 +349,5 @@ BankEntry BankDb::processXiz(std::string filename, | |||
| return entry; | |||
| } | |||
| } | |||
| @@ -3,6 +3,8 @@ | |||
| #include <vector> | |||
| #include <map> | |||
| namespace zyncarla { | |||
| struct BankEntry | |||
| { | |||
| BankEntry(void); | |||
| @@ -53,3 +55,5 @@ class BankDb | |||
| bvec fields; | |||
| svec banks; | |||
| }; | |||
| } | |||
| @@ -10,6 +10,9 @@ | |||
| of the License, or (at your option) any later version. | |||
| */ | |||
| #include "CallbackRepeater.h" | |||
| namespace zyncarla { | |||
| CallbackRepeater::CallbackRepeater(int interval, cb_t cb_) | |||
| :last(time(0)), dt(interval), cb(cb_) | |||
| {} | |||
| @@ -22,3 +25,5 @@ void CallbackRepeater::tick(void) | |||
| last = now; | |||
| } | |||
| } | |||
| } | |||
| @@ -13,6 +13,8 @@ | |||
| #include <functional> | |||
| #include <ctime> | |||
| namespace zyncarla { | |||
| struct CallbackRepeater | |||
| { | |||
| typedef std::function<void(void)> cb_t ; | |||
| @@ -27,3 +29,5 @@ struct CallbackRepeater | |||
| std::time_t dt; | |||
| cb_t cb; | |||
| }; | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| /* | |||
| ZynAddSubFX - a software synthesizer | |||
| CarlaConfig.cpp - CarlaConfiguration file functions | |||
| Config.cpp - Configuration file functions | |||
| Copyright (C) 2003-2005 Nasca Octavian Paul | |||
| Author: Nasca Octavian Paul | |||
| @@ -22,6 +22,8 @@ | |||
| #include "../globals.h" | |||
| #include "XMLwrapper.h" | |||
| namespace zyncarla { | |||
| #define rStdString(name, len, ...) \ | |||
| {STRINGIFY(name) "::s", rMap(length, len) rProp(parameter) DOC(__VA_ARGS__), NULL, rStringCb(name,len)} | |||
| #define rStdStringCb(name, length) rBOIL_BEGIN \ | |||
| @@ -37,7 +39,7 @@ | |||
| #if 1 | |||
| #define rObject CarlaConfig | |||
| #define rObject Config | |||
| static const rtosc::Ports ports = { | |||
| //rString(cfg.LinuxOSSWaveOutDev), | |||
| //rString(cfg.LinuxOSSSeqInDev), | |||
| @@ -51,7 +53,7 @@ static const rtosc::Ports ports = { | |||
| {"cfg.presetsDirList", rDoc("list of preset search directories"), 0, | |||
| [](const char *msg, rtosc::RtData &d) | |||
| { | |||
| CarlaConfig &c = *(CarlaConfig*)d.obj; | |||
| Config &c = *(Config*)d.obj; | |||
| if(rtosc_narguments(msg) != 0) { | |||
| 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, | |||
| [](const char *msg, rtosc::RtData &d) | |||
| { | |||
| CarlaConfig &c = *(CarlaConfig*)d.obj; | |||
| Config &c = *(Config*)d.obj; | |||
| if(rtosc_narguments(msg) != 0) { | |||
| std::string args = rtosc_argument_string(msg); | |||
| @@ -120,14 +122,14 @@ static const rtosc::Ports ports = { | |||
| //rArrayS(cfg.presetsDirList,MAX_BANK_ROOT_DIRS), | |||
| rToggle(cfg.CheckPADsynth, "Old Check For PADsynth functionality within a patch"), | |||
| 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.nameTag) | |||
| {"cfg.OscilPower::i", rProp(parameter) rDoc("Size Of Oscillator Wavetable"), 0, | |||
| [](const char *msg, rtosc::RtData &d) | |||
| { | |||
| CarlaConfig &c = *(CarlaConfig*)d.obj; | |||
| Config &c = *(Config*)d.obj; | |||
| if(rtosc_narguments(msg) == 0) { | |||
| d.reply(d.loc, "i", (int)(log(c.cfg.OscilSize*1.0)/log(2.0))); | |||
| return; | |||
| @@ -136,22 +138,29 @@ static const rtosc::Ports ports = { | |||
| c.cfg.OscilSize = val; | |||
| 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, | |||
| [](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) { | |||
| 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; | |||
| } | |||
| } | |||
| }}, | |||
| {"favorites:", rProp(parameter), 0, | |||
| {"favorites:", /*rProp(parameter)*/ 0, 0, | |||
| [](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]; | |||
| rtosc_arg_t *args = new rtosc_arg_t[MAX_BANK_ROOT_DIRS]; | |||
| memset(argt, 0, MAX_BANK_ROOT_DIRS+1); | |||
| @@ -168,13 +177,15 @@ static const rtosc::Ports ports = { | |||
| delete [] args; | |||
| }}, | |||
| }; | |||
| const rtosc::Ports &CarlaConfig::ports = ::ports; | |||
| const rtosc::Ports &Config::ports = zyncarla::ports; | |||
| #endif | |||
| CarlaConfig::CarlaConfig() | |||
| {} | |||
| Config::Config() | |||
| { | |||
| init(); | |||
| } | |||
| void CarlaConfig::init() | |||
| void Config::init() | |||
| { | |||
| maxstringsize = MAX_STRING_SIZE; //for ui | |||
| //defaults | |||
| @@ -223,14 +234,18 @@ void CarlaConfig::init() | |||
| //banks | |||
| cfg.bankRootDirList[0] = "~/banks"; | |||
| cfg.bankRootDirList[1] = "./"; | |||
| cfg.bankRootDirList[2] = "/usr/share/zynaddsubfx/banks"; | |||
| cfg.bankRootDirList[3] = "/usr/local/share/zynaddsubfx/banks"; | |||
| #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 | |||
| cfg.bankRootDirList[4] = "../banks"; | |||
| cfg.bankRootDirList[4] = "/usr/share/zynaddsubfx/banks"; | |||
| cfg.bankRootDirList[5] = "/usr/local/share/zynaddsubfx/banks"; | |||
| #endif | |||
| cfg.bankRootDirList[5] = "banks"; | |||
| } | |||
| if(cfg.presetsDirList[0].empty()) { | |||
| @@ -242,14 +257,18 @@ void CarlaConfig::init() | |||
| cfg.presetsDirList[1] = "../presets"; | |||
| #endif | |||
| cfg.presetsDirList[2] = "presets"; | |||
| #ifdef ZYN_DATADIR | |||
| cfg.presetsDirList[3] = ZYN_DATADIR "/presets"; | |||
| #else | |||
| cfg.presetsDirList[3] = "/usr/share/zynaddsubfx/presets"; | |||
| cfg.presetsDirList[4] = "/usr/local/share/zynaddsubfx/presets"; | |||
| #endif | |||
| } | |||
| cfg.LinuxALSAaudioDev = "default"; | |||
| cfg.nameTag = ""; | |||
| } | |||
| CarlaConfig::~CarlaConfig() | |||
| Config::~Config() | |||
| { | |||
| delete [] cfg.oss_devs.linux_wave_out; | |||
| 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]; | |||
| getConfigFileName(filename, MAX_STRING_SIZE); | |||
| saveConfig(filename); | |||
| } | |||
| void CarlaConfig::clearbankrootdirlist() | |||
| void Config::clearbankrootdirlist() | |||
| { | |||
| for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | |||
| cfg.bankRootDirList[i].clear(); | |||
| } | |||
| void CarlaConfig::clearpresetsdirlist() | |||
| void Config::clearpresetsdirlist() | |||
| { | |||
| for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | |||
| cfg.presetsDirList[i].clear(); | |||
| } | |||
| void CarlaConfig::readConfig(const char *filename) | |||
| void Config::readConfig(const char *filename) | |||
| { | |||
| XMLwrapper xmlcfg; | |||
| if(xmlcfg.loadXMLfile(filename) < 0) | |||
| @@ -350,7 +369,7 @@ void CarlaConfig::readConfig(const char *filename) | |||
| cfg.presetsDirList[i] = xmlcfg.getparstr("presets_root", ""); | |||
| xmlcfg.exitbranch(); | |||
| } | |||
| //Get favs | |||
| for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++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))); | |||
| } | |||
| void CarlaConfig::saveConfig(const char *filename) const | |||
| void Config::saveConfig(const char *filename) const | |||
| { | |||
| XMLwrapper *xmlcfg = new XMLwrapper(); | |||
| @@ -418,7 +437,7 @@ void CarlaConfig::saveConfig(const char *filename) const | |||
| xmlcfg->addparstr("presets_root", cfg.presetsDirList[i]); | |||
| xmlcfg->endbranch(); | |||
| } | |||
| for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) | |||
| if(!cfg.favoriteList[i].empty()) { | |||
| xmlcfg->beginbranch("FAVSROOT", i); | |||
| @@ -444,8 +463,10 @@ void CarlaConfig::saveConfig(const char *filename) const | |||
| delete (xmlcfg); | |||
| } | |||
| void CarlaConfig::getConfigFileName(char *name, int namesize) const | |||
| void Config::getConfigFileName(char *name, int namesize) const | |||
| { | |||
| name[0] = 0; | |||
| snprintf(name, namesize, "%s%s", getenv("HOME"), "/.zynaddsubfxXML.cfg"); | |||
| } | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| /* | |||
| ZynAddSubFX - a software synthesizer | |||
| CarlaConfig.h - CarlaConfiguration file functions | |||
| Config.h - Configuration file functions | |||
| Copyright (C) 2003-2005 Nasca Octavian Paul | |||
| Author: Nasca Octavian Paul | |||
| @@ -23,6 +23,8 @@ namespace rtosc | |||
| struct Ports; | |||
| } | |||
| namespace zyncarla { | |||
| class oss_devs_t | |||
| { | |||
| public: | |||
| @@ -30,13 +32,13 @@ class oss_devs_t | |||
| }; | |||
| /**Configuration file functions*/ | |||
| class CarlaConfig | |||
| class Config | |||
| { | |||
| public: | |||
| CarlaConfig(); | |||
| CarlaConfig(const CarlaConfig& ) = delete; | |||
| ~CarlaConfig(); | |||
| Config(); | |||
| Config(const Config& ) = delete; | |||
| ~Config(); | |||
| struct { | |||
| oss_devs_t oss_devs; | |||
| int SampleRate, SoundBufferSize, OscilSize, SwapStereo; | |||
| @@ -73,4 +75,7 @@ class CarlaConfig | |||
| void saveConfig(const char *filename) const; | |||
| void getConfigFileName(char *name, int namesize) const; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -16,6 +16,7 @@ | |||
| #include "LASHClient.h" | |||
| namespace zyncarla { | |||
| LASHClient::LASHClient(int *argc, char ***argv) | |||
| { | |||
| @@ -92,3 +93,5 @@ void LASHClient::confirmevent(Event event) | |||
| if(event == Restore) | |||
| lash_send_event(client, lash_event_new_with_type(LASH_Restore_File)); | |||
| } | |||
| } | |||
| @@ -17,6 +17,7 @@ | |||
| #include <pthread.h> | |||
| #include <lash/lash.h> | |||
| namespace zyncarla { | |||
| /** This class wraps up some functions for initialising and polling | |||
| * the LASH daemon.*/ | |||
| @@ -50,5 +51,6 @@ class LASHClient | |||
| lash_client_t *client; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -16,6 +16,7 @@ | |||
| #include "Part.h" | |||
| #include "zyn-version.h" | |||
| #include "../Misc/Stereo.h" | |||
| #include "../Misc/Util.h" | |||
| #include "../Params/LFOParams.h" | |||
| @@ -32,15 +33,18 @@ | |||
| #include <stdio.h> | |||
| #include <sys/stat.h> | |||
| #include <sys/types.h> | |||
| #include <fstream> | |||
| #include <iostream> | |||
| #include <algorithm> | |||
| #include <cmath> | |||
| #include <atomic> | |||
| #include <unistd.h> | |||
| using namespace std; | |||
| using namespace rtosc; | |||
| namespace zyncarla { | |||
| #define rObject Master | |||
| static const Ports sysefxPort = | |||
| @@ -49,12 +53,18 @@ static const Ports sysefxPort = | |||
| rDoc("gain on part to sysefx routing"), 0, | |||
| [](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)); | |||
| if(isdigit(index_1[-1])) | |||
| index_1--; | |||
| @@ -78,9 +88,15 @@ static const Ports sysefsendto = | |||
| {"to#" STRINGIFY(NUM_SYS_EFX) "::i", | |||
| 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)); | |||
| if(isdigit(index_1[-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 rEnd } | |||
| @@ -108,20 +354,22 @@ static const Ports watchPorts = { | |||
| rEnd}, | |||
| }; | |||
| extern const Ports bankPorts; | |||
| static const Ports master_ports = { | |||
| rString(last_xmz, XMZ_PATH_MAX, "File name for last name loaded if any."), | |||
| rRecursp(part, 16, "Part"),//NUM_MIDI_PARTS | |||
| rRecursp(sysefx, 4, "System Effect"),//NUM_SYS_EFX | |||
| rRecursp(insefx, 8, "Insertion Effect"),//NUM_INS_EFX | |||
| rRecur(microtonal, "Micrtonal Mapping Functionality"), | |||
| rRecur(microtonal, "Microtonal Mapping Functionality"), | |||
| 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) { | |||
| d.reply(d.loc, "i", ((Master*)d.obj)->Pkeyshift); | |||
| } 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]); | |||
| m->part[i] = p; | |||
| p->initialize_rt(); | |||
| for(int i=0; i<128; ++i) | |||
| m->activeNotes[i] = 0; | |||
| }}, | |||
| {"active_keys:", rProp("Obtain a list of active notes"), 0, | |||
| rBegin; | |||
| @@ -168,14 +418,16 @@ static const Ports master_ports = { | |||
| keys[i] = m->activeNotes[i] ? 'T' : 'F'; | |||
| d.broadcast(d.loc, keys); | |||
| 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) { | |||
| if(rtosc_narguments(m)==0) { | |||
| d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume); | |||
| } else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') { | |||
| ((Master*)d.obj)->setPvolume(limit<char>(rtosc_argument(m,0).i,0,127)); | |||
| 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) { | |||
| if(rtosc_narguments(m)==0) { | |||
| d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume); | |||
| @@ -229,13 +481,12 @@ static const Ports master_ports = { | |||
| [](const char *,RtData &d) { | |||
| Master *M = (Master*)d.obj; | |||
| M->frozenState = false;}}, | |||
| {"midi-learn/", 0, &rtosc::MidiMapperRT::ports, | |||
| {"automate/", rDoc("MIDI Learn/Plugin Automation support"), &automate_ports, | |||
| [](const char *msg, RtData &d) { | |||
| Master *M = (Master*)d.obj; | |||
| 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, | |||
| [](const char *, RtData &d) { | |||
| d.reply("/close-ui", "");}}, | |||
| @@ -261,8 +512,8 @@ static const Ports master_ports = { | |||
| [](const char *, rtosc::RtData &d) {d.reply("/undo_pause", "");}}, | |||
| {"undo_resume:",rProp(internal) rDoc("resume undo event recording"),0, | |||
| [](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 | |||
| SNIP | |||
| preset_ports.dispatch(msg, data); | |||
| @@ -286,6 +537,14 @@ static const Ports master_ports = { | |||
| rBOIL_END}, | |||
| {"bank/", rDoc("Controls for instrument banks"), &bankPorts, | |||
| [](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 | |||
| @@ -359,18 +618,97 @@ vuData::vuData(void) | |||
| 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), | |||
| microtonal(config->cfg.GzipCompression), bank(config), | |||
| automate(16,4,8), | |||
| frozenState(false), pendingMemory(false), | |||
| synth(synth_), gzip_compression(config->cfg.GzipCompression) | |||
| { | |||
| bToU = 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(); | |||
| swaplr = 0; | |||
| @@ -441,6 +779,7 @@ void Master::defaults() | |||
| for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) { | |||
| part[npart]->defaults(); | |||
| part[npart]->partno = 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) | |||
| return; | |||
| //TODO add chan back | |||
| midi.handleCC(type,par); | |||
| automate.handleMidi(chan, type, par); | |||
| if((type == C_dataentryhi) || (type == C_dataentrylo) | |||
| || (type == C_nrpnhi) || (type == C_nrpnlo)) { //Process RPN and NRPN by the Master (ignore the chan) | |||
| ctl.setparameternumber(type, par); | |||
| @@ -724,13 +1062,19 @@ bool Master::runOSC(float *outl, float *outr, bool offline) | |||
| } | |||
| if(!d.matches) {// && !ports.apropos(msg)) { | |||
| 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", | |||
| uToB->peak(), | |||
| rtosc_argument_string(uToB->peak())); | |||
| 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) | |||
| fprintf(stderr, "backend: %d events per cycle\n",events); | |||
| @@ -1074,6 +1418,8 @@ void Master::add2XML(XMLwrapper& xml) | |||
| microtonal.add2XML(xml); | |||
| xml.endbranch(); | |||
| saveAutomation(xml, automate); | |||
| for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) { | |||
| xml.beginbranch("PART", npart); | |||
| part[npart]->add2XML(xml); | |||
| @@ -1198,6 +1544,8 @@ void Master::getfromXML(XMLwrapper& xml) | |||
| xml.exitbranch(); | |||
| } | |||
| loadAutomation(xml, automate); | |||
| sysefx[0]->changeeffect(0); | |||
| if(xml.enterbranch("SYSTEM_EFFECTS")) { | |||
| for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) { | |||
| @@ -1248,3 +1596,114 @@ void Master::getfromXML(XMLwrapper& xml) | |||
| 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 | |||
| #include "../globals.h" | |||
| #include "Microtonal.h" | |||
| #include <rtosc/miditable.h> | |||
| #include <rtosc/automations.h> | |||
| #include <rtosc/ports.h> | |||
| #include "Time.h" | |||
| @@ -26,6 +26,8 @@ | |||
| #include "../Params/Controller.h" | |||
| #include "../Synth/WatchPoint.h" | |||
| namespace zyncarla { | |||
| class Allocator; | |||
| struct vuData { | |||
| @@ -42,7 +44,7 @@ class Master | |||
| { | |||
| public: | |||
| /** Constructor TODO make private*/ | |||
| Master(const SYNTH_T &synth, class CarlaConfig *config); | |||
| Master(const SYNTH_T &synth, class Config *config); | |||
| /** Destructor*/ | |||
| ~Master(); | |||
| @@ -57,12 +59,23 @@ class Master | |||
| /**This adds the parameters to the XML data*/ | |||
| void add2XML(XMLwrapper& xml); | |||
| static void saveAutomation(XMLwrapper &xml, const rtosc::AutomationMgr &midi); | |||
| static void loadAutomation(XMLwrapper &xml, rtosc::AutomationMgr &midi); | |||
| void defaults(); | |||
| /**loads all settings from a XML file | |||
| * @return 0 for ok or -1 if there is an error*/ | |||
| 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 | |||
| * It is NOT SAFE to call this from a RT context*/ | |||
| void applyparameters(void) NONREALTIME; | |||
| @@ -169,7 +182,7 @@ class Master | |||
| WatchManager watcher; | |||
| //Midi Learn | |||
| rtosc::MidiMapperRT midi; | |||
| rtosc::AutomationMgr automate; | |||
| bool frozenState;//read-only parameters for threadsafe actions | |||
| Allocator *memory; | |||
| @@ -181,8 +194,8 @@ class Master | |||
| //Heartbeat for identifying plugin offline modes | |||
| //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: | |||
| float sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; | |||
| float sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; | |||
| @@ -197,6 +210,13 @@ class Master | |||
| //Callback When Master changes | |||
| void(*mastercb)(void*,Master*); | |||
| void* mastercb_ptr; | |||
| //Return XML data as string. Must be freed. | |||
| char* getXMLData(); | |||
| //Used by loadOSC and saveOSC | |||
| int loadOSCFromStr(const char *filename); | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -25,11 +25,13 @@ | |||
| #include "Util.h" | |||
| #include "Microtonal.h" | |||
| using namespace rtosc; | |||
| #define MAX_LINE_SIZE 80 | |||
| namespace zyncarla { | |||
| #define rObject Microtonal | |||
| using namespace rtosc; | |||
| /** | |||
| * TODO | |||
| @@ -40,25 +42,37 @@ using namespace rtosc; | |||
| * A good lookup table should be a good finalization of this | |||
| */ | |||
| 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 | |||
| 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) | |||
| { | |||
| @@ -570,6 +584,9 @@ int Microtonal::loadscl(SclInfo &scl, const char *filename) | |||
| char tmp[500]; | |||
| OctaveTuning tmpoctave[MAX_OCTAVE_SIZE]; | |||
| if(!file) | |||
| return 2; | |||
| fseek(file, 0, SEEK_SET); | |||
| //loads the short description | |||
| @@ -621,6 +638,9 @@ int Microtonal::loadkbm(KbmInfo &kbm, const char *filename) | |||
| float tmpPAfreq = 440.0f; | |||
| char tmp[500]; | |||
| if(!file) | |||
| return 2; | |||
| fseek(file, 0, SEEK_SET); | |||
| //loads the mapsize | |||
| 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 tmpbuf[100] = {0}; | |||
| for (int i=0;i<getoctavesize();i++){ | |||
| for (int i=0;i<octavesize;i++){ | |||
| if (i!=0) | |||
| strncat(buf, "\n", sizeof(buf)-1); | |||
| tuningtoline(i,tmpbuf,100); | |||
| @@ -852,3 +872,5 @@ void Microtonal::apply(void) | |||
| int err = texttotunings(buf); | |||
| } | |||
| } | |||
| } | |||
| @@ -20,6 +20,9 @@ | |||
| #define MAX_OCTAVE_SIZE 128 | |||
| #define MICROTONAL_MAX_NAME_LEN 120 | |||
| namespace zyncarla { | |||
| class XMLwrapper; | |||
| struct KbmInfo | |||
| @@ -154,4 +157,6 @@ class Microtonal | |||
| const int& gzip_compression; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -56,6 +56,8 @@ | |||
| #include <err.h> | |||
| #endif | |||
| namespace zyncarla { | |||
| using std::string; | |||
| 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 * | |||
| * * | |||
| @@ -451,17 +404,17 @@ namespace Nio | |||
| /* Implementation */ | |||
| class CarlaMiddleWareImpl | |||
| class MiddleWareImpl | |||
| { | |||
| public: | |||
| MiddleWare *parent; | |||
| private: | |||
| 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); | |||
| ~CarlaMiddleWareImpl(void); | |||
| ~MiddleWareImpl(void); | |||
| //Check offline vs online mode in plugins | |||
| void heartBeat(Master *m); | |||
| @@ -745,7 +698,7 @@ public: | |||
| rtosc::UndoHistory undo; | |||
| //MIDI Learn | |||
| rtosc::MidiMappernRT midi_mapper; | |||
| //rtosc::MidiMappernRT midi_mapper; | |||
| //Link To the Realtime | |||
| rtosc::ThreadLink *bToU; | |||
| @@ -774,7 +727,7 @@ public: | |||
| class MwDataObj:public rtosc::RtData | |||
| { | |||
| public: | |||
| MwDataObj(CarlaMiddleWareImpl *mwi_) | |||
| MwDataObj(MiddleWareImpl *mwi_) | |||
| { | |||
| loc_size = 1024; | |||
| loc = new char[loc_size]; | |||
| @@ -797,7 +750,7 @@ class MwDataObj:public rtosc::RtData | |||
| //Chain calls repeat the call into handle() | |||
| //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); | |||
| va_list va; | |||
| @@ -823,7 +776,7 @@ class MwDataObj:public rtosc::RtData | |||
| reply(buffer); | |||
| } | |||
| } | |||
| virtual void reply(const char *msg){ | |||
| virtual void reply(const char *msg) override{ | |||
| mwi->sendToCurrentRemote(msg); | |||
| }; | |||
| //virtual void broadcast(const char *path, const char *args, ...){(void)path;(void)args;}; | |||
| @@ -854,7 +807,7 @@ class MwDataObj:public rtosc::RtData | |||
| bool forwarded; | |||
| private: | |||
| char *buffer; | |||
| CarlaMiddleWareImpl *mwi; | |||
| MiddleWareImpl *mwi; | |||
| }; | |||
| 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 | |||
| 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; | |||
| #endif | |||
| if(finddir == is_dir) | |||
| if(finddir == is_dir && strcmp(".", fn->d_name)) | |||
| files.push_back(fn->d_name); | |||
| } | |||
| @@ -935,13 +889,28 @@ extern const rtosc::Ports bankPorts; | |||
| const rtosc::Ports bankPorts = { | |||
| {"rescan:", 0, 0, | |||
| rBegin; | |||
| impl.bankpos = 0; | |||
| impl.rescanforbanks(); | |||
| //Send updated banks | |||
| int i = 0; | |||
| 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", "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}, | |||
| {"bank_list:", 0, 0, | |||
| rBegin; | |||
| @@ -1089,8 +1058,8 @@ const rtosc::Ports bankPorts = { | |||
| rBegin; | |||
| auto res = impl.search(rtosc_argument(msg, 0).s); | |||
| #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) { | |||
| res_type[i] = 's'; | |||
| res_dat[i].s = res[i].c_str(); | |||
| @@ -1102,8 +1071,8 @@ const rtosc::Ports bankPorts = { | |||
| rBegin; | |||
| auto res = impl.blist(rtosc_argument(msg, 0).s); | |||
| #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) { | |||
| res_type[i] = 's'; | |||
| res_dat[i].s = res[i].c_str(); | |||
| @@ -1128,7 +1097,7 @@ const rtosc::Ports bankPorts = { | |||
| ******************************************************************************/ | |||
| #undef rObject | |||
| #define rObject CarlaMiddleWareImpl | |||
| #define rObject MiddleWareImpl | |||
| #ifndef STRINGIFY | |||
| #define STRINGIFY2(a) #a | |||
| @@ -1180,13 +1149,13 @@ static rtosc::Ports middwareSnoopPorts = { | |||
| GUI::raiseUi(impl.ui, buffer); | |||
| } | |||
| rEnd}, | |||
| {"config/", 0, &CarlaConfig::ports, | |||
| {"config/", 0, &Config::ports, | |||
| rBegin; | |||
| d.obj = impl.config; | |||
| CarlaConfig::ports.dispatch(chomp(msg), d); | |||
| Config::ports.dispatch(chomp(msg), d); | |||
| rEnd}, | |||
| {"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; | |||
| real_preset_ports.dispatch(chomp(msg), d); | |||
| if(strstr(msg, "paste") && rtosc_argument_string(msg)[0] == 's') | |||
| @@ -1201,21 +1170,26 @@ static rtosc::Ports middwareSnoopPorts = { | |||
| rEnd}, | |||
| {"save_xlz:s", 0, 0, | |||
| 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}, | |||
| {"load_xlz:s", 0, 0, | |||
| rBegin; | |||
| const char *file = rtosc_argument(msg, 0).s; | |||
| XMLwrapper xml; | |||
| 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}, | |||
| {"clear_xlz:", 0, 0, | |||
| rBegin; | |||
| impl.midi_mapper.clear(); | |||
| d.chain("/automate/clear", ""); | |||
| rEnd}, | |||
| //scale file stuff | |||
| {"load_xsz:s", 0, 0, | |||
| @@ -1388,51 +1362,51 @@ static rtosc::Ports middwareSnoopPorts = { | |||
| impl.undo.seekHistory(+1); | |||
| rEnd}, | |||
| //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 | |||
| {"ui/title:", 0, 0, [](const char *msg, RtData &d) {}}, | |||
| {"quit:", 0, 0, [](const char *, RtData&) {Pexitprogram = 1;}}, | |||
| @@ -1479,10 +1453,6 @@ static rtosc::Ports middlewareReplyPorts = { | |||
| if(impl.recording_undo) | |||
| impl.undo.recordEvent(msg); | |||
| 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}, | |||
| {"forward:", 0, 0, rBegin; impl.forward = true; rEnd}, | |||
| }; | |||
| @@ -1493,8 +1463,8 @@ static rtosc::Ports middlewareReplyPorts = { | |||
| * 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_)), | |||
| presetsstore(*config), autoSave(-1, [this]() { | |||
| auto master = this->master; | |||
| @@ -1507,8 +1477,8 @@ CarlaMiddleWareImpl::CarlaMiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, | |||
| { | |||
| bToU = 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) | |||
| server = lo_server_new_with_proto(to_s(preferrred_port).c_str(), | |||
| LO_UDP, liblo_error_cb); | |||
| @@ -1561,7 +1531,7 @@ CarlaMiddleWareImpl::CarlaMiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, | |||
| offline = false; | |||
| } | |||
| CarlaMiddleWareImpl::~CarlaMiddleWareImpl(void) | |||
| MiddleWareImpl::~MiddleWareImpl(void) | |||
| { | |||
| if(server) | |||
| @@ -1597,7 +1567,7 @@ CarlaMiddleWareImpl::~CarlaMiddleWareImpl(void) | |||
| * 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); | |||
| uToB->write("/freeze_state",""); | |||
| @@ -1606,7 +1576,7 @@ void CarlaMiddleWareImpl::doReadOnlyOp(std::function<void()> read_only_fn) | |||
| int tries = 0; | |||
| while(tries++ < 10000) { | |||
| if(!bToU->hasNext()) { | |||
| usleep(500); | |||
| os_usleep(500); | |||
| continue; | |||
| } | |||
| 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 | |||
| // - When marked offline the backend doesn't receive another heartbeat until it | |||
| // registers the current beat that it's behind on | |||
| void CarlaMiddleWareImpl::heartBeat(Master *master) | |||
| void MiddleWareImpl::heartBeat(Master *master) | |||
| { | |||
| //Current time | |||
| //Last provided beat | |||
| //Last acknowledged beat | |||
| //Current offline status | |||
| struct timespec time; | |||
| clock_gettime(CLOCK_MONOTONIC, &time); | |||
| 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); | |||
| 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); | |||
| uToB->write("/freeze_state",""); | |||
| @@ -1719,7 +1689,7 @@ bool CarlaMiddleWareImpl::doReadOnlyOpNormal(std::function<void()> read_only_fn, | |||
| int tries = 0; | |||
| while(tries++ < 2000) { | |||
| if(!bToU->hasNext()) { | |||
| usleep(500); | |||
| os_usleep(500); | |||
| continue; | |||
| } | |||
| const char *msg = bToU->read(); | |||
| @@ -1757,7 +1727,7 @@ bool CarlaMiddleWareImpl::doReadOnlyOpNormal(std::function<void()> read_only_fn, | |||
| return true; | |||
| } | |||
| void CarlaMiddleWareImpl::broadcastToRemote(const char *rtmsg) | |||
| void MiddleWareImpl::broadcastToRemote(const char *rtmsg) | |||
| { | |||
| //Always send to the local UI | |||
| sendToRemote(rtmsg, "GUI"); | |||
| @@ -1770,7 +1740,7 @@ void CarlaMiddleWareImpl::broadcastToRemote(const char *rtmsg) | |||
| 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)) { | |||
| 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 | |||
| * 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 | |||
| assert(strcmp(rtmsg, "/part0/kit0/Ppadenableda")); | |||
| @@ -1845,7 +1815,7 @@ void CarlaMiddleWareImpl::bToUhandle(const char *rtmsg) | |||
| } | |||
| //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); | |||
| if(argv != "T") | |||
| @@ -1879,7 +1849,7 @@ void CarlaMiddleWareImpl::kitEnable(const char *msg) | |||
| 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); | |||
| 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. | |||
| */ | |||
| void CarlaMiddleWareImpl::handleMsg(const char *msg) | |||
| void MiddleWareImpl::handleMsg(const char *msg) | |||
| { | |||
| //Check for known bugs | |||
| 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 | |||
| va_list va; | |||
| @@ -1956,7 +1926,7 @@ void CarlaMiddleWareImpl::write(const char *path, const char *args, ...) | |||
| 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); | |||
| char *buffer = uToB->buffer(); | |||
| @@ -1973,9 +1943,9 @@ void CarlaMiddleWareImpl::write(const char *path, const char *args, va_list va) | |||
| /****************************************************************************** | |||
| * MidleWare Forwarding Stubs * | |||
| ******************************************************************************/ | |||
| MiddleWare::MiddleWare(SYNTH_T synth, CarlaConfig* config, | |||
| MiddleWare::MiddleWare(SYNTH_T synth, Config* config, | |||
| 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) | |||
| @@ -2164,3 +2134,5 @@ PresetsStore& MiddleWare::getPresetsStore() | |||
| { | |||
| return impl->presetsstore; | |||
| } | |||
| } | |||
| @@ -14,6 +14,10 @@ | |||
| #include <cstdarg> | |||
| #include <string> | |||
| class Fl_Osc_Interface; | |||
| namespace zyncarla { | |||
| struct SYNTH_T; | |||
| class Master; | |||
| class PresetsStore; | |||
| @@ -22,7 +26,7 @@ class PresetsStore; | |||
| class MiddleWare | |||
| { | |||
| public: | |||
| MiddleWare(SYNTH_T synth, class CarlaConfig *config, | |||
| MiddleWare(SYNTH_T synth, class Config *config, | |||
| int preferred_port = -1); | |||
| ~MiddleWare(void); | |||
| void updateResources(Master *m); | |||
| @@ -41,7 +45,7 @@ class MiddleWare | |||
| void removeAutoSave(void); | |||
| //return UI interface | |||
| class Fl_Osc_Interface *spawnUiApi(void); | |||
| Fl_Osc_Interface *spawnUiApi(void); | |||
| //Set callback to push UI events to | |||
| void setUiCallback(void(*cb)(void*,const char *),void *ui); | |||
| //Set callback to run while busy | |||
| @@ -79,5 +83,8 @@ class MiddleWare | |||
| const PresetsStore& getPresetsStore() const; | |||
| PresetsStore& getPresetsStore(); | |||
| private: | |||
| class CarlaMiddleWareImpl *impl; | |||
| class MiddleWareImpl *impl; | |||
| }; | |||
| } | |||
| @@ -37,6 +37,8 @@ | |||
| #include <rtosc/port-sugar.h> | |||
| #include <iostream> | |||
| namespace zyncarla { | |||
| using rtosc::Ports; | |||
| using rtosc::RtData; | |||
| @@ -45,41 +47,55 @@ static const Ports partPorts = { | |||
| rRecurs(kit, 16, "Kit"),//NUM_KIT_ITEMS | |||
| rRecursp(partefx, 3, "Part Effect"), | |||
| 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 | |||
| #define rChangeCb obj->setPvolume(obj->Pvolume); | |||
| rParamZyn(Pvolume, rShort("Vol"), "Part Volume"), | |||
| rParamZyn(Pvolume, rShort("Vol"), rDefault(96),"Part Volume"), | |||
| #undef rChangeCb | |||
| #define rChangeCb obj->setPpanning(obj->Ppanning); | |||
| rParamZyn(Ppanning, rShort("pan"), "Set Panning"), | |||
| rParamZyn(Ppanning, rShort("pan"), rDefault(64), "Set Panning"), | |||
| #undef rChangeCb | |||
| #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 | |||
| #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), | |||
| "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" | |||
| "Multi-kit - Every applicable kit is run for a note\n" | |||
| "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"), | |||
| 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, | |||
| 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, | |||
| [](const char *, RtData &r) | |||
| {Part *p = (Part*)r.obj; p->Pminkey = p->lastnote;}}, | |||
| @@ -156,20 +172,26 @@ static const Ports partPorts = { | |||
| #undef rObject | |||
| #define rObject Part::Kit | |||
| static const Ports kitPorts = { | |||
| rSelf(Part::Kit, rEnabledBy(Penabled)), | |||
| rRecurp(padpars, "Padnote parameters"), | |||
| rRecurp(adpars, "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, | |||
| rOptions(FX1, FX2, FX3, Off), | |||
| rOptions(FX1, FX2, FX3, Off), rDefault(FX1), | |||
| "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, | |||
| [](const char *, RtData &r) | |||
| {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) { | |||
| //kit[n].Penabled = false; | |||
| kit[n].firstkit = false; | |||
| kit[n].Pmuted = false; | |||
| kit[n].Pminkey = 0; | |||
| kit[n].Pmaxkey = 127; | |||
| @@ -337,6 +360,7 @@ void Part::defaultsinstrument() | |||
| if(n != 0) | |||
| setkititemstatus(n, 0); | |||
| } | |||
| kit[0].firstkit = true; | |||
| kit[0].Penabled = 1; | |||
| kit[0].Padenabled = 1; | |||
| kit[0].adpars->defaults(); | |||
| @@ -1208,3 +1232,5 @@ bool Part::Kit::validNote(char note) const | |||
| { | |||
| return !Pmuted && inRange((uint8_t)note, Pminkey, Pmaxkey); | |||
| } | |||
| } | |||
| @@ -22,6 +22,8 @@ | |||
| #include <functional> | |||
| namespace zyncarla { | |||
| /** Part implementation*/ | |||
| class Part | |||
| { | |||
| @@ -83,6 +85,7 @@ class Part | |||
| struct Kit { | |||
| Kit(void); | |||
| Part *parent; | |||
| bool firstkit; | |||
| bool Penabled, Pmuted; | |||
| unsigned char Pminkey, Pmaxkey; | |||
| char *Pname; | |||
| @@ -104,13 +107,14 @@ class Part | |||
| void setkeylimit(unsigned char Pkeylimit); | |||
| void setkititemstatus(unsigned kititem, bool Penabled_); | |||
| unsigned char partno; /**<if it's the Master's first part*/ | |||
| bool Penabled; /**<if the part is enabled*/ | |||
| unsigned char Pvolume; /**<part volume*/ | |||
| unsigned char Pminkey; /**<the minimum key that the part receives noteon messages*/ | |||
| unsigned char Pmaxkey; //the maximum key that the part receives noteon messages | |||
| void setPvolume(char Pvolume); | |||
| 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 | |||
| void setPpanning(char Ppanning); | |||
| unsigned char Pvelsns; //velocity sensing (amplitude velocity scale) | |||
| @@ -200,4 +204,6 @@ class Part | |||
| const int &gzip_compression, &interpolation; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -31,8 +31,10 @@ | |||
| #include <rtosc/ports.h> | |||
| #include <rtosc/port-sugar.h> | |||
| #include <string> | |||
| using std::string; | |||
| namespace zyncarla { | |||
| using std::string; | |||
| static void dummy(const char *, rtosc::RtData&) {} | |||
| const rtosc::Ports real_preset_ports = | |||
| @@ -491,3 +493,5 @@ bool presetCheckClipboardType() | |||
| printf("PresetCheckClipboardType()<UNIMPLEMENTED>\n"); | |||
| return true; | |||
| } | |||
| } | |||
| @@ -13,8 +13,11 @@ | |||
| #include <string> | |||
| #include <rtosc/ports.h> | |||
| namespace zyncarla { | |||
| extern const rtosc::Ports real_preset_ports; | |||
| extern const rtosc::Ports preset_ports; | |||
| struct Clipboard { | |||
| std::string data; | |||
| std::string type; | |||
| @@ -31,3 +34,5 @@ void presetDelete(int); | |||
| void presetRescan(); | |||
| std::string presetClipboardType(); | |||
| bool presetCheckClipboardType(); | |||
| } | |||
| @@ -17,6 +17,8 @@ | |||
| #include "../globals.h" | |||
| #include "../Nio/Nio.h" | |||
| namespace zyncarla { | |||
| Recorder::Recorder(const SYNTH_T &synth_) | |||
| :status(0), notetrigger(0),synth(synth_) | |||
| {} | |||
| @@ -81,3 +83,4 @@ void Recorder::triggernow() | |||
| } | |||
| //TODO move recorder inside nio system | |||
| } | |||
| @@ -15,6 +15,8 @@ | |||
| #define RECORDER_H | |||
| #include <string> | |||
| namespace zyncarla { | |||
| struct SYNTH_T; | |||
| /**Records sound to a file*/ | |||
| class Recorder | |||
| @@ -43,4 +45,6 @@ class Recorder | |||
| const SYNTH_T &synth; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -1,6 +1,40 @@ | |||
| #include <ostream> | |||
| #include <rtosc/ports.h> | |||
| 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 : | |||
| * - 'parameters' : [parameter...] | |||
| @@ -11,8 +45,12 @@ using namespace rtosc; | |||
| * - 'shortname' : string [OPTIONAL] | |||
| * - 'tooltip' : string [OPTIONAL] | |||
| * - 'type' : type | |||
| * - 'units' : unit-type | |||
| * - 'scale' : scale-type | |||
| * - 'domain' : range [OPTIONAL] | |||
| * - 'options' : [option...] [OPTIONAL] | |||
| * - 'default' : string | |||
| * - 'defaults' : defaults | |||
| * type : {'int', 'float', 'boolean'} | |||
| * action : | |||
| * - 'path' : path-id | |||
| @@ -23,15 +61,11 @@ using namespace rtosc; | |||
| * option : | |||
| * - 'id' : id-number | |||
| * - '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::string; | |||
| static int enum_min(Port::MetaContainer meta) | |||
| @@ -102,7 +136,8 @@ static ostream &add_options(ostream &o, Port::MetaContainer meta) | |||
| * - 'domain' : range [OPTIONAL] | |||
| */ | |||
| 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; | |||
| 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 mdoc = meta.find("documentation"); | |||
| auto msname = meta.find("shortname"); | |||
| auto units = meta.find("unit"); | |||
| auto scale = meta.find("scale"); | |||
| opts options; | |||
| string doc; | |||
| 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 *max = meta["max"]; | |||
| const char *def = meta["default"]; | |||
| def = escape_string(def); | |||
| for(auto m:meta) { | |||
| 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 << " \"name\" : \"" << name << "\",\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 << "\""; | |||
| if(min && max) | |||
| o << ",\n \"range\" : [" << min << "," << max << "]"; | |||
| if(def) | |||
| o << ",\n \"default\" : \"" << def << "\"\n"; | |||
| if(!options.empty()) { | |||
| o << ",\n \"options\" : [\n"; | |||
| int N = options.size(); | |||
| @@ -221,4 +267,4 @@ void dump_json(std::ostream &o, const rtosc::Ports &p) | |||
| o << "}"; | |||
| } | |||
| } | |||
| @@ -11,6 +11,8 @@ | |||
| of the License, or (at your option) any later version. | |||
| */ | |||
| namespace zyncarla { | |||
| template<class T> | |||
| Stereo<T>::Stereo(const T &left, const T &right) | |||
| :l(left), r(right) | |||
| @@ -28,3 +30,5 @@ Stereo<T> &Stereo<T>::operator=(const Stereo<T> &nstr) | |||
| r = nstr.r; | |||
| return *this; | |||
| } | |||
| } | |||
| @@ -13,6 +13,8 @@ | |||
| #ifndef STEREO_H | |||
| #define STEREO_H | |||
| namespace zyncarla { | |||
| template<class T> | |||
| struct Stereo { | |||
| public: | |||
| @@ -28,5 +30,8 @@ struct Stereo { | |||
| //data | |||
| T l, r; | |||
| }; | |||
| } | |||
| #include "Stereo.cpp" | |||
| #endif | |||
| @@ -13,6 +13,8 @@ | |||
| #include <stdint.h> | |||
| #include "../globals.h" | |||
| namespace zyncarla { | |||
| class AbsTime | |||
| { | |||
| public: | |||
| @@ -51,3 +53,5 @@ class RelTime | |||
| int32_t sample; | |||
| const AbsTime &t; | |||
| }; | |||
| } | |||
| @@ -36,6 +36,8 @@ | |||
| #include <rtosc/rtosc.h> | |||
| namespace zyncarla { | |||
| bool isPlugin = false; | |||
| prng_t prng_state = 0x1234; | |||
| @@ -127,10 +129,31 @@ void set_realtime() | |||
| #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); | |||
| } | |||
| #endif | |||
| //!< maximum lenght a pid has on any POSIX system | |||
| //!< 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); | |||
| return buf; | |||
| } | |||
| } | |||
| @@ -23,16 +23,17 @@ | |||
| #include <rtosc/ports.h> | |||
| #include <rtosc/port-sugar.h> | |||
| namespace zyncarla { | |||
| extern bool isPlugin; | |||
| bool fileexists(const char *filename); | |||
| using std::min; | |||
| using std::max; | |||
| //Velocity Sensing function | |||
| 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 | |||
| extern float getdetune(unsigned char type, | |||
| unsigned short int coarsedetune, | |||
| @@ -45,7 +46,7 @@ extern float getdetune(unsigned char type, | |||
| void set_realtime(); | |||
| /**Os independent sleep in microsecond*/ | |||
| void os_sleep(long length); | |||
| void os_usleep(long length); | |||
| //! returns pid padded to maximum pid lenght, posix conform | |||
| std::string os_pid_as_padded_string(); | |||
| @@ -152,11 +153,6 @@ char *rtosc_splat(const char *path, std::set<std::string>); | |||
| #define rParamZyn(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 \ | |||
| {"preset-type:", rProp(internal) rDoc("clipboard type of object"), 0, \ | |||
| [](const char *, rtosc::RtData &d){ \ | |||
| @@ -181,4 +177,8 @@ rPresetType, \ | |||
| rObject &o = *(rObject*)d.obj;\ | |||
| o.pasteArray(paste,field);}} | |||
| } | |||
| #define rUnit(x) rMap(unit, x) | |||
| #endif | |||
| @@ -19,6 +19,8 @@ | |||
| #include "WavFile.h" | |||
| using namespace std; | |||
| namespace zyncarla { | |||
| WavFile::WavFile(string filename, int samplerate, int channels) | |||
| :sampleswritten(0), samplerate(samplerate), channels(channels), | |||
| file(fopen(filename.c_str(), "w")) | |||
| @@ -90,3 +92,5 @@ void WavFile::writeMonoSamples(int nsmps, short int *smps) | |||
| sampleswritten += nsmps; | |||
| } | |||
| } | |||
| } | |||
| @@ -16,6 +16,8 @@ | |||
| #define WAVFILE_H | |||
| #include <string> | |||
| namespace zyncarla { | |||
| class WavFile | |||
| { | |||
| public: | |||
| @@ -33,4 +35,7 @@ class WavFile | |||
| int channels; | |||
| FILE *file; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -14,6 +14,8 @@ | |||
| #include "WaveShapeSmps.h" | |||
| #include <cmath> | |||
| namespace zyncarla { | |||
| void waveShapeSmps(int n, | |||
| float *smps, | |||
| unsigned char type, | |||
| @@ -178,3 +180,5 @@ void waveShapeSmps(int n, | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| @@ -13,10 +13,14 @@ | |||
| #ifndef WAVESHAPESMPS_H | |||
| #define WAVESHAPESMPS_H | |||
| namespace zyncarla { | |||
| //Waveshaping(called by Distorsion effect and waveshape from OscilGen) | |||
| void waveShapeSmps(int n, | |||
| float *smps, | |||
| unsigned char type, | |||
| unsigned char drive); | |||
| } | |||
| #endif | |||
| @@ -27,6 +27,8 @@ | |||
| using namespace std; | |||
| namespace zyncarla { | |||
| int xml_k = 0; | |||
| bool verbose = false; | |||
| @@ -251,7 +253,7 @@ void XMLwrapper::addparreal(const string &name, float val) | |||
| union { float in; uint32_t out; } convert; | |||
| char buf[11]; | |||
| 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", | |||
| stringFrom<float>(val).c_str(), "exact_value", buf); | |||
| } | |||
| @@ -395,6 +397,12 @@ bool XMLwrapper::putXMLdata(const char *xmldata) | |||
| if(root == NULL) | |||
| 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; | |||
| } | |||
| @@ -677,3 +685,5 @@ std::vector<XmlNode> XMLwrapper::getBranch(void) const | |||
| } | |||
| return res; | |||
| } | |||
| } | |||
| @@ -21,6 +21,8 @@ | |||
| #ifndef XML_WRAPPER_H | |||
| #define XML_WRAPPER_H | |||
| namespace zyncarla { | |||
| class XmlAttr | |||
| { | |||
| public: | |||
| @@ -285,4 +287,6 @@ public: | |||
| version_type _fileversion; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -15,8 +15,6 @@ | |||
| #include <iostream> | |||
| #include <cmath> | |||
| using namespace std; | |||
| #include "../Misc/Util.h" | |||
| #include "../Misc/Config.h" | |||
| #include "InMgr.h" | |||
| @@ -24,6 +22,10 @@ using namespace std; | |||
| #include "Compressor.h" | |||
| #include "Nio.h" | |||
| using namespace std; | |||
| namespace zyncarla { | |||
| AlsaEngine::AlsaEngine(const SYNTH_T &synth) | |||
| :AudioOut(synth) | |||
| { | |||
| @@ -397,3 +399,5 @@ void *AlsaEngine::processAudio() | |||
| } | |||
| return NULL; | |||
| } | |||
| } | |||
| @@ -24,6 +24,8 @@ | |||
| #include "OutMgr.h" | |||
| #include "../Misc/Stereo.h" | |||
| namespace zyncarla { | |||
| class AlsaEngine:public AudioOut, MidiIn | |||
| { | |||
| public: | |||
| @@ -74,4 +76,6 @@ class AlsaEngine:public AudioOut, MidiIn | |||
| void *processAudio(); | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -15,12 +15,14 @@ | |||
| #include <cstring> | |||
| #include "SafeQueue.h" | |||
| using namespace std; | |||
| #include "OutMgr.h" | |||
| #include "../Misc/Master.h" | |||
| #include "AudioOut.h" | |||
| using namespace std; | |||
| namespace zyncarla { | |||
| AudioOut::AudioOut(const SYNTH_T &synth_) | |||
| :synth(synth_), samplerate(synth.samplerate), bufferSize(synth.buffersize) | |||
| {} | |||
| @@ -47,3 +49,5 @@ const Stereo<float *> AudioOut::getNext() | |||
| { | |||
| return OutMgr::getInstance().tick(bufferSize); | |||
| } | |||
| } | |||
| @@ -18,6 +18,8 @@ | |||
| #include "../globals.h" | |||
| #include "Engine.h" | |||
| namespace zyncarla { | |||
| class AudioOut:public virtual Engine | |||
| { | |||
| public: | |||
| @@ -50,4 +52,6 @@ class AudioOut:public virtual Engine | |||
| int bufferSize; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -12,8 +12,12 @@ | |||
| */ | |||
| #include "Engine.h" | |||
| namespace zyncarla { | |||
| Engine::Engine() | |||
| {} | |||
| Engine::~Engine() | |||
| {} | |||
| } | |||
| @@ -14,6 +14,9 @@ | |||
| #ifndef ENGINE_H | |||
| #define ENGINE_H | |||
| #include <string> | |||
| namespace zyncarla { | |||
| /**Marker for input/output driver*/ | |||
| class Engine | |||
| { | |||
| @@ -29,4 +32,7 @@ class Engine | |||
| std::string name; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -19,6 +19,8 @@ | |||
| #include "AudioOut.h" | |||
| #include "MidiIn.h" | |||
| #include "NulEngine.h" | |||
| using namespace std; | |||
| #if OSS | |||
| #include "OssEngine.h" | |||
| #include "OssMultiEngine.h" | |||
| @@ -34,7 +36,7 @@ | |||
| #include "PaEngine.h" | |||
| #endif | |||
| using namespace std; | |||
| namespace zyncarla { | |||
| EngineMgr &EngineMgr::getInstance(const SYNTH_T *synth, | |||
| const oss_devs_t *oss_devs) | |||
| @@ -172,3 +174,5 @@ bool EngineMgr::setOutDefault(string name) | |||
| cerr << " Defaulting to the NULL audio backend" << endl; | |||
| return false; | |||
| } | |||
| } | |||
| @@ -16,6 +16,7 @@ | |||
| #include <string> | |||
| #include "Engine.h" | |||
| namespace zyncarla { | |||
| class MidiIn; | |||
| class AudioOut; | |||
| @@ -54,4 +55,7 @@ class EngineMgr | |||
| private: | |||
| EngineMgr(const SYNTH_T *synth, const oss_devs_t &oss_devs); | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -17,10 +17,11 @@ | |||
| #include "../Misc/MiddleWare.h" | |||
| #include <rtosc/thread-link.h> | |||
| #include <iostream> | |||
| using namespace std; | |||
| extern MiddleWare *middleware; | |||
| extern zyncarla::MiddleWare *middleware; | |||
| namespace zyncarla { | |||
| ostream &operator<<(ostream &out, const MidiEvent &ev) | |||
| { | |||
| @@ -172,3 +173,5 @@ void InMgr::setMaster(Master *master_) | |||
| { | |||
| master = master_; | |||
| } | |||
| } | |||
| @@ -16,6 +16,8 @@ | |||
| #include "ZynSema.h" | |||
| #include "SafeQueue.h" | |||
| namespace zyncarla { | |||
| enum midi_type { | |||
| M_NOTE = 1, | |||
| M_CONTROLLER = 2, | |||
| @@ -65,4 +67,6 @@ class InMgr | |||
| class Master *master; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -32,10 +32,12 @@ | |||
| #include "JackEngine.h" | |||
| using namespace std; | |||
| extern char *instance_name; | |||
| namespace zyncarla { | |||
| using namespace std; | |||
| JackEngine::JackEngine(const SYNTH_T &synth) | |||
| :AudioOut(synth), jackClient(NULL) | |||
| { | |||
| @@ -438,3 +440,5 @@ void JackEngine::handleMidi(unsigned long frames) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -23,6 +23,8 @@ | |||
| #include "MidiIn.h" | |||
| #include "AudioOut.h" | |||
| namespace zyncarla { | |||
| typedef jack_default_audio_sample_t jsample_t; | |||
| class JackEngine:public AudioOut, MidiIn | |||
| @@ -83,4 +85,6 @@ class JackEngine:public AudioOut, MidiIn | |||
| void handleMidi(unsigned long frames); | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -26,7 +26,10 @@ | |||
| #include "JackMultiEngine.h" | |||
| extern MiddleWare *middleware; | |||
| extern zyncarla::MiddleWare *middleware; | |||
| namespace zyncarla { | |||
| using std::string; | |||
| struct jack_multi | |||
| @@ -170,3 +173,5 @@ void JackMultiEngine::Stop() | |||
| impl->running = false; | |||
| } | |||
| } | |||
| @@ -15,6 +15,8 @@ | |||
| #include "AudioOut.h" | |||
| namespace zyncarla { | |||
| class JackMultiEngine:public AudioOut | |||
| { | |||
| public: | |||
| @@ -34,4 +36,6 @@ class JackMultiEngine:public AudioOut | |||
| struct jack_multi *impl; | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -15,6 +15,8 @@ | |||
| #include "../globals.h" | |||
| #include "InMgr.h" | |||
| namespace zyncarla { | |||
| void MidiIn::midiProcess(unsigned char head, | |||
| unsigned char num, | |||
| unsigned char value) | |||
| @@ -66,3 +68,5 @@ void MidiIn::midiProcess(unsigned char head, | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| @@ -18,6 +18,8 @@ | |||
| #include "Engine.h" | |||
| namespace zyncarla { | |||
| /**This class is inherited by all the Midi input classes*/ | |||
| class MidiIn:public virtual Engine | |||
| { | |||
| @@ -31,4 +33,6 @@ class MidiIn:public virtual Engine | |||
| unsigned char value); | |||
| }; | |||
| } | |||
| #endif | |||
| @@ -20,6 +20,9 @@ | |||
| #include <cstring> | |||
| #include <iostream> | |||
| #include <algorithm> | |||
| namespace zyncarla { | |||
| using std::string; | |||
| using std::set; | |||
| using std::cerr; | |||
| @@ -183,3 +186,5 @@ void Nio::waveEnd(void) | |||
| { | |||
| out->wave->destroyFile(); | |||
| } | |||
| } | |||
| @@ -14,6 +14,8 @@ | |||
| #include <string> | |||
| #include <set> | |||
| namespace zyncarla { | |||
| class WavFile; | |||
| class Master; | |||
| struct SYNTH_T; | |||
| @@ -61,4 +63,6 @@ namespace Nio | |||
| extern std::string defaultSink; | |||
| }; | |||
| } | |||
| #endif | |||