diff options
| -rw-r--r-- | src/Makefile.am | 19 | ||||
| -rw-r--r-- | src/audiofile.cc | 77 | ||||
| -rw-r--r-- | src/audiofile.h | 49 | ||||
| -rw-r--r-- | src/channel.cc | 33 | ||||
| -rw-r--r-- | src/channel.h | 41 | ||||
| -rw-r--r-- | src/drumgizmo.cc | 7 | ||||
| -rw-r--r-- | src/drumkit.h | 53 | ||||
| -rw-r--r-- | src/drumkitparser.cc | 106 | ||||
| -rw-r--r-- | src/drumkitparser.h | 55 | ||||
| -rw-r--r-- | src/event.cc | 3 | ||||
| -rw-r--r-- | src/event.h | 6 | ||||
| -rw-r--r-- | src/instrument.cc | 48 | ||||
| -rw-r--r-- | src/instrument.h | 54 | ||||
| -rw-r--r-- | src/jackclient.cc | 99 | ||||
| -rw-r--r-- | src/jackclient.h | 6 | ||||
| -rw-r--r-- | src/midimapper.cc | 46 | ||||
| -rw-r--r-- | src/midimapper.h | 7 | ||||
| -rw-r--r-- | src/sample.cc | 18 | ||||
| -rw-r--r-- | src/sample.h | 13 | ||||
| -rw-r--r-- | src/saxparser.cc | 110 | ||||
| -rw-r--r-- | src/saxparser.h | 54 | ||||
| -rw-r--r-- | src/velocity.cc | 59 | ||||
| -rw-r--r-- | src/velocity.h | 49 | 
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__*/ | 
