diff options
Diffstat (limited to 'src/instrumentparser.cc')
-rw-r--r-- | src/instrumentparser.cc | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc new file mode 100644 index 0000000..5198959 --- /dev/null +++ b/src/instrumentparser.cc @@ -0,0 +1,219 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * instrumentparser.cc + * + * Wed Mar 9 13:22:24 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. + */ +#include "instrumentparser.h" + +#include <string.h> +#include <stdio.h> + +#include "path.h" + +InstrumentParser::InstrumentParser(const std::string &file, Instrument &i) + : instrument(i) +{ + s = NULL; + printf("Parsing instrument in %s\n", file.c_str()); + path = getPath(file); + fd = fopen(file.c_str(), "r"); + if(!fd) return; +} + +InstrumentParser::~InstrumentParser() +{ + if(fd) fclose(fd); +} + +void InstrumentParser::startTag(std::string name, + std::map< std::string, std::string> 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(name == "samples") { + } + + if(name == "sample") { + if(attr.find("name") == attr.end()) { + printf("Missing required attribute 'name'.\n"); + return; + } + s = new Sample(attr["name"]); + } + + if(name == "audiofile") { + if(s == NULL) { + printf("Missing Sample!\n"); + return; + } + + if(attr.find("file") == attr.end()) { + printf("Missing required attribute 'file'.\n"); + return; + } + + if(attr.find("channel") == attr.end()) { + printf("Missing required attribute 'channel'.\n"); + return; + } + + AudioFile *af = new AudioFile(path + "/" + attr["file"]); + 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()) { + printf("Missing required attribute 'lower'.\n"); + return; + } + + if(attr.find("upper") == attr.end()) { + printf("Missing required attribute 'upper'.\n"); + return; + } + + lower = atof(attr["lower"].c_str()); + upper = atof(attr["upper"].c_str()); + } + + if(name == "sampleref") { + if(attr.find("name") == attr.end()) { + printf("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) { + printf("Samplref pointed at non-existing sample.\n"); + return; + } + + instrument.addSample(lower, upper, sample); + } +} + +void InstrumentParser::endTag(std::string name) +{ + if(name == "sample") { + if(s == NULL) { + printf("Missing Sample.\n"); + return; + } + + instrument.samplelist.push_back(s); + s = NULL; + } +} + +int InstrumentParser::readData(char *data, size_t size) +{ + if(!fd) return -1; + return fread(data, 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*/ |