From f6cabfe8fe888e00388a815541084b0fa332a462 Mon Sep 17 00:00:00 2001 From: deva Date: Tue, 22 Jul 2008 21:00:01 +0000 Subject: DrumKit parser. Internal drumkit now used in events. This is the first milestone. --- src/Makefile.am | 19 +++++++-- src/audiofile.cc | 77 ++++++++++++++++++++++++++++++++++++ src/audiofile.h | 49 +++++++++++++++++++++++ src/channel.cc | 33 ++++++++++++++++ src/channel.h | 41 +++++++++++++++++++ src/drumgizmo.cc | 7 +++- src/drumkit.h | 53 +++++++++++++++++++++++++ src/drumkitparser.cc | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ src/drumkitparser.h | 55 ++++++++++++++++++++++++++ src/event.cc | 3 +- src/event.h | 6 +-- src/instrument.cc | 48 ++++++++++++++++++++++ src/instrument.h | 54 +++++++++++++++++++++++++ src/jackclient.cc | 99 +++++++++++++++++++--------------------------- src/jackclient.h | 6 ++- src/midimapper.cc | 46 ++++++++++----------- src/midimapper.h | 7 +++- src/sample.cc | 18 +-------- src/sample.h | 13 ++++-- src/saxparser.cc | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/saxparser.h | 54 +++++++++++++++++++++++++ src/velocity.cc | 59 +++++++++++++++++++++++++++ src/velocity.h | 49 +++++++++++++++++++++++ 23 files changed, 895 insertions(+), 117 deletions(-) create mode 100644 src/audiofile.cc create mode 100644 src/audiofile.h create mode 100644 src/channel.cc create mode 100644 src/channel.h create mode 100644 src/drumkit.h create mode 100644 src/drumkitparser.cc create mode 100644 src/drumkitparser.h create mode 100644 src/instrument.cc create mode 100644 src/instrument.h create mode 100644 src/saxparser.cc create mode 100644 src/saxparser.h create mode 100644 src/velocity.cc create mode 100644 src/velocity.h 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 +#include + +#include + +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 +#include + +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 +#include + +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 #include @@ -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 +#include + +#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 #include -#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 +#include + +#include + +#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 #include +#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 +#include "drumkit.h" + #include 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 -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 +#include +#include +#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 +#include +#include + +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 + +#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__*/ -- cgit v1.2.3