summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2008-07-22 21:00:01 +0000
committerdeva <deva>2008-07-22 21:00:01 +0000
commitf6cabfe8fe888e00388a815541084b0fa332a462 (patch)
treed39301b9e194e2e58a24c92ec5526d05fa1b4a3a
parent14309bc447960536c34a438dffb93f520dad40fa (diff)
DrumKit parser. Internal drumkit now used in events. This is the first milestone.
-rw-r--r--src/Makefile.am19
-rw-r--r--src/audiofile.cc77
-rw-r--r--src/audiofile.h49
-rw-r--r--src/channel.cc33
-rw-r--r--src/channel.h41
-rw-r--r--src/drumgizmo.cc7
-rw-r--r--src/drumkit.h53
-rw-r--r--src/drumkitparser.cc106
-rw-r--r--src/drumkitparser.h55
-rw-r--r--src/event.cc3
-rw-r--r--src/event.h6
-rw-r--r--src/instrument.cc48
-rw-r--r--src/instrument.h54
-rw-r--r--src/jackclient.cc99
-rw-r--r--src/jackclient.h6
-rw-r--r--src/midimapper.cc46
-rw-r--r--src/midimapper.h7
-rw-r--r--src/sample.cc18
-rw-r--r--src/sample.h13
-rw-r--r--src/saxparser.cc110
-rw-r--r--src/saxparser.h54
-rw-r--r--src/velocity.cc59
-rw-r--r--src/velocity.h49
23 files changed, 895 insertions, 117 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 472f5fe..7bcc60b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,14 +5,27 @@ drumgizmo_LDADD = $(JACK_LIBS) $(SNDFILE_LIBS)
drumgizmo_CXXFLAGS = $(JACK_CXXFLAGS) $(SNDFILE_CXXFLAGS)
drumgizmo_SOURCES = \
+ audiofile.cc \
+ channel.cc \
drumgizmo.cc \
+ drumkitparser.cc \
event.cc \
+ instrument.cc \
jackclient.cc \
midimapper.cc \
- sample.cc
+ sample.cc \
+ saxparser.cc \
+ velocity.cc
EXTRA_DIST = \
- jackclient.h \
+ audiofile.h \
+ channel.h \
+ drumkit.h \
+ drumkitparser.h \
event.h \
+ instrument.h \
+ jackclient.h \
midimapper.h \
- sample.h
+ sample.h \
+ saxparser.h \
+ velocity.h
diff --git a/src/audiofile.cc b/src/audiofile.cc
new file mode 100644
index 0000000..1c6ac86
--- /dev/null
+++ b/src/audiofile.cc
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiofile.cc
+ *
+ * Tue Jul 22 17:14:11 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 "audiofile.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sndfile.h>
+
+AudioFile::AudioFile(std::string filename)
+{
+ this->filename = filename;
+ data = NULL;
+ size = 0;
+ // load();
+}
+
+AudioFile::~AudioFile()
+{
+ unload();
+}
+
+void AudioFile::unload()
+{
+ if(!data) return;
+
+ free(data);
+ data = NULL;
+ size = 0;
+}
+
+void AudioFile::load()
+{
+ if(data) return;
+
+ filename = "/tmp/aasimonster/" + filename;
+
+ SF_INFO sf_info;
+ SNDFILE *fh = sf_open(filename.c_str(), SFM_READ, &sf_info);
+
+ size = sf_seek(fh, 0, SEEK_END);
+ data = (jack_default_audio_sample_t*)malloc(sizeof(jack_default_audio_sample_t)*size);
+
+ printf("Loading %s, %d samples\n", filename.c_str(), size);
+
+ sf_seek(fh, 0, SEEK_SET);
+ sf_read_float(fh, data, size);
+
+ for(size_t i = 0; i < size; i++) data[i] *= 0.1;
+
+ sf_close(fh);
+}
+
diff --git a/src/audiofile.h b/src/audiofile.h
new file mode 100644
index 0000000..b716a8c
--- /dev/null
+++ b/src/audiofile.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiofile.h
+ *
+ * Tue Jul 22 17:14:11 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_AUDIOFILE_H__
+#define __DRUMGIZMO_AUDIOFILE_H__
+
+#include <jack/jack.h>
+#include <string>
+
+class AudioFile {
+public:
+ AudioFile(std::string filename);
+ ~AudioFile();
+
+ void load();
+ void unload();
+
+ jack_default_audio_sample_t *data;
+ size_t size;
+ std::string channel;
+
+private:
+ std::string filename;
+};
+
+#endif/*__DRUMGIZMO_AUDIOFILE_H__*/
diff --git a/src/channel.cc b/src/channel.cc
new file mode 100644
index 0000000..93a0715
--- /dev/null
+++ b/src/channel.cc
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * channel.cc
+ *
+ * Tue Jul 22 17:14:28 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 "channel.h"
+
+Channel::Channel(std::string name)
+{
+ this->name = name;
+ this->port = NULL;
+}
diff --git a/src/channel.h b/src/channel.h
new file mode 100644
index 0000000..4c512d5
--- /dev/null
+++ b/src/channel.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * channel.h
+ *
+ * Tue Jul 22 17:14:27 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_CHANNEL_H__
+#define __DRUMGIZMO_CHANNEL_H__
+
+#include <string>
+#include <jack/jack.h>
+
+class Channel {
+public:
+ Channel(std::string name);
+
+ std::string name;
+ jack_port_t *port;
+};
+
+#endif/*__DRUMGIZMO_CHANNEL_H__*/
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index 936c231..649b364 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -26,6 +26,8 @@
*/
#include "jackclient.h"
+#include "drumkitparser.h"
+
#include <jack/jack.h>
#include <jack/midiport.h>
@@ -79,7 +81,10 @@ void sendMidi()
int main(int argc, char *argv[])
{
- JackClient client;
+ DrumKitParser parser("/tmp/aasimonster/aasimonster.xml");
+ if(parser.parse()) return 1;
+
+ JackClient client(parser.getDrumkit());
client.activate();
diff --git a/src/drumkit.h b/src/drumkit.h
new file mode 100644
index 0000000..caf1dc2
--- /dev/null
+++ b/src/drumkit.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * drumkit.h
+ *
+ * Tue Jul 22 16:29:16 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_DRUMKIT_H__
+#define __DRUMGIZMO_DRUMKIT_H__
+
+#include <map>
+#include <string>
+
+#include "sample.h"
+#include "instrument.h"
+#include "channel.h"
+
+typedef std::map< std::string, Channel* > Channels;
+typedef std::map< std::string, Sample* > Samples;
+
+typedef unsigned int midi_note_t;
+typedef std::map< midi_note_t, Instrument* > Instruments;
+
+class DrumKit {
+public:
+ std::string name;
+ std::string description;
+
+ Channels channels;
+ Samples samples;
+ Instruments instruments;
+};
+
+#endif/*__DRUMGIZMO_DRUMKIT_H__*/
diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc
new file mode 100644
index 0000000..14e4a88
--- /dev/null
+++ b/src/drumkitparser.cc
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * drumkitparser.cc
+ *
+ * Tue Jul 22 16:24:59 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 "drumkitparser.h"
+
+DrumKitParser::DrumKitParser(char *file)
+{
+ dk = NULL;
+ fd = fopen(file, "r");
+ if(!fd) return;
+ dk = new DrumKit();
+}
+
+DrumKitParser::~DrumKitParser()
+{
+ if(dk) fclose(fd);
+}
+
+void DrumKitParser::startTag(std::string name, std::map< std::string, std::string> attributes)
+{
+ if(name == "drumkit") {
+ dk->name = attributes["name"];
+ dk->description = attributes["description"];
+ }
+
+ if(name == "channels") {}
+
+ if(name == "channel") {
+ Channel *c = new Channel(attributes["name"]);
+ dk->channels[attributes["name"]] = c;
+ }
+
+ if(name == "samples") {}
+
+ if(name == "sample") {
+ Sample *s = new Sample(attributes["name"]);
+ dk->samples[attributes["name"]] = s;
+ lastsample = s;
+ }
+
+ if(name == "audiofile") {
+ AudioFile *af = new AudioFile(attributes["name"]);
+ af->channel = attributes["channel"];
+ lastsample->audiofiles[attributes["name"]] = af;
+ }
+
+ if(name == "instruments") {}
+
+ if(name == "instrument") {
+ midi_note_t m = atoi(attributes["midimap"].c_str());
+ Instrument *i = new Instrument(attributes["name"], m);
+ dk->instruments[m] = i;
+ lastinstrument = i;
+ }
+
+ if(name == "velocity") {
+ Velocity *v = new Velocity(atoi(attributes["lower"].c_str()),
+ atoi(attributes["upper"].c_str()));
+ lastinstrument->addVelocity(v);
+ lastvelocity = v;
+ }
+
+ if(name == "sampleref") {
+ lastvelocity->addSample(dk->samples[attributes["name"]],
+ atof(attributes["probability"].c_str()));
+ }
+}
+
+void DrumKitParser::endTag(std::string name)
+{
+}
+
+DrumKit *DrumKitParser::getDrumkit()
+{
+ return dk;
+}
+
+int DrumKitParser::readData(char *data, size_t size)
+{
+ if(!fd) return 0;
+ return fread(data, 1, size, fd);
+}
+
diff --git a/src/drumkitparser.h b/src/drumkitparser.h
new file mode 100644
index 0000000..6fd696c
--- /dev/null
+++ b/src/drumkitparser.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * drumkitparser.h
+ *
+ * Tue Jul 22 16:24:58 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_DRUMKITPARSER_H__
+#define __DRUMGIZMO_DRUMKITPARSER_H__
+
+#include "saxparser.h"
+#include "drumkit.h"
+
+class DrumKitParser : public SAXParser {
+public:
+ DrumKitParser(char *file);
+ ~DrumKitParser();
+
+ void startTag(std::string name, std::map< std::string, std::string> attributes);
+ void endTag(std::string name);
+
+ DrumKit *getDrumkit();
+
+protected:
+ int readData(char *data, size_t size);
+
+private:
+ FILE *fd;
+ DrumKit *dk;
+
+ Sample *lastsample;
+ Instrument *lastinstrument;
+ Velocity *lastvelocity;
+};
+
+#endif/*__DRUMGIZMO_DRUMKITPARSER_H__*/
diff --git a/src/event.cc b/src/event.cc
index c589807..5a78746 100644
--- a/src/event.cc
+++ b/src/event.cc
@@ -26,10 +26,11 @@
*/
#include "event.h"
-Event::Event(jack_port_t *port, Sample *sample, size_t time, size_t duration)
+Event::Event(jack_port_t *port, AudioFile *sample, size_t time, size_t duration)
{
this->port = port;
this->sample = sample;
+ sample->load();
this->time = time;
this->duration = duration;
}
diff --git a/src/event.h b/src/event.h
index c32297e..b721df0 100644
--- a/src/event.h
+++ b/src/event.h
@@ -30,17 +30,17 @@
#include <jack/jack.h>
#include <set>
-#include "sample.h"
+#include "audiofile.h"
class Event {
public:
- Event(jack_port_t *port, Sample *sample, size_t time, size_t duration = 0);
+ Event(jack_port_t *port, AudioFile *sample, size_t time, size_t duration = 0);
~Event();
bool operator<(const Event& event) const;
jack_port_t *port;
- Sample *sample;
+ AudioFile *sample;
size_t duration;
size_t time;
};
diff --git a/src/instrument.cc b/src/instrument.cc
new file mode 100644
index 0000000..0aa38ac
--- /dev/null
+++ b/src/instrument.cc
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * instrument.cc
+ *
+ * Tue Jul 22 17:14:20 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 "instrument.h"
+
+Instrument::Instrument(std::string name, unsigned int midimap)
+{
+ this->name = name;
+ this->midimap = midimap;
+}
+
+void Instrument::addVelocity(Velocity *velocity)
+{
+ velocities.push_back(velocity);
+}
+
+Velocity *Instrument::getVelocity(unsigned int v)
+{
+ Velocities::iterator i = velocities.begin();
+ while(i != velocities.end()) {
+ if(v >= (*i)->lower && v <= (*i)->upper) return *i;
+ i++;
+ }
+ return NULL;
+}
diff --git a/src/instrument.h b/src/instrument.h
new file mode 100644
index 0000000..96fc6ba
--- /dev/null
+++ b/src/instrument.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * instrument.h
+ *
+ * Tue Jul 22 17:14:19 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_INSTRUMENT_H__
+#define __DRUMGIZMO_INSTRUMENT_H__
+
+#include <string>
+#include <vector>
+
+#include <jack/jack.h>
+
+#include "velocity.h"
+
+class Instrument {
+public:
+ Instrument(std::string name, unsigned int midimap);
+
+ void addVelocity(Velocity *velocity);
+ Velocity *getVelocity(unsigned int velocity);
+
+ std::string name;
+ unsigned int midimap;
+
+ jack_port_t *port;
+
+private:
+ typedef std::vector< Velocity * > Velocities;
+ Velocities velocities;
+};
+
+#endif/*__DRUMGIZMO_INSTRUMENT_H__*/
diff --git a/src/jackclient.cc b/src/jackclient.cc
index 94eb3c8..1f91e6c 100644
--- a/src/jackclient.cc
+++ b/src/jackclient.cc
@@ -48,8 +48,11 @@ extern "C"
return ((JackClient*)arg)->xrun();}
} // extern "C"
-JackClient::JackClient(size_t num_inputs, size_t num_outputs)
+JackClient::JackClient(DrumKit *drumkit)
+ : midimapper(drumkit)
{
+ this->drumkit = drumkit;
+
jack_status_t status;
jack_client = jack_client_open("DrumGizmo", JackNullOption, &status);
@@ -62,27 +65,29 @@ JackClient::JackClient(size_t num_inputs, size_t num_outputs)
0);
// Setup input ports
- for(size_t i = 0; i < num_inputs; i++) {
- char port_name[32];
- sprintf(port_name, "input_%i", i + 1);
- jack_port_t *port = jack_port_register(jack_client,
- port_name,
- JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsInput | JackPortIsTerminal,
- 0);
- input_ports.push_back(port);
+ Instruments::iterator ii = drumkit->instruments.begin();
+ while(ii != drumkit->instruments.end()) {
+ Instrument *instrument = ii->second;
+ instrument->port = jack_port_register(jack_client,
+ instrument->name.c_str(),
+ JACK_DEFAULT_AUDIO_TYPE,
+ JackPortIsInput | JackPortIsTerminal,
+ 0);
+ input_ports.push_back(instrument->port);
+ ii++;
}
// Setup output ports
- for(size_t i = 0; i < num_outputs; i++) {
- char port_name[32];
- sprintf(port_name, "output_%i", i + 1);
- jack_port_t *port = jack_port_register(jack_client,
- port_name,
- JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsOutput | JackPortIsTerminal,
- 0);
- output_ports.push_back(port);
+ Channels::iterator ci = drumkit->channels.begin();
+ while(ci != drumkit->channels.end()) {
+ Channel *channel = ci->second;
+ channel->port = jack_port_register(jack_client,
+ channel->name.c_str(),
+ JACK_DEFAULT_AUDIO_TYPE,
+ JackPortIsOutput | JackPortIsTerminal,
+ 0);
+ output_ports.push_back(channel->port);
+ ci++;
}
//jack_on_shutdown(jack_client, _wrap_jack_shutdown, this);
@@ -94,18 +99,6 @@ JackClient::JackClient(size_t num_inputs, size_t num_outputs)
//jack_set_port_registration_callback(jack_client, _wrap_jack_port_registration, this);
//jack_set_graph_order_callback(jack_client, _wrap_jack_graph_order, this);
//jack_set_xrun_callback(jack_client, _wrap_jack_xrun, this);
-
-
- sample[0] = new Sample("kick.wav");
- sample[1] = new Sample("snare.wav");
- sample[2] = new Sample("crash1.wav");
- sample[3] = new Sample("tom1.wav");
- sample[4] = new Sample("tom2.wav");
- sample[5] = new Sample("tom3.wav");
- sample[6] = new Sample("tom4.wav");
- sample[7] = new Sample("hihat.wav");
- sample[8] = new Sample("crash2.wav");
- sample[9] = new Sample("ride.wav");
}
JackClient::~JackClient()
@@ -130,18 +123,23 @@ int JackClient::process(jack_nframes_t nframes)
jack_midi_event_t midi_event;
jack_midi_event_get(&midi_event, midibuffer, i);
- int s = midimapper.map(midi_event);
- if(s == -1) continue; // -1 is illigal node.
-
- Ports::iterator pi = output_ports.begin();
- while(pi != output_ports.end()) {
-
- // Create trigger event
- Event event(*pi, sample[s], midi_event.time);
- events.insert(event);
-
- pi++;
+ Sample *sample = midimapper.map(midi_event);
+ if(!sample) continue;
+
+ AudioFiles::iterator ai = sample->audiofiles.begin();
+ while(ai != sample->audiofiles.end()) {
+ printf("!\n");
+ AudioFile *audiofile = ai->second;
+ audiofile->load();
+
+ if(drumkit->channels.find(audiofile->channel) != drumkit->channels.end()) {
+ Channel *channel = drumkit->channels[audiofile->channel];
+ Event event(channel->port, audiofile, midi_event.time);
+ events.insert(event);
+ }
+ ai++;
}
+
}
jack_midi_clear_buffer(midibuffer);
@@ -192,23 +190,6 @@ int JackClient::process(jack_nframes_t nframes)
// Remove all dead events
events = nextevents;
- /*
- for(size_t i = 0; i < output_ports.size(); i++) {
- jack_default_audio_sample_t *buffer;
- buffer = (jack_default_audio_sample_t *)jack_port_get_buffer(output_ports[i], nframes);
- for(int j = 0; j < nframes; j++) {
- if(j == pos) drums[i].samples[0].p = -j;
- offset_t p = drums[i].samples[0].p;
- size_t data_size = params->drums[i].samples[0].data_size;
- jack_default_audio_sample_t *samples = params->drums[i].samples[0].data;
- if(p+j > data_size) buffer[j] = 0;
- else buffer[j] = samples[(j + p) % data_size];
- // params->drums[i].samples[0].p ++;
- }
- params->drums[i].samples[0].p += nframes;
- }
- */
-
return 0;
}
diff --git a/src/jackclient.h b/src/jackclient.h
index 8a31441..8efa654 100644
--- a/src/jackclient.h
+++ b/src/jackclient.h
@@ -32,6 +32,7 @@
#include <jack/jack.h>
#include <jack/midiport.h>
+#include "drumkit.h"
#include "event.h"
#include "sample.h"
#include "midimapper.h"
@@ -40,7 +41,7 @@ typedef std::vector< jack_port_t *> Ports;
class JackClient {
public:
- JackClient(size_t num_inputs = 16, size_t num_outputs = 16);
+ JackClient(DrumKit *drumkit);
~JackClient();
void activate();
@@ -62,9 +63,10 @@ private:
Ports output_ports;
jack_port_t *midi_port;
- Sample *sample[32];
Events events;
+ DrumKit *drumkit;
+
MidiMapper midimapper;
};
diff --git a/src/midimapper.cc b/src/midimapper.cc
index b17a351..727074b 100644
--- a/src/midimapper.cc
+++ b/src/midimapper.cc
@@ -28,9 +28,9 @@
#define NOTE_ON 0x90
-MidiMapper::MidiMapper()
+MidiMapper::MidiMapper(DrumKit *drumkit)
{
- // for(int i = 0; i < 255; i++) _map[i] = 1;
+ this->drumkit = drumkit;
/*
35 Acoustic Bass Drum 59 Ride Cymbal 2
36 Bass Drum 1 60 Hi Bongo
@@ -53,29 +53,25 @@ MidiMapper::MidiMapper()
53 Ride Bell 77 Low Wood Block
54 Tambourine 78 Mute Cuica
55 Splash Cymbal 79 Open Cuica
-56 Cowbell 80 Mute Triangle
+56 Cowbell 80 Mute Triangle
57 Crash Cymbal 2 81 Open Triangle
58 Vibraslap
*/
- _map[36] = 0; // kick
- _map[38] = 1; // snare
- _map[49] = 2; // crash1
- _map[50] = 3; // tom1
- _map[48] = 3; // tom2
- _map[47] = 3; // tom3
- _map[45] = 4; // tom4
- _map[43] = 5; // tom5
- _map[41] = 6; // tom6
- _map[46] = 7; // open hihat
- _map[57] = 8; // crash2
- _map[51] = 9; // ride 1
- _map[53] = 9; // ride bell
- _map[59] = 9; // ride 2
}
//http://ccrma-www.stanford.edu/~craig/articles/linuxmidi/misc/essenmidi.html
-int MidiMapper::map(jack_midi_event_t event)
+Sample *MidiMapper::map(jack_midi_event_t event)
{
+ Sample *sample = NULL;
+
+ if(event.size != 3) return NULL;
+ if(event.buffer[0] != NOTE_ON) return NULL;
+
+ int key = event.buffer[1];
+ int velocity = event.buffer[2];
+
+ if(velocity == 0) return NULL;
+
// Parse midi event
printf("[ Time: %d Size: %d ", event.time, event.size);
for(size_t j = 0; j < event.size; j++) {
@@ -84,14 +80,12 @@ int MidiMapper::map(jack_midi_event_t event)
}
printf("]\n");
- if(event.size != 3) return -1;
- if(event.buffer[0] != NOTE_ON) return -1;
-
- int key = event.buffer[1];
- int velocity = event.buffer[2];
+ if(drumkit->instruments.find(key) == drumkit->instruments.end()) return NULL;
- if(velocity == 0) return -1;
- if(_map.find(key) == _map.end()) return -1; // key is not in map.
+ Velocity *v = drumkit->instruments[key]->getVelocity(velocity);
+
+ if(!v) return NULL;
+ sample = v->getSample();
- return _map[key];
+ return sample;
}
diff --git a/src/midimapper.h b/src/midimapper.h
index d0b6a72..a967159 100644
--- a/src/midimapper.h
+++ b/src/midimapper.h
@@ -29,16 +29,19 @@
#include <jack/midiport.h>
+#include "drumkit.h"
+
#include <map>
class MidiMapper {
public:
- MidiMapper();
+ MidiMapper(DrumKit *drumkit);
- int map(jack_midi_event_t event);
+ Sample *map(jack_midi_event_t event);
private:
std::map< int, int > _map;
+ DrumKit *drumkit;
};
#endif/*__DRUMGIZMO_MIDIMAPPER_H__*/
diff --git a/src/sample.cc b/src/sample.cc
index c375645..5a06331 100644
--- a/src/sample.cc
+++ b/src/sample.cc
@@ -31,25 +31,11 @@
#include <sndfile.h>
-Sample::Sample(char *file)
+Sample::Sample(std::string name)
{
- SF_INFO sf_info;
- SNDFILE *fh = sf_open(file, SFM_READ, &sf_info);
-
- size = sf_seek(fh, 0, SEEK_END);
- data = (jack_default_audio_sample_t*)malloc(sizeof(jack_default_audio_sample_t)*size);
-
- printf("Loading %s, %d samples\n", file, size);
-
- sf_seek(fh, 0, SEEK_SET);
- sf_read_float(fh, data, size);
-
- sf_close(fh);
+ this->name = name;
}
Sample::~Sample()
{
- free(data);
- data = NULL;
- size = 0;
}
diff --git a/src/sample.h b/src/sample.h
index 16ff2fe..e3acff1 100644
--- a/src/sample.h
+++ b/src/sample.h
@@ -27,15 +27,20 @@
#ifndef __DRUMGIZMO_SAMPLE_H__
#define __DRUMGIZMO_SAMPLE_H__
-#include <jack/jack.h>
+#include <map>
+#include <string>
+#include "audiofile.h"
+
+typedef std::map< std::string, AudioFile* > AudioFiles;
class Sample {
public:
- Sample(char *file);
+ Sample(std::string name);
~Sample();
- jack_default_audio_sample_t *data;
- size_t size;
+ AudioFiles audiofiles;
+
+ std::string name;
};
#endif/*__DRUMGIZMO_SAMPLE_H__*/
diff --git a/src/saxparser.cc b/src/saxparser.cc
new file mode 100644
index 0000000..89f426b
--- /dev/null
+++ b/src/saxparser.cc
@@ -0,0 +1,110 @@
+/* -*- 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"
+
+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()
+{
+ char buf[32];
+ int len;
+
+ do {
+ len = readData(buf, sizeof(buf) - 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;
+}
+
+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: [", 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..48109f6
--- /dev/null
+++ b/src/saxparser.h
@@ -0,0 +1,54 @@
+/* -*- 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>
+
+class SAXParser {
+public:
+ SAXParser();
+ virtual ~SAXParser();
+
+ int parse();
+
+ virtual void characterData(std::string &data) {}
+ virtual void startTag(std::string name, std::map< std::string, std::string> attributes) {}
+ 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/velocity.cc b/src/velocity.cc
new file mode 100644
index 0000000..4ff398c
--- /dev/null
+++ b/src/velocity.cc
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * velocity.cc
+ *
+ * Tue Jul 22 18:04:58 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 "velocity.h"
+
+Velocity::Velocity(unsigned int lower, unsigned int upper)
+{
+ this->lower = lower;
+ this->upper = upper;
+}
+
+void Velocity::addSample(Sample *sample, float probability)
+{
+ if(samples.find(sample) != samples.end()) {
+ samples[sample] += probability;
+ } else {
+ samples[sample] = probability;
+ }
+}
+
+Sample *Velocity::getSample()
+{
+ Sample *sample = NULL;
+
+ float x = (float)rand() / (float)RAND_MAX;
+ float sum = 0.0;
+
+ Samples::iterator i = samples.begin();
+ while(i != samples.end() && x > sum) {
+ sum += i->second;
+ sample = i->first;
+ i++;
+ }
+
+ return sample;
+}
diff --git a/src/velocity.h b/src/velocity.h
new file mode 100644
index 0000000..10a3eb0
--- /dev/null
+++ b/src/velocity.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * velocity.h
+ *
+ * Tue Jul 22 18:04:58 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_VELOCITY_H__
+#define __DRUMGIZMO_VELOCITY_H__
+
+#include <map>
+
+#include "sample.h"
+
+class Velocity {
+public:
+ Velocity(unsigned int lower, unsigned int upper);
+
+ void addSample(Sample *sample, float probability);
+ Sample *getSample();
+
+ unsigned int lower;
+ unsigned int upper;
+
+private:
+ typedef std::map< Sample *, float > Samples;
+ Samples samples;
+};
+
+#endif/*__DRUMGIZMO_VELOCITY_H__*/