diff options
| -rw-r--r-- | src/configparser.cc | 45 | ||||
| -rw-r--r-- | src/configparser.h | 24 | ||||
| -rw-r--r-- | src/drumkitparser.cc | 409 | ||||
| -rw-r--r-- | src/drumkitparser.h | 39 | ||||
| -rw-r--r-- | src/instrumentparser.cc | 399 | ||||
| -rw-r--r-- | src/instrumentparser.h | 32 | ||||
| -rw-r--r-- | src/midimapparser.cc | 33 | ||||
| -rw-r--r-- | src/midimapparser.h | 22 | ||||
| -rw-r--r-- | src/saxparser.cc | 150 | ||||
| -rw-r--r-- | src/saxparser.h | 37 | 
10 files changed, 569 insertions, 621 deletions
| diff --git a/src/configparser.cc b/src/configparser.cc index 86219dd..e8a6d12 100644 --- a/src/configparser.cc +++ b/src/configparser.cc @@ -32,39 +32,40 @@  ConfigParser::ConfigParser()  { -  str = NULL; +	str = nullptr;  } -void ConfigParser::characterData(std::string &data) +void ConfigParser::characterData(const std::string& data)  { -  if(str) str->append(data); +	if(str) +	{ +		str->append(data); +	}  } -void ConfigParser::startTag(std::string name, attr_t attr) +void ConfigParser::startTag(const std::string& name, attr_t& attr)  { -  if(name == "value" && attr.find("name") != attr.end()) { -    values[attr["name"]] = ""; -    str = &values[attr["name"]]; -  } +	if(name == "value" && attr.find("name") != attr.end()) +	{ +		values[attr["name"]] = ""; +		str = &values[attr["name"]]; +	}  } -void ConfigParser::endTag(std::string name) +void ConfigParser::endTag(const std::string& name)  { -  if(name == "value") str = NULL; +	if(name == "value") +	{ +		str = nullptr; +	}  } -std::string ConfigParser::value(std::string name, std::string def) +std::string ConfigParser::value(const std::string& name, const std::string& def)  { -  if(values.find(name) == values.end()) return def; -  return values[name]; -} +	if(values.find(name) == values.end()) +	{ +		return def; +	} -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()); +	return values[name];  } diff --git a/src/configparser.h b/src/configparser.h index 9aba284..b33af85 100644 --- a/src/configparser.h +++ b/src/configparser.h @@ -24,26 +24,24 @@   *  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__ +#pragma once  #include <map>  #include "saxparser.h" -class ConfigParser : public SAXParser { +class ConfigParser : +	public SAXParser +{  public: -  ConfigParser(); +	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); +	void characterData(const std::string& data) override; +	void startTag(const std::string& name, attr_t& attr) override; +	void endTag(const std::string& name) override; +	std::string value(const std::string& name, const std::string& def = "");  private: -  std::map<std::string, std::string> values; -  std::string *str; +	std::map<std::string, std::string> values; +	std::string* str;  }; - -#endif/*__DRUMGIZMO_CONFIGPARSER_H__*/ diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc index e67d65e..eb0913a 100644 --- a/src/drumkitparser.cc +++ b/src/drumkitparser.cc @@ -34,244 +34,213 @@  #include "path.h"  #include "drumgizmo.h" -DrumKitParser::DrumKitParser(const std::string &file, DrumKit &k) -  : kit(k) -  , refs(REFSFILE) +DrumKitParser::DrumKitParser(const std::string& file, DrumKit& k) +	: kit(k) + 	, refs(REFSFILE)  { -  std::string kitfile = file; +	std::string kitfile = file; -  if(refs.load()) { -    if(file.size() > 1 && file[0] == '@') { -      kitfile = refs.getValue(file.substr(1)); -    } -  } else { -    ERR(drumkitparser, "Error reading refs.conf"); -  } +	if(refs.load()) +	{ +		if(file.size() > 1 && file[0] == '@') +		{ +			kitfile = refs.getValue(file.substr(1)); +		} +	} +	else +	{ +		ERR(drumkitparser, "Error reading refs.conf"); +	} -  //  instr = NULL; -  path = getPath(kitfile); +	//  instr = NULL; +	path = getPath(kitfile); -  fd = fopen(kitfile.c_str(), "r"); +	fd = fopen(kitfile.c_str(), "r"); -  //  DEBUG(kitparser, "Parsing drumkit in %s\n", kitfile.c_str()); +	//  DEBUG(kitparser, "Parsing drumkit in %s\n", kitfile.c_str()); -  if(!fd) return; +	if(!fd) +	{ +		return; +	} -  kit._file = file; +	kit._file = file;  }  DrumKitParser::~DrumKitParser()  { -  if(fd) fclose(fd); +	if(fd) +	{ +		fclose(fd); +	} +  } -void DrumKitParser::startTag(std::string name, -                             std::map<std::string, std::string> attr) +void DrumKitParser::startTag(const std::string& name, +                             attr_t& attr)  { -  if(name == "drumkit") { -    if(attr.find("name") != attr.end()) -      kit._name = attr["name"]; - -    if(attr.find("samplerate") != attr.end()) { -      kit._samplerate = atoi(attr["samplerate"].c_str()); -    } else { -      // If 'samplerate' attribute is missing, assume 44k1Hz -      // TODO: Ask instrument what samplerate is in the audiofiles... -      kit._samplerate = 44100; -    } - -    if(attr.find("description") != attr.end()) -      kit._description = attr["description"]; - -    if(attr.find("version") != attr.end()) { -      try { -        kit._version = VersionStr(attr["version"]); -      } catch(const char *err) { -        ERR(kitparser, "Error parsing version number: %s, using 1.0\n", err); -        kit._version = VersionStr(1,0,0); -      }  -    } else { -      WARN(kitparser, "Missing version number, assuming 1.0\n"); -      kit._version = VersionStr(1,0,0); -    } -  } - -  if(name == "channels") {} - -  if(name == "channel") { -    if(attr.find("name") == attr.end()) { -      DEBUG(kitparser, "Missing channel name.\n"); -      return; -    } -    Channel c(attr["name"]); -    c.num = kit.channels.size(); -    kit.channels.push_back(c); -  } - -  if(name == "instruments") { -  } - -  if(name == "instrument") { -    if(attr.find("name") == attr.end()) { -      DEBUG(kitparser, "Missing name in instrument tag.\n"); -      return; -    } -    if(attr.find("file") == attr.end()) { -      DEBUG(kitparser, "Missing file in instrument tag.\n"); -      return; -    } - -    instr_name = attr["name"]; -    instr_file = attr["file"]; -    if(attr.find("group") != attr.end()) instr_group = attr["group"]; -    else instr_group = ""; -  } - -  if(name == "channelmap") { -    if(attr.find("in") == attr.end()) { -      DEBUG(kitparser, "Missing 'in' in channelmap tag.\n"); -      return; -    } - -    if(attr.find("out") == attr.end()) { -      DEBUG(kitparser, "Missing 'out' in channelmap tag.\n"); -      return; -    } - -    channelmap[attr["in"]] = attr["out"]; -  } +	if(name == "drumkit") +	{ +		if(attr.find("name") != attr.end()) +		{ +			kit._name = attr["name"]; +		} + +		if(attr.find("samplerate") != attr.end()) +		{ +			kit._samplerate = std::stoi(attr["samplerate"]); +		} +		else +		{ +			// If 'samplerate' attribute is missing, assume 44k1Hz +			// TODO: Ask instrument what samplerate is in the audiofiles... +			kit._samplerate = 44100; +		} + +		if(attr.find("description") != attr.end()) +		{ +			kit._description = attr["description"]; +		} + +		if(attr.find("version") != attr.end()) +		{ +			try +			{ +				kit._version = VersionStr(attr["version"]); +			} +			catch(const char *err) +			{ +				ERR(kitparser, "Error parsing version number: %s, using 1.0\n", err); +				kit._version = VersionStr(1,0,0); +			}  +		} +		else +		{ +			WARN(kitparser, "Missing version number, assuming 1.0\n"); +			kit._version = VersionStr(1,0,0); +		} +	} + +	if(name == "channels") +	{ +	 +	} + +	if(name == "channel") +	{ +		if(attr.find("name") == attr.end()) +		{ +			ERR(kitparser, "Missing channel name.\n"); +			return; +		} + +		Channel c(attr["name"]); +		c.num = kit.channels.size(); +		kit.channels.push_back(c); +	} + +	if(name == "instruments") +	{ + +	} + +	if(name == "instrument") +	{ +		if(attr.find("name") == attr.end()) +		{ +			ERR(kitparser, "Missing name in instrument tag.\n"); +			return; +		} +		if(attr.find("file") == attr.end()) +		{ +			ERR(kitparser, "Missing file in instrument tag.\n"); +			return; +		} + +		instr_name = attr["name"]; +		instr_file = attr["file"]; +		if(attr.find("group") != attr.end()) +		{ +			instr_group = attr["group"]; +		} +		else +		{ +			instr_group = ""; +		} +	} + +	if(name == "channelmap") +	{ +		if(attr.find("in") == attr.end()) +		{ +			ERR(kitparser, "Missing 'in' in channelmap tag.\n"); +			return; +		} + +		if(attr.find("out") == attr.end()) +		{ +			ERR(kitparser, "Missing 'out' in channelmap tag.\n"); +			return; +		} + +		channelmap[attr["in"]] = attr["out"]; +	}  } -void DrumKitParser::endTag(std::string name) +void DrumKitParser::endTag(const std::string& name)  { -  if(name == "instrument") { -    Instrument *i = new Instrument(); -    i->setGroup(instr_group); -    //    Instrument &i = kit.instruments[kit.instruments.size() - 1]; -    InstrumentParser parser(path + "/" + instr_file, *i); -    parser.parse(); -    kit.instruments.push_back(i); - -    // Assign kit channel numbers to instruments channels. -    std::vector<InstrumentChannel*>::iterator ic = parser.channellist.begin(); -    while(ic != parser.channellist.end()) { -      InstrumentChannel *c = *ic; - -      std::string cname = c->name; -      if(channelmap.find(cname) != channelmap.end()) cname = channelmap[cname]; - -      for(size_t cnt = 0; cnt < kit.channels.size(); cnt++) { -        if(kit.channels[cnt].name == cname) c->num = kit.channels[cnt].num; -      } -      if(c->num == NO_CHANNEL) { -        DEBUG(kitparser, "Missing channel '%s' in instrument '%s'\n", -               c->name.c_str(), i->name().c_str()); -      } else { -        /* -          DEBUG(kitparser, "Assigned channel '%s' to number %d in instrument '%s'\n", -             c->name.c_str(), c->num, i.name().c_str()); -        */ -      } -      ic++; -    } - -    channelmap.clear(); - -  } +	if(name == "instrument") +	{ +		Instrument* i = new Instrument(); +		i->setGroup(instr_group); +		//    Instrument &i = kit.instruments[kit.instruments.size() - 1]; +		InstrumentParser parser(path + "/" + instr_file, *i); +		parser.parse(); +		kit.instruments.push_back(i); + +		// Assign kit channel numbers to instruments channels. +		std::vector<InstrumentChannel*>::iterator ic = parser.channellist.begin(); +		while(ic != parser.channellist.end()) +		{ +			InstrumentChannel* c = *ic; + +			std::string cname = c->name; +			if(channelmap.find(cname) != channelmap.end()) +			{ +				cname = channelmap[cname]; +			} + +			for(std::size_t cnt = 0; cnt < kit.channels.size(); cnt++) +			{ +				if(kit.channels[cnt].name == cname) +				{ +					c->num = kit.channels[cnt].num; +				} +			} +			if(c->num == NO_CHANNEL) +			{ +				ERR(kitparser, "Missing channel '%s' in instrument '%s'\n", +				      c->name.c_str(), i->name().c_str()); +			} +			else { +				/* +				   DEBUG(kitparser, "Assigned channel '%s' to number %d in instrument '%s'\n", +				   c->name.c_str(), c->num, i.name().c_str()); +				   */ +			} +			ic++; +		} + +		channelmap.clear(); +	}  } -int DrumKitParser::readData(char *data, size_t size) +int DrumKitParser::readData(std::string& data, std::size_t size)  { -  if(!fd) return -1; -  return fread(data, 1, size, fd); -} +	if(!fd) +	{ +		return -1; +	} -#ifdef TEST_DRUMKITPARSER -//deps: drumkit.cc saxparser.cc instrument.cc sample.cc audiofile.cc channel.cc -//cflags: $(EXPAT_CFLAGS) $(SNDFILE_CFLAGS) -//libs: $(EXPAT_LIBS) $(SNDFILE_LIBS) -#include "test.h" - -const char xml[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<drumkit name=\"The Aasimonster\"\n" -"         description=\"A large deathmetal drumkit\">\n" -"  <channels>\n" -"    <channel name=\"Alesis\"/>\n" -"    <channel name=\"Kick-L\"/>\n" -"    <channel name=\"Kick-R\"/>\n" -"    <channel name=\"SnareTop\"/>\n" -"    <channel name=\"SnareTrigger\"/>\n" -"    <channel name=\"SnareBottom\"/>\n" -"    <channel name=\"OH-L\"/>\n" -"    <channel name=\"OH-R\"/>\n" -"    <channel name=\"Hihat\"/>\n" -"    <channel name=\"Ride\"/>\n" -"    <channel name=\"Tom1\"/>\n" -"    <channel name=\"Tom2\"/>\n" -"    <channel name=\"Tom3\"/>\n" -"    <channel name=\"Tom4\"/>\n" -"    <channel name=\"Amb-R\"/>\n" -"    <channel name=\"Amb-L\"/>\n" -"  </channels>\n" -"  <instruments>\n" -"    <instrument name=\"Ride\" file=\"ride.xml\">\n" -"      <channelmap in=\"Alesis\" out=\"Alesis\" gain=\"1.5\"/>\n" -"      <channelmap in=\"Kick-L\" out=\"Kick-L\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Kick-R\" out=\"Kick-R\"/>\n" -"      <channelmap in=\"SnareTop\" out=\"SnareTop\" gain=\"0.5\"/>\n" -"      <channelmap in=\"SnareTrigger\" out=\"SnareTrigger\" gain=\"0.5\"/>\n" -"      <channelmap in=\"SnareBottom\" out=\"SnareBottom\" gain=\"0.5\"/>\n" -"      <channelmap in=\"OH-L\" out=\"OH-L\"/>\n" -"      <channelmap in=\"OH-R\" out=\"OH-R\"/>\n" -"      <channelmap in=\"Hihat\" out=\"Hihat\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Ride\" out=\"Ride\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Tom1\" out=\"Tom1\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Tom2\" out=\"Tom2\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Tom3\" out=\"Tom3\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Tom4\" out=\"Tom4\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Amb-R\" out=\"Amb-R\"/>\n" -"      <channelmap in=\"Amb-L\" out=\"Amb-L\"/>\n" -"    </instrument>\n" -"    <instrument name=\"Snare\" file=\"snare.xml\">\n" -"      <channelmap in=\"Alesis\" out=\"Alesis\" gain=\"1.5\"/>\n" -"      <channelmap in=\"Kick-L\" out=\"Kick-L\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Kick-R\" out=\"Kick-R\"/>\n" -"      <channelmap in=\"SnareTop\" out=\"SnareTop\" gain=\"0.5\"/>\n" -"      <channelmap in=\"SnareTrigger\" out=\"SnareTrigger\" gain=\"0.5\"/>\n" -"      <channelmap in=\"SnareBottom\" out=\"SnareBottom\" gain=\"0.5\"/>\n" -"      <channelmap in=\"OH-L\" out=\"OH-L\"/>\n" -"      <channelmap in=\"OH-R\" out=\"OH-R\"/>\n" -"      <channelmap in=\"Hihat\" out=\"Hihat\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Ride\" out=\"Ride\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Tom1\" out=\"Tom1\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Tom2\" out=\"Tom2\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Tom3\" out=\"Tom3\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Tom4\" out=\"Tom4\" gain=\"0.5\"/>\n" -"      <channelmap in=\"Amb-R\" out=\"Amb-R\"/>\n" -"      <channelmap in=\"Amb-L\" out=\"Amb-L\"/>\n" -"    </instrument>\n" -"  </instruments>\n" -"</drumkit>\n" -  ; - -#define FNAME "/tmp/drumkittest.xml" - -TEST_BEGIN; - -FILE *fp = fopen(FNAME, "w"); -fprintf(fp, "%s", xml); -fclose(fp); - -DrumKit kit; -DrumKitParser p(FNAME, kit); -TEST_EQUAL_INT(p.parse(), 0, "Parsing went well?"); - -TEST_EQUAL_STR(kit.name(), "The Aasimonster", "Compare name"); -TEST_EQUAL_INT(kit.instruments.size(), 2, "How many instruments?"); - -unlink(FNAME); - -TEST_END; - -#endif/*TEST_DRUMKITPARSER*/ +	return fread((char*)data.c_str(), 1, size, fd); +} diff --git a/src/drumkitparser.h b/src/drumkitparser.h index d9ec4fe..5c97b4e 100644 --- a/src/drumkitparser.h +++ b/src/drumkitparser.h @@ -24,37 +24,34 @@   *  along with DrumGizmo; if not, write to the Free Software   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.   */ -#ifndef __DRUMGIZMO_DRUMKITPARSER_H__ -#define __DRUMGIZMO_DRUMKITPARSER_H__ +#pragma once  #include "saxparser.h"  #include "drumkit.h"  #include "configfile.h" -class DrumKitParser : public SAXParser { +class DrumKitParser +	: public SAXParser +{  public: -  DrumKitParser(const std::string &kitfile, DrumKit &kit); -  ~DrumKitParser(); - -  void startTag(std::string name, -                std::map< std::string, std::string> attributes); -  void endTag(std::string name); +	DrumKitParser(const std::string& kitfile, DrumKit& kit); +	~DrumKitParser();  protected: -  int readData(char *data, size_t size); +	void startTag(const std::string& name, attr_t& attributes) override; +	void endTag(const std::string& name) override; + +	int readData(std::string& data, std::size_t size) override;  private: -  FILE *fd; -  DrumKit &kit; -  //  Instrument *instr; -  std::string path; +	FILE* fd; +	DrumKit& kit; +	std::string path; -  std::map<std::string, std::string> channelmap; -  std::string instr_file; -  std::string instr_name; -  std::string instr_group; +	std::map<std::string, std::string> channelmap; +	std::string instr_file; +	std::string instr_name; +	std::string instr_group; -  ConfigFile refs; +	ConfigFile refs;  }; - -#endif/*__DRUMGIZMO_DRUMKITPARSER_H__*/ diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc index 5d6acef..c04aee3 100644 --- a/src/instrumentparser.cc +++ b/src/instrumentparser.cc @@ -35,228 +35,207 @@  #include "nolocale.h" -InstrumentParser::InstrumentParser(const std::string &file, Instrument &i) -  : instrument(i) +InstrumentParser::InstrumentParser(const std::string& file, Instrument& i) +	: instrument(i)  { -  s = NULL; -  //  DEBUG(instrparser,"Parsing instrument in %s\n", file.c_str()); -  path = getPath(file); -  fd = fopen(file.c_str(), "r"); -  if(!fd) return; +	//  DEBUG(instrparser,"Parsing instrument in %s\n", file.c_str()); +	path = getPath(file); +	fd = fopen(file.c_str(), "r"); + +	if(!fd) +	{ +		ERR(instrparser, "The following instrument file could not be opened: %s\n", file.c_str()); +		return; +	}  }  InstrumentParser::~InstrumentParser()  { -  if(fd) fclose(fd); +	if(fd) +	{ +		fclose(fd); +	}  } -void InstrumentParser::startTag(std::string name, -                                std::map<std::string, std::string> attr) +void InstrumentParser::startTag(const std::string& name, attr_t& attr)  { -  if(name == "instrument") { -    if(attr.find("name") != attr.end()) -      instrument._name = attr["name"]; - -    if(attr.find("description") != attr.end()) -      instrument._description = attr["description"]; - -    if(attr.find("version") != attr.end()) { -      try { -        instrument.version = VersionStr(attr["version"]); -      } catch(const char *err) { -        ERR(instrparser, "Error parsing version number: %s, using 1.0\n", err); -        instrument.version = VersionStr(1,0,0); -      }  -    } else { -      WARN(instrparser, "Missing version number, assuming 1.0\n"); -      instrument.version = VersionStr(1,0,0); -    } -  } - -  if(name == "samples") { -  } - -  if(name == "sample") { -    if(attr.find("name") == attr.end()) { -      DEBUG(instrparser,"Missing required attribute 'name'.\n"); -      return; -    } -    -    float power;  -    if(attr.find("power") == attr.end()) { -      power = -1;  -    } else { -      power = atof_nol(attr["power"].c_str()); -      DEBUG(instrparser, "Instrument power set to %f\n", power); -    } -     -    // TODO get rid of new or delete it properly -    s = new Sample(attr["name"], power); -  } - -  if(name == "audiofile") { -    if(s == NULL) { -      DEBUG(instrparser,"Missing Sample!\n"); -      return; -    } -     -    if(attr.find("file") == attr.end()) { -      DEBUG(instrparser,"Missing required attribute 'file'.\n"); -      return; -    } - -    if(attr.find("channel") == attr.end()) { -      DEBUG(instrparser,"Missing required attribute 'channel'.\n"); -      return; -    } -    int filechannel = 1; // default, override with optional attribute -    if(attr.find("filechannel") != attr.end()) { -        filechannel = atoi(attr["filechannel"].c_str()); -        if(filechannel < 1) { -            DEBUG(instrparser,"Invalid value for attribute 'filechannel'.\n"); -            filechannel = 1; -        } -    } -    filechannel = filechannel - 1; // 1-based in file, but zero-based internally -    // TODO do those next two lines correspond with proper deletes? If not fix it. -    AudioFile *af = new AudioFile(path + "/" + attr["file"], filechannel); -    InstrumentChannel *ch = new InstrumentChannel(attr["channel"]); -    channellist.push_back(ch); -    s->addAudioFile(ch, af); -    instrument.audiofiles.push_back(af); -  } - -  if(name == "velocities") { -  } - -  if(name == "velocity") { -    if(attr.find("lower") == attr.end()) { -      DEBUG(instrparser,"Missing required attribute 'lower'.\n"); -      return; -    } - -    if(attr.find("upper") == attr.end()) { -      DEBUG(instrparser,"Missing required attribute 'upper'.\n"); -      return; -    } - -    lower = atof_nol(attr["lower"].c_str()); -    upper = atof_nol(attr["upper"].c_str()); -  } - -  if(name == "sampleref") { -    if(attr.find("name") == attr.end()) { -      DEBUG(instrparser,"Missing required attribute 'name'.\n"); -      return; -    } - -    Sample *sample = NULL; -    std::vector<Sample *>::iterator i = instrument.samplelist.begin(); -    while(i != instrument.samplelist.end()) { -      if((*i)->name == attr["name"]) { -        sample = *i; -        break; -      } -      i++; -    } - -    if(sample == NULL) { -      DEBUG(instrparser,"Samplref pointed at non-existing sample.\n"); -      return; -    } - -    if(instrument.version == VersionStr("1.0")) { -      // Old "velocity group" algorithm needs this -      instrument.addSample(lower, upper, sample); -    } -  } +	if(name == "instrument") +	{ +		if(attr.find("name") != attr.end()) +		{ +			instrument._name = attr["name"]; +		} + +		if(attr.find("description") != attr.end()) +		{ +			instrument._description = attr["description"]; +		} + +		if(attr.find("version") != attr.end()) +		{ +			try { +				instrument.version = VersionStr(attr["version"]); +			} +			catch(const char *err) +			{ +				ERR(instrparser, "Error parsing version number: %s, using 1.0\n", err); +				instrument.version = VersionStr(1,0,0); +			}  +		} +		else +		{ +			WARN(instrparser, "Missing version number, assuming 1.0\n"); +			instrument.version = VersionStr(1,0,0); +		} +	} + +	if(name == "samples") +	{ + +	} + +	if(name == "sample") +	{ +		if(attr.find("name") == attr.end()) +		{ +			ERR(instrparser,"Missing required attribute 'name'.\n"); +			return; +		} + +		float power;  +		if(attr.find("power") == attr.end()) +		{ +			power = -1;  +		} +		else +		{ +			power = atof_nol(attr["power"].c_str()); +			DEBUG(instrparser, "Instrument power set to %f\n", power); +		} + +		// TODO get rid of new or delete it properly +		s = new Sample(attr["name"], power); +	} + +	if(name == "audiofile") +	{ +		if(s == nullptr) +		{ +			ERR(instrparser,"Missing Sample!\n"); +			return; +		} + +		if(attr.find("file") == attr.end()) +		{ +			ERR(instrparser,"Missing required attribute 'file'.\n"); +			return; +		} + +		if(attr.find("channel") == attr.end()) +		{ +			ERR(instrparser,"Missing required attribute 'channel'.\n"); +			return; +		} + +		int filechannel = 1; // default, override with optional attribute +		if(attr.find("filechannel") != attr.end()) +		{ +			filechannel = std::stoi(attr["filechannel"]); +			if(filechannel < 1) +			{ +				ERR(instrparser,"Invalid value for attribute 'filechannel'.\n"); +				filechannel = 1; +			} +		} + +		filechannel = filechannel - 1; // 1-based in file, but zero-based internally +		// TODO do those next two lines correspond with proper deletes? If not fix it. +		AudioFile *af = new AudioFile(path + "/" + attr["file"], filechannel); +		InstrumentChannel *ch = new InstrumentChannel(attr["channel"]); +		channellist.push_back(ch); +		s->addAudioFile(ch, af); +		instrument.audiofiles.push_back(af); +	} + +	if(name == "velocities") +	{ + +	} + +	if(name == "velocity") +	{ +		if(attr.find("lower") == attr.end()) +		{ +			ERR(instrparser,"Missing required attribute 'lower'.\n"); +			return; +		} + +		if(attr.find("upper") == attr.end()) +		{ +			ERR(instrparser,"Missing required attribute 'upper'.\n"); +			return; +		} + +		lower = atof_nol(attr["lower"].c_str()); +		upper = atof_nol(attr["upper"].c_str()); +	} + +	if(name == "sampleref") +	{ +		if(attr.find("name") == attr.end()) +		{ +			ERR(instrparser,"Missing required attribute 'name'.\n"); +			return; +		} + +		Sample* sample = nullptr; +		std::vector<Sample *>::iterator i = instrument.samplelist.begin(); +		while(i != instrument.samplelist.end()) +		{ +			if((*i)->name == attr["name"]) +			{ +				sample = *i; +				break; +			} +			i++; +		} + +		if(sample == nullptr) +		{ +			ERR(instrparser,"Samplref pointed at non-existing sample.\n"); +			return; +		} + +		if(instrument.version == VersionStr("1.0")) +		{ +			// Old "velocity group" algorithm needs this +			instrument.addSample(lower, upper, sample); +		} +	}  } -void InstrumentParser::endTag(std::string name) +void InstrumentParser::endTag(const std::string& name)  { -  if(name == "sample") { -    if(s == NULL) { -      DEBUG(instrparser,"Missing Sample.\n"); -      return; -    } - -    instrument.samplelist.push_back(s); - -    s = NULL; -  } - -  if(name == "instrument") { -    instrument.finalise(); -  } +	if(name == "sample") +	{ +		if(s == nullptr) +		{ +			ERR(instrparser,"Missing Sample.\n"); +			return; +		} + +		instrument.samplelist.push_back(s); + +		s = nullptr; +	} + +	if(name == "instrument") { +		instrument.finalise(); +	}  } -int InstrumentParser::readData(char *data, size_t size) +int InstrumentParser::readData(std::string& data, std::size_t size)  { -  if(!fd) return -1; -  return fread(data, 1, size, fd); +	if(!fd) return -1; +	return fread((char*)data.c_str(), 1, size, fd);  } - - -#ifdef TEST_INSTRUMENTPARSER -//deps: saxparser.cc instrument.cc sample.cc audiofile.cc channel.cc -//cflags: $(EXPAT_CFLAGS) $(SNDFILE_CFLAGS) -//libs: $(EXPAT_LIBS) $(SNDFILE_LIBS) -#include "test.h" - -const char xml[] =  -"<?xml version='1.0' encoding='UTF-8'?>\n" -"<instrument name=\"kick-r\">\n" -" <samples>\n" -"  <sample name=\"kick-r-1\">\n" -"   <audiofile channel=\"Alesis\" file=\"samples/1-kick-r-Alesis-3.wav\"/>\n" -"   <audiofile channel=\"Amb L\" file=\"samples/1-kick-r-Amb L-3.wav\"/>\n" -"   <audiofile channel=\"Amb R\" file=\"samples/1-kick-r-Amb R-3.wav\"/>\n" -"   <audiofile channel=\"Kick L\" file=\"samples/1-kick-r-Kick L-3.wav\"/>\n" -"   <audiofile channel=\"Kick R\" file=\"samples/1-kick-r-Kick R-3.wav\"/>\n" -"  </sample>\n" -"  <sample name=\"kick-r-2\">\n" -"   <audiofile channel=\"Alesis\" file=\"samples/2-kick-r-Alesis-3.wav\"/>\n" -"   <audiofile channel=\"Amb L\" file=\"samples/2-kick-r-Amb L-3.wav\"/>\n" -"   <audiofile channel=\"Amb R\" file=\"samples/2-kick-r-Amb R-3.wav\"/>\n" -"   <audiofile channel=\"Kick L\" file=\"samples/2-kick-r-Kick L-3.wav\"/>\n" -"   <audiofile channel=\"Kick R\" file=\"samples/2-kick-r-Kick R-3.wav\"/>\n" -"  </sample>\n" -"  <sample name=\"kick-r-3\">\n" -"   <audiofile channel=\"Alesis\" file=\"samples/3-kick-r-Alesis-3.wav\"/>\n" -"   <audiofile channel=\"Amb L\" file=\"samples/3-kick-r-Amb L-3.wav\"/>\n" -"   <audiofile channel=\"Amb R\" file=\"samples/3-kick-r-Amb R-3.wav\"/>\n" -"   <audiofile channel=\"Kick L\" file=\"samples/3-kick-r-Kick L-3.wav\"/>\n" -"   <audiofile channel=\"Kick R\" file=\"samples/3-kick-r-Kick R-3.wav\"/>\n" -"  </sample>\n" -" </samples>\n" -" <velocities>\n" -"  <velocity lower=\"0\" upper=\"0.7\">\n" -"   <sampleref name=\"kick-r-1\"/>\n" -"   <sampleref name=\"kick-r-2\"/>\n" -"  </velocity>\n" -"  <velocity lower=\"0.7\" upper=\"1.0\">\n" -"   <sampleref name=\"kick-r-3\"/>\n" -"  </velocity>\n" -" </velocities>\n" -"</instrument>\n" -  ; - -#define FNAME "/tmp/instrtest.xml" - -TEST_BEGIN; - -FILE *fp = fopen(FNAME, "w"); -fprintf(fp, "%s", xml); -fclose(fp); - -Instrument instr; -InstrumentParser p(FNAME, instr); -TEST_EQUAL_INT(p.parse(), 0, "Parsing went well?"); - -TEST_EQUAL_STR(instr.name(), "kick-r", "Compare name"); - -unlink(FNAME); - -TEST_END; - -#endif/*TEST_INSTRUMENTPARSER*/ diff --git a/src/instrumentparser.h b/src/instrumentparser.h index 4971922..15fadef 100644 --- a/src/instrumentparser.h +++ b/src/instrumentparser.h @@ -24,37 +24,35 @@   *  along with DrumGizmo; if not, write to the Free Software   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.   */ -#ifndef __DRUMGIZMO_INSTRUMENTPARSER_H__ -#define __DRUMGIZMO_INSTRUMENTPARSER_H__ +#pragma once  #include "saxparser.h"  #include "instrument.h"  #include <vector> -class InstrumentParser : public SAXParser { +class InstrumentParser +	: public SAXParser +{  public: -  InstrumentParser(const std::string &instrfile, Instrument &instrument); -  ~InstrumentParser(); +	InstrumentParser(const std::string& instrfile, Instrument &instrument); +	~InstrumentParser(); -  void startTag(std::string name, -                std::map< std::string, std::string> attributes); -  void endTag(std::string name); - -  std::vector<InstrumentChannel *> channellist; +	std::vector<InstrumentChannel*> channellist;  protected: -  int readData(char *data, size_t size); +	int readData(std::string& data, std::size_t size) override; + +	virtual void startTag(const std::string& name, attr_t& attr) override; +	virtual void endTag(const std::string& name) override;  private: -	FILE *fd{nullptr}; -  Instrument &instrument; -	Sample *s{nullptr}; +	FILE* fd{nullptr}; +	Instrument& instrument; +	Sample* s{nullptr}; -  std::string path; +	std::string path;  	level_t lower{0};  	level_t upper{0};  }; - -#endif/*__DRUMGIZMO_INSTRUMENTPARSER_H__*/ diff --git a/src/midimapparser.cc b/src/midimapparser.cc index e81b871..3c8eed4 100644 --- a/src/midimapparser.cc +++ b/src/midimapparser.cc @@ -26,27 +26,36 @@   */  #include "midimapparser.h" -MidiMapParser::MidiMapParser(std::string file) +MidiMapParser::MidiMapParser(const std::string& file)  { -  fd = fopen(file.c_str(), "r"); +	fd = fopen(file.c_str(), "r");  }  MidiMapParser::~MidiMapParser()  { -  if(fd) fclose(fd); +	if(fd) +	{ +		fclose(fd); +	}  } -void MidiMapParser::startTag(std::string name, attr_t attr) +void MidiMapParser::startTag(const 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"]; -    } -  } +	if(name == "map") +	{ +		if(attr.find("note") != attr.end() && attr.find("instr") != attr.end()) +		{ +			midimap[std::stoi(attr["note"])] = attr["instr"]; +		} +	}  } -int MidiMapParser::readData(char *data, size_t size) +int MidiMapParser::readData(std::string& data, std::size_t size)  { -  if(!fd) return -1; -  return fread(data, 1, size, fd); +	if(!fd) +	{ +		return -1; +	} + +	return fread((char*)data.c_str(), 1, size, fd);  } diff --git a/src/midimapparser.h b/src/midimapparser.h index 32cd9e8..67a0b4a 100644 --- a/src/midimapparser.h +++ b/src/midimapparser.h @@ -24,29 +24,27 @@   *  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__ +#pragma once  #include <stdio.h>  #include "saxparser.h" -  #include "midimapper.h" -class MidiMapParser : public SAXParser { +class MidiMapParser +	: public SAXParser +{  public: -  MidiMapParser(std::string file); -  ~MidiMapParser(); +	MidiMapParser(const std::string& file); +	~MidiMapParser(); -  void startTag(std::string name, attr_t attr); +	void startTag(const std::string& name, attr_t& attr) override; -  midimap_t midimap; +	midimap_t midimap;  protected: -  int readData(char *data, size_t size); +	int readData(std::string& data, size_t size) override;  private: -  FILE *fd; +	FILE* fd;  }; - -#endif/*__DRUMGIZMO_MIDIMAPPARSER_H__*/ diff --git a/src/saxparser.cc b/src/saxparser.cc index f163dfc..5c28962 100644 --- a/src/saxparser.cc +++ b/src/saxparser.cc @@ -30,106 +30,102 @@  #include <string.h>  #include <hugin.hpp> -static void character_hndl(void *p, const XML_Char *s, int len) +SAXParser::SAXParser()  { -  SAXParser *parser = (SAXParser*)XML_GetUserData(p); -  std::string chars; -  chars.append(s, len); -  parser->characterData(chars); +	p = XML_ParserCreate(nullptr); +	if(!p) { +		ERR(sax, "Couldn't allocate memory for parser\n"); +		// throw Exception(...); TODO +		return; +	} + +	XML_SetUserData(p, this); +	XML_UseParserAsHandlerArg(p); +	XML_SetElementHandler(p, start_hndl, end_hndl); +	XML_SetCharacterDataHandler(p, character_hndl);  } -static void start_hndl(void *p, const char *el, const char **attr) +SAXParser::~SAXParser()  { -  SAXParser *parser = (SAXParser*)XML_GetUserData(p); +	XML_ParserFree(p); +} -  // Convert to comfy C++ values... -  std::string name = el; -  std::map< std::string, std::string > attributes; +int SAXParser::parse() +{ +	DEBUG(sax, "parse()\n"); + +	std::string buf; +	int len; + +	do { +		len = readData(buf, 32); +		if(len <= -1) { +			parseError("", 0, "Could not read data", 0); +			return 1; +		} +		if(!XML_Parse(p, (char*)buf.c_str(), len, len == 0)) { +			parseError(buf, len, XML_ErrorString(XML_GetErrorCode(p)), +				   (int)XML_GetCurrentLineNumber(p)); +			return 1; +		} + +		buf.clear(); +	} while(len); + +	return 0; +} -  while(*attr) { -    std::string at_name = *attr; -    attr++; -    std::string at_value = *attr; -    attr++; +int SAXParser::parse(const std::string& buffer) +{ +	DEBUG(sax, "parse(buffer %d bytes)\n", (int)buffer.length()); -    attributes.insert(make_pair(at_name, at_value)); -  } +	if(!XML_Parse(p, buffer.c_str(), buffer.length(), true)) { +		parseError(buffer, buffer.length(), +			   XML_ErrorString(XML_GetErrorCode(p)), +			   (int)XML_GetCurrentLineNumber(p)); +		return 1; +	} -  parser->startTag(name, attributes); +	return 0;  } -static void end_hndl(void *p, const char *el) +void SAXParser::parseError(const std::string& buf, std::size_t len, const std::string& error, std::size_t lineno)  { -  SAXParser *parser = (SAXParser*)XML_GetUserData(p); -  std::string name = el; -  parser->endTag(name); -} +	fprintf(stderr, "SAXParser error at line %d: %s\n", (int)lineno, error.c_str()); +	fprintf(stderr, "Buffer %u bytes: \n[\n", (int)len); +	fwrite((char*)buf.c_str(), len, 1, stderr); -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); +	fprintf(stderr, "\n]\n"); +	fflush(stderr);  } -SAXParser::~SAXParser() +void SAXParser::character_hndl(void* p, const XML_Char* s, int len)  { -  XML_ParserFree(p); +	SAXParser* parser = (SAXParser*)XML_GetUserData(p); +	std::string chars(s, len); +	parser->characterData(chars);  } -int SAXParser::parse() +void SAXParser::start_hndl(void* p, const char* el, const char** attr)  { -  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; -} +	SAXParser* parser = (SAXParser*)XML_GetUserData(p); -int SAXParser::parse(std::string buffer) -{ -  DEBUG(sax, "parse(buffer %d bytes)\n", (int)buffer.length()); +	// Convert to comfy C++ values... +	attr_t attributes; + +	while(*attr) { +		std::string at_name = *attr++; +		std::string at_value = *attr++; -  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; -  } +		attributes.emplace(at_name, at_value); +	} -  return 0; +	parser->startTag(std::string(el), attributes);  } -void SAXParser::parseError(char *buf, size_t len, std::string error, int lineno) +void SAXParser::end_hndl(void* p, const char* el)  { -  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); +	SAXParser* parser = (SAXParser*)XML_GetUserData(p); +	parser->endTag(std::string(el));  } diff --git a/src/saxparser.h b/src/saxparser.h index 6acbcdc..680df1d 100644 --- a/src/saxparser.h +++ b/src/saxparser.h @@ -24,34 +24,37 @@   *  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__ +#pragma once  #include <string>  #include <map>  #include <expat.h> -typedef std::map< std::string, std::string> attr_t; -  class SAXParser {  public: -  SAXParser(); -  virtual ~SAXParser(); +	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) {} +	//! Parses the data obtained by readData in chunks. +	int parse(); -  virtual void parseError(char *buf, size_t len, std::string error, int lineno); +	//! Parses all the data in the buffer. +	int parse(const std::string& buffer);  protected: -  virtual int readData(char *data, size_t size) { return 0; } +	using attr_t = std::map<std::string, std::string>; + +	virtual void characterData(const std::string& data) {} +	virtual void startTag(const std::string& name, attr_t& attr) {} +	virtual void endTag(const std::string& name) {} +	virtual void parseError(const std::string& buf, std::size_t len, const std::string& error, std::size_t lineno); + +	virtual int readData(std::string& data, std::size_t size) { return 0; }  private: -  XML_Parser p; -}; +	XML_Parser p; -#endif/*__DRUMGIZMO_SAXPARSER_H__*/ +	static void character_hndl(void* p, const XML_Char* s, int len); +	static void start_hndl(void* p, const char* el, const char** attr); +	static void end_hndl(void* p, const char* el); +}; | 
