diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2015-09-20 11:36:22 +0200 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2015-09-20 11:36:22 +0200 |
commit | 24bb55371a5d8d81b23521ebdfcde68f0035697c (patch) | |
tree | 61cf42dc518420738262dcc9ccf75e932a63136f /src |
Basic project based on DrumGizmo.
Diffstat (limited to 'src')
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__*/ |