Browse Source

Update included zynaddsubfx, now using custom c++ namespace

tags/1.9.8
falkTX 7 years ago
parent
commit
be2989b590
100 changed files with 1570 additions and 431 deletions
  1. +1
    -0
      .gitignore
  2. +8
    -1
      data/copy-zynaddsubfx
  3. +1
    -1
      source/native-plugins/Makefile
  4. +2
    -0
      source/native-plugins/zynaddsubfx-fx.cpp
  5. +4
    -0
      source/native-plugins/zynaddsubfx-src.cpp
  6. +4
    -2
      source/native-plugins/zynaddsubfx-synth.cpp
  7. +5
    -0
      source/native-plugins/zynaddsubfx/Containers/MultiPseudoStack.cpp
  8. +4
    -0
      source/native-plugins/zynaddsubfx/Containers/MultiPseudoStack.h
  9. +4
    -0
      source/native-plugins/zynaddsubfx/Containers/NotePool.cpp
  10. +4
    -0
      source/native-plugins/zynaddsubfx/Containers/NotePool.h
  11. +4
    -0
      source/native-plugins/zynaddsubfx/Containers/ScratchString.cpp
  12. +5
    -0
      source/native-plugins/zynaddsubfx/Containers/ScratchString.h
  13. +4
    -0
      source/native-plugins/zynaddsubfx/DSP/AnalogFilter.cpp
  14. +3
    -0
      source/native-plugins/zynaddsubfx/DSP/AnalogFilter.h
  15. +4
    -0
      source/native-plugins/zynaddsubfx/DSP/FFTwrapper.cpp
  16. +5
    -0
      source/native-plugins/zynaddsubfx/DSP/FFTwrapper.h
  17. +4
    -0
      source/native-plugins/zynaddsubfx/DSP/Filter.cpp
  18. +4
    -0
      source/native-plugins/zynaddsubfx/DSP/Filter.h
  19. +4
    -0
      source/native-plugins/zynaddsubfx/DSP/FormantFilter.cpp
  20. +3
    -0
      source/native-plugins/zynaddsubfx/DSP/FormantFilter.h
  21. +4
    -0
      source/native-plugins/zynaddsubfx/DSP/SVFilter.cpp
  22. +4
    -0
      source/native-plugins/zynaddsubfx/DSP/SVFilter.h
  23. +4
    -0
      source/native-plugins/zynaddsubfx/DSP/Unison.cpp
  24. +6
    -0
      source/native-plugins/zynaddsubfx/DSP/Unison.h
  25. +23
    -10
      source/native-plugins/zynaddsubfx/Effects/Alienwah.cpp
  26. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/Alienwah.h
  27. +29
    -11
      source/native-plugins/zynaddsubfx/Effects/Chorus.cpp
  28. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/Chorus.h
  29. +26
    -13
      source/native-plugins/zynaddsubfx/Effects/Distorsion.cpp
  30. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/Distorsion.h
  31. +22
    -10
      source/native-plugins/zynaddsubfx/Effects/DynamicFilter.cpp
  32. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/DynamicFilter.h
  33. +6
    -2
      source/native-plugins/zynaddsubfx/Effects/EQ.cpp
  34. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/EQ.h
  35. +26
    -7
      source/native-plugins/zynaddsubfx/Effects/Echo.cpp
  36. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/Echo.h
  37. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/Effect.cpp
  38. +34
    -5
      source/native-plugins/zynaddsubfx/Effects/Effect.h
  39. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/EffectLFO.cpp
  40. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/EffectLFO.h
  41. +19
    -18
      source/native-plugins/zynaddsubfx/Effects/EffectMgr.cpp
  42. +31
    -3
      source/native-plugins/zynaddsubfx/Effects/EffectMgr.h
  43. +51
    -18
      source/native-plugins/zynaddsubfx/Effects/Phaser.cpp
  44. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/Phaser.h
  45. +40
    -12
      source/native-plugins/zynaddsubfx/Effects/Reverb.cpp
  46. +4
    -0
      source/native-plugins/zynaddsubfx/Effects/Reverb.h
  47. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/Allocator.cpp
  48. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/Allocator.h
  49. +25
    -6
      source/native-plugins/zynaddsubfx/Misc/Bank.cpp
  50. +6
    -2
      source/native-plugins/zynaddsubfx/Misc/Bank.h
  51. +14
    -6
      source/native-plugins/zynaddsubfx/Misc/BankDb.cpp
  52. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/BankDb.h
  53. +5
    -0
      source/native-plugins/zynaddsubfx/Misc/CallbackRepeater.cpp
  54. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/CallbackRepeater.h
  55. +51
    -30
      source/native-plugins/zynaddsubfx/Misc/Config.cpp
  56. +11
    -6
      source/native-plugins/zynaddsubfx/Misc/Config.h
  57. +3
    -0
      source/native-plugins/zynaddsubfx/Misc/LASHClient.cpp
  58. +2
    -0
      source/native-plugins/zynaddsubfx/Misc/LASHClient.h
  59. +492
    -33
      source/native-plugins/zynaddsubfx/Misc/Master.cpp
  60. +25
    -5
      source/native-plugins/zynaddsubfx/Misc/Master.h
  61. +39
    -17
      source/native-plugins/zynaddsubfx/Misc/Microtonal.cpp
  62. +5
    -0
      source/native-plugins/zynaddsubfx/Misc/Microtonal.h
  63. +119
    -147
      source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp
  64. +10
    -3
      source/native-plugins/zynaddsubfx/Misc/MiddleWare.h
  65. +56
    -30
      source/native-plugins/zynaddsubfx/Misc/Part.cpp
  66. +7
    -1
      source/native-plugins/zynaddsubfx/Misc/Part.h
  67. +5
    -1
      source/native-plugins/zynaddsubfx/Misc/PresetExtractor.cpp
  68. +5
    -0
      source/native-plugins/zynaddsubfx/Misc/PresetExtractor.h
  69. +3
    -0
      source/native-plugins/zynaddsubfx/Misc/Recorder.cpp
  70. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/Recorder.h
  71. +55
    -9
      source/native-plugins/zynaddsubfx/Misc/Schema.cpp
  72. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/Stereo.cpp
  73. +5
    -0
      source/native-plugins/zynaddsubfx/Misc/Stereo.h
  74. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/Time.h
  75. +26
    -1
      source/native-plugins/zynaddsubfx/Misc/Util.cpp
  76. +10
    -10
      source/native-plugins/zynaddsubfx/Misc/Util.h
  77. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/WavFile.cpp
  78. +5
    -0
      source/native-plugins/zynaddsubfx/Misc/WavFile.h
  79. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/WaveShapeSmps.cpp
  80. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/WaveShapeSmps.h
  81. +11
    -1
      source/native-plugins/zynaddsubfx/Misc/XMLwrapper.cpp
  82. +4
    -0
      source/native-plugins/zynaddsubfx/Misc/XMLwrapper.h
  83. +6
    -2
      source/native-plugins/zynaddsubfx/Nio/AlsaEngine.cpp
  84. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/AlsaEngine.h
  85. +6
    -2
      source/native-plugins/zynaddsubfx/Nio/AudioOut.cpp
  86. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/AudioOut.h
  87. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/Engine.cpp
  88. +6
    -0
      source/native-plugins/zynaddsubfx/Nio/Engine.h
  89. +5
    -1
      source/native-plugins/zynaddsubfx/Nio/EngineMgr.cpp
  90. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/EngineMgr.h
  91. +5
    -2
      source/native-plugins/zynaddsubfx/Nio/InMgr.cpp
  92. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/InMgr.h
  93. +6
    -2
      source/native-plugins/zynaddsubfx/Nio/JackEngine.cpp
  94. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/JackEngine.h
  95. +6
    -1
      source/native-plugins/zynaddsubfx/Nio/JackMultiEngine.cpp
  96. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/JackMultiEngine.h
  97. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/MidiIn.cpp
  98. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/MidiIn.h
  99. +5
    -0
      source/native-plugins/zynaddsubfx/Nio/Nio.cpp
  100. +4
    -0
      source/native-plugins/zynaddsubfx/Nio/Nio.h

+ 1
- 0
.gitignore View File

@@ -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


+ 8
- 1
data/copy-zynaddsubfx View File

@@ -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


+ 1
- 1
source/native-plugins/Makefile View File

@@ -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)


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

@@ -34,6 +34,8 @@ using juce::roundToIntAccurate;
using juce::FloatVectorOperations;
using juce::SharedResourcePointer;

using namespace zyncarla;

// -----------------------------------------------------------------------

template<class ZynFX>


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

@@ -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(){}
}
}

+ 4
- 2
source/native-plugins/zynaddsubfx-synth.cpp View File

@@ -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];


+ 5
- 0
source/native-plugins/zynaddsubfx/Containers/MultiPseudoStack.cpp View File

@@ -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;
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Containers/MultiPseudoStack.h View File

@@ -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(); }
};

}

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

@@ -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");
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Containers/NotePool.h View File

@@ -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);
};

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Containers/ScratchString.cpp View File

@@ -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;
//}

}

+ 5
- 0
source/native-plugins/zynaddsubfx/Containers/ScratchString.h View File

@@ -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];
};

}


+ 4
- 0
source/native-plugins/zynaddsubfx/DSP/AnalogFilter.cpp View File

@@ -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);
}

}

+ 3
- 0
source/native-plugins/zynaddsubfx/DSP/AnalogFilter.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/DSP/FFTwrapper.cpp View File

@@ -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;
}

}

+ 5
- 0
source/native-plugins/zynaddsubfx/DSP/FFTwrapper.h View File

@@ -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

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

@@ -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
}

}

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

@@ -16,6 +16,8 @@

#include "../globals.h"

namespace zyncarla {

class Filter
{
public:
@@ -53,4 +55,6 @@ class Filter
}
};

}

#endif

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

@@ -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;
}
}

}

+ 3
- 0
source/native-plugins/zynaddsubfx/DSP/FormantFilter.h View File

@@ -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

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

@@ -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;
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/DSP/SVFilter.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/DSP/Unison.cpp View File

@@ -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;
}

}

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

@@ -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

+ 23
- 10
source/native-plugins/zynaddsubfx/Effects/Alienwah.cpp View File

@@ -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;
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/Alienwah.h View File

@@ -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

+ 29
- 11
source/native-plugins/zynaddsubfx/Effects/Chorus.cpp View File

@@ -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;
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/Chorus.h View File

@@ -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

+ 26
- 13
source/native-plugins/zynaddsubfx/Effects/Distorsion.cpp View File

@@ -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
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/Distorsion.h View File

@@ -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

+ 22
- 10
source/native-plugins/zynaddsubfx/Effects/DynamicFilter.cpp View File

@@ -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;
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/DynamicFilter.h View File

@@ -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

+ 6
- 2
source/native-plugins/zynaddsubfx/Effects/EQ.cpp View File

@@ -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
}
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/EQ.h View File

@@ -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

+ 26
- 7
source/native-plugins/zynaddsubfx/Effects/Echo.cpp View File

@@ -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
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/Echo.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/Effect.cpp View File

@@ -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;
}

}

+ 34
- 5
source/native-plugins/zynaddsubfx/Effects/Effect.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/EffectLFO.cpp View File

@@ -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;
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/EffectLFO.h View File

@@ -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

+ 19
- 18
source/native-plugins/zynaddsubfx/Effects/EffectMgr.cpp View File

@@ -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();
}

}

+ 31
- 3
source/native-plugins/zynaddsubfx/Effects/EffectMgr.h View File

@@ -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

+ 51
- 18
source/native-plugins/zynaddsubfx/Effects/Phaser.cpp View File

@@ -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;
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/Phaser.h View File

@@ -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

+ 40
- 12
source/native-plugins/zynaddsubfx/Effects/Reverb.cpp View File

@@ -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;
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Effects/Reverb.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/Allocator.cpp View File

@@ -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
*/

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/Allocator.h View File

@@ -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
*/

}

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

@@ -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 += "/";
}

}

+ 6
- 2
source/native-plugins/zynaddsubfx/Misc/Bank.h View File

@@ -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

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

@@ -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;
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/BankDb.h View File

@@ -3,6 +3,8 @@
#include <vector>
#include <map>

namespace zyncarla {

struct BankEntry
{
BankEntry(void);
@@ -53,3 +55,5 @@ class BankDb
bvec fields;
svec banks;
};

}

+ 5
- 0
source/native-plugins/zynaddsubfx/Misc/CallbackRepeater.cpp View File

@@ -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;
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/CallbackRepeater.h View File

@@ -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;
};

}

+ 51
- 30
source/native-plugins/zynaddsubfx/Misc/Config.cpp View File

@@ -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");
}

}

+ 11
- 6
source/native-plugins/zynaddsubfx/Misc/Config.h View File

@@ -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

+ 3
- 0
source/native-plugins/zynaddsubfx/Misc/LASHClient.cpp View File

@@ -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));
}

}

+ 2
- 0
source/native-plugins/zynaddsubfx/Misc/LASHClient.h View 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

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

@@ -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;
}


}

+ 25
- 5
source/native-plugins/zynaddsubfx/Misc/Master.h View File

@@ -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

+ 39
- 17
source/native-plugins/zynaddsubfx/Misc/Microtonal.cpp View File

@@ -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);
}
}

}

+ 5
- 0
source/native-plugins/zynaddsubfx/Misc/Microtonal.h View File

@@ -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

+ 119
- 147
source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp View File

@@ -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;
}

}

+ 10
- 3
source/native-plugins/zynaddsubfx/Misc/MiddleWare.h View File

@@ -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;
};

}


+ 56
- 30
source/native-plugins/zynaddsubfx/Misc/Part.cpp View File

@@ -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);
}

}

+ 7
- 1
source/native-plugins/zynaddsubfx/Misc/Part.h View File

@@ -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

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

@@ -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;
}

}

+ 5
- 0
source/native-plugins/zynaddsubfx/Misc/PresetExtractor.h View File

@@ -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();

}

+ 3
- 0
source/native-plugins/zynaddsubfx/Misc/Recorder.cpp View File

@@ -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
}

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/Recorder.h View File

@@ -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

+ 55
- 9
source/native-plugins/zynaddsubfx/Misc/Schema.cpp View File

@@ -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 << "}";
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/Stereo.cpp View File

@@ -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;
}

}

+ 5
- 0
source/native-plugins/zynaddsubfx/Misc/Stereo.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/Time.h View File

@@ -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;
};

}

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

@@ -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;
}

}

+ 10
- 10
source/native-plugins/zynaddsubfx/Misc/Util.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/WavFile.cpp View File

@@ -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;
}
}

}

+ 5
- 0
source/native-plugins/zynaddsubfx/Misc/WavFile.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/WaveShapeSmps.cpp View File

@@ -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;
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/WaveShapeSmps.h View File

@@ -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

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

@@ -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;
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Misc/XMLwrapper.h View File

@@ -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

+ 6
- 2
source/native-plugins/zynaddsubfx/Nio/AlsaEngine.cpp View File

@@ -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;
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/AlsaEngine.h View File

@@ -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

+ 6
- 2
source/native-plugins/zynaddsubfx/Nio/AudioOut.cpp View File

@@ -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);
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/AudioOut.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/Engine.cpp View File

@@ -12,8 +12,12 @@
*/
#include "Engine.h"

namespace zyncarla {

Engine::Engine()
{}

Engine::~Engine()
{}

}

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

@@ -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

+ 5
- 1
source/native-plugins/zynaddsubfx/Nio/EngineMgr.cpp View File

@@ -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;
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/EngineMgr.h View File

@@ -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

+ 5
- 2
source/native-plugins/zynaddsubfx/Nio/InMgr.cpp View File

@@ -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_;
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/InMgr.h View File

@@ -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

+ 6
- 2
source/native-plugins/zynaddsubfx/Nio/JackEngine.cpp View File

@@ -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)
}
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/JackEngine.h View File

@@ -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

+ 6
- 1
source/native-plugins/zynaddsubfx/Nio/JackMultiEngine.cpp View File

@@ -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;
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/JackMultiEngine.h View File

@@ -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

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/MidiIn.cpp View File

@@ -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;
}
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/MidiIn.h View File

@@ -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

+ 5
- 0
source/native-plugins/zynaddsubfx/Nio/Nio.cpp View File

@@ -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();
}

}

+ 4
- 0
source/native-plugins/zynaddsubfx/Nio/Nio.h View File

@@ -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

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save