diff options
Diffstat (limited to 'src')
35 files changed, 678 insertions, 1722 deletions
| diff --git a/src/Makefile.am b/src/Makefile.am index df904db..897732c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,70 +1,10 @@ -bin_PROGRAMS = drumgizmo - -drumgizmo_LDADD = $(ALSA_LIBS) $(JACK_LIBS) $(SNDFILE_LIBS) $(SMF_LIBS) \ -	$(PTHREAD_CFLAGS) - -drumgizmo_CXXFLAGS = $(ALSA_CFLAGS) $(JACK_CXXFLAGS) $(SNDFILE_CXXFLAGS) \ -	 $(SMF_CFLAGS) $(PTHREAD_LIBS) - -drumgizmo_SOURCES = \ -	audioinputengine.cc \ -	audioinputenginejackmidi.cc \ -	audiooutputengine.cc \ -	audiooutputenginealsa.cc \ -	audiooutputenginejack.cc \ -	audiooutputenginesndfile.cc \ -	audiofile.cc \ -	cli.cc \ -	channel.cc \ -	channelmixer.cc \ -	drumgizmo.cc \ -	drumkitparser.cc \ -	event.cc \ -	instrument.cc \ -	midimapper.cc \ -	midiplayer.cc \ -	mutex.cc \ -	sample.cc \ -	saxparser.cc \ -	thread.cc \ -	velocity.cc - -#	beatmapper.cc - -EXTRA_DIST = \ -	audio.h \ -	audioinputengine.h \ -	audioinputenginejackmidi.h \ -	audiooutputengine.h \ -	audiooutputenginealsa.h \ -	audiooutputenginejack.h \ -	audiooutputenginesndfile.h \ -	audiofile.h \ -	channel.h \ -	channelmixer.h \ -	drumgizmo.h \ -	drumkit.h \ -	drumkitparser.h \ -	event.h \ -	instrument.h \ -	midimapper.h \ -	midiplayer.h \ -	mutex.h \ -	rangemap.h \ -	sample.h \ -	saxparser.h \ -	thread.h \ -	velocity.h - -#	beatmapper.h -  ################  # Test Section #  ################ -TEST_SOURCE_DEPS = ${drumgizmo_SOURCES} ${EXTRA_DIST} +TEST_SOURCE_DEPS = ${EXTRA_DIST}  TEST_SCRIPT_DIR = $(top_srcdir)/tools  include ${TEST_SCRIPT_DIR}/Makefile.am.test -include Makefile.am.test
\ No newline at end of file +include Makefile.am.test diff --git a/src/audio.h b/src/audio.h index 85a84a0..dc890cc 100644 --- a/src/audio.h +++ b/src/audio.h @@ -27,14 +27,6 @@  #ifndef __DRUMGIZMO_AUDIO_H__  #define __DRUMGIZMO_AUDIO_H__ -typedef unsigned int channels_t; -typedef unsigned int channel_t; - -#define ALL_CHANNELS ((channel_t)0xffffffff) -#define NO_CHANNEL ((channel_t)0xfffffffe) - -typedef float sample_t; - -typedef float level_t; +#include <audiotypes.h>  #endif/*__DRUMGIZMO_AUDIO_H__*/ diff --git a/src/audiofile.cc b/src/audiofile.cc index 2533b33..61b49e9 100644 --- a/src/audiofile.cc +++ b/src/audiofile.cc @@ -37,6 +37,8 @@ AudioFile::AudioFile(std::string filename)    data = NULL;    size = 0; + +  load();  }  AudioFile::~AudioFile() diff --git a/src/audiofile.h b/src/audiofile.h index a3d607d..53fe2a7 100644 --- a/src/audiofile.h +++ b/src/audiofile.h @@ -43,7 +43,6 @@ public:  	sample_t *data;  	size_t size; -private:    std::string filename;  }; diff --git a/src/audioinputengine.cc b/src/audioinputengine.cc index 201d851..95c7c13 100644 --- a/src/audioinputengine.cc +++ b/src/audioinputengine.cc @@ -26,19 +26,6 @@   */  #include "audioinputengine.h" -#include "audioinputenginejackmidi.h" -#include "audioinputenginemidifile.h" - -AudioInputEngine *createAudioInputEngine(std::string engine) -{ -  AudioInputEngine *e = NULL; - -  if(engine == "jackmidi") e = new AudioInputEngineJackMidi(); -  if(engine == "midifile") e = new AudioInputEngineMidiFile(); - -  return e; -} -  #ifdef TEST_AUDIOINPUTENGINE  //Additional dependency files  //deps: diff --git a/src/audioinputengine.h b/src/audioinputengine.h index d10a31c..c17b964 100644 --- a/src/audioinputengine.h +++ b/src/audioinputengine.h @@ -29,18 +29,22 @@  #include <string> -#include "event.h" +#include <event.h> + +#include "instrument.h"  class AudioInputEngine {  public: -  AudioInputEngine() {} -  virtual ~AudioInputEngine() {} +  virtual bool init(Instruments &instruments) = 0; -  virtual bool init(EventQueue *e) = 0; +  virtual void setParm(std::string parm, std::string value) = 0; -  virtual void run(size_t pos, size_t len) = 0; -}; +  virtual bool start() = 0; +  virtual void stop() = 0; -AudioInputEngine *createAudioInputEngine(std::string engine); +  virtual void pre() = 0; +  virtual event_t *run(size_t pos, size_t len, size_t *nevents) = 0; +  virtual void post() = 0; +};  #endif/*__DRUMGIZMO_AUDIOINPUTENGINE_H__*/ diff --git a/src/audioinputenginejackmidi.cc b/src/audioinputenginejackmidi.cc deleted file mode 100644 index 49bfde4..0000000 --- a/src/audioinputenginejackmidi.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            audioinputenginejackmidi.cc - * - *  Sun Feb 27 11:33:31 CET 2011 - *  Copyright 2011 Bent Bisballe Nyeng - *  deva@aasimon.org - ****************************************************************************/ - -/* - *  This file is part of DrumGizmo. - * - *  DrumGizmo is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  DrumGizmo is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with DrumGizmo; if not, write to the Free Software - *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. - */ -#include "audioinputenginejackmidi.h" - -#define NOTE_ON 0x90 - -extern "C" { -  static int _wrap_jack_process(jack_nframes_t nframes, void *arg){ -    return ((AudioInputEngineJackMidi*)arg)->process(nframes);} -} - -AudioInputEngineJackMidi::AudioInputEngineJackMidi() -{ -  pos = 0; -} - -AudioInputEngineJackMidi::~AudioInputEngineJackMidi() -{ -  //  wait_stop(); -  jack_client_close(jack_client); -} - -int AudioInputEngineJackMidi::process(jack_nframes_t nframes) -{ -  //  printf("               jk: %d\n", pos); - -  void *midibuffer = jack_port_get_buffer(midi_port, nframes); - -  jack_nframes_t midievents = jack_midi_get_event_count(midibuffer); -  //  if(midievents) printf("#%d\n", midievents); -  for(jack_nframes_t i = 0; i < midievents; i++) { -    jack_midi_event_t event; -    jack_midi_event_get(&event, midibuffer, i); -     -     -    if(event.size != 3) continue; -    if((event.buffer[0] & NOTE_ON) != NOTE_ON) continue; -     -    int key = event.buffer[1]; -    int velocity = event.buffer[2]; -     -    //if(velocity == 0) continue; -     -    printf("Event key:%d vel:%d\n", key, velocity); -    Event *evt = new EventSine(0, key * 10, (float)velocity / 127.0, 1000); -    eventqueue->post(evt, pos + event.time); -  } -   -  jack_midi_clear_buffer(midibuffer); -     -  pos += nframes; - -  return 0; -} - -bool AudioInputEngineJackMidi::init(EventQueue *e) -{ -  eventqueue = e; - -	jack_status_t status; - -	jack_client = jack_client_open("DrumGizmo", JackNullOption, &status); - -	midi_port = jack_port_register(jack_client, -                                 "drumgizmo_midiin", -                                 JACK_DEFAULT_MIDI_TYPE, -                                 JackPortIsInput,// | JackPortIsTerminal, -                                 0); - -  jack_set_process_callback(jack_client, _wrap_jack_process, this); - -  jack_activate(jack_client); - -  return true; -} - -#ifdef TEST_AUDIOINPUTENGINEJACKMIDI -//Additional dependency files -//deps: -//Required cflags (autoconf vars may be used) -//cflags: -//Required link options (autoconf vars may be used) -//libs: -#include "test.h" - -TEST_BEGIN; - -// TODO: Put some testcode here (see test.h for usable macros). - -TEST_END; - -#endif/*TEST_AUDIOINPUTENGINEJACKMIDI*/ diff --git a/src/audioinputenginemidifile.h b/src/audioinputenginemidifile.h deleted file mode 100644 index fbdeffa..0000000 --- a/src/audioinputenginemidifile.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            audioinputenginemidifile.h - * - *  Sun Feb 27 11:43:32 CET 2011 - *  Copyright 2011 Bent Bisballe Nyeng - *  deva@aasimon.org - ****************************************************************************/ - -/* - *  This file is part of DrumGizmo. - * - *  DrumGizmo is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or - *  (at your option) any later version. - * - *  DrumGizmo is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with DrumGizmo; if not, write to the Free Software - *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. - */ -#ifndef __DRUMGIZMO_AUDIOINPUTENGINEMIDIFILE_H__ -#define __DRUMGIZMO_AUDIOINPUTENGINEMIDIFILE_H__ - -#include "audioinputengine.h" - -class AudioInputEngineMidiFile : public AudioInputEngine { -public: -  AudioInputEngineMidiFile() {} -  ~AudioInputEngineMidiFile() {} - -  bool init(EventQueue *eventqueue) { return true; } -  void run(size_t pos, size_t len) {} -}; - -#endif/*__DRUMGIZMO_AUDIOINPUTENGINEMIDIFILE_H__*/ diff --git a/src/audiooutputengine.cc b/src/audiooutputengine.cc index 73ef355..7070222 100644 --- a/src/audiooutputengine.cc +++ b/src/audiooutputengine.cc @@ -26,17 +26,3 @@   */  #include "audiooutputengine.h" -#include "audiooutputenginealsa.h" -#include "audiooutputenginejack.h" -#include "audiooutputenginesndfile.h" - -AudioOutputEngine *createAudioOutputEngine(std::string engine) -{ -  AudioOutputEngine *e = NULL; - -  if(engine == "alsa") e = new AudioOutputEngineAlsa(); -  if(engine == "jack") e = new AudioOutputEngineJack(); -  if(engine == "sndfile") e = new AudioOutputEngineSndFile("out.wav"); - -  return e; -} diff --git a/src/audiooutputengine.h b/src/audiooutputengine.h index 09dcbd7..864ecc5 100644 --- a/src/audiooutputengine.h +++ b/src/audiooutputengine.h @@ -28,24 +28,23 @@  #define __DRUMGIZMO_AUDIOOUTPUTENGINE_H__  #include <string> +#include <stdlib.h> +#include <audiotypes.h>  #include "channel.h" -class DrumGizmo; -  class AudioOutputEngine {  public: -  AudioOutputEngine() {} -  virtual ~AudioOutputEngine() {} +  virtual bool init(Channels channels) = 0; -  virtual bool init(Channels *channels) = 0; +  virtual void setParm(std::string parm, std::string value) = 0; -  virtual void run(DrumGizmo *drumgizmo) = 0; +  virtual bool start() = 0; +  virtual void stop() = 0; -protected: -  Channels *channels; +  virtual void pre(size_t nsamples) = 0; +  virtual void run(int ch, sample_t *samples, size_t nsamples) = 0; +  virtual void post(size_t nsamples) = 0;  }; -AudioOutputEngine *createAudioOutputEngine(std::string engine); -  #endif/*__DRUMGIZMO_AUDIOOUTPUTENGINE_H__*/ diff --git a/src/audiooutputenginealsa.cc b/src/audiooutputenginealsa.cc deleted file mode 100644 index 635cf70..0000000 --- a/src/audiooutputenginealsa.cc +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            audiooutputenginealsa.cc - * - *  Thu Sep 16 11:22:52 CEST 2010 - *  Copyright 2010 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 "audiooutputenginealsa.h" - -#include "drumgizmo.h" - -#include <string> -#include <math.h> -#include <sys/time.h> - -#define T(x, msg) if(x < 0) { printf("%s failed: %s\n", msg, snd_strerror(x)); fflush(stdout); return false; } -#define T_(x, msg) if(x < 0) { printf("%s failed: %s\n", msg, snd_strerror(x)); fflush(stdout); return; } - -AudioOutputEngineAlsa::AudioOutputEngineAlsa() -{ -  printf("AudioOutputEngineAlsa\n"); -	int rc; - -  std::string pcmname = "default"; - -  rc = snd_pcm_open(&handle, pcmname.c_str(), -                    SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); -  T_(rc, "snd_pcm_open"); -} - -AudioOutputEngineAlsa::~AudioOutputEngineAlsa() -{ -  printf("~AudioOutputEngineAlsa\n"); -  if(handle) snd_pcm_close(handle); -} - -bool AudioOutputEngineAlsa::init(Channels *channels) -{ -  this->channels = channels; - -  if(!handle) { -    printf("No handle!\n"); -    return false; -  } - -  int rc; -  unsigned int srate = 44100; -  snd_pcm_uframes_t frames = 32; - -  // Allocate a hardware parameters object. -  snd_pcm_hw_params_alloca(¶ms); -  //  if(rc < 0) return false; - -  // Fill it in with default values. -  rc = snd_pcm_hw_params_any(handle, params); -  T(rc, "snd_pcm_hw_params_any"); - -  rc = snd_pcm_hw_params_set_access(handle, params, -                                    SND_PCM_ACCESS_MMAP_NONINTERLEAVED); -  T(rc, "snd_pcm_hw_params_set_access"); - -  rc = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_FLOAT); -  T(rc, "snd_pcm_hw_params_set_format"); - -  rc = snd_pcm_hw_params_set_channels(handle, params, channels->size()); -  T(rc, "snd_pcm_hw_params_set_channels"); - -  rc = snd_pcm_hw_params_set_rate_near(handle, params, &srate, 0); -  T(rc, "snd_pcm_hw_params_set_rate_near"); - -  rc = snd_pcm_hw_params_set_period_size_near(handle, params, &frames, 0); -  T(rc, "snd_pcm_hw_params_set_period_size_near"); - -  rc = snd_pcm_hw_params(handle, params); -  T(rc, "snd_pcm_hw_params"); - -  // SW Params: -  /* -    rc = snd_pcm_sw_params_current(pcm, sw); -    rc = snd_pcm_sw_params_set_start_threshold(pcm, sw, ~0U); -    rc = snd_pcm_sw_params_set_stop_threshold(pcm, sw, ~0U); -    rc = snd_pcm_sw_params(pcm, sw); -    rc = snd_pcm_hw_params_get_buffer_size(hw, &buffer_size); -  */ - -  channels_t nchannels; -  rc = snd_pcm_hw_params_get_channels(params, &nchannels); -  printf("channels: %d rc: %d\n", nchannels, rc); -  T(rc, "snd_pcm_hw_params_get_channels"); -  if(nchannels != channels->size()) return false; - -  channel_t c = 0; -  Channels::iterator i = channels->begin(); -  while(i != channels->end()) { -    i->num = c; - -    i++; -    c++; -  } - -  return true; -} - -#define MICRO 1000000 -void AudioOutputEngineAlsa::run(DrumGizmo *drumgizmo) -{ -  int rc; - -  snd_pcm_uframes_t nframes; - -  while(drumgizmo->isRunning()) { -    timeval tim; -    gettimeofday(&tim, NULL); -    useconds_t t1 = tim.tv_sec * MICRO + tim.tv_usec; - -    snd_pcm_uframes_t offset = 0; - -    //    unsigned int nchannels = 2; -    //    rc = snd_pcm_hw_params_get_channels(params, &nchannels); -    //    printf("channels: %d rc: %d\n", nchannels, rc); -    //    T_(rc, "snd_pcm_hw_params_get_channels"); -    nframes = snd_pcm_avail_update(handle); -    //    printf("%d\n", rc); -    //    T_(rc, "snd_pcm_avail_update"); - -    //  rc = snd_pcm_hw_params_get_buffer_size(params, &nframes); -    //  T_(rc, "nd_pcm_hw_params_get_buffer_size"); -   -    //    nframes = 960; - -    const snd_pcm_channel_area_t *areas; -    rc = snd_pcm_mmap_begin(handle, &areas, &offset, &nframes); -    T_(rc, "snd_pcm_mmap_begin"); - -    drumgizmo->pre((size_t)nframes); - -    Channels::iterator i = channels->begin(); -    while(i != channels->end()) { -      const snd_pcm_channel_area_t *a = &areas[i->num]; -      sample_t *p = (sample_t*)a->addr + offset; -      memset(p, 0, nframes * sizeof(sample_t)); -      drumgizmo->getSamples(&(*i), p, (size_t)nframes); - -      i++; -    } -    drumgizmo->post((size_t)nframes); - -    switch(snd_pcm_state(handle)) { -    case SND_PCM_STATE_PREPARED: -      rc = snd_pcm_mmap_commit(handle, offset, nframes); -      T_(rc, "snd_pcm_mmap_commit"); -      rc = snd_pcm_start(handle); -      T_(rc, "snd_pcm_start"); -      break; -    case SND_PCM_STATE_RUNNING: -      rc = snd_pcm_mmap_commit(handle, offset, nframes); -      T_(rc, "snd_pcm_mmap_commit"); -      break; -    default: -      break; -    } - -    useconds_t msec = ((useconds_t)nframes * MICRO)/44100; - -    gettimeofday(&tim, NULL); -    useconds_t t2 = tim.tv_sec * MICRO + tim.tv_usec; - -    struct timespec slp; -    slp.tv_sec = 0; -    slp.tv_nsec = (msec - (t2 - t1)) * 1000; - -    nanosleep(&slp, NULL); - -  } -} diff --git a/src/audiooutputenginealsa.h b/src/audiooutputenginealsa.h deleted file mode 100644 index 8aef940..0000000 --- a/src/audiooutputenginealsa.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            audiooutputenginealsa.h - * - *  Thu Sep 16 11:22:52 CEST 2010 - *  Copyright 2010 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_AUDIOOUTPUTENGINEALSA_H__ -#define __DRUMGIZMO_AUDIOOUTPUTENGINEALSA_H__ - -// Use the newer ALSA API -#define ALSA_PCM_NEW_HW_PARAMS_API - -#include <asoundlib.h> - -#include "audiooutputengine.h" - -class AudioOutputEngineAlsa : public AudioOutputEngine { -public: -  AudioOutputEngineAlsa(); -  ~AudioOutputEngineAlsa(); - -  bool init(Channels *channels); - -  void run(DrumGizmo *drumgizmo); -   -private: -  snd_pcm_t *handle; -  snd_pcm_hw_params_t *params; -}; - -#endif/*__DRUMGIZMO_AUDIOOUTPUTENGINEALSA_H__*/ diff --git a/src/audiooutputenginejack.cc b/src/audiooutputenginejack.cc deleted file mode 100644 index f29404d..0000000 --- a/src/audiooutputenginejack.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            audiooutputenginejack.cc - * - *  Thu Sep 16 10:28:37 CEST 2010 - *  Copyright 2010 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 "audiooutputenginejack.h" - -#include <string.h> -#include "drumgizmo.h" - -extern "C" { -  static int _wrap_jack_process(jack_nframes_t nframes, void *arg){ -    return ((AudioOutputEngineJack*)arg)->process(nframes);} -} - -AudioOutputEngineJack::AudioOutputEngineJack() -{ -	jack_status_t status; - -	jack_client = jack_client_open("DrumGizmo", JackNullOption, &status); -  jack_set_process_callback(jack_client, _wrap_jack_process, this); -} - -AudioOutputEngineJack::~AudioOutputEngineJack() -{ -	jack_client_close(jack_client); -} - -bool AudioOutputEngineJack::init(Channels *channels) -{ -  this->channels = channels; - -  Channels::iterator i = channels->begin(); -  while(i != channels->end()) { - -    jack_port_t *port = -      jack_port_register(jack_client, -                         i->name.c_str(), -                         JACK_DEFAULT_AUDIO_TYPE, -                         JackPortIsOutput | JackPortIsTerminal, -                         0); - -    output_ports.push_back(port); -    i->num = output_ports.size() - 1; - -    i++; -  } - -  return true; -} - -void AudioOutputEngineJack::run(DrumGizmo *drumgizmo) -{ -  gizmo = drumgizmo; - -  jack_activate(jack_client); - -  jack_connect(jack_client, "DrumGizmo:port0", "system:playback_1"); -  jack_connect(jack_client, "DrumGizmo:port1", "system:playback_2"); - -  while(drumgizmo->isRunning()) { -    sleep(1); -  } -} - -int AudioOutputEngineJack::process(jack_nframes_t nframes) -{ -  gizmo->pre(nframes); - -  Channels::iterator i = channels->begin(); -  while(i != channels->end()) { -    jack_port_t *port = output_ports[i->num]; -    jack_default_audio_sample_t *buffer; -    buffer = (jack_default_audio_sample_t *)jack_port_get_buffer(port, nframes); -     -    memset(buffer, 0, nframes * sizeof(sample_t)); -    gizmo->getSamples(&(*i), buffer, nframes); -     -    i++; -  } - -  gizmo->post(nframes); - -  return 0; -} diff --git a/src/audiooutputenginejack.h b/src/audiooutputenginejack.h deleted file mode 100644 index 41d9964..0000000 --- a/src/audiooutputenginejack.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            audiooutputenginejack.h - * - *  Thu Sep 16 10:28:37 CEST 2010 - *  Copyright 2010 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_AUDIOOUTPUTENGINEJACK_H__ -#define __DRUMGIZMO_AUDIOOUTPUTENGINEJACK_H__ - -#include <vector> - -#include <jack/jack.h> - -#include "audiooutputengine.h" - -class AudioOutputEngineJack : public AudioOutputEngine { -public: -  AudioOutputEngineJack(); -  ~AudioOutputEngineJack(); - -  bool init(Channels *channels); - -  void run(DrumGizmo *drumgizmo); - -  // Internal callback method. *must* be public. -  int process(jack_nframes_t nframes); - -private: -	jack_client_t *jack_client; -  std::vector< jack_port_t *> output_ports; - -  jack_port_t *port0; -  jack_port_t *port1; - -  DrumGizmo *gizmo; -}; - - -#endif/*__DRUMGIZMO_AUDIOOUTPUTENGINEJACK_H__*/ diff --git a/src/audiooutputenginesndfile.cc b/src/audiooutputenginesndfile.cc deleted file mode 100644 index f311180..0000000 --- a/src/audiooutputenginesndfile.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            audiooutputenginesndfile.cc - * - *  Tue Sep 21 09:31:30 CEST 2010 - *  Copyright 2010 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 "audiooutputenginesndfile.h" - -#include "drumgizmo.h" - -AudioOutputEngineSndFile::AudioOutputEngineSndFile(std::string file) -{ -  filename = file; -} - -AudioOutputEngineSndFile::~AudioOutputEngineSndFile() -{ -  if(fh) sf_close(fh); -} - -bool AudioOutputEngineSndFile::init(Channels *channels) -{ -  this->channels = channels; - -  sf_info.channels = channels->size(); -  sf_info.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; -  sf_info.samplerate = 44100; - -  fh = sf_open(filename.c_str(), SFM_WRITE, &sf_info); -  if(!fh) { -    printf("Load error...\n"); -    return false; -  } - -  channel_t c = 0; -  Channels::iterator i = channels->begin(); -  while(i != channels->end()) { -    i->num = c; -    i++; -    c++; -  } - -  return true; -} - -void AudioOutputEngineSndFile::run(DrumGizmo *gizmo) -{ -  sample_t s[channels->size()]; - -  while(gizmo->isRunning()) { - -    gizmo->pre(1); -    Channels::iterator i = channels->begin(); -    while(i != channels->end()) { -      s[i->num] = 0.0; -      gizmo->getSamples(&(*i), &(s[i->num]), 1); -      i++; -    } - -    gizmo->post(1); - -    sf_writef_float(fh, s, 1);  -  } -} diff --git a/src/audiooutputenginesndfile.h b/src/audiooutputenginesndfile.h deleted file mode 100644 index adfbe96..0000000 --- a/src/audiooutputenginesndfile.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            audiooutputenginesndfile.h - * - *  Tue Sep 21 09:31:29 CEST 2010 - *  Copyright 2010 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_AUDIOOUTPUTENGINESNDFILE_H__ -#define __DRUMGIZMO_AUDIOOUTPUTENGINESNDFILE_H__ - -#include <string> - -#include <sndfile.h> - -#include "audiooutputengine.h" - -class AudioOutputEngineSndFile : public AudioOutputEngine { -public: -  AudioOutputEngineSndFile(std::string filename); -  ~AudioOutputEngineSndFile(); - -  bool init(Channels *channels); - -  void run(DrumGizmo *drumgizmo); -   -private: -  std::string filename; -  SF_INFO sf_info; -  SNDFILE *fh; -}; - -#endif/*__DRUMGIZMO_AUDIOOUTPUTENGINESNDFILE_H__*/ diff --git a/src/channel.h b/src/channel.h index 7aadc3c..2484d92 100644 --- a/src/channel.h +++ b/src/channel.h @@ -32,6 +32,9 @@  #include "audio.h" +#define ALL_CHANNELS ((channel_t)0xffffffff) +#define NO_CHANNEL ((channel_t)0xfffffffe) +  class Channel {  public:    Channel(std::string name = ""); diff --git a/src/cli.cc b/src/cli.cc deleted file mode 100644 index bb0eae2..0000000 --- a/src/cli.cc +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            cli.cc - * - *  Thu Sep 16 10:23:22 CEST 2010 - *  Copyright 2010 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 <config.h> -#include <getopt.h> - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -#include "drumgizmo.h" - -#include "audiooutputengine.h" -#include "audioinputengine.h" - -#include "event.h" - -static const char version_str[] = -"DrumGizmo v" VERSION "\n" -; - -static const char copyright_str[] = -"Copyright (C) 2008-2009 Bent Bisballe Nyeng - Aasimon.org.\n" -"This is free software.  You may redistribute copies of it under the terms of\n" -"the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n" -"There is NO WARRANTY, to the extent permitted by law.\n" -"\n" -"Written by Bent Bisballe Nyeng (deva@aasimon.org)\n" -; - -static const char usage_str[] = -"Usage: %s [options] drumkitfile\n" -"Options:\n" -"  -p, --preload          Load entire kit audio files into memory (uses ALOT of memory).\n" -"  -o, --outputengine alsa|jack|sndfile  Use said audio engine.\n" -"  -i, --inputengine jackmidi|midifile  Use said audio engine.\n" -"  -v, --version          Print version information and exit.\n" -"  -h, --help             Print this message and exit.\n" -; - -int main(int argc, char *argv[]) -{ -  int c; - -  std::string outputengine; -  std::string inputengine; -  bool preload = false; - -  int option_index = 0; -  while(1) { -    static struct option long_options[] = { -      {"preload", no_argument, 0, 'p'}, -      {"outputengine", required_argument, 0, 'o'}, -      {"inputengine", required_argument, 0, 'i'}, -      {"help", no_argument, 0, 'h'}, -      {"version", no_argument, 0, 'v'}, -      {0, 0, 0, 0} -    }; -     -    c = getopt_long (argc, argv, "hvpo:i:", long_options, &option_index); -     -    if (c == -1) -      break; - -    switch(c) { -    case 'o': -      outputengine = optarg; -      break; - -    case 'i': -      inputengine = optarg; -      break; - -    case 'p': -      preload = true; -      break; -  -    case '?': -    case 'h': -      printf("%s", version_str); -      printf(usage_str, argv[0]); -      return 0; - -    case 'v': -      printf("%s", version_str); -      printf("%s", copyright_str); -      return 0; - -    default: -      break; -    } -  } - -  if(outputengine == "") { -    printf("Missing output engine\n"); -    return 1; -  } - -  AudioOutputEngine *oe = createAudioOutputEngine(outputengine); - -  if(oe == NULL) { -    printf("Invalid output engine: %s\n", outputengine.c_str()); -    return 1; -  } - - -  if(inputengine == "") { -    printf("Missing input engine\n"); -    return 1; -  } - -  AudioInputEngine *ie = createAudioInputEngine(inputengine); - -  if(ie == NULL) { -    printf("Invalid input engine: %s\n", outputengine.c_str()); -    return 1; -  } - -  std::string kitfile; - -  if(option_index < argc) { -    printf("non-option ARGV-elements: "); -    while (optind < argc) { -      if(kitfile != "") { -        fprintf(stderr, "Can only handle a single kitfile.\n"); -        printf(usage_str, argv[0]); -        return 1; -      } -      kitfile = argv[optind++]; -    } -    printf("\n"); -  } else { -    fprintf(stderr, "Missing kitfile.\n"); -    printf(usage_str, argv[0]); -    return 1; -  } -   -  printf("Using kitfile: %s\n", kitfile.c_str()); - -  Channels channels; -  Channel c1; c1.num = 0; -  Channel c2; c2.num = 1; -  channels.push_back(c1); -  channels.push_back(c2); -  ChannelMixer m(channels, &channels[0]); - -  DrumGizmo gizmo(*oe, *ie, m); -  if(/*kitfile == "" ||*/ !gizmo.loadkit(kitfile)) { -    printf("Failed to load \"%s\".\n", kitfile.c_str()); -    return 1; -  } - -  if(!gizmo.init(preload)) { -    printf("Failed init drumkit.\n"); -    return 1; -  } - -  gizmo.run(); - -  printf("Quit.\n"); fflush(stdout); - -  delete oe; -  delete ie; - -  return 0; -} diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index 161517e..de8e610 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -29,83 +29,178 @@  #include <math.h>  #include <stdio.h> +#include <event.h> +#include <audiotypes.h> + +#include <string.h> +  #include "drumkitparser.h" -#include "audiooutputengine.h" -#include "audioinputengine.h" -#include "event.h" - -DrumGizmo::DrumGizmo(AudioOutputEngine &o, -                     AudioInputEngine &i, -                     ChannelMixer &m) -  : mixer(m), oe(o), ie(i) + +DrumGizmo::DrumGizmo(AudioOutputEngine *o, AudioInputEngine *i) +  : oe(o), ie(i)  { -  time = 0; -  Channel c1; c1.num = 0; c1.name="left"; -  Channel c2; c2.num = 1; c2.name="right"; -  channels.push_back(c1); -  channels.push_back(c2);  }  DrumGizmo::~DrumGizmo()  { +  /*    AudioFiles::iterator i = audiofiles.begin();    while(i != audiofiles.end()) {      AudioFile *audiofile = i->second;      delete audiofile;      i++;    } +  */  }  bool DrumGizmo::loadkit(const std::string &kitfile)  { -  /*    DrumKitParser parser(kitfile, kit);    if(parser.parse()) return false; +  /* +  Instruments::iterator i = kit.instruments.begin(); +  while(i != kit.instruments.end()) { +    Instrument &instr = i->second; +    InstrumentParser iparser(instr.file, instr); +    if(iparser.parse()) return false; +    i++; +  }    */ -    return true;  }  bool DrumGizmo::init(bool preload)  {    if(preload) { +    /*      AudioFiles::iterator i = audiofiles.begin();      while(i != audiofiles.end()) {        AudioFile *audiofile = i->second;        audiofile->load();        i++;      } +    */    } -  if(!oe.init(&channels)) return false; - -  if(!ie.init(&eventqueue)) return false; +  if(!ie->init(kit.instruments)) return false; +  if(!oe->init(kit.channels)) return false;    return true;  } -void DrumGizmo::run() +void DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)  { -  is_running = true; -  oe.run(this); +  ie->pre(); +  oe->pre(nsamples); + + +  // +  // Read new events +  // + +  size_t nev; +  event_t *evs = ie->run(pos, nsamples, &nev); + +  for(size_t e = 0; e < nev; e++) { +    /* +      printf("Event: type: %d\tinstrument: %d\tvelocity: %f\toffset: %d\n", +      evs[e].type, +      evs[e].instrument, +      evs[e].velocity, +      evs[e].offset); +    */ +    if(evs[e].type == TYPE_ONSET) { +      Instrument *i = NULL; +      int d = evs[e].instrument; +      /* +        Instruments::iterator it = kit.instruments.begin(); +        while(d-- && it != kit.instruments.end()) { +        i = &(it->second); +        it++; +        } +      */ +       +      if(d < (int)kit.instruments.size()) { +        i = &kit.instruments[d]; +      } +       +      if(i == NULL) { +        printf("Missing Instrument %d.\n", evs[e].instrument); +        continue; +      } +       +      Sample *s = i->sample(evs[e].velocity); +       +      if(s == NULL) { +        printf("Missing Sample.\n"); +        continue; +      } +       +      Channels::iterator j = kit.channels.begin(); +      while(j != kit.channels.end()) { +        Channel &ch = *j; +        AudioFile *af = s->getAudioFile(&ch); +        if(af == NULL) { +          //printf("Missing AudioFile.\n"); +        } else { +          printf("Adding event %d.\n", evs[e].offset); +          Event *evt = new EventSample(ch.num, 1.0, af); +          evt->offset = evs[e].offset + pos; +          activeevents[ch.num].push_back(evt); +        } +        j++; +      } +    } +     +    if(evs[e].type == TYPE_STOP) { +      printf("Stoooooop!\n"); +      //    running = false; +    } +     +  } +     +  free(evs); +   +   +  // +  // Write audio +  // +   +  for(size_t c = 0; c < kit.channels.size(); c++) { +    memset(samples, 0, nsamples * sizeof(sample_t)); +    getSamples(c, pos, samples, nsamples); +    oe->run(c, samples, nsamples); +  } +   +  ie->post(); +  oe->post(nsamples); +   +  pos += nsamples;  } -void DrumGizmo::pre(size_t sz) +void DrumGizmo::run()  { -  ie.run(time, sz); +  ie->start(); +  oe->start(); -  for(size_t n = 0; n < sz; n++) { -    while(eventqueue.hasEvent(time + n)) { -      Event *event = eventqueue.take(time + n); -      activeevents[event->channel].push_back(event); -    } +  size_t pos = 0; +  size_t nsamples = 512; +  sample_t samples[nsamples]; + +  bool running = true; + +  while(running) { +    run(pos, samples, nsamples);    } + +  ie->stop(); +  oe->stop();  } -void DrumGizmo::getSamples(Channel *c, sample_t *s, size_t sz) +void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)  { -  for(std::list< Event* >::iterator i = activeevents[c->num].begin(); -      i != activeevents[c->num].end(); +  for(std::list< Event* >::iterator i = activeevents[ch].begin(); +      i != activeevents[ch].end();        i++) {      bool removeevent = false; @@ -113,59 +208,15 @@ void DrumGizmo::getSamples(Channel *c, sample_t *s, size_t sz)      Event::type_t type = event->type();      switch(type) { -    case Event::sine: -      { -        EventSine *evt = (EventSine *)event; -        for(size_t n = 0; n < sz; n++) { -           -          if(evt->offset > (time + n)) continue; - -          if(evt->t > evt->len) { -            removeevent = true; -            break; -          } - -          float x = (float)evt->t / 44100.0; -          float gain = evt->gain; -          gain *= 1.0 - ((float)evt->t / (float)evt->len); -          sample_t val = gain * sin(2.0 * M_PI * evt->freq * x); -          s[n] += val; - -          evt->t++; -        } -      } -      break; - -    case Event::noise: -      { -        EventNoise *evt = (EventNoise *)event; -        for(size_t n = 0; n < sz; n++) { - -          if(evt->offset > (time + n)) continue; - -          if(evt->t > evt->len) { -            removeevent = true; -            break; -          } - -          float gain = evt->gain; -          gain *= 1.0 - ((float)evt->t / (float)evt->len); -          sample_t val = (float)rand() / (float)RAND_MAX; -          s[n] += val * gain; -          evt->t++; -        } -      } -      break; -      case Event::sample:        { -        /*          EventSample *evt = (EventSample *)event; -        AudioFile *af = audiofiles[evt->file]; +        AudioFile *af = evt->file;          af->load(); // Make sure it is loaded. +        //        printf("playing: %s (%d)\n", af->filename.c_str(), sz);          for(size_t n = 0; n < sz; n++) { -          if(evt->offset > (time + n)) continue; +          if(evt->offset > (pos + n)) continue;            if(evt->t > af->size) {              removeevent = true; @@ -178,24 +229,16 @@ void DrumGizmo::getSamples(Channel *c, sample_t *s, size_t sz)            s[n] += val * gain;            evt->t++;          } -        */        }        break;      } -     +      if(removeevent) {        delete event; -      i = activeevents[c->num].erase(i); -      if(activeevents[0].size() + -         activeevents[1].size() + -         eventqueue.size() == 0) {/*is_running = false;*/} +      i = activeevents[ch].erase(i);      } -  } -} -void DrumGizmo::post(size_t sz) -{ -  time += sz; +  }  }  void DrumGizmo::stop() diff --git a/src/drumgizmo.h b/src/drumgizmo.h index 4c6683b..1bdb5b5 100644 --- a/src/drumgizmo.h +++ b/src/drumgizmo.h @@ -30,20 +30,19 @@  #include <string>  #include <list> -#include "drumkit.h" -#include "audio.h" -#include "event.h" +#include "audiooutputengine.h" +#include "audioinputengine.h" -#include "channelmixer.h" +#include "events.h" +#include "audiofile.h" +#include "drumkit.h" -class AudioOutputEngine; -class AudioInputEngine; +#define MAX_NUM_CHANNELS 512  class DrumGizmo {  public: -  DrumGizmo(AudioOutputEngine &outputengine, -            AudioInputEngine &inputengine, -            ChannelMixer &mixer); +  DrumGizmo(AudioOutputEngine *outputengine, +            AudioInputEngine *inputengine);    ~DrumGizmo();    bool loadkit(const std::string &kitfile); @@ -51,29 +50,22 @@ public:    bool init(bool preload = true);    void run(); +  void run(size_t pos, sample_t *samples, size_t nsamples);    void stop(); -  void pre(size_t sz); -  void getSamples(Channel *c, sample_t *s, size_t sz); -  void post(size_t sz); +  void getSamples(int ch, int pos, sample_t *s, size_t sz);    bool isRunning() { return is_running; } -  Channels channels; -  ChannelMixer mixer; - -  EventQueue eventqueue; -  private:    bool is_running; -  AudioOutputEngine &oe; -  AudioInputEngine &ie; +  AudioOutputEngine *oe; +  AudioInputEngine *ie; -  std::list< Event* > activeevents[100]; -  timepos_t time; +  std::list< Event* > activeevents[MAX_NUM_CHANNELS]; -  AudioFiles audiofiles; +  std::map<std::string, AudioFile *> audiofiles;  #ifdef TEST_DRUMGIZMO  public: diff --git a/src/drumkit.h b/src/drumkit.h index d79a3e4..f9883b6 100644 --- a/src/drumkit.h +++ b/src/drumkit.h @@ -2,8 +2,8 @@  /***************************************************************************   *            drumkit.h   * - *  Tue Jul 22 16:29:16 CEST 2008 - *  Copyright 2008 Bent Bisballe Nyeng + *  Wed Mar  9 15:27:26 CET 2011 + *  Copyright 2011 Bent Bisballe Nyeng   *  deva@aasimon.org   ****************************************************************************/ @@ -32,13 +32,20 @@  #include "channel.h"  #include "instrument.h" -#include "midimap.h" +class DrumKitParser;  class DrumKit { +  friend class DrumKitParser;  public: -  std::string name; -  std::string description; +  std::string name(); +  std::string description(); +      Instruments instruments; +  Channels channels; +  +private: +  std::string _name; +  std::string _description;  };  #endif/*__DRUMGIZMO_DRUMKIT_H__*/ diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc index 499b78c..1c16574 100644 --- a/src/drumkitparser.cc +++ b/src/drumkitparser.cc @@ -29,12 +29,19 @@  #include <string.h>  #include <stdio.h> -#define DIR_SEPERATOR '/' +#include "instrumentparser.h" +#include "path.h"  DrumKitParser::DrumKitParser(const std::string &kitfile, DrumKit &k)    : kit(k)  { +  //  instr = NULL; +  path = getPath(kitfile); +    fd = fopen(kitfile.c_str(), "r"); + +  printf("Parsing drumkit in %s\n", kitfile.c_str()); +    if(!fd) return;  } @@ -44,38 +51,93 @@ DrumKitParser::~DrumKitParser()  }  void DrumKitParser::startTag(std::string name, -                             std::map< std::string, std::string> attributes) +                             std::map< std::string, std::string> attr)  {    if(name == "drumkit") { -    kit.name = attributes["name"]; -    kit.description = attributes["description"]; +    if(attr.find("name") != attr.end()) +      kit._name = attr["name"]; + +    if(attr.find("description") != attr.end()) +      kit._description = attr["description"];    }    if(name == "channels") {}    if(name == "channel") { -    //    Channel *c = new Channel(attributes["name"]); -    //    dk->channels[attributes["name"]] = c; +    if(attr.find("name") == attr.end()) { +      printf("Missing channel name.\n"); +      return; +    } +    Channel c(attr["name"]); +    c.num = kit.channels.size(); +    kit.channels.push_back(c);    }    if(name == "instruments") {    }    if(name == "instrument") { +    if(attr.find("name") == attr.end()) { +      printf("Missing name in instrument tag.\n"); +      return; +    } +    if(attr.find("file") == attr.end()) { +      printf("Missing file in instrument tag.\n"); +      return; +    } +    Instrument i; +    InstrumentParser parser(path + "/" + attr["file"], i); +    parser.parse(); +    kit.instruments.push_back(i);//[attr["name"]] = i; + +    // Assign kit channel numbers to instruments channels. +    std::vector<InstrumentChannel*>::iterator ic = parser.channellist.begin(); +    while(ic != parser.channellist.end()) { +      InstrumentChannel *c = *ic; + +      for(size_t cnt = 0; cnt < kit.channels.size(); cnt++) { +        if(kit.channels[cnt].name == c->name) c->num = kit.channels[cnt].num; +      } +      if(c->num == NO_CHANNEL) { +        printf("Missing channel '%s' in instrument '%s'\n", +               c->name.c_str(), i.name().c_str()); +      } else { +        printf("Assigned channel '%s' to number %d in instrument '%s'\n", +               c->name.c_str(), c->num, i.name().c_str()); +      } +      ic++; +    } + +    //instr = &kit.instruments[attr["name"]];    } - +  /*    if(name == "channelmap") { +    if(instr == NULL) { +      printf("Missing instrument.\n"); +      return; +    } + +    if(attr.find("in") == attr.end()) { +      printf("Missing 'in' in channelmap tag.\n"); +      return; +    } + +    if(attr.find("out") == attr.end()) { +      printf("Missing 'out' in channelmap tag.\n"); +      return; +    } +    instr->channelmap[attr["in"]] = attr["out"];    } - -  if(name == "midimaps") { -  } - -  if(name == "midimap") { -  } +  */  }  void DrumKitParser::endTag(std::string name)  { +  /* +  if(name == "instrument") { +    instr = NULL; +  } +  */  }  int DrumKitParser::readData(char *data, size_t size) @@ -84,3 +146,92 @@ int DrumKitParser::readData(char *data, size_t size)    return fread(data, 1, size, fd);  } +#ifdef TEST_DRUMKITPARSER +//deps: drumkit.cc saxparser.cc instrument.cc sample.cc audiofile.cc channel.cc +//cflags: $(EXPAT_CFLAGS) $(SNDFILE_CFLAGS) +//libs: $(EXPAT_LIBS) $(SNDFILE_LIBS) +#include "test.h" + +const char xml[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<drumkit name=\"The Aasimonster\"\n" +"         description=\"A large deathmetal drumkit\">\n" +"  <channels>\n" +"    <channel name=\"Alesis\"/>\n" +"    <channel name=\"Kick-L\"/>\n" +"    <channel name=\"Kick-R\"/>\n" +"    <channel name=\"SnareTop\"/>\n" +"    <channel name=\"SnareTrigger\"/>\n" +"    <channel name=\"SnareBottom\"/>\n" +"    <channel name=\"OH-L\"/>\n" +"    <channel name=\"OH-R\"/>\n" +"    <channel name=\"Hihat\"/>\n" +"    <channel name=\"Ride\"/>\n" +"    <channel name=\"Tom1\"/>\n" +"    <channel name=\"Tom2\"/>\n" +"    <channel name=\"Tom3\"/>\n" +"    <channel name=\"Tom4\"/>\n" +"    <channel name=\"Amb-R\"/>\n" +"    <channel name=\"Amb-L\"/>\n" +"  </channels>\n" +"  <instruments>\n" +"    <instrument name=\"Ride\" file=\"ride.xml\">\n" +"      <channelmap in=\"Alesis\" out=\"Alesis\" gain=\"1.5\"/>\n" +"      <channelmap in=\"Kick-L\" out=\"Kick-L\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Kick-R\" out=\"Kick-R\"/>\n" +"      <channelmap in=\"SnareTop\" out=\"SnareTop\" gain=\"0.5\"/>\n" +"      <channelmap in=\"SnareTrigger\" out=\"SnareTrigger\" gain=\"0.5\"/>\n" +"      <channelmap in=\"SnareBottom\" out=\"SnareBottom\" gain=\"0.5\"/>\n" +"      <channelmap in=\"OH-L\" out=\"OH-L\"/>\n" +"      <channelmap in=\"OH-R\" out=\"OH-R\"/>\n" +"      <channelmap in=\"Hihat\" out=\"Hihat\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Ride\" out=\"Ride\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Tom1\" out=\"Tom1\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Tom2\" out=\"Tom2\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Tom3\" out=\"Tom3\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Tom4\" out=\"Tom4\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Amb-R\" out=\"Amb-R\"/>\n" +"      <channelmap in=\"Amb-L\" out=\"Amb-L\"/>\n" +"    </instrument>\n" +"    <instrument name=\"Snare\" file=\"snare.xml\">\n" +"      <channelmap in=\"Alesis\" out=\"Alesis\" gain=\"1.5\"/>\n" +"      <channelmap in=\"Kick-L\" out=\"Kick-L\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Kick-R\" out=\"Kick-R\"/>\n" +"      <channelmap in=\"SnareTop\" out=\"SnareTop\" gain=\"0.5\"/>\n" +"      <channelmap in=\"SnareTrigger\" out=\"SnareTrigger\" gain=\"0.5\"/>\n" +"      <channelmap in=\"SnareBottom\" out=\"SnareBottom\" gain=\"0.5\"/>\n" +"      <channelmap in=\"OH-L\" out=\"OH-L\"/>\n" +"      <channelmap in=\"OH-R\" out=\"OH-R\"/>\n" +"      <channelmap in=\"Hihat\" out=\"Hihat\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Ride\" out=\"Ride\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Tom1\" out=\"Tom1\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Tom2\" out=\"Tom2\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Tom3\" out=\"Tom3\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Tom4\" out=\"Tom4\" gain=\"0.5\"/>\n" +"      <channelmap in=\"Amb-R\" out=\"Amb-R\"/>\n" +"      <channelmap in=\"Amb-L\" out=\"Amb-L\"/>\n" +"    </instrument>\n" +"  </instruments>\n" +"</drumkit>\n" +  ; + +#define FNAME "/tmp/drumkittest.xml" + +TEST_BEGIN; + +FILE *fp = fopen(FNAME, "w"); +fprintf(fp, "%s", xml); +fclose(fp); + +DrumKit kit; +DrumKitParser p(FNAME, kit); +TEST_EQUAL_INT(p.parse(), 0, "Parsing went well?"); + +TEST_EQUAL_STR(kit.name(), "The Aasimonster", "Compare name"); +TEST_EQUAL_INT(kit.instruments.size(), 2, "How many instruments?"); + +unlink(FNAME); + +TEST_END; + +#endif/*TEST_DRUMKITPARSER*/ diff --git a/src/drumkitparser.h b/src/drumkitparser.h index 783ed5f..f585043 100644 --- a/src/drumkitparser.h +++ b/src/drumkitparser.h @@ -45,6 +45,8 @@ protected:  private:    FILE *fd;    DrumKit &kit; +  //  Instrument *instr; +  std::string path;  };  #endif/*__DRUMGIZMO_DRUMKITPARSER_H__*/ diff --git a/src/event.cc b/src/event.cc deleted file mode 100644 index 717fa12..0000000 --- a/src/event.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            event.cc - * - *  Sat Sep 18 22:02:16 CEST 2010 - *  Copyright 2010 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 "event.h" - -void EventQueue::post(Event *event, timepos_t time) -{ -  MutexAutolock lock(mutex); -  event->offset = time; -  queue.insert(std::pair<timepos_t, Event*>(time, event)); -} - -Event *EventQueue::take(timepos_t time) -{ -  MutexAutolock lock(mutex); -  std::multimap<timepos_t, Event*>::iterator i = queue.find(time); -  if(i == queue.end()) return NULL; -  Event *event = i->second; -  queue.erase(i); -  return event; -} - -bool EventQueue::hasEvent(timepos_t time) -{ -  MutexAutolock lock(mutex); -  return queue.find(time) != queue.end(); -} diff --git a/src/event.h b/src/event.h deleted file mode 100644 index 2128386..0000000 --- a/src/event.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            event.h - * - *  Sat Sep 18 22:02:16 CEST 2010 - *  Copyright 2010 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_EVENT_H__ -#define __DRUMGIZMO_EVENT_H__ - -#include <map> -#include <stdio.h> -#include <string> -#include <sndfile.h> - -#include "audio.h" -#include "mutex.h" - -typedef unsigned int timepos_t; - -class Event { -public: -  typedef enum { -    sine, -    noise, -    sample -  } type_t; -   -  virtual type_t type() = 0; - -  channel_t channel; -  timepos_t offset; -}; - -class EventSine : public Event { -public: -  EventSine(channel_t c, float f, float g, timepos_t l) -  { -    channel = c; -    freq = f; -    gain = g; -    len = l; -    t = 0; -  } -  Event::type_t type() { return Event::sine; } - -  float freq; -  float gain; -  timepos_t len; - -  unsigned int t; -}; - -class EventNoise : public Event { -public: -  EventNoise(channel_t c, float g, timepos_t l) -  { -    channel = c; -    gain = g; -    len = l; -    t = 0; -  } -  Event::type_t type() { return Event::noise; } - -  float gain; -  timepos_t len; - -  unsigned int t; -}; - -class EventSample : public Event { -public: -  EventSample(channel_t c, float g, std::string f) -  { -    channel = c; -    gain = g; -    t = 0; -    file = f; -  } - -  Event::type_t type() { return Event::sample; } - -  float gain; - -  unsigned int t; - -  std::string file; -}; - - - -class EventQueue { -public: -  void post(Event *event, timepos_t time); -  Event *take(timepos_t time); -  bool hasEvent(timepos_t time); -  size_t size() { return queue.size(); } - -private: -  std::multimap< timepos_t, Event* > queue; -  Mutex mutex; -}; - -#endif/*__DRUMGIZMO_EVENT_H__*/ diff --git a/src/instrument.cc b/src/instrument.cc index b710757..1b3c31a 100644 --- a/src/instrument.cc +++ b/src/instrument.cc @@ -27,14 +27,17 @@  #include "instrument.h"  #include <stdlib.h> +#include <stdio.h> -Instrument::Instrument(std::string name) +#include "sample.h" + +Instrument::Instrument()  { -  this->name = name;  }  Sample *Instrument::sample(level_t level)  { +  //  printf("Find level %f\n", level);    std::vector<Sample*> s = samples.get(level);    if(s.size() == 0) return NULL;    size_t idx = rand()%(s.size()); @@ -46,6 +49,16 @@ void Instrument::addSample(level_t a, level_t b, Sample *s)    samples.insert(a, b, s);  } +std::string Instrument::name() +{ +  return _name; +} + +std::string Instrument::description() +{ +  return _description; +} +  #ifdef TEST_INSTRUMENT  //deps: channel.cc sample.cc audiofile.cc  //cflags: $(SNDFILE_CFLAGS) diff --git a/src/instrument.h b/src/instrument.h index b01379f..fb8aeac 100644 --- a/src/instrument.h +++ b/src/instrument.h @@ -31,59 +31,34 @@  #include <vector>  #include "rangemap.h" +  #include "sample.h" +class InstrumentParser;  class Instrument { +  friend class InstrumentParser;  public: -  Instrument(std::string name); +  Instrument();    Sample *sample(level_t level); -  void addSample(level_t a, level_t b, Sample *s); +  std::string name(); +  std::string description(); + +  //  std::map<std::string, std::string> channelmap; + +  std::vector<AudioFile*> audiofiles;  private: -  std::string name; +  std::string _name; +  std::string _description;    RangeMap<level_t, Sample*> samples; -}; +  void addSample(level_t a, level_t b, Sample *s); -typedef std::map< std::string, Instrument > Instruments; +  std::vector<Sample*> samplelist; +}; -/* - * <?xml version='1.0' encoding='UTF-8'?> - * <instrument name="kick-r"> - *  <samples> - *   <sample name="kick-r-1"> - *    <audiofile channel="Alesis-3" file="samples/1-kick-r-Alesis-3.wav"/> - *    <audiofile channel="Amb L-3" file="samples/1-kick-r-Amb L-3.wav"/> - *    <audiofile channel="Amb R-3" file="samples/1-kick-r-Amb R-3.wav"/> - *    <audiofile channel="Kick L-3" file="samples/1-kick-r-Kick L-3.wav"/> - *    <audiofile channel="Kick R-3" file="samples/1-kick-r-Kick R-3.wav"/> - *   </sample> - *   <sample name="kick-r-2"> - *    <audiofile channel="Alesis-3" file="samples/2-kick-r-Alesis-3.wav"/> - *    <audiofile channel="Amb L-3" file="samples/2-kick-r-Amb L-3.wav"/> - *    <audiofile channel="Amb R-3" file="samples/2-kick-r-Amb R-3.wav"/> - *    <audiofile channel="Kick L-3" file="samples/2-kick-r-Kick L-3.wav"/> - *    <audiofile channel="Kick R-3" file="samples/2-kick-r-Kick R-3.wav"/> - *   </sample> - *   <sample name="kick-r-3"> - *    <audiofile channel="Alesis-3" file="samples/3-kick-r-Alesis-3.wav"/> - *    <audiofile channel="Amb L-3" file="samples/3-kick-r-Amb L-3.wav"/> - *    <audiofile channel="Amb R-3" file="samples/3-kick-r-Amb R-3.wav"/> - *    <audiofile channel="Kick L-3" file="samples/3-kick-r-Kick L-3.wav"/> - *    <audiofile channel="Kick R-3" file="samples/3-kick-r-Kick R-3.wav"/> - *   </sample> - *  </samples> - *  <velocities> - *   <velocity lower="0" upper="99"> - *    <sampleref name="kick-r-1"/> - *    <sampleref name="kick-r-2"/> - *   </velocity> - *   <velocity lower="100" upper="127"> - *    <sampleref name="kick-r-3"/> - *   </velocity> - *  </velocities> - * </instrument> - */ +//typedef std::map< std::string, Instrument > Instruments; +typedef std::vector< Instrument > Instruments;  #endif/*__DRUMGIZMO_INSTRUMENT_H__*/ diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc new file mode 100644 index 0000000..5198959 --- /dev/null +++ b/src/instrumentparser.cc @@ -0,0 +1,219 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            instrumentparser.cc + * + *  Wed Mar  9 13:22:24 CET 2011 + *  Copyright 2011 Bent Bisballe Nyeng + *  deva@aasimon.org + ****************************************************************************/ + +/* + *  This file is part of DrumGizmo. + * + *  DrumGizmo is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  DrumGizmo is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with DrumGizmo; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "instrumentparser.h" + +#include <string.h> +#include <stdio.h> + +#include "path.h" + +InstrumentParser::InstrumentParser(const std::string &file, Instrument &i) +  : instrument(i) +{ +  s = NULL; +  printf("Parsing instrument in %s\n", file.c_str()); +  path = getPath(file); +  fd = fopen(file.c_str(), "r"); +  if(!fd) return; +} + +InstrumentParser::~InstrumentParser() +{ +  if(fd) fclose(fd); +} + +void InstrumentParser::startTag(std::string name, +                                std::map< std::string, std::string> attr) +{ +  if(name == "instrument") { +    if(attr.find("name") != attr.end()) +      instrument._name = attr["name"]; + +    if(attr.find("description") != attr.end()) +      instrument._description = attr["description"]; +  } + +  if(name == "samples") { +  } + +  if(name == "sample") { +    if(attr.find("name") == attr.end()) { +      printf("Missing required attribute 'name'.\n"); +      return; +    } +    s = new Sample(attr["name"]); +  } + +  if(name == "audiofile") { +    if(s == NULL) { +      printf("Missing Sample!\n"); +      return; +    } +     +    if(attr.find("file") == attr.end()) { +      printf("Missing required attribute 'file'.\n"); +      return; +    } + +    if(attr.find("channel") == attr.end()) { +      printf("Missing required attribute 'channel'.\n"); +      return; +    } + +    AudioFile *af = new AudioFile(path + "/" + attr["file"]); +    InstrumentChannel *ch = new InstrumentChannel(attr["channel"]); +    channellist.push_back(ch); +    s->addAudioFile(ch, af); +    instrument.audiofiles.push_back(af); +  } + +  if(name == "velocities") { +  } + +  if(name == "velocity") { +    if(attr.find("lower") == attr.end()) { +      printf("Missing required attribute 'lower'.\n"); +      return; +    } + +    if(attr.find("upper") == attr.end()) { +      printf("Missing required attribute 'upper'.\n"); +      return; +    } + +    lower = atof(attr["lower"].c_str()); +    upper = atof(attr["upper"].c_str()); +  } + +  if(name == "sampleref") { +    if(attr.find("name") == attr.end()) { +      printf("Missing required attribute 'name'.\n"); +      return; +    } + +    Sample *sample = NULL; +    std::vector<Sample *>::iterator i = instrument.samplelist.begin(); +    while(i != instrument.samplelist.end()) { +      if((*i)->name == attr["name"]) { +        sample = *i; +        break; +      } +      i++; +    } + +    if(sample == NULL) { +      printf("Samplref pointed at non-existing sample.\n"); +      return; +    } + +    instrument.addSample(lower, upper, sample); +  } +} + +void InstrumentParser::endTag(std::string name) +{ +  if(name == "sample") { +    if(s == NULL) { +      printf("Missing Sample.\n"); +      return; +    } + +    instrument.samplelist.push_back(s); +    s = NULL; +  } +} + +int InstrumentParser::readData(char *data, size_t size) +{ +  if(!fd) return -1; +  return fread(data, 1, size, fd); +} + + +#ifdef TEST_INSTRUMENTPARSER +//deps: saxparser.cc instrument.cc sample.cc audiofile.cc channel.cc +//cflags: $(EXPAT_CFLAGS) $(SNDFILE_CFLAGS) +//libs: $(EXPAT_LIBS) $(SNDFILE_LIBS) +#include "test.h" + +const char xml[] =  +"<?xml version='1.0' encoding='UTF-8'?>\n" +"<instrument name=\"kick-r\">\n" +" <samples>\n" +"  <sample name=\"kick-r-1\">\n" +"   <audiofile channel=\"Alesis\" file=\"samples/1-kick-r-Alesis-3.wav\"/>\n" +"   <audiofile channel=\"Amb L\" file=\"samples/1-kick-r-Amb L-3.wav\"/>\n" +"   <audiofile channel=\"Amb R\" file=\"samples/1-kick-r-Amb R-3.wav\"/>\n" +"   <audiofile channel=\"Kick L\" file=\"samples/1-kick-r-Kick L-3.wav\"/>\n" +"   <audiofile channel=\"Kick R\" file=\"samples/1-kick-r-Kick R-3.wav\"/>\n" +"  </sample>\n" +"  <sample name=\"kick-r-2\">\n" +"   <audiofile channel=\"Alesis\" file=\"samples/2-kick-r-Alesis-3.wav\"/>\n" +"   <audiofile channel=\"Amb L\" file=\"samples/2-kick-r-Amb L-3.wav\"/>\n" +"   <audiofile channel=\"Amb R\" file=\"samples/2-kick-r-Amb R-3.wav\"/>\n" +"   <audiofile channel=\"Kick L\" file=\"samples/2-kick-r-Kick L-3.wav\"/>\n" +"   <audiofile channel=\"Kick R\" file=\"samples/2-kick-r-Kick R-3.wav\"/>\n" +"  </sample>\n" +"  <sample name=\"kick-r-3\">\n" +"   <audiofile channel=\"Alesis\" file=\"samples/3-kick-r-Alesis-3.wav\"/>\n" +"   <audiofile channel=\"Amb L\" file=\"samples/3-kick-r-Amb L-3.wav\"/>\n" +"   <audiofile channel=\"Amb R\" file=\"samples/3-kick-r-Amb R-3.wav\"/>\n" +"   <audiofile channel=\"Kick L\" file=\"samples/3-kick-r-Kick L-3.wav\"/>\n" +"   <audiofile channel=\"Kick R\" file=\"samples/3-kick-r-Kick R-3.wav\"/>\n" +"  </sample>\n" +" </samples>\n" +" <velocities>\n" +"  <velocity lower=\"0\" upper=\"0.7\">\n" +"   <sampleref name=\"kick-r-1\"/>\n" +"   <sampleref name=\"kick-r-2\"/>\n" +"  </velocity>\n" +"  <velocity lower=\"0.7\" upper=\"1.0\">\n" +"   <sampleref name=\"kick-r-3\"/>\n" +"  </velocity>\n" +" </velocities>\n" +"</instrument>\n" +  ; + +#define FNAME "/tmp/instrtest.xml" + +TEST_BEGIN; + +FILE *fp = fopen(FNAME, "w"); +fprintf(fp, "%s", xml); +fclose(fp); + +Instrument instr; +InstrumentParser p(FNAME, instr); +TEST_EQUAL_INT(p.parse(), 0, "Parsing went well?"); + +TEST_EQUAL_STR(instr.name(), "kick-r", "Compare name"); + +unlink(FNAME); + +TEST_END; + +#endif/*TEST_INSTRUMENTPARSER*/ diff --git a/src/audioinputenginejackmidi.h b/src/instrumentparser.h index 9807a40..2a7a9c9 100644 --- a/src/audioinputenginejackmidi.h +++ b/src/instrumentparser.h @@ -1,8 +1,8 @@  /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */  /*************************************************************************** - *            audioinputenginejackmidi.h + *            instrumentparser.h   * - *  Sun Feb 27 11:33:31 CET 2011 + *  Wed Mar  9 13:22:24 CET 2011   *  Copyright 2011 Bent Bisballe Nyeng   *  deva@aasimon.org   ****************************************************************************/ @@ -24,32 +24,37 @@   *  along with DrumGizmo; if not, write to the Free Software   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.   */ -#ifndef __DRUMGIZMO_AUDIOINPUTENGINEJACKMIDI_H__ -#define __DRUMGIZMO_AUDIOINPUTENGINEJACKMIDI_H__ +#ifndef __DRUMGIZMO_INSTRUMENTPARSER_H__ +#define __DRUMGIZMO_INSTRUMENTPARSER_H__ -#include <jack/jack.h> -#include <jack/midiport.h> +#include "saxparser.h" +#include "instrument.h" -#include "audioinputengine.h" -#include "event.h" +#include <vector> -class AudioInputEngineJackMidi : public AudioInputEngine { +class InstrumentParser : public SAXParser {  public: -  AudioInputEngineJackMidi(); -  ~AudioInputEngineJackMidi(); +  InstrumentParser(const std::string &instrfile, Instrument &instrument); +  ~InstrumentParser(); -  bool init(EventQueue *e); -  void run(size_t pos, size_t len) {} +  void startTag(std::string name, +                std::map< std::string, std::string> attributes); +  void endTag(std::string name); -  void thread_main(); +  std::vector<InstrumentChannel *> channellist; -  int process(jack_nframes_t nframes); +protected: +  int readData(char *data, size_t size);  private: -  size_t pos; -  EventQueue *eventqueue; -  jack_client_t *jack_client; -  jack_port_t *midi_port; +  FILE *fd; +  Instrument &instrument; +  Sample *s; + +  std::string path; + +  level_t lower; +  level_t upper;  }; -#endif/*__DRUMGIZMO_AUDIOINPUTENGINEJACKMIDI_H__*/ +#endif/*__DRUMGIZMO_INSTRUMENTPARSER_H__*/ diff --git a/src/jackclient.cc b/src/jackclient.cc deleted file mode 100644 index cac1b74..0000000 --- a/src/jackclient.cc +++ /dev/null @@ -1,260 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            jackclient.cc - * - *  Sun Jul 20 21:48:44 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 "jackclient.h" - -extern "C" -{ -  void _wrap_jack_shutdown(void *arg){ -    ((JackClient*)arg)->shutdown();} -  int _wrap_jack_process(jack_nframes_t nframes, void *arg){ -    return ((JackClient*)arg)->process(nframes);} -  void _wrap_jack_thread_init(void *arg){ -    ((JackClient*)arg)->thread_init();} -  void _wrap_jack_freewheel_mode(int freewheel_mode, void *arg){ -    ((JackClient*)arg)->freewheel_mode(freewheel_mode);} -  int _wrap_jack_buffer_size(jack_nframes_t nframes, void *arg){ -    return ((JackClient*)arg)->buffer_size(nframes);} -  int _wrap_jack_sample_rate(jack_nframes_t nframes, void *arg){ -    return ((JackClient*)arg)->sample_rate(nframes);} -  void _wrap_jack_port_registration(jack_port_id_t port, int i, void *arg){ -    ((JackClient*)arg)->port_registration(port, i);} -  int _wrap_jack_graph_order(void *arg){ -    return ((JackClient*)arg)->graph_order();} -  int _wrap_jack_xrun(void *arg){ -    return ((JackClient*)arg)->xrun();} -}  // extern "C" - -JackClient::JackClient(DrumKit *drumkit) -  : midimapper(drumkit) -{ -  this->drumkit = drumkit; - -	jack_status_t status; - -	jack_client = jack_client_open("DrumGizmo", JackNullOption, &status); - -	// Setup input port -	midi_port = jack_port_register(jack_client, -                                 "midi_in", -                                 JACK_DEFAULT_MIDI_TYPE, -                                 JackPortIsInput,// | JackPortIsTerminal, -                                 0); - -	// Setup input ports -  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); - -    BeatMapper *beatmapper = new BeatMapper(instrument); -    beatmappers.push_back(beatmapper); - -    //    input_ports.push_back(instrument->port); -    ii++; -	} - -	// Setup output ports -  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); -  jack_set_process_callback(jack_client, _wrap_jack_process, this); -	//jack_set_thread_init_callback(jack_client, _wrap_jack_thread_init, this); -	//jack_set_freewheel_callback(jack_client, _wrap_jack_freewheel_mode, this); -	//jack_set_buffer_size_callback(jack_client, _wrap_jack_buffer_size, this); -	//jack_set_sample_rate_callback(jack_client, _wrap_jack_sample_rate, this); -	//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); -} - -JackClient::~JackClient() -{ -	jack_client_close(jack_client); -} - -void JackClient::activate() -{ -	jack_activate(jack_client); -} - -void JackClient::shutdown() -{ -} - -int JackClient::process(jack_nframes_t nframes) -{ -  // -  // Look for midi input -  // -	void *midibuffer = jack_port_get_buffer(midi_port, nframes); -	jack_nframes_t midievents = jack_midi_get_event_count(midibuffer); -	for(jack_nframes_t i = 0; i < midievents; i++) { -		jack_midi_event_t midi_event; -		jack_midi_event_get(&midi_event, midibuffer, i); -     -    Sample *sample = midimapper.map(midi_event); -    if(!sample) continue; - -    AudioFiles::iterator ai = sample->audiofiles.begin(); -    while(ai != sample->audiofiles.end()) { -      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); - -  // -  // Look for audio trigger input -  // -  //  std::vector< BeatMapper >::iterator bi = beatmappers.begin(); -  //  while(bi != beatmappers.end()) { -  for(size_t bi = 0; bi < beatmappers.size(); bi++) { -    BeatMapper *beatmapper = beatmappers[bi];//*bi; - -    Sample *sample = beatmapper->map(nframes); -    if(!sample) continue; - -    AudioFiles::iterator ai = sample->audiofiles.begin(); -    while(ai != sample->audiofiles.end()) { -      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, 0); -        events.insert(event); -      } -      ai++; -    } - -    //bi++; -  } - -  // -  // Reset ports  -  // -  Ports::iterator pi = output_ports.begin(); -  while(pi != output_ports.end()) { -     -    jack_default_audio_sample_t *buffer; -    buffer = (jack_default_audio_sample_t *)jack_port_get_buffer(*pi, nframes); -     -    for(size_t j = 0; j < nframes; j++) { -      buffer[j] = 0; -    } -     -    pi++; -  } - -  Events nextevents; - -  // -  // Handle events -  // -  Events::iterator ei = events.begin(); -  while(ei != events.end()) { - -    Event event = *ei; - -    jack_default_audio_sample_t *buffer; -    buffer = (jack_default_audio_sample_t *)jack_port_get_buffer(event.port, nframes); -     -    size_t dtime = nframes - event.time; // how much buffer is left? -    size_t size = event.sample->size - event.duration; // how much audio is left? -    if(size > dtime) size = dtime; -     -    for(size_t j = event.time; j < event.time + size; j++) { -      buffer[j] += event.sample->data[event.duration + j - event.time]; -    } -     -    if(event.duration + size < event.sample->size) { -      Event e(event.port, event.sample, 0, event.duration + size); -      nextevents.insert(e); -    } -     -    ei++; -  } - -  // Remove all dead events -  events = nextevents; - -	return 0; -} - -void JackClient::thread_init() -{ -} - -void JackClient::freewheel_mode(int freewheel_mode) -{ -} - -int JackClient::buffer_size(jack_nframes_t nframes) -{ -  return 0; -} - -int JackClient::sample_rate(jack_nframes_t nframes) -{ -  return 0; -} - -void JackClient::port_registration(jack_port_id_t port, int i) -{ -} - -int JackClient::graph_order() -{ -  return 0; -} - -int JackClient::xrun() -{ -  return 0; -} diff --git a/src/jackclient.h b/src/jackclient.h deleted file mode 100644 index 21e1615..0000000 --- a/src/jackclient.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            jackclient.h - * - *  Sun Jul 20 21:48:44 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_JACKCLIENT_H__ -#define __DRUMGIZMO_JACKCLIENT_H__ - -#include <vector> - -#include <jack/jack.h> -#include <jack/midiport.h> - -#include "drumkit.h" -#include "event.h" -#include "sample.h" -#include "midimapper.h" -#include "beatmapper.h" - -typedef std::vector< jack_port_t *> Ports; - -class JackClient { -public: -  JackClient(DrumKit *drumkit); -  ~JackClient(); - -  void activate(); - -  // Callbacks -  void shutdown(); -  int process(jack_nframes_t nframes); -  void thread_init(); -  void freewheel_mode(int freewheel_mode); -  int buffer_size(jack_nframes_t nframes); -  int sample_rate(jack_nframes_t nframes); -  void port_registration(jack_port_id_t port, int i); -  int graph_order(); -  int xrun(); - -private: -	jack_client_t *jack_client; -  //  Ports input_ports; -  Ports output_ports; -  jack_port_t *midi_port; - -  Events events; - -  DrumKit *drumkit; - -  MidiMapper midimapper; -  std::vector< BeatMapper* > beatmappers; -}; - -#endif/*__DRUMGIZMO_JACKCLIENT_H__*/ diff --git a/src/audioinputenginemidifile.cc b/src/path.cc index 878ca1b..3812b87 100644 --- a/src/audioinputenginemidifile.cc +++ b/src/path.cc @@ -1,8 +1,8 @@  /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */  /*************************************************************************** - *            audioinputenginemidifile.cc + *            path.cc   * - *  Sun Feb 27 11:43:32 CET 2011 + *  Tue May  3 14:42:47 CEST 2011   *  Copyright 2011 Bent Bisballe Nyeng   *  deva@aasimon.org   ****************************************************************************/ @@ -24,9 +24,21 @@   *  along with DrumGizmo; if not, write to the Free Software   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.   */ -#include "audioinputenginemidifile.h" +#include "path.h" -#ifdef TEST_AUDIOINPUTENGINEMIDIFILE +#include <libgen.h> +#include <string.h> +#include <stdlib.h> + +std::string getPath(std::string file) +{ +  char *b = strdup(file.c_str()); +  std::string p = dirname(b); +  free(b); +  return p; +} + +#ifdef TEST_PATH  //Additional dependency files  //deps:  //Required cflags (autoconf vars may be used) @@ -37,8 +49,13 @@  TEST_BEGIN; -// TODO: Put some testcode here (see test.h for usable macros). +std::string a = "../dir/file"; +TEST_EQUAL_STR(getPath(a), "../dir", "relative path"); + +std::string b = "/abs/path/file"; +TEST_EQUAL_STR(getPath(b), "/abs/path", "absolute path"); +  TEST_END; -#endif/*TEST_AUDIOINPUTENGINEMIDIFILE*/ +#endif/*TEST_PATH*/ @@ -1,9 +1,9 @@  /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */  /*************************************************************************** - *            cli.h + *            path.h   * - *  Thu Sep 16 10:23:22 CEST 2010 - *  Copyright 2010 Bent Bisballe Nyeng + *  Tue May  3 14:42:46 CEST 2011 + *  Copyright 2011 Bent Bisballe Nyeng   *  deva@aasimon.org   ****************************************************************************/ @@ -24,6 +24,11 @@   *  along with DrumGizmo; if not, write to the Free Software   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.   */ -#ifndef __DRUMGIZMO_CLI_H__ -#define __DRUMGIZMO_CLI_H__ -#endif/*__DRUMGIZMO_CLI_H__*/ +#ifndef __DRUMGIZMO_PATH_H__ +#define __DRUMGIZMO_PATH_H__ + +#include <string> + +std::string getPath(std::string file); + +#endif/*__DRUMGIZMO_PATH_H__*/ diff --git a/src/sample.cc b/src/sample.cc index f0bb099..be897c7 100644 --- a/src/sample.cc +++ b/src/sample.cc @@ -47,8 +47,19 @@ void Sample::addAudioFile(Channel *c, AudioFile *a)  AudioFile *Sample::getAudioFile(Channel *c)  { +  /*    if(audiofiles.find(c) == audiofiles.end()) return NULL;    return audiofiles[c]; +  */ + +  AudioFiles::iterator i = audiofiles.begin(); +  while(i != audiofiles.end()) { +    Channel *ch = i->first; +    if(c->num == ch->num) return i->second; +    i++; +  } + +  return NULL;  }  #ifdef TEST_SAMPLE diff --git a/src/sample.h b/src/sample.h index c4d82f8..70cfee2 100644 --- a/src/sample.h +++ b/src/sample.h @@ -35,15 +35,18 @@  typedef std::map< Channel*, AudioFile* > AudioFiles; +class InstrumentParser;  class Sample { +  friend class InstrumentParser;  public: -  Sample(std::string name = ""); +  Sample(std::string name);    ~Sample(); -  void addAudioFile(InstrumentChannel *c, AudioFile *a);    AudioFile *getAudioFile(InstrumentChannel *c);  private: +  void addAudioFile(InstrumentChannel *c, AudioFile *a); +    std::string name;    AudioFiles audiofiles;  }; | 
