summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2015-09-20 11:36:22 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2015-09-20 11:36:22 +0200
commit24bb55371a5d8d81b23521ebdfcde68f0035697c (patch)
tree61cf42dc518420738262dcc9ccf75e932a63136f /src
Basic project based on DrumGizmo.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am44
-rw-r--r--src/camsync.ttl144
-rw-r--r--src/configfile.cc347
-rw-r--r--src/configfile.h57
-rw-r--r--src/configparser.cc70
-rw-r--r--src/configparser.h49
-rw-r--r--src/configuration.cc38
-rw-r--r--src/configuration.h44
-rw-r--r--src/input_lv2.cc117
-rw-r--r--src/input_lv2.h56
-rw-r--r--src/lv2.cc235
-rw-r--r--src/lv2_event.h281
-rw-r--r--src/lv2_gui.cc237
-rw-r--r--src/lv2_gui.h40
-rw-r--r--src/lv2_instance.h48
-rw-r--r--src/manifest.ttl7
-rw-r--r--src/message.h121
-rw-r--r--src/messagehandler.cc89
-rw-r--r--src/messagehandler.h66
-rw-r--r--src/messagereceiver.cc78
-rw-r--r--src/messagereceiver.h75
-rw-r--r--src/midimapparser.cc52
-rw-r--r--src/midimapparser.h52
-rw-r--r--src/midimapper.cc41
-rw-r--r--src/midimapper.h46
-rw-r--r--src/mutex.cc155
-rw-r--r--src/mutex.h55
-rw-r--r--src/nolocale.h78
-rw-r--r--src/output_lv2.cc82
-rw-r--r--src/output_lv2.h61
-rw-r--r--src/path.cc51
-rw-r--r--src/path.h34
-rw-r--r--src/saxparser.cc135
-rw-r--r--src/saxparser.h57
-rw-r--r--src/semaphore.cc111
-rw-r--r--src/semaphore.h45
-rw-r--r--src/thread.cc68
-rw-r--r--src/thread.h56
-rw-r--r--src/versionstr.cc151
-rw-r--r--src/versionstr.h112
40 files changed, 3685 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..038bcce
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,44 @@
+include $(top_srcdir)/plugingui/Makefile.am.plugingui
+
+plugindir = $(libdir)/lv2/camsync.lv2
+
+plugin_LTLIBRARIES = camsync.la
+
+plugin_DATA = manifest.ttl camsync.ttl
+
+EXTRA_DIST = \
+ $(plugin_DATA) \
+ input_lv2.h \
+ output_lv2.h \
+ lv2_event.h \
+ lv2_gui.h \
+ lv2_instance.h
+
+camsync_la_CXXFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/plugingui \
+ -I$(top_srcdir)/include $(SNDFILE_CXXFLAGS) \
+ $(PTHREAD_CFLAGS) $(EXPAT_CFLAGS) $(LV2_CFLAGS) \
+ $(PLUGIN_GUI_CFLAGS) $(SSEFLAGS) $(ZITA_CPPFLAGS) \
+ -DUSE_THREAD $(SAMPLERATE_CFLAGS)
+
+camsync_la_SOURCES = \
+ configfile.cc \
+ configuration.cc \
+ configparser.cc \
+ events.cc \
+ messagehandler.cc \
+ messagereceiver.cc \
+ mutex.cc \
+ path.cc \
+ semaphore.cc \
+ saxparser.cc \
+ thread.cc \
+ versionstr.cc
+ $(PLUGIN_GUI_SOURCES) \
+ lv2.cc \
+ lv2_gui.cc \
+ input_lv2.cc \
+ output_lv2.cc
+
+camsync_la_LDFLAGS = -module -avoid-version
+camsync_la_LIBADD = $(LV2_LIBS) $(PLUGIN_GUI_LIBS) \
+ $(ZITA_LIBS) $(SNDFILE_LIBS) $(EXPAT_LIBS) $(SAMPLERATE_LIBS)
diff --git a/src/camsync.ttl b/src/camsync.ttl
new file mode 100644
index 0000000..23345f3
--- /dev/null
+++ b/src/camsync.ttl
@@ -0,0 +1,144 @@
+# LV2 DrumGizmo Plugin
+# Copyright 2011 Bent Bisballe Nyeng <deva@aasimon.org>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix uiext: <http://lv2plug.in/ns/extensions/ui#> .
+@prefix state: <http://lv2plug.in/ns/ext/state#> .
+
+<http://drumgizmo.org/lv2-gui>
+ a uiext:external ;
+ uiext:binary <drumgizmo.so> .
+
+<http://drumgizmo.org/lv2>
+ a lv2:InstrumentPlugin ;
+ doap:name "DrumGizmo" ;
+ doap:maintainer [
+ foaf:name "DrumGizmo.org";
+ foaf:homepage <http://www.drumgizmo.org> ;
+ ] ;
+ doap:license <http://usefulinc.com/doap/licenses/gpl> ;
+ uiext:ui <http://drumgizmo.org/lv2-gui> ;
+ doap:license <http://opensource.org/licenses/gpl-3.0> ;
+ lv2:optionalFeature <http://lv2plug.in/ns/ext/uri-map> ;
+ lv2:optionalFeature <http://lv2plug.in/ns/ext/event> ;
+ lv2:extensionData state:interface ;
+lv2:port [
+ a atom:AtomPort ,
+ lv2:InputPort;
+ atom:bufferType atom:Sequence ;
+ atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ;
+ lv2:index 0 ;
+ lv2:symbol "control" ;
+ lv2:name "Control"
+ ] , [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 1 ;
+ lv2:symbol "out1" ;
+ lv2:name "Out1"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 2 ;
+ lv2:symbol "out2" ;
+ lv2:name "Out2"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 3 ;
+ lv2:symbol "out3" ;
+ lv2:name "Out3"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 4 ;
+ lv2:symbol "out4" ;
+ lv2:name "Out4"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 5 ;
+ lv2:symbol "out5" ;
+ lv2:name "Out5"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 6 ;
+ lv2:symbol "out6" ;
+ lv2:name "Out6"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 7 ;
+ lv2:symbol "out7" ;
+ lv2:name "Out7"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 8 ;
+ lv2:symbol "out8" ;
+ lv2:name "Out8"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 9 ;
+ lv2:symbol "out9" ;
+ lv2:name "Out9"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 10 ;
+ lv2:symbol "out10" ;
+ lv2:name "Out10"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 11 ;
+ lv2:symbol "out11" ;
+ lv2:name "Out11"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 12 ;
+ lv2:symbol "out12" ;
+ lv2:name "Out12"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 13 ;
+ lv2:symbol "out13" ;
+ lv2:name "Out13"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 14 ;
+ lv2:symbol "out14" ;
+ lv2:name "Out14"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 15 ;
+ lv2:symbol "out15" ;
+ lv2:name "Out15"
+ ], [
+ a lv2:AudioPort ,
+ lv2:OutputPort ;
+ lv2:index 16 ;
+ lv2:symbol "out16" ;
+ lv2:name "Out16"
+ ] .
diff --git a/src/configfile.cc b/src/configfile.cc
new file mode 100644
index 0000000..6b0d14f
--- /dev/null
+++ b/src/configfile.cc
@@ -0,0 +1,347 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * configfile.cc
+ *
+ * Thu May 14 14:51:39 CEST 2015
+ * Copyright 2015 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "configfile.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef WIN32
+#include <direct.h>
+#include <windows.h>
+#include <Shlobj.h>
+#include <Shlwapi.h>
+#else
+#endif
+
+#include <hugin.hpp>
+
+#ifdef WIN32
+ #define SEP "\\"
+#else
+ #define SEP "/"
+#endif
+
+#define CONFIGDIRNAME ".drumgizmo"
+
+/**
+ * Return the path containing the config files.
+ */
+static std::string configPath()
+{
+#ifdef WIN32
+ std::string configpath;
+ TCHAR szPath[256];
+ if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
+ NULL, 0, szPath))) {
+ configpath = szPath;
+ }
+#else
+ std::string configpath = strdup(getenv("HOME"));
+#endif
+ configpath += SEP;
+ configpath += CONFIGDIRNAME;
+
+ return configpath;
+}
+
+/**
+ * Calling this makes sure that the config path exists
+ */
+static bool createConfigPath()
+{
+ std::string configpath = configPath();
+
+ struct stat st;
+ if(stat(configpath.c_str(), &st) == 0) {
+ DEBUG(configfile, "No configuration exists, creating directory '%s'\n",
+ configpath.c_str());
+#ifdef WIN32
+ if(mkdir(configpath.c_str()) < 0) {
+#else
+ if(mkdir(configpath.c_str(), 0755) < 0) {
+#endif
+ DEBUG(configfile, "Could not create config directory\n");
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
+ConfigFile::ConfigFile(std::string filename)
+ : filename(filename)
+ , fp(NULL)
+{
+}
+
+ConfigFile::~ConfigFile()
+{
+}
+
+bool ConfigFile::load()
+{
+ DEBUG(configfile, "Loading config file...\n");
+ if(!open("r")) {
+ return false;
+ }
+
+ values.clear();
+
+ std::string line;
+ while(true) {
+ line = readLine();
+
+ if(line == "") break;
+
+ if(!parseLine(line)) {
+ return false;
+ }
+ }
+
+ close();
+
+ return true;
+}
+
+bool ConfigFile::save()
+{
+ DEBUG(configfile, "Saving configuration...\n");
+
+ createConfigPath();
+
+ if(!open("w")) {
+ return false;
+ }
+
+ std::map<std::string, std::string>::iterator v = values.begin();
+ for(; v != values.end(); ++v) {
+ fprintf(fp, "%s:%s\n", v->first.c_str(), v->second.c_str());
+ }
+
+ close();
+
+ return true;
+}
+
+std::string ConfigFile::getValue(const std::string& key)
+{
+ if(values.find(key) != values.end()) {
+ return values[key];
+ }
+
+ return "";
+}
+
+void ConfigFile::setValue(const std::string& key, const std::string& value)
+{
+ values[key] = value;
+}
+
+bool ConfigFile::open(std::string mode)
+{
+ if(fp) close();
+
+ std::string configpath = configPath();
+
+ std::string configfile = configpath;
+ configfile += SEP;
+ configfile += filename;
+
+ DEBUG(configfile, "Opening config file '%s'\n", configfile.c_str());
+ fp = fopen(configfile.c_str(), mode.c_str());
+
+ if(!fp) return false;
+
+ return true;
+}
+
+void ConfigFile::close()
+{
+ fclose(fp);
+ fp = NULL;
+}
+
+std::string ConfigFile::readLine()
+{
+ if(!fp) return "";
+
+ std::string line;
+
+ char buf[1024];
+ while(!feof(fp)) {
+ char *s = fgets(buf, sizeof(buf), fp);
+ if(s) {
+ line += buf;
+ if(buf[strlen(buf) - 1] == '\n') break;
+ }
+ }
+
+ return line;
+}
+
+bool ConfigFile::parseLine(const std::string& line)
+{
+ std::string key;
+ std::string value;
+ enum {
+ before_key,
+ in_key,
+ after_key,
+ before_value,
+ in_value,
+ in_value_single_quoted,
+ in_value_double_quoted,
+ after_value,
+ } state = before_key;
+
+ for(std::size_t p = 0; p < line.size(); ++p) {
+ switch(state) {
+ case before_key:
+ if(line[p] == '#') {
+ // Comment: Ignore line.
+ p = line.size();
+ continue;
+ }
+ if(std::isspace(line[p])) {
+ continue;
+ }
+ key += line[p];
+ state = in_key;
+ break;
+
+ case in_key:
+ if(std::isspace(line[p])) {
+ state = after_key;
+ continue;
+ }
+ if(line[p] == ':' || line[p] == '=') {
+ state = before_value;
+ continue;
+ }
+ key += line[p];
+ break;
+
+ case after_key:
+ if(std::isspace(line[p])) {
+ continue;
+ }
+ if(line[p] == ':' || line[p] == '=') {
+ state = before_value;
+ continue;
+ }
+ ERR(configfile, "Bad symbol."
+ " Expecting only whitespace or key/value seperator: '%s'",
+ line.c_str());
+ return false;
+
+ case before_value:
+ if(std::isspace(line[p])) {
+ continue;
+ }
+ if(line[p] == '\'') {
+ state = in_value_single_quoted;
+ continue;
+ }
+ if(line[p] == '"') {
+ state = in_value_double_quoted;
+ continue;
+ }
+ value += line[p];
+ state = in_value;
+ break;
+
+ case in_value:
+ if(std::isspace(line[p])) {
+ state = after_value;
+ continue;
+ }
+ if(line[p] == '#') {
+ // Comment: Ignore the rest of the line.
+ p = line.size();
+ state = after_value;
+ continue;
+ }
+ value += line[p];
+ break;
+
+ case in_value_single_quoted:
+ if(line[p] == '\'') {
+ state = after_value;
+ continue;
+ }
+ value += line[p];
+ break;
+
+ case in_value_double_quoted:
+ if(line[p] == '"') {
+ state = after_value;
+ continue;
+ }
+ value += line[p];
+ break;
+
+ case after_value:
+ if(std::isspace(line[p])) {
+ continue;
+ }
+ if(line[p] == '#') {
+ // Comment: Ignore the rest of the line.
+ p = line.size();
+ continue;
+ }
+ ERR(configfile, "Bad symbol."
+ " Expecting only whitespace or key/value seperator: '%s'",
+ line.c_str());
+ return false;
+ }
+ }
+
+ if(state == before_key) {
+ // Line did not contain any data (empty or comment)
+ return true;
+ }
+
+ // If state == in_value_XXX_quoted here, the string was not terminated.
+ if(state != after_value && state != in_value) {
+ ERR(configfile,"Malformed line: '%s'", line.c_str());
+ return false;
+ }
+
+ DEBUG(configfile, "key['%s'] value['%s']\n", key.c_str(), value.c_str());
+
+ if(key != "") {
+ values[key] = value;
+ }
+
+ return true;
+}
diff --git a/src/configfile.h b/src/configfile.h
new file mode 100644
index 0000000..a6c50bd
--- /dev/null
+++ b/src/configfile.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * configfile.h
+ *
+ * Thu May 14 14:51:38 CEST 2015
+ * Copyright 2015 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_CONFIGFILE_H__
+#define __DRUMGIZMO_CONFIGFILE_H__
+
+#include <string>
+#include <map>
+#include <stdio.h>
+
+class ConfigFile {
+public:
+ ConfigFile(std::string filename);
+ virtual ~ConfigFile();
+
+ virtual bool load();
+ virtual bool save();
+
+ virtual std::string getValue(const std::string& key);
+ virtual void setValue(const std::string& key, const std::string& value);
+
+protected:
+ std::map<std::string, std::string> values;
+ std::string filename;
+
+ virtual bool open(std::string mode);
+ void close();
+ std::string readLine();
+ bool parseLine(const std::string& line);
+
+ FILE* fp;
+};
+
+#endif/*__DRUMGIZMO_CONFIGFILE_H__*/
diff --git a/src/configparser.cc b/src/configparser.cc
new file mode 100644
index 0000000..96e701b
--- /dev/null
+++ b/src/configparser.cc
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * configparser.cc
+ *
+ * Sat Jun 29 21:55:02 CEST 2013
+ * Copyright 2013 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "configparser.h"
+
+#include <hugin.hpp>
+
+#include "saxparser.h"
+
+ConfigParser::ConfigParser()
+{
+ str = NULL;
+}
+
+void ConfigParser::characterData(std::string &data)
+{
+ if(str) str->append(data);
+}
+
+void ConfigParser::startTag(std::string name, attr_t attr)
+{
+ if(name == "value" && attr.find("name") != attr.end()) {
+ values[attr["name"]] = "";
+ str = &values[attr["name"]];
+ }
+}
+
+void ConfigParser::endTag(std::string name)
+{
+ if(name == "value") str = NULL;
+}
+
+std::string ConfigParser::value(std::string name, std::string def)
+{
+ if(values.find(name) == values.end()) return def;
+ return values[name];
+}
+
+void ConfigParser::parseError(char *buf, size_t len, std::string error,
+ int lineno)
+{
+ std::string buffer;
+ buffer.append(buf, len);
+ ERR(configparser, "sax parser error '%s' at line %d. "
+ "Buffer: [%d bytes]<%s>\n",
+ error.c_str(), lineno, (int)len, buffer.c_str());
+}
diff --git a/src/configparser.h b/src/configparser.h
new file mode 100644
index 0000000..e67babd
--- /dev/null
+++ b/src/configparser.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * configparser.h
+ *
+ * Sat Jun 29 21:55:02 CEST 2013
+ * Copyright 2013 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_CONFIGPARSER_H__
+#define __DRUMGIZMO_CONFIGPARSER_H__
+
+#include <map>
+
+#include "saxparser.h"
+
+class ConfigParser : public SAXParser {
+public:
+ ConfigParser();
+
+ void characterData(std::string &data);
+ void startTag(std::string name, attr_t attr);
+ void endTag(std::string name);
+ std::string value(std::string name, std::string def = "");
+ void parseError(char *buf, size_t len, std::string error, int lineno);
+
+private:
+ std::map<std::string, std::string> values;
+ std::string *str;
+};
+
+#endif/*__DRUMGIZMO_CONFIGPARSER_H__*/
diff --git a/src/configuration.cc b/src/configuration.cc
new file mode 100644
index 0000000..5c733ee
--- /dev/null
+++ b/src/configuration.cc
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * configuration.cc
+ *
+ * Sat Oct 8 14:37:14 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "configuration.h"
+
+bool Conf::enable_velocity_modifier = true;
+float Conf::velocity_modifier_falloff = 0.5;
+float Conf::velocity_modifier_weight = 0.25;
+
+bool Conf::enable_velocity_randomiser = false;
+float Conf::velocity_randomiser_weight = 0.1;
+
+int Conf::samplerate = 44100;
+
+bool Conf::enable_resampling = true;
diff --git a/src/configuration.h b/src/configuration.h
new file mode 100644
index 0000000..b8be49f
--- /dev/null
+++ b/src/configuration.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * configuration.h
+ *
+ * Sat Oct 8 14:37:13 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_CONFIGURATION_H__
+#define __DRUMGIZMO_CONFIGURATION_H__
+
+namespace Conf {
+ extern bool enable_velocity_modifier;
+ extern float velocity_modifier_falloff;
+ extern float velocity_modifier_weight;
+
+ extern bool enable_velocity_randomiser;
+ extern float velocity_randomiser_weight;
+
+ extern int samplerate;
+
+ extern bool enable_resampling;
+};
+
+
+#endif/*__DRUMGIZMO_CONFIGURATION_H__*/
diff --git a/src/input_lv2.cc b/src/input_lv2.cc
new file mode 100644
index 0000000..e70d293
--- /dev/null
+++ b/src/input_lv2.cc
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * input_lv2.cc
+ *
+ * Wed Jul 13 14:27:02 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "input_lv2.h"
+
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
+
+#include <midimapparser.h>
+
+#include <hugin.hpp>
+
+InputLV2::InputLV2()
+{
+ eventPort = NULL;
+}
+
+InputLV2::~InputLV2()
+{
+}
+
+bool InputLV2::init(Instruments &i)
+{
+ instruments = &i;
+ return true;
+}
+
+void InputLV2::setParm(std::string parm, std::string value)
+{
+}
+
+bool InputLV2::start()
+{
+ return true;
+}
+
+void InputLV2::stop()
+{
+}
+
+void InputLV2::pre()
+{
+}
+
+event_t *InputLV2::run(size_t pos, size_t len, size_t *nevents)
+{
+ if(eventPort == NULL) {
+ *nevents = 0;
+ return NULL;
+ }
+
+ event_t *list;
+ size_t listsize;
+
+ list = (event_t *)malloc(sizeof(event_t) * 1000);
+ listsize = 0;
+
+ LV2_Atom_Event* ev = lv2_atom_sequence_begin(&eventPort->body);
+
+ while(!lv2_atom_sequence_is_end(&eventPort->body,
+ eventPort->atom.size,
+ ev)) {
+ uint8_t* const data = (uint8_t*)(ev+1);
+
+ if ((data[0] & 0xF0) == 0x80) { // note off
+ int key = data[1];
+
+ DEBUG(lv2input, "Event (off) key:%d\n", key);
+ }
+
+ if ((data[0] & 0xF0) == 0x90) { // note on
+ int key = data[1];
+ int velocity = data[2];
+
+ DEBUG(lv2input, "Event key:%d vel:%d\n", key, velocity);
+
+ int i = mmap.lookup(key);
+ if(velocity && i != -1) {
+ list[listsize].type = TYPE_ONSET;
+ list[listsize].instrument = i;
+ list[listsize].velocity = velocity / 127.0;
+ list[listsize].offset = ev->time.frames;
+ listsize++;
+ }
+ }
+ ev = lv2_atom_sequence_next(ev);
+ }
+
+ *nevents = listsize;
+ return list;
+}
+
+void InputLV2::post()
+{
+}
diff --git a/src/input_lv2.h b/src/input_lv2.h
new file mode 100644
index 0000000..32e2fd8
--- /dev/null
+++ b/src/input_lv2.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * input_lv2.h
+ *
+ * Wed Jul 13 14:27:02 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_INPUT_LV2_H__
+#define __DRUMGIZMO_INPUT_LV2_H__
+
+#include <audioinputenginemidi.h>
+
+#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
+
+class InputLV2 : public AudioInputEngineMidi {
+public:
+ InputLV2();
+ ~InputLV2();
+
+ bool init(Instruments &instruments);
+
+ void setParm(std::string parm, std::string value);
+
+ bool start();
+ void stop();
+
+ void pre();
+ event_t *run(size_t pos, size_t len, size_t *nevents);
+ void post();
+
+ LV2_Atom_Sequence *eventPort;
+
+private:
+ Instruments *instruments;
+};
+
+#endif/*__DRUMGIZMO_INPUT_LV2_H__*/
diff --git a/src/lv2.cc b/src/lv2.cc
new file mode 100644
index 0000000..d87665d
--- /dev/null
+++ b/src/lv2.cc
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * lv2.cc
+ *
+ * Wed Jul 13 13:50:33 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
+#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "lv2_gui.h"
+#include "lv2_instance.h"
+
+#include <hugin.hpp>
+
+#define DRUMGIZMO_URI "http://drumgizmo.org/lv2"
+#define NS_DG DRUMGIZMO_URI "/atom#"
+
+// Stuff to handle DrumGizmo* transmission from instance to GUI.
+static LV2_DrumGizmo_Descriptor dg_descriptor;
+
+static DrumGizmo *dg_get_pci(LV2_Handle instance)
+{
+ DGLV2 *dglv2 = (DGLV2 *)instance;
+ return dglv2->dg;
+}
+
+LV2_State_Status
+dg_save(LV2_Handle instance,
+ LV2_State_Store_Function store,
+ LV2_State_Handle handle,
+ uint32_t flags,
+ const LV2_Feature *const * features)
+{
+ DGLV2 *dglv2 = (DGLV2 *)instance;
+
+ if(!dglv2 || !dglv2->map || !dglv2->map->map) {
+ // Missing urid feature?
+ return LV2_STATE_ERR_NO_FEATURE;
+ }
+
+ std::string config = dglv2->dg->configString();
+
+ // Backwards compatible fix for errornously stored '\0' byte in < v0.9.8.
+ // Remove when we reach v1.0
+ config += "\n";
+
+ store(handle,
+ dglv2->map->map(dglv2->map->handle, NS_DG "config"),
+ config.data(),
+ config.length(),
+ dglv2->map->map(dglv2->map->handle, LV2_ATOM__Chunk),
+ LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
+
+ return LV2_STATE_SUCCESS;
+}
+
+LV2_State_Status
+dg_restore(LV2_Handle instance,
+ LV2_State_Retrieve_Function retrieve,
+ LV2_State_Handle handle,
+ uint32_t flags,
+ const LV2_Feature *const * features)
+{
+ DGLV2 *dglv2 = (DGLV2 *)instance;
+
+ if(!dglv2 || !dglv2->map || !dglv2->map->map) {
+ // Missing urid feature?
+ return LV2_STATE_ERR_NO_FEATURE;
+ }
+
+ size_t size;
+ uint32_t type;
+
+ const char* data =
+ (const char*)retrieve(handle,
+ dglv2->map->map(dglv2->map->handle, NS_DG "config"),
+ &size, &type, &flags);
+
+ DEBUG(lv2, "Config string size: %d, data*: %p\n", (int)size, data);
+
+ if(data && size) {
+ std::string config;
+
+ // Fix for errornously stored '\0' byte in < v0.9.8.
+ // Remove when we reach v1.0
+ if(data[size - 1] == '\0') size--;
+
+ config.append(data, size);
+ dglv2->dg->setConfigString(config);
+ }
+
+ return LV2_STATE_SUCCESS;
+}
+
+static LV2_State_Interface dg_persist = {
+ dg_save,
+ dg_restore
+};
+
+LV2_Handle instantiate(const struct _LV2_Descriptor *descriptor,
+ double sample_rate,
+ const char *bundle_path,
+ const LV2_Feature *const *features)
+{
+ DGLV2 *dglv2 = new DGLV2;
+
+ dglv2->map = NULL;
+ for (int i = 0 ; features[i] ; i++) {
+ if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) {
+ dglv2->map = (LV2_URID_Map*)features[i]->data;
+ }
+ }
+
+ dg_descriptor.get_pci = dg_get_pci;
+
+ dglv2->in = new InputLV2();
+ dglv2->out = new OutputLV2();
+
+ dglv2->buffer = NULL;
+ dglv2->buffer_size = 0;
+
+ dglv2->dg = new DrumGizmo(dglv2->out, dglv2->in);
+ dglv2->dg->setSamplerate(sample_rate);
+
+ return (LV2_Handle)dglv2;
+}
+
+void connect_port(LV2_Handle instance,
+ uint32_t port,
+ void *data_location)
+{
+ DGLV2 *dglv2 = (DGLV2 *)instance;
+
+ if(port == 0) {// MIDI in
+ dglv2->in->eventPort = (LV2_Atom_Sequence*)data_location;
+ } else {// Audio Port
+ if(port - 1 < NUM_OUTPUTS) {
+ dglv2->out->outputPorts[port - 1].samples = (sample_t*)data_location;
+ dglv2->out->outputPorts[port - 1].size = 0;
+ }
+ }
+}
+
+void activate(LV2_Handle instance)
+{
+ // We don't really need to do anything here.
+ DGLV2 *dglv2 = (DGLV2 *)instance;
+ (void)dglv2;
+}
+
+void run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ static size_t pos = 0;
+ DGLV2 *dglv2 = (DGLV2 *)instance;
+
+ dglv2->dg->run(pos, dglv2->buffer, sample_count);
+
+ pos += sample_count;
+}
+
+void deactivate(LV2_Handle instance)
+{
+ // We don't really need to do anything here.
+ DGLV2 *dglv2 = (DGLV2 *)instance;
+ dglv2->dg->stop();
+}
+
+void cleanup(LV2_Handle instance)
+{
+ DGLV2 *dglv2 = (DGLV2 *)instance;
+ delete dglv2->dg;
+ delete dglv2->in;
+ delete dglv2->out;
+}
+
+const void* extension_data(const char *uri)
+{
+ if(!strcmp(uri, PLUGIN_INSTANCE_URI)) return &dg_descriptor;
+ if(!strcmp(uri, LV2_STATE__interface)) return &dg_persist;
+ return NULL;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static const LV2_Descriptor descriptor = {
+ DRUMGIZMO_URI,
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ extension_data
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor* lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0:
+ return &descriptor;
+ default:
+ return NULL;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/lv2_event.h b/src/lv2_event.h
new file mode 100644
index 0000000..2c340ba
--- /dev/null
+++ b/src/lv2_event.h
@@ -0,0 +1,281 @@
+/*
+ LV2 Event Extension
+ Copyright 2008-2011 David Robillard <http://drobilla.net>
+ Copyright 2006-2007 Lars Luthman <lars.luthman@gmail.com>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#ifndef LV2_EVENT_H
+#define LV2_EVENT_H
+
+#define LV2_EVENT_URI "http://lv2plug.in/ns/ext/event"
+#define LV2_EVENT_AUDIO_STAMP 0
+
+#include <stdint.h>
+
+/**
+ @file event.h
+ C API for the LV2 Event extension <http://lv2plug.in/ns/ext/event>.
+
+ This extension is a generic transport mechanism for time stamped events
+ of any type (e.g. MIDI, OSC, ramps, etc). Each port can transport mixed
+ events of any type; the type of events and timestamps are defined by a URI
+ which is mapped to an integer by the host for performance reasons.
+
+ This extension requires the host to support the LV2 URI Map extension.
+ Any host which supports this extension MUST guarantee that any call to
+ the LV2 URI Map uri_to_id function with the URI of this extension as the
+ 'map' argument returns a value within the range of uint16_t.
+*/
+
+/**
+ The best Pulses Per Quarter Note for tempo-based uint32_t timestamps.
+ Equal to 2^12 * 5 * 7 * 9 * 11 * 13 * 17, which is evenly divisble
+ by all integers from 1 through 18 inclusive, and powers of 2 up to 2^12.
+*/
+static const uint32_t LV2_EVENT_PPQN = 3136573440U;
+
+/**
+ An LV2 event (header only).
+
+ LV2 events are generic time-stamped containers for any type of event.
+ The type field defines the format of a given event's contents.
+
+ This struct defines the header of an LV2 event. An LV2 event is a single
+ chunk of POD (plain old data), usually contained in a flat buffer (see
+ LV2_EventBuffer below). Unless a required feature says otherwise, hosts may
+ assume a deep copy of an LV2 event can be created safely using a simple:
+
+ memcpy(ev_copy, ev, sizeof(LV2_Event) + ev->size); (or equivalent)
+*/
+typedef struct {
+
+ /**
+ The frames portion of timestamp. The units used here can optionally be
+ set for a port (with the lv2ev:timeUnits property), otherwise this is
+ audio frames, corresponding to the sample_count parameter of the LV2 run
+ method (e.g. frame 0 is the first frame for that call to run).
+ */
+ uint32_t frames;
+
+ /**
+ The sub-frames portion of timestamp. The units used here can optionally
+ be set for a port (with the lv2ev:timeUnits property), otherwise this is
+ 1/(2^32) of an audio frame.
+ */
+ uint32_t subframes;
+
+ /**
+ The type of this event, as a number which represents some URI
+ defining an event type. This value MUST be some value previously
+ returned from a call to the uri_to_id function defined in the LV2
+ URI map extension (see lv2_uri_map.h).
+ There are special rules which must be followed depending on the type
+ of an event. If the plugin recognizes an event type, the definition
+ of that event type will describe how to interpret the event, and
+ any required behaviour. Otherwise, if the type is 0, this event is a
+ non-POD event and lv2_event_unref MUST be called if the event is
+ 'dropped' (see above). Even if the plugin does not understand an event,
+ it may pass the event through to an output by simply copying (and NOT
+ calling lv2_event_unref). These rules are designed to allow for generic
+ event handling plugins and large non-POD events, but with minimal hassle
+ on simple plugins that "don't care" about these more advanced features.
+ */
+ uint16_t type;
+
+ /**
+ The size of the data portion of this event in bytes, which immediately
+ follows. The header size (12 bytes) is not included in this value.
+ */
+ uint16_t size;
+
+ /* size bytes of data follow here */
+
+} LV2_Event;
+
+
+/**
+ A buffer of LV2 events (header only).
+
+ Like events (which this contains) an event buffer is a single chunk of POD:
+ the entire buffer (including contents) can be copied with a single memcpy.
+ The first contained event begins sizeof(LV2_EventBuffer) bytes after the
+ start of this struct.
+
+ After this header, the buffer contains an event header (defined by struct
+ LV2_Event), followed by that event's contents (padded to 64 bits), followed
+ by another header, etc:
+
+ | | | | | | |
+ | | | | | | | | | | | | | | | | | | | | | | | | |
+ |FRAMES |SUBFRMS|TYP|LEN|DATA..DATA..PAD|FRAMES | ...
+*/
+typedef struct {
+
+ /**
+ The contents of the event buffer. This may or may not reside in the
+ same block of memory as this header, plugins must not assume either.
+ The host guarantees this points to at least capacity bytes of allocated
+ memory (though only size bytes of that are valid events).
+ */
+ uint8_t* data;
+
+ /**
+ The size of this event header in bytes (including everything).
+
+ This is to allow for extending this header in the future without
+ breaking binary compatibility. Whenever this header is copied,
+ it MUST be done using this field (and NOT the sizeof this struct).
+ */
+ uint16_t header_size;
+
+ /**
+ The type of the time stamps for events in this buffer.
+ As a special exception, '0' always means audio frames and subframes
+ (1/UINT32_MAX'th of a frame) in the sample rate passed to instantiate.
+
+ INPUTS: The host must set this field to the numeric ID of some URI
+ defining the meaning of the frames/subframes fields of contained events
+ (obtained by the LV2 URI Map uri_to_id function with the URI of this
+ extension as the 'map' argument, see lv2_uri_map.h). The host must
+ never pass a plugin a buffer which uses a stamp type the plugin does not
+ 'understand'. The value of this field must never change, except when
+ connect_port is called on the input port, at which time the host MUST
+ have set the stamp_type field to the value that will be used for all
+ subsequent run calls.
+
+ OUTPUTS: The plugin may set this to any value that has been returned
+ from uri_to_id with the URI of this extension for a 'map' argument.
+ When connected to a buffer with connect_port, output ports MUST set this
+ field to the type of time stamp they will be writing. On any call to
+ connect_port on an event input port, the plugin may change this field on
+ any output port, it is the responsibility of the host to check if any of
+ these values have changed and act accordingly.
+ */
+ uint16_t stamp_type;
+
+ /**
+ The number of events in this buffer.
+
+ INPUTS: The host must set this field to the number of events contained
+ in the data buffer before calling run(). The plugin must not change
+ this field.
+
+ OUTPUTS: The plugin must set this field to the number of events it has
+ written to the buffer before returning from run(). Any initial value
+ should be ignored by the plugin.
+ */
+ uint32_t event_count;
+
+ /**
+ The size of the data buffer in bytes.
+ This is set by the host and must not be changed by the plugin.
+ The host is allowed to change this between run() calls.
+ */
+ uint32_t capacity;
+
+ /**
+ The size of the initial portion of the data buffer containing data.
+
+ INPUTS: The host must set this field to the number of bytes used
+ by all events it has written to the buffer (including headers)
+ before calling the plugin's run().
+ The plugin must not change this field.
+
+ OUTPUTS: The plugin must set this field to the number of bytes
+ used by all events it has written to the buffer (including headers)
+ before returning from run().
+ Any initial value should be ignored by the plugin.
+ */
+ uint32_t size;
+
+} LV2_Event_Buffer;
+
+
+/**
+ Opaque pointer to host data.
+*/
+typedef void* LV2_Event_Callback_Data;
+
+
+/**
+ Non-POD events feature.
+
+ To support this feature the host must pass an LV2_Feature struct to the
+ plugin's instantiate method with URI "http://lv2plug.in/ns/ext/event"
+ and data pointed to an instance of this struct. Note this feature
+ is not mandatory to support the event extension.
+*/
+typedef struct {
+
+ /**
+ Opaque pointer to host data.
+
+ The plugin MUST pass this to any call to functions in this struct.
+ Otherwise, it must not be interpreted in any way.
+ */
+ LV2_Event_Callback_Data callback_data;
+
+ /**
+ Take a reference to a non-POD event.
+
+ If a plugin receives an event with type 0, it means the event is a
+ pointer to some object in memory and not a flat sequence of bytes
+ in the buffer. When receiving a non-POD event, the plugin already
+ has an implicit reference to the event. If the event is stored AND
+ passed to an output, lv2_event_ref MUST be called on that event.
+ If the event is only stored OR passed through, this is not necessary
+ (as the plugin already has 1 implicit reference).
+
+ @param event An event received at an input that will not be copied to
+ an output or stored in any way.
+
+ @param context The calling context. Like event types, this is a mapped
+ URI, see lv2_context.h. Simple plugin with just a run() method should
+ pass 0 here (the ID of the 'standard' LV2 run context). The host
+ guarantees that this function is realtime safe iff @a context is
+ realtime safe.
+
+ PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS.
+ */
+ uint32_t (*lv2_event_ref)(LV2_Event_Callback_Data callback_data,
+ LV2_Event* event);
+
+ /**
+ Drop a reference to a non-POD event.
+
+ If a plugin receives an event with type 0, it means the event is a
+ pointer to some object in memory and not a flat sequence of bytes
+ in the buffer. If the plugin does not pass the event through to
+ an output or store it internally somehow, it MUST call this function
+ on the event (more information on using non-POD events below).
+
+ @param event An event received at an input that will not be copied to an
+ output or stored in any way.
+
+ @param context The calling context. Like event types, this is a mapped
+ URI, see lv2_context.h. Simple plugin with just a run() method should
+ pass 0 here (the ID of the 'standard' LV2 run context). The host
+ guarantees that this function is realtime safe iff @a context is
+ realtime safe.
+
+ PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS.
+ */
+ uint32_t (*lv2_event_unref)(LV2_Event_Callback_Data callback_data,
+ LV2_Event* event);
+
+} LV2_Event_Feature;
+
+
+#endif /* LV2_EVENT_H */
diff --git a/src/lv2_gui.cc b/src/lv2_gui.cc
new file mode 100644
index 0000000..858e097
--- /dev/null
+++ b/src/lv2_gui.cc
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * lv2.cc
+ *
+ * Wed Jul 13 13:50:33 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "lv2_gui.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <lv2/lv2plug.in/ns/ext/instance-access/instance-access.h>
+#include <lv2/lv2plug.in/ns/extensions/ui/ui.h>
+
+#include "lv2_instance.h"
+
+// From: http://codesearch.google.com/#50sg5qT6WNE/src/lv2_ui_dssi.c
+// git://repo.or.cz/nekobee.git/src/lv2_ui_dssi.c
+
+#define DRUMGIZMO_UI_URI "http://drumgizmo.org/lv2-gui"
+
+#include <plugingui.h>
+
+/**
+ * When LV2_EXTERNAL_UI_URI UI is instantiated, the returned
+ * LV2UI_Widget handle must be cast to pointer to struct lv2_external_ui.
+ * UI is created in invisible state.
+ */
+struct lv2_external_ui
+{
+ /**
+ * Host calls this function regulary. UI library implementing the
+ * callback may do IPC or redraw the UI.
+ *
+ * @param _this_ the UI context
+ */
+ void (* run)(struct lv2_external_ui * _this_);
+
+ /**
+ * Host calls this function to make the plugin UI visible.
+ *
+ * @param _this_ the UI context
+ */
+ void (* show)(struct lv2_external_ui * _this_);
+
+ /**
+ * Host calls this function to make the plugin UI invisible again.
+ *
+ * @param _this_ the UI context
+ */
+ void (* hide)(struct lv2_external_ui * _this_);
+};
+
+/** UI extension suitable for out-of-process UIs */
+#define LV2_EXTERNAL_UI_URI "http://lv2plug.in/ns/extensions/ui#external"
+
+/**
+ * On UI instantiation, host must supply LV2_EXTERNAL_UI_URI
+ * feature. LV2_Feature::data must be pointer to struct lv2_external_ui_host. */
+struct lv2_external_ui_host
+{
+ /**
+ * Callback that plugin UI will call
+ * when UI (GUI window) is closed by user.
+ * This callback wil; be called during execution of lv2_external_ui::run()
+ * (i.e. not from background thread).
+ *
+ * After this callback is called, UI is defunct. Host must call
+ * LV2UI_Descriptor::cleanup(). If host wants to make the UI visible
+ * again UI must be reinstantiated.
+ *
+ * @param controller Host context associated with plugin UI, as
+ * supplied to LV2UI_Descriptor::instantiate()
+ */
+ void (* ui_closed)(LV2UI_Controller controller);
+
+ /**
+ * Optional (may be NULL) "user friendly" identifier which the UI
+ * may display to allow a user to easily associate this particular
+ * UI instance with the correct plugin instance as it is represented
+ * by the host (e.g. "track 1" or "channel 4").
+ *
+ * If supplied by host, the string will be referenced only during
+ * LV2UI_Descriptor::instantiate()
+ */
+ const char * plugin_human_id;
+};
+
+struct DG_GUI {
+ struct lv2_external_ui virt;
+
+ LV2_Handle instance_handle;
+ LV2_Extension_Data_Feature *data_access;
+ DrumGizmo *instance;
+ LV2UI_Controller controller;
+
+ GUI::PluginGUI *gui;
+ struct lv2_external_ui_host *ui_host_ptr;
+};
+
+static void ui_run(struct lv2_external_ui * _this_)
+{
+ struct DG_GUI *dggui = (struct DG_GUI *)_this_;
+ dggui->gui->processEvents();
+}
+
+static void ui_show(struct lv2_external_ui * _this_)
+{
+ struct DG_GUI *dggui = (struct DG_GUI *)_this_;
+ dggui->gui->show();
+}
+
+static void ui_hide(struct lv2_external_ui * _this_)
+{
+ struct DG_GUI *dggui = (struct DG_GUI *)_this_;
+ if(dggui->gui) dggui->gui->hide();
+}
+
+static void closeHandler(void *ptr)
+{
+ struct DG_GUI *gui = (struct DG_GUI *)ptr;
+
+ if(gui->ui_host_ptr && gui->ui_host_ptr->ui_closed) {
+ gui->ui_host_ptr->ui_closed(gui->controller);
+ }
+
+ delete gui->gui;
+ gui->gui = NULL;
+}
+
+static LV2UI_Handle ui_instantiate(const struct _LV2UI_Descriptor * descriptor,
+ const char * plugin_uri,
+ const char * bundle_path,
+ LV2UI_Write_Function write_function,
+ LV2UI_Controller controller,
+ LV2UI_Widget * widget,
+ const LV2_Feature * const * features)
+{
+ printf("ui_instantiate\n");
+
+ struct DG_GUI* pt = new struct DG_GUI;
+
+ pt->ui_host_ptr = NULL;
+ pt->controller = controller;
+
+ while (*features != NULL) {
+ std::string uri = (*features)->URI;
+ void *data = (*features)->data;
+
+ printf("DGUI: feature: %s\n", uri.c_str());
+
+ if(uri == LV2_INSTANCE_ACCESS_URI) {
+ pt->instance_handle = data;
+ }
+
+ if(uri == LV2_DATA_ACCESS_URI) {
+ pt->data_access = (LV2_Extension_Data_Feature *)data;
+ }
+
+ if(uri == LV2_EXTERNAL_UI_URI) {
+ pt->ui_host_ptr = (struct lv2_external_ui_host *)data;
+ }
+ features++;
+ }
+
+ LV2_DrumGizmo_Descriptor *dgd =
+ (LV2_DrumGizmo_Descriptor *)(*pt->data_access->data_access)(PLUGIN_INSTANCE_URI);
+
+ pt->instance = dgd->get_pci(pt->instance_handle);
+ pt->virt.run = ui_run;
+ pt->virt.show = ui_show;
+ pt->virt.hide = ui_hide;
+ pt->gui = new GUI::PluginGUI();
+ pt->gui->setWindowClosedCallback(closeHandler, pt);
+
+ *widget = (LV2UI_Widget)pt;
+
+ return pt;
+}
+
+static void ui_cleanup(LV2UI_Handle ui)
+{
+ struct DG_GUI* pt = (struct DG_GUI*)ui;
+ delete pt->gui;
+ pt->gui = NULL;
+ delete pt;
+}
+
+static void ui_port_event(LV2UI_Handle ui,
+ uint32_t port_index,
+ uint32_t buffer_size,
+ uint32_t format,
+ const void * buffer)
+{
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static LV2UI_Descriptor descriptor = {
+ DRUMGIZMO_UI_URI,
+ ui_instantiate,
+ ui_cleanup,
+ ui_port_event,
+ NULL
+};
+
+const LV2UI_Descriptor *lv2ui_descriptor(uint32_t index)
+{
+ if(index == 0) return &descriptor;
+ return NULL;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/lv2_gui.h b/src/lv2_gui.h
new file mode 100644
index 0000000..2857445
--- /dev/null
+++ b/src/lv2_gui.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * lv2_gui.h
+ *
+ * Fri Oct 21 10:48:53 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_LV2_GUI_H__
+#define __DRUMGIZMO_LV2_GUI_H__
+
+#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
+#include <lv2/lv2plug.in/ns/ext/data-access/data-access.h>
+
+#define PLUGIN_INSTANCE_URI "http://drumgizmo.org/ns/drumgizmo-plugin-instance"
+
+class DrumGizmo;
+struct LV2_DrumGizmo_Descriptor {
+ DrumGizmo *(*get_pci)(LV2_Handle instance);
+};
+
+#endif/*__DRUMGIZMO_LV2_GUI_H__*/
diff --git a/src/lv2_instance.h b/src/lv2_instance.h
new file mode 100644
index 0000000..e050e22
--- /dev/null
+++ b/src/lv2_instance.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * lv2_instance.h
+ *
+ * Sun Nov 20 15:27:41 CET 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_LV2_INSTANCE_H__
+#define __DRUMGIZMO_LV2_INSTANCE_H__
+
+#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
+#include <lv2/lv2plug.in/ns/ext/state/state.h>
+#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
+
+#include "input_lv2.h"
+#include "output_lv2.h"
+
+#include <drumgizmo.h>
+
+typedef struct {
+ InputLV2 *in;
+ OutputLV2 *out;
+ DrumGizmo *dg;
+ sample_t *buffer;
+ size_t buffer_size;
+ LV2_URID_Map* map;
+} DGLV2;
+
+#endif/*__DRUMGIZMO_LV2_INSTANCE_H__*/
diff --git a/src/manifest.ttl b/src/manifest.ttl
new file mode 100644
index 0000000..65a8953
--- /dev/null
+++ b/src/manifest.ttl
@@ -0,0 +1,7 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://drumgizmo.org/lv2>
+ a lv2:Plugin ;
+ lv2:binary <drumgizmo.so> ;
+ rdfs:seeAlso <drumgizmo.ttl> .
diff --git a/src/message.h b/src/message.h
new file mode 100644
index 0000000..07b0300
--- /dev/null
+++ b/src/message.h
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * message.h
+ *
+ * Wed Mar 20 15:50:57 CET 2013
+ * Copyright 2013 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_MESSAGE_H__
+#define __DRUMGIZMO_MESSAGE_H__
+
+#include <string>
+
+class MessageHandler;
+
+class Message {
+public:
+ typedef enum {
+ // Engine -> GUI Messages:
+ LoadStatus, // Signal GUI the current load status.
+ LoadStatusMidimap, // Signal GUI the current load status of the midimap.
+
+ // GUI -> Engine, Engine -> Engine Messages:
+ LoadDrumKit, // Signal engine to load drumkit.
+ LoadMidimap, // Signal engine to load midimap.
+ EngineSettingsMessage, // Request or receive engine settings.
+ ChangeSettingMessage, // Update named setting in engine.
+ } type_t;
+
+ typedef enum {
+ NormalProcessing, // Just add to the queue
+ FilterMultiple, // Ignore top message if it has the same type.
+ // SyncWait, // Block the send call until the message has been handled by the receiver.
+ } processing_mode_t;
+
+ virtual ~Message() {}
+ virtual type_t type() = 0;
+ virtual processing_mode_t processing_mode() { return NormalProcessing; }
+};
+
+class LoadStatusMessage : public Message {
+public:
+ type_t type() { return Message::LoadStatus; }
+ processing_mode_t processing_mode() { return FilterMultiple; }
+ unsigned int number_of_files;
+ unsigned int numer_of_files_loaded;
+ std::string current_file;
+};
+
+class LoadStatusMessageMidimap : public Message {
+public:
+ type_t type() { return Message::LoadStatusMidimap; }
+ bool success;
+};
+
+class LoadDrumKitMessage : public Message {
+public:
+ type_t type() { return Message::LoadDrumKit; }
+ std::string drumkitfile;
+};
+
+class LoadMidimapMessage : public Message {
+public:
+ type_t type() { return Message::LoadMidimap; }
+ std::string midimapfile;
+};
+
+class EngineSettingsMessage : public Message {
+public:
+ type_t type() { return Message::EngineSettingsMessage; }
+ std::string midimapfile;
+ bool midimap_loaded;
+
+ std::string drumkitfile;
+ bool drumkit_loaded;
+
+ float enable_velocity_modifier;
+ float velocity_modifier_falloff;
+ float velocity_modifier_weight;
+ float enable_velocity_randomiser;
+ float velocity_randomiser_weight;
+};
+
+class ChangeSettingMessage : public Message {
+public:
+ typedef enum {
+ enable_velocity_modifier,
+ velocity_modifier_weight,
+ velocity_modifier_falloff,
+ } setting_name_t;
+
+ ChangeSettingMessage(setting_name_t n, float v) {
+ name = n;
+ value = v;
+ }
+
+ type_t type() { return Message::ChangeSettingMessage; }
+
+ setting_name_t name;
+ float value;
+};
+
+#endif/*__DRUMGIZMO_MESSAGE_H__*/
diff --git a/src/messagehandler.cc b/src/messagehandler.cc
new file mode 100644
index 0000000..52a89a5
--- /dev/null
+++ b/src/messagehandler.cc
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * messagehandler.cc
+ *
+ * Fri Jun 14 20:30:43 CEST 2013
+ * Copyright 2013 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "messagehandler.h"
+
+#include <hugin.hpp>
+
+#include "messagereceiver.h"
+
+// Global messagehandler:
+MessageHandler msghandler;
+
+MessageHandler::MessageHandler()
+{
+}
+
+void MessageHandler::addReceiver(message_receiver_id_t id,
+ MessageReceiver *receiver)
+{
+ MutexAutolock l(mutex);
+
+ receivers[id] = receiver;
+}
+
+void MessageHandler::removeReceiver(MessageReceiver *receiver)
+{
+ MutexAutolock l(mutex);
+
+ std::map<message_receiver_id_t, MessageReceiver *>::iterator i =
+ receivers.begin();
+ while(i != receivers.end()) {
+ if(i->second == receiver) {
+ receivers.erase(i);
+ break;
+ }
+ i++;
+ }
+}
+
+bool MessageHandler::sendMessage(message_receiver_id_t id, Message* msg)
+{
+ MutexAutolock l(mutex);
+
+ if(receivers.find(id) == receivers.end()) {
+ //WARN(msghandler, "Could not find id %d\n", id);
+ delete msg;
+ return false;
+ }
+
+ //DEBUG(msghandler, "Sending message to id %d\n", id);
+
+ MessageReceiver *receiver = receivers[id];
+ /* // This code causes sporadic segfaults on windows.
+ if(msg->processing_mode() == Message::FilterMultiple) {
+ Message *pmsg;
+ MutexAutolock lock(receiver->message_mutex); // Make peek/receive atomic.
+ while( (pmsg = receiver->peekMessage()) != NULL) {
+ if(pmsg->type() != msg->type()) break;
+ // Remove all old messages with same type.
+ delete receiver->receiveMessage();
+ }
+ }
+ */
+ receiver->sendMessage(msg);
+ return true;
+}
diff --git a/src/messagehandler.h b/src/messagehandler.h
new file mode 100644
index 0000000..9812777
--- /dev/null
+++ b/src/messagehandler.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * messagehandler.h
+ *
+ * Fri Jun 14 20:30:43 CEST 2013
+ * Copyright 2013 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_MESSAGEHANDLER_H__
+#define __DRUMGIZMO_MESSAGEHANDLER_H__
+
+#include <map>
+
+#include "message.h"
+#include "mutex.h"
+
+typedef enum {
+ MSGRCV_ENGINE = 1,
+ MSGRCV_UI = 2,
+ MSGRCV_LOADER = 3,
+} message_receiver_id_t;
+
+class MessageReceiver;
+
+class MessageHandler {
+public:
+ MessageHandler();
+
+ void addReceiver(message_receiver_id_t id, MessageReceiver *receiver);
+ void removeReceiver(MessageReceiver *receiver);
+
+ /**
+ * Send Message to receiver with specified id.
+ * @return Return true if id is registered. Return false if id is not
+ * currently registered.
+ */
+ bool sendMessage(message_receiver_id_t id, Message* msg);
+
+private:
+ std::map<message_receiver_id_t, MessageReceiver *> receivers;
+
+ Mutex mutex;
+};
+
+// Global MessageHandler;
+extern MessageHandler msghandler;
+
+#endif/*__DRUMGIZMO_MESSAGEHANDLER_H__*/
diff --git a/src/messagereceiver.cc b/src/messagereceiver.cc
new file mode 100644
index 0000000..a24482b
--- /dev/null
+++ b/src/messagereceiver.cc
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * messagereceiver.cc
+ *
+ * Sun Jun 16 12:09:06 CEST 2013
+ * Copyright 2013 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "messagereceiver.h"
+
+#include <hugin.hpp>
+
+MessageReceiver::MessageReceiver(message_receiver_id_t id)
+{
+ msghandler.addReceiver(id, this);
+}
+
+MessageReceiver::~MessageReceiver()
+{
+ msghandler.removeReceiver(this);
+}
+
+void MessageReceiver::sendMessage(Message *msg)
+{
+ MutexAutolock l(message_mutex);
+
+ message_queue.push_back(msg);
+}
+
+Message *MessageReceiver::receiveMessage()
+{
+ Message *msg = NULL;
+ if(message_queue.size()) {
+ msg = message_queue.front();
+ message_queue.pop_front();
+ }
+ return msg;
+}
+
+Message *MessageReceiver::peekMessage()
+{
+ Message *msg = NULL;
+ if(message_queue.size()) {
+ msg = message_queue.front();
+ }
+ return msg;
+}
+
+void MessageReceiver::handleMessages(size_t max)
+{
+ MutexAutolock l(message_mutex);
+ bool process_all = false;
+ if(max == 0) process_all = true;
+
+ while((process_all || max--) && peekMessage()) {
+ Message *msg = receiveMessage();
+ handleMessage(msg);
+ delete msg;
+ }
+}
diff --git a/src/messagereceiver.h b/src/messagereceiver.h
new file mode 100644
index 0000000..2794091
--- /dev/null
+++ b/src/messagereceiver.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * messagereceiver.h
+ *
+ * Sun Jun 16 12:09:06 CEST 2013
+ * Copyright 2013 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_MESSAGERECEIVER_H__
+#define __DRUMGIZMO_MESSAGERECEIVER_H__
+
+#include <list>
+
+#include "mutex.h"
+#include "message.h"
+#include "messagehandler.h"
+
+class MessageReceiver {
+ friend class MessageHandler;
+public:
+ MessageReceiver(message_receiver_id_t id);
+ ~MessageReceiver();
+
+ /**
+ * Receive message from the message queue.
+ */
+ Message *receiveMessage();
+
+ /**
+ * Receive message from the message queue without removing it.
+ */
+ Message *peekMessage();
+
+ /**
+ * Add a message to the message queue.
+ */
+ void sendMessage(Message *msg);
+
+ /**
+ * Handle messages from the event queue.
+ * @param max_number_of_events the maximum number of events to be handled in
+ * this call. 0 means all.
+ */
+ void handleMessages(size_t max_number_of_events = 0);
+
+ /**
+ * Handler to be implemented in child classes.
+ * Handles a single event.
+ */
+ virtual void handleMessage(Message *msg) = 0;
+
+private:
+ Mutex message_mutex;
+ std::list<Message *> message_queue;
+};
+
+#endif/*__DRUMGIZMO_MESSAGERECEIVER_H__*/
diff --git a/src/midimapparser.cc b/src/midimapparser.cc
new file mode 100644
index 0000000..9d30a05
--- /dev/null
+++ b/src/midimapparser.cc
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * midimapparser.cc
+ *
+ * Mon Aug 8 16:55:30 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "midimapparser.h"
+
+MidiMapParser::MidiMapParser(std::string file)
+{
+ fd = fopen(file.c_str(), "r");
+}
+
+MidiMapParser::~MidiMapParser()
+{
+ if(fd) fclose(fd);
+}
+
+void MidiMapParser::startTag(std::string name, attr_t attr)
+{
+ if(name == "map") {
+ if(attr.find("note") != attr.end() && attr.find("instr") != attr.end()) {
+ midimap[atoi(attr["note"].c_str())] = attr["instr"];
+ }
+ }
+}
+
+int MidiMapParser::readData(char *data, size_t size)
+{
+ if(!fd) return -1;
+ return fread(data, 1, size, fd);
+}
diff --git a/src/midimapparser.h b/src/midimapparser.h
new file mode 100644
index 0000000..98ab886
--- /dev/null
+++ b/src/midimapparser.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * midimapparser.h
+ *
+ * Mon Aug 8 16:55:30 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_MIDIMAPPARSER_H__
+#define __DRUMGIZMO_MIDIMAPPARSER_H__
+
+#include <stdio.h>
+
+#include "saxparser.h"
+
+#include "midimapper.h"
+
+class MidiMapParser : public SAXParser {
+public:
+ MidiMapParser(std::string file);
+ ~MidiMapParser();
+
+ void startTag(std::string name, attr_t attr);
+
+ midimap_t midimap;
+
+protected:
+ int readData(char *data, size_t size);
+
+private:
+ FILE *fd;
+};
+
+#endif/*__DRUMGIZMO_MIDIMAPPARSER_H__*/
diff --git a/src/midimapper.cc b/src/midimapper.cc
new file mode 100644
index 0000000..d4ff94e
--- /dev/null
+++ b/src/midimapper.cc
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * midimapper.cc
+ *
+ * Mon Jul 21 15:24:08 CEST 2008
+ * Copyright 2008 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "midimapper.h"
+
+int MidiMapper::lookup(int note)
+{
+ if(midimap.find(note) == midimap.end()) return -1;
+ std::string instr = midimap[note];
+ if(instrmap.find(instr) == instrmap.end()) return -1;
+ return instrmap[instr];
+}
+
+void MidiMapper::clear()
+{
+ midimap.clear();
+ instrmap.clear();
+}
diff --git a/src/midimapper.h b/src/midimapper.h
new file mode 100644
index 0000000..7439c4b
--- /dev/null
+++ b/src/midimapper.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * midimapper.h
+ *
+ * Mon Jul 21 15:24:07 CEST 2008
+ * Copyright 2008 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_MIDIMAPPER_H__
+#define __DRUMGIZMO_MIDIMAPPER_H__
+
+#include <map>
+#include <string>
+
+typedef std::map<int, std::string> midimap_t;
+typedef std::map<std::string, int> instrmap_t;
+
+class MidiMapper {
+public:
+ void clear();
+
+ int lookup(int note);
+
+ instrmap_t instrmap;
+ midimap_t midimap;
+};
+
+#endif/*__DRUMGIZMO_MIDIMAPPER_H__*/
diff --git a/src/mutex.cc b/src/mutex.cc
new file mode 100644
index 0000000..22d59a6
--- /dev/null
+++ b/src/mutex.cc
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * mutex.cc
+ *
+ * Thu Nov 12 10:51:32 CET 2009
+ * Copyright 2009 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Pracro.
+ *
+ * Pracro 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.
+ *
+ * Pracro 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 Pracro; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "mutex.h"
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <pthread.h>
+#endif
+
+struct mutex_private_t {
+#ifdef WIN32
+ HANDLE mutex;
+#else
+ pthread_mutex_t mutex;
+#endif
+};
+
+Mutex::Mutex()
+{
+ prv = new struct mutex_private_t();
+#ifdef WIN32
+ prv->mutex = CreateMutex(NULL, // default security attributes
+ FALSE, // initially not owned
+ NULL); // unnamed mutex
+#else
+ pthread_mutex_init (&prv->mutex, NULL);
+#endif
+}
+
+Mutex::~Mutex()
+{
+#ifdef WIN32
+ CloseHandle(prv->mutex);
+#else
+ pthread_mutex_destroy(&prv->mutex);
+#endif
+
+ if(prv) delete prv;
+}
+
+void Mutex::lock()
+{
+#ifdef WIN32
+ WaitForSingleObject(prv->mutex, // handle to mutex
+ INFINITE); // no time-out interval
+#else
+ pthread_mutex_lock(&prv->mutex);
+#endif
+}
+
+void Mutex::unlock()
+{
+#ifdef WIN32
+ ReleaseMutex(prv->mutex);
+#else
+ pthread_mutex_unlock(&prv->mutex);
+#endif
+}
+
+MutexAutolock::MutexAutolock(Mutex &m)
+ : mutex(m)
+{
+ mutex.lock();
+}
+
+MutexAutolock::~MutexAutolock()
+{
+ mutex.unlock();
+}
+
+#ifdef TEST_MUTEX
+//deps:
+//cflags: $(PTHREAD_CFLAGS)
+//libs: $(PTHREAD_LIBS)
+#include <test.h>
+
+#include <unistd.h>
+
+volatile int cnt = 0;
+
+static void* thread_run(void *data)
+{
+ Mutex *mutex = (Mutex*)data;
+ mutex->lock();
+ cnt++;
+ mutex->unlock();
+ return NULL;
+}
+
+TEST_BEGIN;
+
+Mutex mutex;
+
+mutex.lock();
+TEST_FALSE(mutex.trylock(), "Testing if trylock works negative.");
+mutex.unlock();
+TEST_TRUE(mutex.trylock(), "Testing if trylock works positive.");
+mutex.unlock();
+
+mutex.lock();
+
+pthread_attr_t attr;
+pthread_t tid;
+pthread_attr_init(&attr);
+pthread_create(&tid, &attr, thread_run, &mutex);
+
+sleep(1);
+TEST_EQUAL_INT(cnt, 0, "Testing if lock prevent cnt from increasing.");
+mutex.unlock();
+
+sleep(1);
+TEST_EQUAL_INT(cnt, 1, "Testing if unlock makes cnt increase.");
+
+pthread_join(tid, NULL);
+pthread_attr_destroy(&attr);
+
+{
+ TEST_TRUE(mutex.trylock(), "Testing if autolock has not yet locked the mutex.");
+ mutex.unlock();
+ MutexAutolock mlock(mutex);
+ TEST_FALSE(mutex.trylock(), "Testing if autolock worked.");
+}
+
+TEST_TRUE(mutex.trylock(), "Testing if autolock has released the lock on the mutex.");
+mutex.unlock();
+
+TEST_END;
+
+#endif/*TEST_MUTEX*/
diff --git a/src/mutex.h b/src/mutex.h
new file mode 100644
index 0000000..11704d4
--- /dev/null
+++ b/src/mutex.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * mutex.h
+ *
+ * Thu Nov 12 10:51:32 CET 2009
+ * Copyright 2009 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Pracro.
+ *
+ * Pracro 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.
+ *
+ * Pracro 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 Pracro; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __PRACRO_MUTEX_H__
+#define __PRACRO_MUTEX_H__
+
+struct mutex_private_t;
+
+class Mutex {
+public:
+ Mutex();
+ ~Mutex();
+
+ bool trylock();
+ void lock();
+ void unlock();
+
+private:
+ struct mutex_private_t* prv;
+};
+
+class MutexAutolock {
+public:
+ MutexAutolock(Mutex &mutex);
+ ~MutexAutolock();
+
+private:
+ Mutex &mutex;
+};
+
+#endif/*__PRACRO_MUTEX_H__*/
diff --git a/src/nolocale.h b/src/nolocale.h
new file mode 100644
index 0000000..816dd9c
--- /dev/null
+++ b/src/nolocale.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * nolocale.h
+ *
+ * Fri Feb 13 12:48:10 CET 2015
+ * Copyright 2015 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_NOLOCALE_H__
+#define __DRUMGIZMO_NOLOCALE_H__
+
+#include <locale.h>
+#include <stdarg.h>
+
+static inline double atof_nol(const char *nptr)
+{
+ double res;
+
+ const char *locale = setlocale(LC_NUMERIC, "C");
+
+ res = atof(nptr);
+
+ setlocale(LC_NUMERIC, locale);
+
+ return res;
+}
+
+static inline int sprintf_nol(char *str, const char *format, ...)
+{
+ int ret;
+
+ const char *locale = setlocale(LC_NUMERIC, "C");
+
+ va_list vl;
+ va_start(vl, format);
+ ret = vsprintf(str, format, vl);
+ va_end(vl);
+
+ setlocale(LC_NUMERIC, locale);
+
+ return ret;
+}
+
+static inline int snprintf_nol(char *str, size_t size, const char *format, ...)
+{
+ int ret;
+
+ const char *locale = setlocale(LC_NUMERIC, "C");
+
+ va_list vl;
+ va_start(vl, format);
+ ret = vsnprintf(str, size, format, vl);
+ va_end(vl);
+
+ setlocale(LC_NUMERIC, locale);
+
+ return ret;
+}
+
+#endif/*__DRUMGIZMO_NOLOCALE_H__*/
diff --git a/src/output_lv2.cc b/src/output_lv2.cc
new file mode 100644
index 0000000..09999cb
--- /dev/null
+++ b/src/output_lv2.cc
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * output_lv2.cc
+ *
+ * Wed Jul 13 14:27:06 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "output_lv2.h"
+
+#include <string.h>
+
+OutputLV2::OutputLV2()
+{
+ for(size_t i = 0; i < NUM_OUTPUTS; i++) {
+ outputPorts[i].size = 0;
+ outputPorts[i].samples = NULL;
+ }
+}
+
+OutputLV2::~OutputLV2()
+{
+}
+
+bool OutputLV2::init(Channels channels)
+{
+ return true;
+}
+
+void OutputLV2::setParm(std::string parm, std::string value)
+{
+}
+
+bool OutputLV2::start()
+{
+ return true;
+}
+
+void OutputLV2::stop()
+{
+}
+
+void OutputLV2::pre(size_t nsamples)
+{
+}
+
+void OutputLV2::run(int ch, sample_t *samples, size_t nsamples)
+{
+ if(ch < NUM_OUTPUTS) {
+ if(outputPorts[ch].samples) {
+ memcpy(outputPorts[ch].samples, samples, nsamples * sizeof(sample_t));
+ }
+ }
+}
+
+void OutputLV2::post(size_t nsamples)
+{
+}
+
+sample_t *OutputLV2::getBuffer(int ch)
+{
+ if(ch < NUM_OUTPUTS) return outputPorts[ch].samples;
+ return NULL;
+}
diff --git a/src/output_lv2.h b/src/output_lv2.h
new file mode 100644
index 0000000..a3a2555
--- /dev/null
+++ b/src/output_lv2.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * output_lv2.h
+ *
+ * Wed Jul 13 14:27:06 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_OUTPUT_LV2_H__
+#define __DRUMGIZMO_OUTPUT_LV2_H__
+
+#include <audiooutputengine.h>
+
+#define NUM_OUTPUTS 64
+
+class OutputPort {
+public:
+ size_t size;
+ sample_t *samples;
+};
+
+class OutputLV2 : public AudioOutputEngine {
+public:
+ OutputLV2();
+ ~OutputLV2();
+
+ bool init(Channels channels);
+
+ void setParm(std::string parm, std::string value);
+
+ bool start();
+ void stop();
+
+ void pre(size_t nsamples);
+ void run(int ch, sample_t *samples, size_t nsamples);
+ void post(size_t nsamples);
+
+ sample_t *getBuffer(int c);
+
+ OutputPort outputPorts[NUM_OUTPUTS];
+};
+
+#endif/*__DRUMGIZMO_OUTPUT_LV2_H__*/
diff --git a/src/path.cc b/src/path.cc
new file mode 100644
index 0000000..1b4ede3
--- /dev/null
+++ b/src/path.cc
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * path.cc
+ *
+ * Tue May 3 14:42:47 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "path.h"
+
+#ifndef __MINGW32__
+#include <libgen.h>
+#endif/*__MINGW32__*/
+
+#include <string.h>
+#include <stdlib.h>
+
+std::string getPath(std::string file)
+{
+ std::string p;
+#ifndef __MINGW32__
+ char *b = strdup(file.c_str());
+ p = dirname(b);
+ free(b);
+#else
+ char drive[_MAX_DRIVE];
+ char dir[_MAX_DIR];
+ _splitpath(file.c_str(), drive, dir, NULL, NULL);
+ p = std::string(drive) + dir;
+#endif
+
+ return p;
+}
diff --git a/src/path.h b/src/path.h
new file mode 100644
index 0000000..bdad0a5
--- /dev/null
+++ b/src/path.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * path.h
+ *
+ * Tue May 3 14:42:46 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_PATH_H__
+#define __DRUMGIZMO_PATH_H__
+
+#include <string>
+
+std::string getPath(std::string file);
+
+#endif/*__DRUMGIZMO_PATH_H__*/
diff --git a/src/saxparser.cc b/src/saxparser.cc
new file mode 100644
index 0000000..1bd98a8
--- /dev/null
+++ b/src/saxparser.cc
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * saxparser.cc
+ *
+ * Tue Jul 22 16:26:22 CEST 2008
+ * Copyright 2008 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "saxparser.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <hugin.hpp>
+
+static void character_hndl(void *p, const XML_Char *s, int len)
+{
+ SAXParser *parser = (SAXParser*)XML_GetUserData(p);
+ std::string chars;
+ chars.append(s, len);
+ parser->characterData(chars);
+}
+
+static void start_hndl(void *p, const char *el, const char **attr)
+{
+ SAXParser *parser = (SAXParser*)XML_GetUserData(p);
+
+ // Convert to comfy C++ values...
+ std::string name = el;
+ std::map< std::string, std::string > attributes;
+
+ while(*attr) {
+ std::string at_name = *attr;
+ attr++;
+ std::string at_value = *attr;
+ attr++;
+
+ attributes.insert(make_pair(at_name, at_value));
+ }
+
+ parser->startTag(name, attributes);
+}
+
+static void end_hndl(void *p, const char *el)
+{
+ SAXParser *parser = (SAXParser*)XML_GetUserData(p);
+ std::string name = el;
+ parser->endTag(name);
+}
+
+
+SAXParser::SAXParser()
+{
+ p = XML_ParserCreate(NULL);
+ if(!p) {
+ fprintf(stderr, "Couldn't allocate memory for parser\n");
+ // throw Exception(...);
+ return;
+ }
+
+ XML_SetUserData(p, this);
+ XML_UseParserAsHandlerArg(p);
+ XML_SetElementHandler(p, start_hndl, end_hndl);
+ XML_SetCharacterDataHandler(p, character_hndl);
+}
+
+SAXParser::~SAXParser()
+{
+ XML_ParserFree(p);
+}
+
+int SAXParser::parse()
+{
+ DEBUG(sax, "parse()\n");
+
+ char buf[32];
+ int len;
+
+ do {
+ len = readData(buf, sizeof(buf) - 1);
+ if(len == -1) {
+ parseError((char*)"", 0, "Could not read data", 0);
+ return 1;
+ }
+ if(!XML_Parse(p, buf, len, len == 0)) {
+ parseError(buf, len, XML_ErrorString(XML_GetErrorCode(p)),
+ (int)XML_GetCurrentLineNumber(p));
+ return 1;
+ }
+
+ memset(buf, 0, sizeof(buf));
+ } while(len);
+
+ return 0;
+}
+
+int SAXParser::parse(std::string buffer)
+{
+ DEBUG(sax, "parse(buffer %d bytes)\n", (int)buffer.length());
+
+ if(!XML_Parse(p, buffer.c_str(), buffer.length(), true)) {
+ parseError((char*)buffer.c_str(), buffer.length(),
+ XML_ErrorString(XML_GetErrorCode(p)),
+ (int)XML_GetCurrentLineNumber(p));
+ return 1;
+ }
+
+ return 0;
+}
+
+void SAXParser::parseError(char *buf, size_t len, std::string error, int lineno)
+{
+ fprintf(stderr, "SAXParser error at line %d: %s\n", lineno, error.c_str());
+ fprintf(stderr, "\tBuffer %u bytes: [", (int)len);
+ if(fwrite(buf, len, 1, stderr) != len) {}
+ fprintf(stderr, "]\n");
+ fflush(stderr);
+}
diff --git a/src/saxparser.h b/src/saxparser.h
new file mode 100644
index 0000000..aff90d7
--- /dev/null
+++ b/src/saxparser.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * saxparser.h
+ *
+ * Tue Jul 22 16:26:21 CEST 2008
+ * Copyright 2008 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_SAXPARSER_H__
+#define __DRUMGIZMO_SAXPARSER_H__
+
+#include <string>
+#include <map>
+#include <expat.h>
+
+typedef std::map< std::string, std::string> attr_t;
+
+class SAXParser {
+public:
+ SAXParser();
+ virtual ~SAXParser();
+
+ int parse();
+ int parse(std::string buffer);
+
+ virtual void characterData(std::string &data) {}
+ virtual void startTag(std::string name, attr_t attr) {}
+ virtual void endTag(std::string name) {}
+
+ virtual void parseError(char *buf, size_t len, std::string error, int lineno);
+
+protected:
+ virtual int readData(char *data, size_t size) { return 0; }
+
+private:
+ XML_Parser p;
+};
+
+#endif/*__DRUMGIZMO_SAXPARSER_H__*/
diff --git a/src/semaphore.cc b/src/semaphore.cc
new file mode 100644
index 0000000..47ce8e0
--- /dev/null
+++ b/src/semaphore.cc
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * semaphore.cc
+ *
+ * Sat Oct 8 17:44:13 CEST 2005
+ * Copyright 2005 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Pracro.
+ *
+ * Pracro 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.
+ *
+ * Pracro 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 Pracro; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "semaphore.h"
+
+#include <hugin.hpp>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+// Make sure we don't include /this/ file...
+#include <../include/semaphore.h>
+#endif
+
+struct semaphore_private_t {
+#ifdef WIN32
+ HANDLE semaphore;
+#else
+ sem_t semaphore;
+#endif
+};
+
+Semaphore::Semaphore(const char *name)
+{
+ this->name = name;
+ DEBUG(semaphore, "Create [%s]\n", name);
+
+ prv = new struct semaphore_private_t();
+
+#ifdef WIN32
+ prv->semaphore = CreateSemaphore(NULL, // default security attributes
+ 0, // initial count
+ 2147483647, // maximum count (Max LONG)
+ NULL); // unnamed semaphore
+#else
+ sem_init(&prv->semaphore, 0, 0);
+#endif
+}
+
+Semaphore::~Semaphore()
+{
+ DEBUG(semaphore, "Delete [%s]\n", name);
+
+#ifdef WIN32
+ CloseHandle(prv->semaphore);
+#else
+ sem_destroy(&prv->semaphore);
+#endif
+
+ if(prv) delete prv;
+}
+
+void Semaphore::post()
+{
+ DEBUG(semaphore, "Post [%s]\n", name);
+
+#ifdef WIN32
+ ReleaseSemaphore(prv->semaphore, 1, NULL);
+#else
+ sem_post(&prv->semaphore);
+#endif
+}
+
+void Semaphore::wait()
+{
+ DEBUG(semaphore, "Wait [%s]\n", name);
+
+#ifdef WIN32
+ WaitForSingleObject(prv->semaphore, INFINITE);
+#else
+ sem_wait(&prv->semaphore);
+#endif
+}
+
+#ifdef TEST_SEMAPHORE
+//deps:
+//cflags: -I.. $(PTHREAD_CFLAGS)
+//libs: $(PTHREAD_LIBS)
+#include <test.h>
+
+TEST_BEGIN;
+
+// TODO: Put some testcode here (see test.h for usable macros).
+TEST_TRUE(false, "No tests yet!");
+
+TEST_END;
+
+#endif/*TEST_SEMAPHORE*/
diff --git a/src/semaphore.h b/src/semaphore.h
new file mode 100644
index 0000000..7e39f5a
--- /dev/null
+++ b/src/semaphore.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * semaphore.h
+ *
+ * Sat Oct 8 17:44:13 CEST 2005
+ * Copyright 2005 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of Pracro.
+ *
+ * Pracro 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.
+ *
+ * Pracro 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 Pracro; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __PRACRO_SEMAPHORE_H__
+#define __PRACRO_SEMAPHORE_H__
+
+struct semaphore_private_t;
+
+class Semaphore {
+public:
+ Semaphore(const char *name = "");
+ ~Semaphore();
+
+ void post();
+ void wait();
+
+private:
+ struct semaphore_private_t *prv;
+ const char *name;
+};
+
+#endif/*__PRACRO_SEMAPHORE_H__*/
diff --git a/src/thread.cc b/src/thread.cc
new file mode 100644
index 0000000..6e216e9
--- /dev/null
+++ b/src/thread.cc
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * thread.cc
+ *
+ * Tue Jan 24 08:11:37 CET 2012
+ * Copyright 2012 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "thread.h"
+
+#include <stdio.h>
+#include <hugin.hpp>
+
+Thread::Thread()
+{}
+
+Thread::~Thread()
+{}
+
+void Thread::run()
+{
+ DEBUG(thread, "Thread::run()\n");
+#ifdef WIN32
+ tid = CreateThread(NULL, 0, thread_run, this, 0, NULL);
+#else
+ pthread_create(&tid, NULL, thread_run, this);
+#endif/*WIN32*/
+}
+
+void Thread::wait_stop()
+{
+#ifdef WIN32
+ WaitForSingleObject(tid, INFINITE);
+#else
+ pthread_join(tid, NULL);
+#endif/*WIN32*/
+}
+
+#ifdef WIN32
+DWORD WINAPI
+#else
+void*
+#endif/*WIN32*/
+Thread::thread_run(void *data)
+{
+ DEBUG(thread, "Thread run\n");
+ Thread *t = (Thread*)data;
+ t->thread_main();
+ return 0;
+}
diff --git a/src/thread.h b/src/thread.h
new file mode 100644
index 0000000..f2c1dd0
--- /dev/null
+++ b/src/thread.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * thread.h
+ *
+ * Tue Jan 24 08:11:37 CET 2012
+ * Copyright 2012 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#else
+#include <pthread.h>
+#endif/*WIN32*/
+
+class Thread {
+public:
+ Thread();
+ virtual ~Thread();
+
+ void run();
+ void wait_stop();
+
+protected:
+ virtual void thread_main() = 0;
+
+private:
+#ifdef WIN32
+ HANDLE tid;
+ static DWORD WINAPI
+#else
+ pthread_t tid;
+ static void*
+#endif/*WIN32*/
+ thread_run(void *data);
+};
diff --git a/src/versionstr.cc b/src/versionstr.cc
new file mode 100644
index 0000000..90557f6
--- /dev/null
+++ b/src/versionstr.cc
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * versionstr.cc
+ *
+ * Wed Jul 22 11:41:32 CEST 2009
+ * Copyright 2009 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "versionstr.h"
+
+#include <memory.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+// Workaround - major, minor and patch are defined as macros when using _GNU_SOURCES
+#ifdef major
+#undef major
+#endif
+#ifdef minor
+#undef minor
+#endif
+#ifdef patch
+#undef patch
+#endif
+
+VersionStr::VersionStr(std::string v) throw(const char *)
+{
+ memset(version, 0, sizeof(version));
+ set(v);
+}
+
+VersionStr::VersionStr(size_t major, size_t minor, size_t patch)
+{
+ version[0] = major;
+ version[1] = minor;
+ version[2] = patch;
+}
+
+void VersionStr::set(std::string v) throw(const char *)
+{
+ std::string num;
+ size_t idx = 0;
+ for(size_t i = 0; i < v.length(); i++) {
+ if(v[i] == '.') {
+ if(idx > 2) throw "Version string is too long.";
+ version[idx] = atoi(num.c_str());
+ idx++;
+ num = "";
+ } else if(v[i] >= '0' && v[i] <= '9') {
+ num.append(1, v[i]);
+ } else {
+ throw "Version string contains illegal character.";
+ }
+ }
+ if(idx > 2) throw "Version string is too long.";
+ version[idx] = atoi(num.c_str());
+}
+
+VersionStr::operator std::string() const
+{
+ std::string v;
+ char buf[64];
+ if(patch()) {
+ sprintf(buf, "%d.%d.%d", (int)major(), (int)minor(), (int)patch());
+ } else {
+ sprintf(buf, "%d.%d", (int)major(), (int)minor());
+ }
+ v = buf;
+ return v;
+}
+
+void VersionStr::operator=(std::string v) throw(const char *)
+{
+ set(v);
+}
+
+// return a - b simplified as -1, 0 or 1
+static int vdiff(const VersionStr &a, const VersionStr &b)
+{
+ if(a.major() < b.major()) return -1;
+ if(a.major() > b.major()) return 1;
+ if(a.minor() < b.minor()) return -1;
+ if(a.minor() > b.minor()) return 1;
+ if(a.patch() < b.patch()) return -1;
+ if(a.patch() > b.patch()) return 1;
+ return 0;
+}
+
+bool VersionStr::operator<(const VersionStr &other) const
+{
+ if(vdiff(*this, other) == -1) return true;
+ return false;
+}
+
+bool VersionStr::operator>(const VersionStr &other) const
+{
+ if(vdiff(*this, other) == 1) return true;
+ return false;
+}
+
+bool VersionStr::operator==(const VersionStr &other) const
+{
+ if(vdiff(*this, other) == 0) return true;
+ return false;
+}
+
+bool VersionStr::operator<=(const VersionStr &other) const
+{
+ if(vdiff(*this, other) != 1) return true;
+ return false;
+}
+
+bool VersionStr::operator>=(const VersionStr &other) const
+{
+ if(vdiff(*this, other) != -1) return true;
+ return false;
+}
+
+size_t VersionStr::major() const
+{
+ return version[0];
+}
+
+size_t VersionStr::minor() const
+{
+ return version[1];
+}
+
+size_t VersionStr::patch() const
+{
+ return version[2];
+}
diff --git a/src/versionstr.h b/src/versionstr.h
new file mode 100644
index 0000000..ecb1df3
--- /dev/null
+++ b/src/versionstr.h
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set et sw=2 ts=2: */
+/***************************************************************************
+ * versionstr.h
+ *
+ * Wed Jul 22 11:41:32 CEST 2009
+ * Copyright 2009 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __PRACRO_VERSIONSTR_H__
+#define __PRACRO_VERSIONSTR_H__
+
+#include <string>
+
+// Workaround - major, minor and patch are defined as macros when using _GNU_SOURCES
+#ifdef major
+#undef major
+#endif
+#ifdef minor
+#undef minor
+#endif
+#ifdef patch
+#undef patch
+#endif
+
+/**
+ * VersionStr class.
+ * It hold a version number and is capable of correct sorting, as well as string
+ * conversion both ways.
+ */
+class VersionStr {
+public:
+ /**
+ * Constructor.
+ * Throws an exeption if the string does not parse.
+ * @param v A std::string containing a version string on the form a.b or a.b.c
+ */
+ VersionStr(std::string v) throw(const char *);
+
+ /**
+ * Constructor.
+ * @param major A size_t containing the major version number.
+ * @param minor A size_t containing the minor version number.
+ * @param patch A size_t containing the patch level.
+ */
+ VersionStr(size_t major = 0, size_t minor = 0, size_t patch = 0);
+
+ /**
+ * Typecast to std::string operator.
+ * It simply converts the version numbers into a string of the form major.minor
+ * (if patch i 0) or major.minor.patch
+ */
+ operator std::string() const;
+
+ /**
+ * Assignment from std::string operator.
+ * Same as in the VersionStr(std::string v) constructor.
+ * Throws an exeption if the string does not parse.
+ */
+ void operator=(std::string v) throw(const char *);
+
+ /**
+ * Comparison operator.
+ * The version objects are sorted according to their major, minor and patch
+ * level numbers.
+ */
+ bool operator<(const VersionStr &other) const;
+ bool operator==(const VersionStr &other) const;
+ bool operator>(const VersionStr &other) const;
+ bool operator>=(const VersionStr &other) const;
+ bool operator<=(const VersionStr &other) const;
+
+
+ /**
+ * @return Major version number.
+ */
+ size_t major() const;
+
+ /**
+ * @return Minor version number.
+ */
+ size_t minor() const;
+
+ /**
+ * @return Patch level.
+ */
+ size_t patch() const;
+
+private:
+ void set(std::string v) throw(const char *);
+ size_t version[3];
+};
+
+#endif/*__PRACRO_VERSIONSTR_H__*/