summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2017-11-25 16:49:06 +1100
committerDamien Zammit <damien@zamaudio.com>2017-11-25 16:49:06 +1100
commit3e13e6170f467eaf2ba8579441c8f9d0bf1f0c40 (patch)
tree8c50a7ee136e4054812fbdcdff33119dd179ab68
parentd3fe6f5d7d60d2e6d7b9a9e850f36f5091c10992 (diff)
ZamSFZ: Add velocity remapping to limit number of layers
-rw-r--r--plugins/ZamSFZ/Sfz.cpp97
-rw-r--r--plugins/ZamSFZ/Sfz.hpp5
-rw-r--r--plugins/ZamSFZ/ZamSFZPlugin.hpp2
-rw-r--r--plugins/ZamSFZ/libsfz/sfz.cpp2
4 files changed, 103 insertions, 3 deletions
diff --git a/plugins/ZamSFZ/Sfz.cpp b/plugins/ZamSFZ/Sfz.cpp
index c58bea9..be51654 100644
--- a/plugins/ZamSFZ/Sfz.cpp
+++ b/plugins/ZamSFZ/Sfz.cpp
@@ -4,6 +4,101 @@
#include <string>
#define BLOCK_SIZE 512
+void Sfz::remapvelocityranges(::sfz::Instrument *inst)
+{
+ int i, k, r, key, oldkey, l, lowest, idx;
+ ::sfz::SFZRegion *reg;
+ std::vector< ::sfz::SFZRegion > tmp;
+ std::vector< ::sfz::SFZRegion* > remap;
+ int layer[128] = {0};
+
+ if (!inst)
+ return;
+
+ for (i = 0; i < inst->regions.size(); i++) {
+ if (inst->regions[i]->lokey == inst->regions[i]->hikey) {
+ key = inst->regions[i]->lokey;
+ } else {
+ key = inst->regions[i]->pitch_keycenter;
+ }
+ layer[key]++;
+ }
+
+ for (key = 0; key < 128; key++) {
+ lowest = 2;
+ idx = -1;
+ for (i = 0; i < layer[key]; i++) {
+ // find next region with correct key
+ for (r = idx+1; r < inst->regions.size(); r++) {
+ if (inst->regions[r]->lokey == inst->regions[r]->hikey) {
+ k = inst->regions[r]->lokey;
+ } else {
+ k = inst->regions[r]->pitch_keycenter;
+ }
+ if (k != key)
+ continue;
+
+ if (inst->regions[r]->lovel <= lowest) {
+ idx = r;
+ lowest = inst->regions[r]->hivel + 2;
+ break;
+ }
+ }
+ if (idx >= 0) {
+ // push found region to new vector
+ tmp.push_back(*(inst->regions[idx]));
+ }
+ }
+ }
+
+ for (i = 0; i < tmp.size(); i++) {
+ printf("tmp: k:%d (%d, %d) %s\n", tmp[i].lokey, tmp[i].lovel, tmp[i].hivel, tmp[i].sample.c_str());
+ }
+
+ oldkey = -1;
+ for (i = 0; i < tmp.size(); i++) {
+ if (tmp[i].lokey == tmp[i].hikey) {
+ key = tmp[i].lokey;
+ } else {
+ key = tmp[i].pitch_keycenter;
+ }
+ if (key != oldkey) {
+ if (layer[key] > MAX_LAYERS) {
+ // Remap velocities
+ // Choose staggered layers
+ int chosen, lo, hi;
+ lo = 0;
+ hi = 0;
+ for (k = 1; k <= MAX_LAYERS; k++) {
+ chosen = k * layer[key] / MAX_LAYERS;
+ lo = hi + 1;
+ hi = k * 127 / MAX_LAYERS;
+ reg = new ::sfz::SFZRegion(inst);
+
+ tmp[(chosen - 1) + i].lovel = lo;
+ tmp[(chosen - 1) + i].hivel = hi;
+ *reg = tmp[(chosen - 1) + i];
+ remap.push_back(reg);
+ }
+ } else {
+ // 1:1 mapping
+ for (k = 0; k < layer[key]; k++) {
+ reg = new ::sfz::SFZRegion(inst);
+ *reg = tmp[k + i];
+ remap.push_back(reg);
+ }
+ }
+ }
+ oldkey = key;
+ }
+
+ inst->regions.clear();
+ for (i = 0; i < remap.size(); i++) {
+ inst->regions.push_back(remap[i]);
+ printf("k:%d (%d, %d) %s\n", remap[i]->lokey, remap[i]->lovel, remap[i]->hivel, remap[i]->sample.c_str());
+ }
+}
+
void Sfz::readsamples(SNDFILE *infile,
int channels, int note, int layer)
{
@@ -58,6 +153,8 @@ void Sfz::loadsamples(std::string path, std::string filename)
}
::sfz::Instrument* sfzinstrument = &sfzfile.instrument;
+ remapvelocityranges(sfzinstrument);
+
SNDFILE *infile = NULL;
SF_INFO sfinfo;
diff --git a/plugins/ZamSFZ/Sfz.hpp b/plugins/ZamSFZ/Sfz.hpp
index 18e2b9b..5566495 100644
--- a/plugins/ZamSFZ/Sfz.hpp
+++ b/plugins/ZamSFZ/Sfz.hpp
@@ -6,8 +6,8 @@
#include <rubberband/RubberBandStretcher.h>
#include <sndfile.h>
#include <math.h>
-#define MAX_LAYERS 25
-#define MAX_SAMPLES 64000
+#define MAX_LAYERS 12
+#define MAX_SAMPLES 130000
class Sfz {
@@ -33,4 +33,5 @@ public:
void loadsamples(std::string path, std::string filename);
void readsamples (SNDFILE *infile, int channels, int note, int layer);
void pitchshiftsamples(int srate);
+ void remapvelocityranges(::sfz::Instrument *inst);
};
diff --git a/plugins/ZamSFZ/ZamSFZPlugin.hpp b/plugins/ZamSFZ/ZamSFZPlugin.hpp
index d9bab5e..e9b520c 100644
--- a/plugins/ZamSFZ/ZamSFZPlugin.hpp
+++ b/plugins/ZamSFZ/ZamSFZPlugin.hpp
@@ -23,7 +23,7 @@
#include "Sfz.hpp"
#define MAX_VOICES 128
-#define MAX_ENV (MAX_SAMPLES / 10)
+#define MAX_ENV (MAX_SAMPLES / 100)
START_NAMESPACE_DISTRHO
diff --git a/plugins/ZamSFZ/libsfz/sfz.cpp b/plugins/ZamSFZ/libsfz/sfz.cpp
index 5df0c78..8ecb28d 100644
--- a/plugins/ZamSFZ/libsfz/sfz.cpp
+++ b/plugins/ZamSFZ/libsfz/sfz.cpp
@@ -400,7 +400,9 @@ SFZRegion::SFZRegion(Instrument* i)
void SFZRegion::clear()
{
+ lokey = 1;
hikey = 127;
+ lovel = 1;
hivel = 127;
pitch_keycenter = 60; // C4
pitch_keytrack = 100;