summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2016-07-20 01:22:34 +1000
committerDamien Zammit <damien@zamaudio.com>2016-07-20 01:22:34 +1000
commit404058e2bdcf41165d00e61fa3f78a273920b81b (patch)
tree228f9b63e8f02fcf1f86c00f67f92be24af6a906 /plugins
parent27f9c885aa4243e6e02df0ab82046aee87c46cf3 (diff)
Improved SFZ parser
Signed-off-by: Damien Zammit <damien@zamaudio.com>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/ZamSFZ/Sfz.cpp17
-rw-r--r--plugins/ZamSFZ/Sfz.hpp3
-rw-r--r--plugins/ZamSFZ/ZamSFZPlugin.cpp11
-rw-r--r--plugins/ZamSFZ/ZamSFZPlugin.hpp3
-rw-r--r--plugins/ZamSFZ/ZamSFZUI.cpp2
-rw-r--r--plugins/ZamSFZ/ZamSFZUI.hpp5
-rw-r--r--plugins/ZamSFZ/libsfz/LICENSE19
-rw-r--r--plugins/ZamSFZ/libsfz/sfz.cpp3031
-rw-r--r--plugins/ZamSFZ/libsfz/sfz.h356
9 files changed, 525 insertions, 2922 deletions
diff --git a/plugins/ZamSFZ/Sfz.cpp b/plugins/ZamSFZ/Sfz.cpp
index 800f437..c58bea9 100644
--- a/plugins/ZamSFZ/Sfz.cpp
+++ b/plugins/ZamSFZ/Sfz.cpp
@@ -50,10 +50,13 @@ void Sfz::clearsamples()
void Sfz::loadsamples(std::string path, std::string filename)
{
int note, i, j, k, key;
- ::sfz::File* sfzfile = NULL;
- ::sfz::Instrument* sfzinstrument = NULL;
- sfzfile = new ::sfz::File(filename, path);
- sfzinstrument = sfzfile->GetInstrument();
+ ::sfz::SFZParser sfzfile;
+ std::string fullsfzpath = path + std::string("/") + filename;
+ if (sfzfile.readsfz(fullsfzpath) == -1) {
+ printf("Can't open SFZ\n");
+ return;
+ }
+ ::sfz::Instrument* sfzinstrument = &sfzfile.instrument;
SNDFILE *infile = NULL;
SF_INFO sfinfo;
@@ -73,10 +76,11 @@ void Sfz::loadsamples(std::string path, std::string filename)
layers[note].keymiddle = key;
layers[note].dsemitones = 0;
infile = NULL;
- if ((infile = sf_open(sfzinstrument->regions[i]->sample.c_str(), SFM_READ, &sfinfo)) == NULL) {
+ std::string fullsamplepath = path + std::string("/") + sfzinstrument->regions[i]->sample;
+ if ((infile = sf_open(fullsamplepath.c_str(), SFM_READ, &sfinfo)) == NULL) {
printf("Missing samples\n");
puts (sf_strerror (NULL));
- printf("File: %s\n",sfzinstrument->regions[i]->sample.c_str());
+ printf("File: %s\n",fullsamplepath.c_str());
}
readsamples (infile, sfinfo.channels, note, layers[note].max);
k = layers[note].max;
@@ -97,7 +101,6 @@ void Sfz::loadsamples(std::string path, std::string filename)
}
printf("All samples loaded, Woot!\n");
}
- delete sfzfile;
for (i = 0; i < 128; i++) {
if (!(layers[i].keymiddle == i)) {
k = layers[i].keymiddle;
diff --git a/plugins/ZamSFZ/Sfz.hpp b/plugins/ZamSFZ/Sfz.hpp
index 5698283..18e2b9b 100644
--- a/plugins/ZamSFZ/Sfz.hpp
+++ b/plugins/ZamSFZ/Sfz.hpp
@@ -5,7 +5,8 @@
#include "libsfz/sfz.h"
#include <rubberband/RubberBandStretcher.h>
#include <sndfile.h>
-#define MAX_LAYERS 8
+#include <math.h>
+#define MAX_LAYERS 25
#define MAX_SAMPLES 64000
class Sfz {
diff --git a/plugins/ZamSFZ/ZamSFZPlugin.cpp b/plugins/ZamSFZ/ZamSFZPlugin.cpp
index c7bd616..8208bad 100644
--- a/plugins/ZamSFZ/ZamSFZPlugin.cpp
+++ b/plugins/ZamSFZ/ZamSFZPlugin.cpp
@@ -91,17 +91,22 @@ void ZamSFZPlugin::setState(const char* key, const char* value)
path.assign(value, 0, strlen(value) - strlen(tmp));
loading = true;
printf("Path: %s\nFile: %s\n", path.c_str(), filename.c_str());
- sfz.clearsamples();
+ sfz.clearsamples();
sfz.loadsamples(path, filename);
sfz.pitchshiftsamples((int)getSampleRate());
loading = false;
}
}
-void ZamSFZPlugin::initState(unsigned int key, String& val, d_string&)
+String ZamSFZPlugin::getState(const char*) const
+{
+ return String("filepath");
+}
+
+void ZamSFZPlugin::initState(unsigned int key, String& val, String&)
{
if (key == 0)
- val = "filepath";
+ val = "filepath";
}
void ZamSFZPlugin::loadProgram(uint32_t index)
diff --git a/plugins/ZamSFZ/ZamSFZPlugin.hpp b/plugins/ZamSFZ/ZamSFZPlugin.hpp
index 170b76a..3602776 100644
--- a/plugins/ZamSFZ/ZamSFZPlugin.hpp
+++ b/plugins/ZamSFZ/ZamSFZPlugin.hpp
@@ -120,7 +120,8 @@ protected:
void run(const float** inputs, float** outputs, uint32_t frames,
const MidiEvent* midievent, uint32_t midicount) override;
void setState(const char* key, const char* value) override;
- void initState(unsigned int, String&, d_string&) override;
+ String getState(const char* key) const override;
+ void initState(unsigned int, String&, String&) override;
// -------------------------------------------------------------------
private:
diff --git a/plugins/ZamSFZ/ZamSFZUI.cpp b/plugins/ZamSFZ/ZamSFZUI.cpp
index 6c4b5f4..a4b282b 100644
--- a/plugins/ZamSFZ/ZamSFZUI.cpp
+++ b/plugins/ZamSFZ/ZamSFZUI.cpp
@@ -84,7 +84,7 @@ void ZamSFZUI::stateChanged(const char* key, const char*)
}
}
-void ZamSFZUI::d_uiFileBrowserSelected(const char* filename)
+void ZamSFZUI::uiFileBrowserSelected(const char* filename)
{
// if a file was selected, tell DSP
if (filename != nullptr)
diff --git a/plugins/ZamSFZ/ZamSFZUI.hpp b/plugins/ZamSFZ/ZamSFZUI.hpp
index b90daaf..bae978e 100644
--- a/plugins/ZamSFZ/ZamSFZUI.hpp
+++ b/plugins/ZamSFZ/ZamSFZUI.hpp
@@ -19,8 +19,7 @@
#define ZAMSFZUI_HPP_INCLUDED
#include "DistrhoUI.hpp"
-#include "ImageKnob.hpp"
-#include "ImageButton.hpp"
+#include "ImageWidgets.hpp"
#include "ZamSFZArtwork.hpp"
using DGL::Image;
@@ -46,7 +45,7 @@ protected:
void programLoaded(uint32_t index) override;
void stateChanged(const char* key, const char* value) override;
- void d_uiFileBrowserSelected(const char* filename) override;
+ void uiFileBrowserSelected(const char* filename) override;
// -------------------------------------------------------------------
// Widget Callbacks
diff --git a/plugins/ZamSFZ/libsfz/LICENSE b/plugins/ZamSFZ/libsfz/LICENSE
deleted file mode 100644
index 5c53037..0000000
--- a/plugins/ZamSFZ/libsfz/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2009 Anders Dahnielson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/plugins/ZamSFZ/libsfz/sfz.cpp b/plugins/ZamSFZ/libsfz/sfz.cpp
index 23ecf28..5df0c78 100644
--- a/plugins/ZamSFZ/libsfz/sfz.cpp
+++ b/plugins/ZamSFZ/libsfz/sfz.cpp
@@ -1,2648 +1,437 @@
-/* -*- Mode: C++ ; c-basic-offset: 8 -*- */
-
-// SFZ 1.0
-// Copyright (c) 2008-2009, Anders Dahnielson
-//
-// Contact: anders@dahnielson.com
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
#include "sfz.h"
+namespace sfz {
-#include <iostream>
-#include <sstream>
-
-#include <boost/lexical_cast.hpp>
-
-namespace sfz
+SFZParser::SFZParser()
{
+}
- /////////////////////////////////////////////////////////////
- // class Articulation
-
- Articulation::Articulation()
- {
- }
-
- Articulation::~Articulation()
- {
- }
-
- /////////////////////////////////////////////////////////////
- // class Definition
-
- Definition::Definition()
- {
- }
-
- Definition::~Definition()
- {
- }
-
- /////////////////////////////////////////////////////////////
- // class Region
-
- Region::Region()
- {
- }
-
- Region::~Region()
- {
- }
-
- bool
- Region::OnKey(uint8_t chan, uint8_t key, uint8_t vel,
- int bend, uint8_t bpm, uint8_t chanaft, uint8_t polyaft,
- uint8_t prog, float rand, trigger_t trig, uint8_t* cc,
- float timer, uint8_t seq, bool* sw, uint8_t last_sw_key, uint8_t prev_sw_key)
- {
- // chan (MIDI channel)
- // key (MIDI note)
- // vel (MIDI velocity)
-
- // bend (MIDI pitch bend)
- // bpm (host BPM)
- // chanaft (MIDI channel pressure)
- // polyaft (MIDI polyphonic aftertouch)
- // prog (MIDI program change)
- // rand (generated random number)
- // trigger (how it was triggered)
- // cc (all 128 CC values)
-
- // timer (time since previous region in the group was triggered)
- // seq (the state of the region sequence counter)
- // sw (the state of region key switches, 128 possible values)
- // last_sw_key (the last key pressed in the key switch range)
- // prev_sw_key (the previous note value)
-
- bool is_triggered (
- chan >= lochan && chan <= hichan &&
- key >= lokey && key <= hikey &&
- vel >= lovel && vel <= hivel &&
- bend >= lobend && bend <= hibend &&
- bpm >= lobpm && bpm <= hibpm &&
- chanaft >= lochanaft && chanaft <= hichanaft &&
- polyaft >= lopolyaft && polyaft <= hipolyaft &&
- prog >= loprog && prog <= hiprog &&
- rand >= lorand && rand <= hirand &&
- timer >= lotimer && timer <= hitimer &&
- seq == seq_position &&
- ((sw_last >= sw_lokey && sw_last <= sw_hikey) ? (last_sw_key == sw_last) : true) &&
- ((sw_down >= sw_lokey && sw_down <= sw_hikey) ? (sw[sw_down]) : true) &&
- ((sw_up >= sw_lokey && sw_up <= sw_hikey) ? (!sw[sw_up]) : true) &&
- ((sw_previous != -1) ? (prev_sw_key == sw_previous) : true) &&
- ((trigger && trig) != 0)
- );
-
- if (!is_triggered)
- return false;
-
- for (int i = 0; i < 128; ++i)
- {
- if (!(cc[i] >= locc[i] && cc[i] <= hicc[i]))
- return false;
- }
-
- return true;
- }
-
- bool
- Region::OnControl(uint8_t chan, uint8_t cont, uint8_t val,
- int bend, uint8_t bpm, uint8_t chanaft, uint8_t polyaft,
- uint8_t prog, float rand, trigger_t trig, uint8_t* cc,
- float timer, uint8_t seq, bool* sw, uint8_t last_sw_key, uint8_t prev_sw_key)
- {
- // chan (MIDI channel)
- // cont (MIDI controller)
- // val (MIDI controller value)
-
- // bend (MIDI pitch bend)
- // bpm (host BPM)
- // chanaft (MIDI channel pressure)
- // polyaft (MIDI polyphonic aftertouch)
- // prog (MIDI program change)
- // rand (generated random number)
- // trigger (how it was triggered)
- // cc (all CC values)
-
- // timer (time since previous region in the group was triggered)
- // seq (the state of the region sequence counter)
- // sw (the state of region key switches, 128 possible values)
- // last_sw_key (the last key pressed in the key switch range)
- // prev_sw_key (the previous note value)
-
- bool is_triggered = (
- chan >= lochan && chan <= hichan &&
- ((val >= on_locc[cont] && val <= on_hicc[cont]) ||
- (val >= start_locc[cont] && val <= start_hicc[cont])) &&
- bend >= lobend && bend <= hibend &&
- bpm >= lobpm && bpm <= hibpm &&
- chanaft >= lochanaft && chanaft <= hichanaft &&
- polyaft >= lopolyaft && polyaft <= hipolyaft &&
- prog >= loprog && prog <= hiprog &&
- rand >= lorand && rand <= hirand &&
- timer >= lotimer && timer <= hitimer &&
- seq == seq_position &&
- ((sw_last >= sw_lokey && sw_last <= sw_hikey) ? (last_sw_key == sw_last) : true) &&
- ((sw_down >= sw_lokey && sw_down <= sw_hikey) ? (sw[sw_down]) : true) &&
- ((sw_up >= sw_lokey && sw_up <= sw_hikey) ? (!sw[sw_up]) : true) &&
- ((sw_previous != -1) ? (prev_sw_key == sw_previous) : true) &&
- ((trigger && trig) != 0)
- );
-
- if (!is_triggered)
- return false;
-
- for (int i = 0; i < 128; ++i)
- {
- if (!(cc[i] >= locc[i] && cc[i] <= hicc[i]))
- return false;
- }
+SFZParser::~SFZParser()
+{
+}
- return true;
- }
+int SFZParser::readsfz(std::string path)
+{
+ FILE* fp;
+ uint32_t len;
- Articulation*
- Region::GetArticulation(int bend, uint8_t bpm, uint8_t chanaft, uint8_t polyaft, uint8_t* cc)
- {
- return new Articulation(); //todo: implement GetArticulation()
+ if (! (fp = fopen(path.c_str(), "rb"))) {
+ return -1;
}
- /////////////////////////////////////////////////////////////
- // class Instrument
+ fseek(fp, 0, SEEK_END);
+ len = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
- Instrument::Instrument()
- {
- }
-
- Instrument::~Instrument()
- {
- for (uint32_t i = 0; i < regions.size(); i++) {
- delete regions[i];
- }
- }
+ char sfz[len];
- /////////////////////////////////////////////////////////////
- // class Group
+ fread(sfz, 1, len, fp);
+ fclose(fp);
+
+ SFZParser::read(sfz, len);
+ return 0;
+}
- Group::Group() :
- id(0)
- {
- Reset();
+void SFZParser::read(const char* text, unsigned int length)
+{
+ const char* p = text;
+ const char* end = text + length;
+ char c;
+
+ SFZRegion curGroup(&instrument);
+ SFZRegion curRegion(&instrument);
+ SFZRegion *buildingRegion = NULL;
+ bool inControl = false;
+ std::string defaultPath;
+
+ while (p < end) {
+ // We're at the start of a line; skip any whitespace.
+ while (p < end) {
+ c = *p;
+ if (c != ' ' && c != '\t')
+ break;
+ p += 1;
+ }
+ if (p >= end)
+ break;
+
+ // Check if it's a comment line.
+ if (c == '/' && *(p+1) == '/') {
+ // Skip to end of line.
+ while (p < end) {
+ c = *++p;
+ if (c == '\n' || c == '\r')
+ break;
+ }
+ p = handleLineEnd(p);
+ continue;
+ }
+
+ // Check if it's a blank line.
+ if (c == '\r' || c == '\n') {
+ p = handleLineEnd(p);
+ continue;
+ }
+
+ // Handle elements on the line.
+ while (p < end) {
+ c = *p;
+
+ // Tag.
+ if (c == '<') {
+ p += 1;
+ const char* tagStart = p;
+ while (p < end) {
+ c = *p++;
+ if (c == '\n' || c == '\r') {
+ error(std::string("Unterminated tag"));
+ goto fatalError;
+ }
+ else if (c == '>')
+ break;
+ }
+ if (p >= end) {
+ error(std::string("Unterminated tag"));
+ goto fatalError;
+ }
+ StringSlice tag(tagStart, p - 1);
+ if (tag == "region") {
+ if (buildingRegion && buildingRegion == &curRegion)
+ finishRegion(&curRegion);
+ curRegion = curGroup;
+ buildingRegion = &curRegion;
+ inControl = false;
+ }
+ else if (tag == "group") {
+ if (buildingRegion && buildingRegion == &curRegion)
+ finishRegion(&curRegion);
+ curGroup.clear();
+ buildingRegion = &curGroup;
+ inControl = false;
+ }
+ else if (tag == "control") {
+ if (buildingRegion && buildingRegion == &curRegion)
+ finishRegion(&curRegion);
+ curGroup.clear();
+ buildingRegion = NULL;
+ inControl = true;
+ }
+ else
+ error(std::string("Illegal tag"));
+ }
+
+ // Comment.
+ else if (c == '/' && *(p+1) == '/') {
+ // Skip to end of line.
+ while (p < end) {
+ c = *p;
+ if (c == '\r' || c == '\n')
+ break;
+ p += 1;
+ }
+ }
+
+ // Parameter.
+ else {
+ // Get the parameter name.
+ const char* parameterStart = p;
+ while (p < end) {
+ c = *p++;
+ if (c == '=' || c == ' ' || c == '\t' || c == '\r' || c == '\n')
+ break;
+ }
+ if (p >= end || c != '=') {
+ error(std::string("Malformed parameter"));
+ goto nextElement;
+ }
+ StringSlice opcode(parameterStart, p - 1);
+ if (inControl) {
+ if (opcode == "default_path")
+ p = readPathInto(&defaultPath, p, end);
+ else {
+ const char* valueStart = p;
+ while (p < end) {
+ c = *p;
+ if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
+ break;
+ p++;
+ }
+ std::string value(valueStart, p - valueStart);
+ std::string fauxOpcode =
+ std::string(opcode.start, opcode.length()) + " (in <control>)";
+ printf("Unsupported: %s\n", fauxOpcode.c_str());
+ }
+ }
+ else if (opcode == "sample") {
+ std::string path;
+ p = readPathInto(&path, p, end);
+ if (!path.empty()) {
+ printf("`%s'\n", path.c_str());
+ if (buildingRegion)
+ buildingRegion->sample = path;
+ else
+ error("Adding sample outside a group or region");
+ }
+ else
+ error(std::string("Empty sample path"));
+ }
+ else {
+ const char* valueStart = p;
+ while (p < end) {
+ c = *p;
+ if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
+ break;
+ p++;
+ }
+ std::string value(valueStart, p - valueStart);
+ if (buildingRegion == NULL)
+ error("Setting a parameter outside a region or group");
+ else if (opcode == "lokey")
+ buildingRegion->lokey = keyValue(value);
+ else if (opcode == "hikey")
+ buildingRegion->hikey = keyValue(value);
+ else if (opcode == "key") {
+ buildingRegion->hikey =
+ buildingRegion->lokey =
+ buildingRegion->pitch_keycenter =
+ keyValue(value);
+ }
+ else if (opcode == "lovel")
+ buildingRegion->lovel = atoi(value.c_str());
+ else if (opcode == "hivel")
+ buildingRegion->hivel = atoi(value.c_str());
+ else if (opcode == "trigger")
+ buildingRegion->trigger = (SFZRegion::Trigger) triggerValue(value);
+ else if (opcode == "group")
+ buildingRegion->group = (unsigned long) atol(value.c_str());
+ else if (opcode == "off_by")
+ buildingRegion->off_by = (unsigned long) atol(value.c_str());
+ else if (opcode == "offset")
+ buildingRegion->offset = (unsigned long) atol(value.c_str());
+ else if (opcode == "end") {
+ int64_t end = (unsigned long) atol(value.c_str());
+ if (end < 0)
+ buildingRegion->negative_end = true;
+ else
+ buildingRegion->end = end;
+ }
+ else if (opcode == "loop_mode") {
+ bool modeIsSupported =
+ value == "no_loop" ||
+ value == "one_shot" ||
+ value == "loop_continuous";
+ if (modeIsSupported)
+ buildingRegion->loop_mode = (SFZRegion::LoopMode) loopModeValue(value);
+ else {
+ std::string fauxOpcode =
+ std::string(opcode.start, opcode.length()) + "=" + value;
+ printf("Unsupported: %s\n", fauxOpcode.c_str());
+ }
+ }
+ else if (opcode == "loop_start")
+ buildingRegion->loop_start = (unsigned long) atol(value.c_str());
+ else if (opcode == "loop_end")
+ buildingRegion->loop_end = (unsigned long) atol(value.c_str());
+ else if (opcode == "transpose")
+ buildingRegion->transpose = atoi(value.c_str());
+ else if (opcode == "tune")
+ buildingRegion->tune = atoi(value.c_str());
+ else if (opcode == "pitch_keycenter")
+ buildingRegion->pitch_keycenter = keyValue(value);
+ else if (opcode == "pitch_keytrack")
+ buildingRegion->pitch_keytrack = atoi(value.c_str());
+ else if (opcode == "bend_up")
+ buildingRegion->bend_up = atoi(value.c_str());
+ else if (opcode == "bend_down")
+ buildingRegion->bend_down = atoi(value.c_str());
+ else if (opcode == "volume")
+ buildingRegion->volume = atof(value.c_str());
+ else if (opcode == "pan")
+ buildingRegion->pan = atof(value.c_str());
+ else if (opcode == "amp_veltrack")
+ buildingRegion->amp_veltrack = atof(value.c_str());
+ else if (opcode == "default_path")
+ error(std::string("\"default_path\" outside of <control> tag"));
+ else
+ error(std::string("Unsupported"));
+ }
+ }
+
+ // Skip to next element.
+nextElement:
+ c = 0;
+ while (p < end) {
+ c = *p;
+ if (c != ' ' && c != '\t')
+ break;
+ p += 1;
+ }
+ if (c == '\r' || c == '\n') {
+ p = handleLineEnd(p);
+ break;
+ }
+ }
+ }
+
+fatalError:
+ if (buildingRegion && buildingRegion == &curRegion)
+ finishRegion(buildingRegion);
+}
+
+const char* SFZParser::handleLineEnd(const char* p)
+{
+ // Check for DOS-style line ending.
+ char lineEndChar = *p++;
+ if (lineEndChar == '\r' && *p == '\n')
+ p += 1;
+ line += 1;
+ return p;
+}
+
+const char* SFZParser::readPathInto(std::string* pathOut, const char* pIn, const char* endIn)
+{
+ // Paths are kind of funny to parse because they can contain whitespace.
+ const char* p = pIn;
+ const char* end = endIn;
+ const char* pathStart = p;
+ const char* potentialEnd = NULL;
+ while (p < end) {
+ char c = *p;
+ if (c == ' ') {
+ // Is this space part of the path? Or the start of the next opcode? We
+ // don't know yet.
+ potentialEnd = p;
+ p += 1;
+ // Skip any more spaces.
+ while (p < end && *p == ' ')
+ p += 1;
+ }
+ else if (c == '\n' || c == '\r' || c == '\t')
+ break;
+ else if (c == '=') {
+ // We've been looking at an opcode; we need to rewind to
+ // potentialEnd.
+ p = potentialEnd;
+ break;
+ }
+ p += 1;
}
-
- Group::~Group()
- {
-
+ if (p > pathStart) {
+ std::string path(pathStart, p);
+ *pathOut = path;
}
+ else
+ *pathOut = std::string("");
+ return p;
+}
- void
- Group::Reset()
- {
- // This is where all the default values are set.
-
- // sample definition default
- sample = "";
-
- // input control
- lochan = 1; hichan = 16;
- lokey = 0; hikey = 127;
- lovel = 0; hivel = 127;
- lobend = -8192; hibend = 8192;
- lobpm = 0; hibpm = 500;
- lochanaft = 0; hichanaft = 127;
- lopolyaft = 0; hipolyaft = 127;
- loprog = 0; hiprog = 127;
- lorand = 0.0; hirand = 1.0;
- lotimer = 0.0; hitimer = 0.0;
-
- seq_length = 1;
- seq_position = 1;
-
- sw_lokey = -1; sw_hikey = -1;
- sw_last = -1;
- sw_down = -1;
- sw_up = -1;
- sw_previous = -1;
- sw_vel = VEL_CURRENT;
-
- trigger = TRIGGER_ATTACK;
-
- group = 0;
- off_by = 0;
- off_mode = OFF_FAST;
-
- // sample player
- count = 0;
- delay = 0; delay_random = 0;
- delay_beats = 0; stop_beats = 0;
- delay_samples = 0;
- end = 0;
- loop_crossfade = 0;
- offset = 0; offset_random = 0;
- loop_mode = NO_LOOP;
- loop_start = 0; loop_end = 0;
- sync_beats = 0; sync_offset = 0;
-
- // amplifier
- volume = 0;
- pan = 0;
- width = 100;
- position = 0;
- amp_keytrack = 0;
- amp_keycenter = 60;
- amp_veltrack = 100;
- amp_random = 0;
- rt_decay = 0;
- xfin_lokey = 0; xfin_hikey = 0;
- xfout_lokey = 127; xfout_hikey = 127;
- xf_keycurve = POWER;
- xfin_lovel = 0; xfin_hivel = 0;
- xfout_lovel = 127; xfout_hivel = 127;
- xf_velcurve = POWER;
- xf_cccurve = POWER;
-
- // pitch
- transpose = 0;
- tune = 0;
- pitch_keycenter = 60;
- pitch_keytrack = 100;
- pitch_veltrack = 0;
- pitch_random = 0;
- bend_up = 200;
- bend_down = -200;
- bend_step = 1;
-
- // filter
- fil_type = LPF_2P;
- cutoff = 0;
- cutoff_chanaft = 0;
- cutoff_polyaft = 0;
- resonance = 0;
- fil_keytrack = 0;
- fil_keycenter = 60;
- fil_veltrack = 0;
- fil_random = 0;
-
- fil2_type = LPF_2P;
- cutoff2 = 0;
- cutoff2_chanaft = 0;
- cutoff2_polyaft = 0;
- resonance2 = 0;
- fil2_keytrack = 0;
- fil2_keycenter = 60;
- fil2_veltrack = 0;
- fil2_random = 0;
-
- // per voice equalizer
- eq1_freq = 50;
- eq2_freq = 500;
- eq3_freq = 5000;
- eq1_vel2freq = 0;
- eq2_vel2freq = 0;
- eq3_vel2freq = 0;
- eq1_bw = 1;
- eq2_bw = 1;
- eq3_bw = 1;
- eq1_gain = 0;
- eq2_gain = 0;
- eq3_gain = 0;
- eq1_vel2gain = 0;
- eq2_vel2gain = 0;
- eq3_vel2gain = 0;
-
- // CCs
- for (int i = 0; i < 128; ++i)
- {
- // input control
- locc[i] = 0;
- hicc[i] = 127;
- start_locc[i] = -1;
- start_hicc[i] = -1;
- stop_locc[i] = -1;
- stop_hicc[i] = -1;
- on_locc[i] = -1;
- on_hicc[i] = -1;
-
- // sample player
- delay_oncc[i] = 0;
- delay_samples_oncc[i] = 0;
- offset_oncc[i] = 0;
-
- // amplifier
- amp_velcurve_[i] = 0; //fixme: 20 log (127^2 / i^2)
- gain_oncc[i] = 0;
- xfin_locc[i] = 0;
- xfin_hicc[i] = 0;
- xfout_locc[i] = 127;
- xfout_hicc[i] = 127;
-
- // filter
- cutoff_oncc[i] = 0;
- cutoff_smoothcc[i] = 0;
- cutoff_stepcc[i] = 0;
- cutoff_curvecc[i] = 0;
- resonance_oncc[i] = 0;
- resonance_smoothcc[i] = 0;
- resonance_stepcc[i] = 0;
- resonance_curvecc[i] = 0;
-
- cutoff2_oncc[i] = 0;
- cutoff2_smoothcc[i] = 0;
- cutoff2_stepcc[i] = 0;
- cutoff2_curvecc[i] = 0;
- resonance2_oncc[i] = 0;
- resonance2_smoothcc[i] = 0;
- resonance2_stepcc[i] = 0;
- resonance2_curvecc[i] = 0;
-
- // per voice equalizer
- eq1_freq_oncc[i] = 0;
- eq2_freq_oncc[i] = 0;
- eq3_freq_oncc[i] = 0;
- eq1_bw_oncc[i] = 0;
- eq2_bw_oncc[i] = 0;
- eq3_bw_oncc[i] = 0;
- eq1_gain_oncc[i] = 0;
- eq2_gain_oncc[i] = 0;
- eq3_gain_oncc[i] = 0;
+int SFZParser::keyValue(const std::string& str)
+{
+ char c = str[0];
+ if (c >= '0' && c <= '9')
+ return atoi(str.c_str());
+
+ int note = 0;
+ static const int notes[] = {
+ 12 + 0, 12 + 2, 3, 5, 7, 8, 10,
+ };
+ if (c >= 'A' && c <= 'G')
+ note = notes[c - 'A'];
+ else if (c >= 'a' && c <= 'g')
+ note = notes[c - 'a'];
+ int octaveStart = 1;
+ c = str[1];
+ if (c == 'b' || c == '#') {
+ octaveStart += 1;
+ if (c == 'b')
+ note -= 1;
+ else
+ note += 1;
}
- }
-
- Region*
- Group::RegionFactory()
- {
- // This is where the current group setting are copied to the new region.
-
- Region* region = new Region();
-
- region->id = id++;
-
- // sample definition
- region->sample = sample;
-
- // input control
- region->lochan = lochan;
- region->hichan = hichan;
- region->lokey = lokey;
- region->hikey = hikey;
- region->lovel = lovel;
- region->hivel = hivel;
- region->locc = locc;
- region->hicc = hicc;
- region->lobend = lobend;
- region->hibend = hibend;
- region->lobpm = lobpm;
- region->hibpm = hibpm;
- region->lochanaft = lochanaft;
- region->hichanaft = hichanaft;
- region->lopolyaft = lopolyaft;
- region->hipolyaft = hipolyaft;
- region->loprog = loprog;
- region->hiprog = hiprog;
- region->lorand = lorand;
- region->hirand = hirand;
- region->lotimer = lotimer;
- region->hitimer = hitimer;
- region->seq_length = seq_length;
- region->seq_position = seq_position;
- region->start_locc = start_locc;
- region->start_hicc = start_hicc;
- region->stop_locc = stop_locc;
- region->stop_hicc = stop_hicc;
- region->sw_lokey = sw_lokey;
- region->sw_hikey = sw_hikey;
- region->sw_last = sw_last;
- region->sw_down = sw_down;
- region->sw_up = sw_up;
- region->sw_previous = sw_previous;
- region->sw_vel = sw_vel;
- region->trigger = trigger;
- region->group = group;
- region->off_by = off_by;
- region->off_mode = off_mode;
- region->on_locc = on_locc;
- region->on_hicc = on_hicc;
-
- // sample player
- region->count = count;
- region->delay = delay;
- region->delay_random = delay_random;
- region->delay_oncc = delay_oncc;
- region->delay_beats = delay_beats;
- region->stop_beats = stop_beats;
- region->delay_samples = delay_samples;
- region->delay_samples_oncc = delay_samples_oncc;
- region->end = end;
- region->loop_crossfade = loop_crossfade;
- region->offset = offset;
- region->offset_random = offset_random;
- region->offset_oncc = offset_oncc;
- region->loop_mode = loop_mode;
- region->loop_start = loop_start;
- region->loop_end = loop_end;
- region->sync_beats = sync_beats;
- region->sync_offset = sync_offset;
-
- // amplifier
- region->volume = volume;
- region->pan = pan;
- region->width = width;
- region->position = position;
- region->amp_keytrack = amp_keytrack;
- region->amp_keycenter = amp_keycenter;
- region->amp_veltrack = amp_veltrack;
- region->amp_velcurve_ = amp_velcurve_;
- region->amp_random = amp_random;
- region->rt_decay = rt_decay;
- region->gain_oncc = gain_oncc;
- region->xfin_lokey = xfin_lokey;
- region->xfin_hikey = xfin_hikey;
- region->xfout_lokey = xfout_lokey;
- region->xfout_hikey = xfout_hikey;
- region->xf_keycurve = xf_keycurve;
- region->xfin_lovel = xfin_lovel;
- region->xfin_hivel = xfin_lovel;
- region->xfout_lovel = xfout_lovel;
- region->xfout_hivel = xfout_hivel;
- region->xf_velcurve = xf_velcurve;
- region->xfin_locc = xfin_locc;
- region->xfin_hicc = xfin_hicc;
- region->xfout_locc = xfout_locc;
- region->xfout_hicc = xfout_hicc;
- region->xf_cccurve = xf_cccurve;
-
- // pitch
- region->transpose = transpose;
- region->tune = tune;
- region->pitch_keycenter = pitch_keycenter;
- region->pitch_keytrack = pitch_keytrack;
- region->pitch_veltrack = pitch_veltrack;
- region->pitch_random = pitch_random;
- region->bend_up = bend_up;
- region->bend_down = bend_down;
- region->bend_step = bend_step;
-
- // filter
- region->fil_type = fil_type;
- region->cutoff = cutoff;
- region->cutoff_oncc = cutoff_oncc;
- region->cutoff_smoothcc = cutoff_smoothcc;
- region->cutoff_stepcc = cutoff_stepcc;
- region->cutoff_curvecc = cutoff_curvecc;
- region->cutoff_chanaft = cutoff_chanaft;
- region->cutoff_polyaft = cutoff_polyaft;
- region->resonance = resonance;
- region->resonance_oncc = resonance_oncc;
- region->resonance_smoothcc = resonance_smoothcc;
- region->resonance_stepcc = resonance_stepcc;
- region->resonance_curvecc = resonance_curvecc;
- region->fil_keytrack = fil_keytrack;
- region->fil_keycenter = fil_keycenter;
- region->fil_veltrack = fil_veltrack;
- region->fil_random = fil_random;
-
- region->fil2_type = fil2_type;
- region->cutoff2 = cutoff2;
- region->cutoff2_oncc = cutoff2_oncc;
- region->cutoff2_smoothcc = cutoff2_smoothcc;
- region->cutoff2_stepcc = cutoff2_stepcc;
- region->cutoff2_curvecc = cutoff2_curvecc;
- region->cutoff2_chanaft = cutoff2_chanaft;
- region->cutoff2_polyaft = cutoff2_polyaft;
- region->resonance2 = resonance2;
- region->resonance2_oncc = resonance2_oncc;
- region->resonance2_smoothcc = resonance2_smoothcc;
- region->resonance2_stepcc = resonance2_stepcc;
- region->resonance2_curvecc = resonance2_curvecc;
- region->fil2_keytrack = fil2_keytrack;
- region->fil2_keycenter = fil2_keycenter;
- region->fil2_veltrack = fil2_veltrack;
- region->fil2_random = fil2_random;
-
- // per voice equalizer
- region->eq1_freq = eq1_freq;
- region->eq2_freq = eq2_freq;
- region->eq3_freq = eq3_freq;
- region->eq1_freq_oncc = eq1_freq_oncc;
- region->eq2_freq_oncc = eq2_freq_oncc;
- region->eq3_freq_oncc = eq3_freq_oncc;
- region->eq1_vel2freq = eq1_vel2freq;
- region->eq2_vel2freq = eq2_vel2freq;
- region->eq3_vel2freq = eq3_vel2freq;
- region->eq1_bw = eq1_bw;
- region->eq2_bw = eq2_bw;
- region->eq3_bw = eq3_bw;
- region->eq1_bw_oncc = eq1_bw_oncc;
- region->eq2_bw_oncc = eq2_bw_oncc;
- region->eq3_bw_oncc = eq3_bw_oncc;
- region->eq1_gain = eq1_gain;
- region->eq2_gain = eq2_gain;
- region->eq3_gain = eq3_gain;
- region->eq1_gain_oncc = eq1_gain_oncc;
- region->eq2_gain_oncc = eq2_gain_oncc;
- region->eq3_gain_oncc = eq3_gain_oncc;
- region->eq1_vel2gain = eq1_vel2gain;
- region->eq2_vel2gain = eq2_vel2gain;
- region->eq3_vel2gain = eq3_vel2gain;
-
- return region;
- }
-
- /////////////////////////////////////////////////////////////
- // class File
-
- File::File(std::string file, std::string path) :
- _instrument(new Instrument()),
- _current_section(GROUP),
- _current_group(new Group()),
- default_path(path.c_str()),
- octave_offset(0),
- note_offset(0)
- {
-
- enum token_type_t { HEADER, OPCODE };
- token_type_t token_type;
- std::string token_string;
-
- default_path = default_path + "/";
- std::string fullpath = default_path + file;
- std::ifstream fs(fullpath.c_str());
- std::string token;
- std::string line;
- token_type = HEADER;
-
- int currentLine = 0;
-
- while (std::getline(fs, line))
- {
- currentLine++;
- printf("line %d: %s\n", currentLine, line.c_str());
- // COMMENT
- std::string::size_type slash_index = line.find("//");
- if (slash_index != std::string::npos)
- line.resize(slash_index);
-
- // #include
- if (line.find("#include ") == 0) {
- size_t fname_start = line.find("\"");
- if (fname_start == std::string::npos) continue;
-
- size_t fname_end = line.find("\"", fname_start + 1);
- if (fname_end == std::string::npos || fname_start == fname_end)
- continue;
- std::string fname = line.substr(fname_start + 1, fname_end - fname_start - 1);
+ int octave = atoi(str.substr(octaveStart).c_str());
+ // A3 == 57.
+ int result = octave * 12 + note + (57 - 4 * 12);
+ return result;
+}
- std::string cd = default_path;
- int cl = currentLine;
- File(file, cd);
- default_path = cd;
- currentLine = cl;
- continue;
- }
-
- // DEFINITION
- std::stringstream linestream(line);
- int spaces = 0;
- while (linestream >> token)
- {
- linestream >> std::noskipws;
- if (token[0] == '<' && token[token.size()-1] == '>')
- {
- // HEAD
- if (!token_string.empty())
- {
- switch (token_type)
- {
- case HEADER:
- push_header(token_string);
- break;
- case OPCODE:
- push_opcode(token_string);
- break;
- }
- token_string.erase();
- }
- token_string.append(token);
- token_type = HEADER;
- }
- else if (token.find('=') != std::string::npos)
- {
- // HEAD
- if (!token_string.empty())
- {
- switch (token_type)
- {
- case HEADER:
- push_header(token_string);
- break;
- case OPCODE:
- push_opcode(token_string);
- break;
- }
- token_string.erase();
- }
- token_string.append(token);
- token_type = OPCODE;
- }
- else
- {
- // TAIL
- token_string.append(spaces, ' ');
- token_string.append(token);
- }
- spaces = 0;
- while (isspace(linestream.peek())) {
- linestream.ignore();
- spaces++;
- }
- }
+int SFZParser::triggerValue(const std::string& str)
+{
+ if (str == "release")
+ return SFZRegion::RELEASE;
+ else if (str == "first")
+ return SFZRegion::FIRST;
+ else if (str == "legato")
+ return SFZRegion::LEGATO;
+ return SFZRegion::ATTACK;
+}
+
+int SFZParser::loopModeValue(const std::string& str)
+{
+ if (str == "no_loop")
+ return SFZRegion::NO_LOOP;
+ else if (str == "one_shot")
+ return SFZRegion::ONE_SHOT;
+ else if (str == "loop_continuous")
+ return SFZRegion::LOOP_CONTINUOUS;
+ else if (str == "loop_sustain")
+ return SFZRegion::LOOP_SUSTAIN;
+ return SFZRegion::SAMPLE_LOOP;
+}
+
+void SFZParser::finishRegion(SFZRegion* region)
+{
+ SFZRegion* newRegion = new SFZRegion(region->instrument);
+ *newRegion = *region;
+ instrument.regions.push_back(newRegion);
+}
- // EOL
- if (!token_string.empty())
- {
- switch (token_type)
- {
- case HEADER:
- push_header(token_string);
- break;
- case OPCODE:
- push_opcode(token_string);
- break;
- }
- token_string.erase();
- }
- }
- }
+void SFZParser::error(const std::string& message)
+{
+ std::string fullMessage = message;
+ printf("%s\n", fullMessage.c_str());
+}
- File::~File()
- {
- delete _current_group;
- delete _instrument;
- }
+// ----------------------------------------
- Instrument*
- File::GetInstrument()
- {
- return _instrument;
- }
+SFZRegion::SFZRegion(Instrument* i)
+{
+ instrument = i;
+ clear();
+}
- void
- File::push_header(std::string token)
- {
- if (token == "<group>")
- {
- _current_section = GROUP;
- _current_group->Reset();
- }
- else if (token == "<region>")
- {
- _current_section = REGION;
- _current_region = _current_group->RegionFactory();
- _instrument->regions.push_back(_current_region);
- }
- else if (token == "<control>")
- {
- _current_section = CONTROL;
- octave_offset = 0;
- note_offset = 0;
- }
- else
- {
- _current_section = UNKNOWN;
- std::cerr << "The header '" << token << "' is unsupported by libsfz!" << std::endl;
- }
+void SFZRegion::clear()
+{
+ hikey = 127;
+ hivel = 127;
+ pitch_keycenter = 60; // C4
+ pitch_keytrack = 100;
+ bend_up = 200;
+ bend_down = -200;
+ volume = pan = 0.0;
+ amp_veltrack = 100.0;
+}
+
+void SFZRegion::dump()
+{
+ printf("%d - %d, vel %d - %d", lokey, hikey, lovel, hivel);
+ if (!sample.empty()) {
+ printf(": %s", sample.c_str());
}
-
- void
- File::push_opcode(std::string token)
- {
- if (_current_section == UNKNOWN)
- return;
-
- std::string::size_type delimiter_index = token.find('=');
- std::string key = token.substr(0, delimiter_index);
- std::string value = token.substr(delimiter_index + 1);
-
- // sample definition
- if ("sample" == key)
- {
- std::string path = default_path + value;
- for (uint32_t i = 0; i < path.length(); i++) if (path[i] == '\\') path[i] = '/';
- switch (_current_section)
- {
- case REGION:
- _current_region->sample = path;
- case GROUP:
- _current_group->sample = path;
- }
- return;
- }
+ printf("\n");
+}
- // control header directives
- else if ("default_path" == key)
- {
- switch (_current_section)
- {
- case CONTROL:
- default_path = value;
- }
- return;
- }
- else if ("octave_offset" == key)
- {
- switch (_current_section)
- {
- case CONTROL:
- octave_offset = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("note_offset" == key)
- {
- switch (_current_section)
- {
- case CONTROL:
- note_offset = boost::lexical_cast<int>(value);
- }
- return;
- }
- // input controls
- else if ("lochan" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lochan = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->lochan = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("hichan" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hichan = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->hichan = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("lokey" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("hikey" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("key" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- _current_region->hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- _current_group->hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("lovel" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lovel = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->lovel = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("hivel" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hivel = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->hivel = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("lobend" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lobend = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->lobend = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("hibend" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hibend = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->hibend = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("lobpm" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lobpm = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->lobpm = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("hibpm" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hibpm = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->hibpm = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("lochanaft" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lochanaft = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->lochanaft = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("hichanaft" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hichanaft = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->hichanaft = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("lopolyaft" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lopolyaft = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->lopolyaft = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("hipolyaft" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hipolyaft = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->hipolyaft = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("loprog" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->loprog = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->loprog = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("hiprog" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hiprog = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->hiprog = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("lorand" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lorand = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->lorand = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("hirand" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hirand = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->hirand = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("lotimer" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->lotimer = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->lotimer = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("hitimer" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hitimer = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->hitimer = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("seq_length" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->seq_length = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->seq_length = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("seq_position" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->seq_position = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->seq_position = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("sw_lokey" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->sw_lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->sw_lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("sw_hikey" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->sw_hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->sw_hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("sw_last" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->sw_last = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->sw_last = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("sw_down" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->sw_down = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->sw_down = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("sw_up" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->sw_up = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->sw_up = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("sw_previous" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->sw_previous = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->sw_previous = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("sw_vel" == key)
- {
- switch (_current_section)
- {
- case REGION:
- if (value == "current")
- _current_region->sw_vel = VEL_CURRENT;
- else if (value == "previous")
- _current_region->sw_vel = VEL_PREVIOUS;
- case GROUP:
- if (value == "current")
- _current_group->sw_vel = VEL_CURRENT;
- else if (value == "previous")
- _current_group->sw_vel = VEL_PREVIOUS;
- }
- return;
- }
- else if ("trigger" == key)
- {
- switch (_current_section)
- {
- case REGION:
- if (value == "attack")
- _current_region->trigger = TRIGGER_ATTACK;
- else if (value == "release")
- _current_region->trigger = TRIGGER_RELEASE;
- else if (value == "first")
- _current_region->trigger = TRIGGER_FIRST;
- else if (value == "legato")
- _current_region->trigger = TRIGGER_LEGATO;
- case GROUP:
- if (value == "attack")
- _current_group->trigger = TRIGGER_ATTACK;
- else if (value == "release")
- _current_group->trigger = TRIGGER_RELEASE;
- else if (value == "first")
- _current_group->trigger = TRIGGER_FIRST;
- else if (value == "legato")
- _current_group->trigger = TRIGGER_LEGATO;
- }
- return;
- }
- else if ("group" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->group = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->group = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("off_by" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->off_by = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->off_by = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("off_mode" == key)
- {
- switch (_current_section)
- {
- case REGION:
- if (value == "fast")
- _current_region->off_mode = OFF_FAST;
- else if (value == "normal")
- _current_region->off_mode = OFF_NORMAL;
- case GROUP:
- if (value == "fast")
- _current_group->off_mode = OFF_FAST;
- else if (value == "normal")
- _current_group->off_mode = OFF_NORMAL;
- }
- return;
- }
-
- // sample player
- else if ("count" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->count = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->count = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("delay" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->delay = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->delay = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("delay_random" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->delay_random = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->delay_random = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("delay_beats" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->delay_beats = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->delay_beats = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("stop_beats" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->stop_beats = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->stop_beats = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("delay_samples" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->delay_samples = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->delay_samples = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("end" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->end = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->end = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("loop_crossfade" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->loop_crossfade = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->loop_crossfade = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("offset_random" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->offset_random = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->offset_random = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("loop_mode" == key)
- {
- switch (_current_section)
- {
- case REGION:
- if (value == "no_loop")
- _current_region->loop_mode = NO_LOOP;
- else if (value == "one_shot")
- _current_region->loop_mode = ONE_SHOT;
- else if (value == "loop_continous")
- _current_region->loop_mode = LOOP_CONTINOUS;
- else if (value == "loop_sustain")
- _current_region->loop_mode = LOOP_SUSTAIN;
- case GROUP:
- if (value == "no_loop")
- _current_group->loop_mode = NO_LOOP;
- else if (value == "one_shot")
- _current_group->loop_mode = ONE_SHOT;
- else if (value == "loop_continous")
- _current_group->loop_mode = LOOP_CONTINOUS;
- else if (value == "loop_sustain")
- _current_group->loop_mode = LOOP_SUSTAIN;
- }
- return;
- }
- else if ("loop_start" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->loop_start = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->loop_start = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("loop_end" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->loop_end = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->loop_end = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("sync_beats" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->sync_beats = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->sync_beats = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("sync_offset" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->sync_offset = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->sync_offset = boost::lexical_cast<int>(value);
- }
- return;
- }
+// -----------------------------------------
- // amplifier
- else if ("volume" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->volume = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->volume = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("pan" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->pan = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->pan = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("width" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->width = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->width = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("position" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->position = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->position = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("amp_keytrack" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->amp_keytrack = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->amp_keytrack = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("amp_keycenter" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->amp_keycenter = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->amp_keycenter = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("amp_veltrack" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->amp_veltrack = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->amp_veltrack = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("amp_random" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->amp_random = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->amp_random = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("rt_decay" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->rt_decay = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->rt_decay = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("xfin_lokey" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfin_lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->xfin_lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("xfin_hikey" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfin_hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->xfin_hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("xfout_lokey" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfout_lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->xfout_lokey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("xfout_hikey" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfout_hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->xfout_hikey = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("xf_keycurve" == key)
- {
- switch (_current_section)
- {
- case REGION:
- if (value == "gain")
- _current_region->xf_keycurve = GAIN;
- else if (value == "power")
- _current_region->xf_keycurve = POWER;
- case GROUP:
- if (value == "gain")
- _current_group->xf_keycurve = GAIN;
- else if (value == "power")
- _current_group->xf_keycurve = POWER;
- }
- return;
- }
- else if ("xfin_lovel" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfin_lovel = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->xfin_lovel = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("xfin_hivel" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfin_hivel = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->xfin_hivel = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("xfout_lovel" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfout_lovel = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->xfout_lovel = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("xfout_hivel" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfout_hivel = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->xfout_hivel = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("xf_velcurve" == key)
- {
- switch (_current_section)
- {
- case REGION:
- if (value == "gain")
- _current_region->xf_velcurve = GAIN;
- else if (value == "power")
- _current_region->xf_velcurve = POWER;
- case GROUP:
- if (value == "gain")
- _current_group->xf_velcurve = GAIN;
- else if (value == "power")
- _current_group->xf_velcurve = POWER;
- }
- return;
- }
- else if ("xf_cccurve" == key)
- {
- switch (_current_section)
- {
- case REGION:
- if (value == "gain")
- _current_region->xf_cccurve = GAIN;
- else if (value == "power")
- _current_region->xf_cccurve = POWER;
- case GROUP:
- if (value == "gain")
- _current_group->xf_cccurve = GAIN;
- else if (value == "power")
- _current_group->xf_cccurve = POWER;
- }
- return;
- }
-
- // pitch
- else if ("transpose" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->transpose = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->transpose = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("tune" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->tune = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->tune = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("pitch_keycenter" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->pitch_keycenter = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->pitch_keycenter = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("pitch_keytrack" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->pitch_keytrack = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->pitch_keytrack = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("pitch_veltrack" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->pitch_veltrack = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->pitch_veltrack = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("pitch_random" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->pitch_random = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->pitch_random = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("bend_up" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->bend_up = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->bend_up = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("bend_down" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->bend_down = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->bend_down = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("bend_step" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->bend_step = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->bend_step = boost::lexical_cast<int>(value);
- }
- return;
- }
-
- // filter
- else if ("fil_type" == key)
- {
- switch (_current_section)
- {
- case REGION:
- if (value == "lpf_1p")
- _current_region->fil_type = LPF_1P;
- else if (value == "hpf_1p")
- _current_region->fil_type = HPF_1P;
- else if (value == "bpf_1p")
- _current_region->fil_type = BPF_1P;
- else if (value == "brf_1p")
- _current_region->fil_type = BRF_1P;
- else if (value == "apf_1p")
- _current_region->fil_type = APF_1P;
- else if (value == "lpf_2p")
- _current_region->fil_type = LPF_2P;
- else if (value == "hpf_2p")
- _current_region->fil_type = HPF_2P;
- else if (value == "bpf_2p")
- _current_region->fil_type = BPF_2P;
- else if (value == "brf_2p")
- _current_region->fil_type = BRF_2P;
- else if (value == "pkf_2p")
- _current_region->fil_type = PKF_2P;
- else if (value == "lpf_4p")
- _current_region->fil_type = LPF_4P;
- else if (value == "hpf_4p")
- _current_region->fil_type = HPF_4P;
- else if (value == "lpf_6p")
- _current_region->fil_type = LPF_6P;
- else if (value == "hpf_6p")
- _current_region->fil_type = HPF_6P;
- case GROUP:
- if (value == "lpf_1p")
- _current_group->fil_type = LPF_1P;
- else if (value == "hpf_1p")
- _current_group->fil_type = HPF_1P;
- else if (value == "bpf_1p")
- _current_group->fil_type = BPF_1P;
- else if (value == "brf_1p")
- _current_group->fil_type = BRF_1P;
- else if (value == "apf_1p")
- _current_group->fil_type = APF_1P;
- else if (value == "lpf_2p")
- _current_group->fil_type = LPF_2P;
- else if (value == "hpf_2p")
- _current_group->fil_type = HPF_2P;
- else if (value == "bpf_2p")
- _current_group->fil_type = BPF_2P;
- else if (value == "brf_2p")
- _current_group->fil_type = BRF_2P;
- else if (value == "pkf_2p")
- _current_group->fil_type = PKF_2P;
- else if (value == "lpf_4p")
- _current_group->fil_type = LPF_4P;
- else if (value == "hpf_4p")
- _current_group->fil_type = HPF_4P;
- else if (value == "lpf_6p")
- _current_group->fil_type = LPF_6P;
- else if (value == "hpf_6p")
- _current_group->fil_type = HPF_6P;
- }
- return;
- }
- else if ("fil2_type" == key)
- {
- switch (_current_section)
- {
- case REGION:
- if (value == "lpf_1p")
- _current_region->fil2_type = LPF_1P;
- else if (value == "hpf_1p")
- _current_region->fil2_type = HPF_1P;
- else if (value == "bpf_1p")
- _current_region->fil2_type = BPF_1P;
- else if (value == "brf_1p")
- _current_region->fil2_type = BRF_1P;
- else if (value == "apf_1p")
- _current_region->fil2_type = APF_1P;
- else if (value == "lpf_2p")
- _current_region->fil2_type = LPF_2P;
- else if (value == "hpf_2p")
- _current_region->fil2_type = HPF_2P;
- else if (value == "bpf_2p")
- _current_region->fil2_type = BPF_2P;
- else if (value == "brf_2p")
- _current_region->fil2_type = BRF_2P;
- else if (value == "pkf_2p")
- _current_region->fil2_type = PKF_2P;
- else if (value == "lpf_4p")
- _current_region->fil2_type = LPF_4P;
- else if (value == "hpf_4p")
- _current_region->fil2_type = HPF_4P;
- else if (value == "lpf_6p")
- _current_region->fil2_type = LPF_6P;
- else if (value == "hpf_6p")
- _current_region->fil2_type = HPF_6P;
- case GROUP:
- if (value == "lpf_1p")
- _current_group->fil2_type = LPF_1P;
- else if (value == "hpf_1p")
- _current_group->fil2_type = HPF_1P;
- else if (value == "bpf_1p")
- _current_group->fil2_type = BPF_1P;
- else if (value == "brf_1p")
- _current_group->fil2_type = BRF_1P;
- else if (value == "apf_1p")
- _current_group->fil2_type = APF_1P;
- else if (value == "lpf_2p")
- _current_group->fil2_type = LPF_2P;
- else if (value == "hpf_2p")
- _current_group->fil2_type = HPF_2P;
- else if (value == "bpf_2p")
- _current_group->fil2_type = BPF_2P;
- else if (value == "brf_2p")
- _current_group->fil2_type = BRF_2P;
- else if (value == "pkf_2p")
- _current_group->fil2_type = PKF_2P;
- else if (value == "lpf_4p")
- _current_group->fil2_type = LPF_4P;
- else if (value == "hpf_4p")
- _current_group->fil2_type = HPF_4P;
- else if (value == "lpf_6p")
- _current_group->fil2_type = LPF_6P;
- else if (value == "hpf_6p")
- _current_group->fil2_type = HPF_6P;
- }
- return;
- }
- else if ("cutoff" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->cutoff = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("cutoff2" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff2 = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->cutoff2 = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("cutoff_chanaft" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff_chanaft = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff_chanaft = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff2_chanaft" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff2_chanaft = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff2_chanaft = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff_polyaft" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff_polyaft = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff_polyaft = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff2_polyaft" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff2_polyaft = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff2_polyaft = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("resonance" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->resonance = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("resonance2" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance2 = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->resonance2 = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("fil_keytrack" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->fil_keytrack = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->fil_keytrack = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("fil2_keytrack" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->fil2_keytrack = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->fil2_keytrack = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("fil_keycenter" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->fil_keycenter = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->fil_keycenter = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("fil2_keycenter" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->fil2_keycenter = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- case GROUP:
- _current_group->fil2_keycenter = boost::lexical_cast<int>(value) + note_offset + 12 * octave_offset;
- }
- return;
- }
- else if ("fil_veltrack" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->fil_veltrack = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->fil_veltrack = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("fil2_veltrack" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->fil2_veltrack = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->fil2_veltrack = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("fil_random" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->fil_random = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->fil_random = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("fil2_random" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->fil2_random = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->fil2_random = boost::lexical_cast<int>(value);
- }
- return;
- }
-
- // per voice equalizer
- else if ("eq1_freq" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq1_freq = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq1_freq = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq2_freq" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq2_freq = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq2_freq = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq3_freq" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq3_freq = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq3_freq = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq1_vel2freq" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq1_vel2freq = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq1_vel2freq = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq2_vel2freq" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq2_vel2freq = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq2_vel2freq = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq3_vel2freq" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq3_vel2freq = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq3_vel2freq = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq1_bw" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq1_bw = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq1_bw = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq2_bw" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq2_bw = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq2_bw = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq3_bw" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq3_bw = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq3_bw = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq1_gain" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq1_gain = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq1_gain = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq2_gain" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq2_gain = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq2_gain = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq3_gain" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq3_gain = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq3_gain = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq1_vel2gain" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq1_vel2gain = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq1_vel2gain = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq2_vel2gain" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq2_vel2gain = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq2_vel2gain = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("eq3_vel2gain" == key)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq3_vel2gain = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->eq3_vel2gain = boost::lexical_cast<float>(value);
- }
- return;
- }
-
- //fixme: parse amp_velcurve_N
-
- // CCs
- else
- {
- std::string::size_type delimiter_index = key.find("cc");
- std::string key_cc = key.substr(0, delimiter_index);
- int num_cc = boost::lexical_cast<int>(key.substr(delimiter_index + 2));
-
- // input controls
- if ("lo" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->locc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->locc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("hi" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->hicc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->hicc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("start_lo" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->start_locc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->start_locc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("start_hi" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->start_hicc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->start_hicc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("stop_lo" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->stop_locc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->stop_locc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("stop_hi" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->stop_hicc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->stop_hicc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("on_lo" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->on_locc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->on_locc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("on_hi" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->on_hicc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->on_hicc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
-
- // sample player
- else if ("delay_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->delay_oncc[num_cc] = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->delay_oncc[num_cc] = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("delay_samples_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->delay_samples_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->delay_samples_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("offset_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->offset_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->offset_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
-
- // amplifier
- else if ("gain_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->gain_oncc[num_cc] = boost::lexical_cast<float>(value);
- case GROUP:
- _current_group->gain_oncc[num_cc] = boost::lexical_cast<float>(value);
- }
- return;
- }
- else if ("xfin_lo" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfin_locc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->xfin_locc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("xfin_hi" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfin_hicc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->xfin_hicc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("xfout_lo" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfout_locc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->xfout_locc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("xfout_hi" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->xfout_hicc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->xfout_hicc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
-
- // filter
- else if ("cutoff_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff2_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff2_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff2_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff_smooth" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff_smoothcc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff_smoothcc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff2_smooth" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff2_smoothcc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff2_smoothcc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff_step" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff_stepcc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff_stepcc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff2_step" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff2_stepcc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff2_stepcc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff_curve" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff_curvecc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff_curvecc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("cutoff2_curve" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->cutoff2_curvecc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->cutoff2_curvecc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("resonance_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->resonance_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("resonance2_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance2_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->resonance2_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("resonance_smooth" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance_smoothcc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->resonance_smoothcc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("resonance2_smooth" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance2_smoothcc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->resonance2_smoothcc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("resonance_step" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance_stepcc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->resonance_stepcc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("resonance2_step" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance2_stepcc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->resonance2_stepcc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("resonance_curve" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance_curvecc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->resonance_curvecc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("resonance2_curve" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->resonance2_curvecc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->resonance2_curvecc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
-
- // per voice equalizer
- else if ("eq1_freq_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq1_freq_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->eq1_freq_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("eq2_freq_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq2_freq_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->eq2_freq_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("eq3_freq_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq3_freq_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->eq3_freq_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("eq1_bw_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq1_bw_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->eq1_bw_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("eq2_bw_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq2_bw_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->eq2_bw_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("eq3_bw_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq3_bw_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->eq3_bw_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("eq1_gain_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq1_gain_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->eq1_gain_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("eq2_gain_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq2_gain_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->eq2_gain_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- else if ("eq3_gain_on" == key_cc)
- {
- switch (_current_section)
- {
- case REGION:
- _current_region->eq3_gain_oncc[num_cc] = boost::lexical_cast<int>(value);
- case GROUP:
- _current_group->eq3_gain_oncc[num_cc] = boost::lexical_cast<int>(value);
- }
- return;
- }
- }
+Instrument::Instrument()
+{
+}
- std::cerr << "The opcode '" << key << "' is unsupported by libsfz!" << std::endl;
+Instrument::~Instrument()
+{
+ uint32_t i;
+ for (i = 0; i < regions.size(); i++) {
+ delete regions[i];
}
-
+}
-} // !namespace sfz
+}
diff --git a/plugins/ZamSFZ/libsfz/sfz.h b/plugins/ZamSFZ/libsfz/sfz.h
index 3dfe480..d5d24ab 100644
--- a/plugins/ZamSFZ/libsfz/sfz.h
+++ b/plugins/ZamSFZ/libsfz/sfz.h
@@ -1,286 +1,110 @@
-/* -*- Mode: C++ ; c-basic-offset: 8 -*- */
-#ifndef LIBSFZ_SFZ_H
-#define LIBSFZ_SFZ_H
-
-// SFZ 1.0
-// Copyright (c) 2008-2009, Anders Dahnielson
-//
-// Contact: anders@dahnielson.com
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-#include <fstream>
-#include <iostream>
-#include <vector>
+#include <stdio.h>
+#include <string.h>
#include <string>
-#include <stdexcept>
-
-#include <boost/array.hpp>
-
-#define TRIGGER_ATTACK ((unsigned char) (1 << 0)) // 0x01
-#define TRIGGER_RELEASE ((unsigned char) (1 << 1)) // 0x02
-#define TRIGGER_FIRST ((unsigned char) (1 << 2)) // 0x04
-#define TRIGGER_LEGATO ((unsigned char) (1 << 3)) // 0x08
-
-namespace sfz
-{
-
- // Forward declarations
- class Articulation;
- class Region;
- class Group;
- class Instrument;
- class File;
-
- // Enumerations
- enum sw_vel_t { VEL_CURRENT, VEL_PREVIOUS };
- enum off_mode_t { OFF_FAST, OFF_NORMAL };
- enum loop_mode_t { NO_LOOP, ONE_SHOT, LOOP_CONTINOUS, LOOP_SUSTAIN };
- enum curve_t { GAIN, POWER };
- enum filter_t { LPF_1P, HPF_1P, BPF_1P, BRF_1P, APF_1P,
- LPF_2P, HPF_2P, BPF_2P, BRF_2P, PKF_2P,
- LPF_4P, HPF_4P,
- LPF_6P, HPF_6P };
-
- typedef unsigned char trigger_t;
- typedef unsigned char uint8_t;
-
- /////////////////////////////////////////////////////////////
- // class Articulation
-
- // Articulation containing all performance parameters for synthesis
- class Articulation
- {
- public:
- Articulation();
- virtual ~Articulation();
- };
-
- /////////////////////////////////////////////////////////////
- // class Definition
-
- // Base definition used by groups and regions
- class Definition
- {
- public:
- Definition();
- virtual ~Definition();
-
- // sample definition
- std::string sample;
-
- // input controls
- int lochan; int hichan;
- int lokey; int hikey;
- int lovel; int hivel;
- boost::array<int, 128> locc; boost::array<int, 128> hicc;
- int lobend; int hibend;
- int lobpm; int hibpm;
- int lochanaft; int hichanaft;
- int lopolyaft; int hipolyaft;
- int loprog; int hiprog;
- float lorand; float hirand;
- float lotimer; float hitimer;
-
- int seq_length;
- int seq_position;
-
- boost::array<int, 128> start_locc; boost::array<int, 128> start_hicc;
- boost::array<int, 128> stop_locc; boost::array<int, 128> stop_hicc;
-
- int sw_lokey; int sw_hikey;
- int sw_last;
- int sw_down;
- int sw_up;
- int sw_previous;
- sw_vel_t sw_vel;
+#include <vector>
+#include <cstdlib>
+#include <inttypes.h>
- trigger_t trigger;
+namespace sfz {
- int group;
- int off_by;
- off_mode_t off_mode;
+class Instrument;
- boost::array<int, 128> on_locc; boost::array<int, 128> on_hicc;
+class StringSlice {
+public:
+ StringSlice(const char* startIn, const char* endIn)
+ : start(startIn), end(endIn) {}
- // sample player
- int count;
- float delay; float delay_random; boost::array<float, 128> delay_oncc;
- int delay_beats; int stop_beats;
- int delay_samples; boost::array<int, 128> delay_samples_oncc;
- int end;
- float loop_crossfade;
- int offset; int offset_random; boost::array<int, 128> offset_oncc;
- loop_mode_t loop_mode;
- int loop_start; int loop_end;
- int sync_beats;
- int sync_offset;
-
- // amplifier
- float volume;
- float pan;
- float width;
- float position;
- float amp_keytrack; int amp_keycenter; float amp_veltrack; boost::array<float, 128> amp_velcurve_; float amp_random;
- float rt_decay;
- boost::array<float, 128> gain_oncc;
- int xfin_lokey; int xfin_hikey;
- int xfout_lokey; int xfout_hikey;
- curve_t xf_keycurve;
- int xfin_lovel; int xfin_hivel;
- int xfout_lovel; int xfout_hivel;
- curve_t xf_velcurve;
- boost::array<int, 128> xfin_locc; boost::array<int, 128> xfin_hicc;
- boost::array<int, 128> xfout_locc; boost::array<int, 128> xfout_hicc;
- curve_t xf_cccurve;
+ unsigned int length() {
+ return end - start;
+ }
- // pitch
- int transpose;
- int tune;
- int pitch_keycenter; int pitch_keytrack; int pitch_veltrack; int pitch_random;
- int bend_up; int bend_down; int bend_step;
+ bool operator==(const char* other) {
+ return strncmp(start, other, length()) == 0;
+ }
+ bool operator!=(const char* other) {
+ return strncmp(start, other, length()) != 0;
+ }
- // filter
- filter_t fil_type; filter_t fil2_type;
- float cutoff; float cutoff2;
- boost::array<int, 128> cutoff_oncc; boost::array<int, 128> cutoff2_oncc;
- boost::array<int, 128> cutoff_smoothcc; boost::array<int, 128> cutoff2_smoothcc;
- boost::array<int, 128> cutoff_stepcc; boost::array<int, 128> cutoff2_stepcc;
- boost::array<int, 128> cutoff_curvecc; boost::array<int, 128> cutoff2_curvecc;
- int cutoff_chanaft; int cutoff2_chanaft;
- int cutoff_polyaft; int cutoff2_polyaft;
- float resonance; float resonance2;
- boost::array<int, 128> resonance_oncc; boost::array<int, 128> resonance2_oncc;
- boost::array<int, 128> resonance_smoothcc; boost::array<int, 128> resonance2_smoothcc;
- boost::array<int, 128> resonance_stepcc; boost::array<int, 128> resonance2_stepcc;
- boost::array<int, 128> resonance_curvecc; boost::array<int, 128> resonance2_curvecc;
- int fil_keytrack; int fil2_keytrack;
- int fil_keycenter; int fil2_keycenter;
- int fil_veltrack; int fil2_veltrack;
- int fil_random; int fil2_random;
+ const char* start;
+ const char* end;
+};
- // per voice equalizer
- float eq1_freq; float eq2_freq; float eq3_freq;
- boost::array<float, 128> eq1_freq_oncc; boost::array<float, 128> eq2_freq_oncc; boost::array<float, 128> eq3_freq_oncc;
- float eq1_vel2freq; float eq2_vel2freq; float eq3_vel2freq;
- float eq1_bw; float eq2_bw; float eq3_bw;
- boost::array<float, 128> eq1_bw_oncc; boost::array<float, 128> eq2_bw_oncc; boost::array<float, 128> eq3_bw_oncc;
- float eq1_gain; float eq2_gain; float eq3_gain;
- boost::array<float, 128> eq1_gain_oncc; boost::array<float, 128> eq2_gain_oncc; boost::array<float, 128> eq3_gain_oncc;
- float eq1_vel2gain; float eq2_vel2gain; float eq3_vel2gain;
+class SFZRegion {
+public:
+ enum Trigger {
+ ATTACK, RELEASE, FIRST, LEGATO
};
-
- /////////////////////////////////////////////////////////////
- // class Region
-
- /// Defines Region information of an Instrument
- class Region :
- public Definition
- {
- public:
- Region();
- virtual ~Region();
-
- /// Return true if region is triggered by key
- bool OnKey(uint8_t chan, uint8_t key, uint8_t vel,
- int bend, uint8_t bpm, uint8_t chanaft, uint8_t polyaft,
- uint8_t prog, float rand, trigger_t trig, uint8_t* cc,
- float timer, uint8_t seq, bool* sw, uint8_t last_sw_key, uint8_t prev_sw_key);
-
- /// Return true if region is triggered by control change
- bool OnControl(uint8_t chan, uint8_t cont, uint8_t val,
- int bend, uint8_t bpm, uint8_t chanaft, uint8_t polyaft,
- uint8_t prog, float rand, trigger_t trig, uint8_t* cc,
- float timer, uint8_t seq, bool* sw, uint8_t last_sw_key, uint8_t prev_sw_key);
-
- /// Return an articulation for the current state
- Articulation* GetArticulation(int bend, uint8_t bpm, uint8_t chanaft, uint8_t polyaft, uint8_t* cc);
-
- // unique region id
- int id;
+ enum LoopMode {
+ SAMPLE_LOOP, NO_LOOP, ONE_SHOT, LOOP_CONTINUOUS, LOOP_SUSTAIN
};
-
- /////////////////////////////////////////////////////////////
- // class Instrument
-
- /// Provides all neccessary information for the synthesis of an Instrument
- class Instrument
- {
- public:
- Instrument();
- virtual ~Instrument();
-
- /// List of Regions belonging to this Instrument
- std::vector<Region*> regions;
+ enum OffMode {
+ FAST, NORMAL
};
- /////////////////////////////////////////////////////////////
- // class Group
- /// A Group act just as a template containing Region default values
- class Group :
- public Definition
- {
- public:
- Group();
- virtual ~Group();
-
- /// Reset Group to default values
- void Reset();
-
- /// Create a new Region
- Region* RegionFactory();
-
- // id counter
- int id;
-
- };
-
- /////////////////////////////////////////////////////////////
- // class File
-
- /// Parses SFZ files and provides abstract access to the data
- class File
- {
- public:
- /// Load an existing SFZ file
- File(std::string file, std::string path);
- virtual ~File();
+ SFZRegion(Instrument* i);
+ void clear();
+ void dump();
+
+ bool matches(unsigned char note, unsigned char velocity, Trigger trigger) {
+ return
+ note >= lokey && note <= hikey &&
+ velocity >= lovel && velocity <= hivel &&
+ (trigger == this->trigger ||
+ (this->trigger == ATTACK && (trigger == FIRST || trigger == LEGATO)));
+ }
+
+ Instrument* instrument;
+ unsigned char lokey, hikey;
+ unsigned char lovel, hivel;
+ Trigger trigger;
+ unsigned long group, off_by;
+ OffMode off_mode;
+
+ std::string sample;
+ unsigned long offset;
+ unsigned long end;
+ bool negative_end;
+ LoopMode loop_mode;
+ unsigned long loop_start, loop_end;
+ int transpose;
+ int tune;
+ int pitch_keycenter, pitch_keytrack;
+ int bend_up, bend_down;
+
+ float volume, pan;
+ float amp_veltrack;
+};
+
+class Instrument
+{
+public:
+ Instrument();
+ ~Instrument();
- /// Returns a pointer to the instrument object
- Instrument* GetInstrument();
+ std::vector<SFZRegion*> regions;
+};
- private:
- void push_header(std::string token);
- void push_opcode(std::string token);
+class SFZParser {
+public:
+ SFZParser();
+ ~SFZParser();
- /// Pointer to the Instrument belonging to this file
- Instrument* _instrument;
+ void read(const char* text, unsigned int length);
+ int readsfz(std::string path);
- // state variables
- enum section_t { UNKNOWN, GROUP, REGION, CONTROL };
- section_t _current_section;
- Region* _current_region;
- Group* _current_group;
+ Instrument instrument;
- // control header directives
- std::string default_path;
- int octave_offset;
- int note_offset;
- };
+protected:
+ int line;
-} // !namespace sfz
+ const char* handleLineEnd(const char* p);
+ const char* readPathInto(std::string* pathOut, const char* p, const char* end);
+ int keyValue(const std::string& str);
+ int triggerValue(const std::string& str);
+ int loopModeValue(const std::string& str);
+ void finishRegion(SFZRegion* region);
+ void error(const std::string& message);
+};
-#endif // !LIBSFZ_SFZ_H
+}