diff options
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__*/  | 
