summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordeva <deva>2011-07-15 13:02:33 +0000
committerdeva <deva>2011-07-15 13:02:33 +0000
commitcd0e36773992e26985bdec1f7a5341f83fa3e521 (patch)
tree4710fb3f2465f4b464f5f6176261a67cfde2e46e /src
parente190d38057892b69246391841b234a368bc2b4ad (diff)
New input/output plugin architecture. New LV2 plugin.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am64
-rw-r--r--src/audio.h10
-rw-r--r--src/audiofile.cc2
-rw-r--r--src/audiofile.h1
-rw-r--r--src/audioinputengine.cc13
-rw-r--r--src/audioinputengine.h18
-rw-r--r--src/audioinputenginejackmidi.cc116
-rw-r--r--src/audioinputenginemidifile.h41
-rw-r--r--src/audiooutputengine.cc14
-rw-r--r--src/audiooutputengine.h19
-rw-r--r--src/audiooutputenginealsa.cc194
-rw-r--r--src/audiooutputenginealsa.h51
-rw-r--r--src/audiooutputenginejack.cc106
-rw-r--r--src/audiooutputenginejack.h59
-rw-r--r--src/audiooutputenginesndfile.cc84
-rw-r--r--src/audiooutputenginesndfile.h51
-rw-r--r--src/channel.h3
-rw-r--r--src/cli.cc189
-rw-r--r--src/drumgizmo.cc221
-rw-r--r--src/drumgizmo.h36
-rw-r--r--src/drumkit.h17
-rw-r--r--src/drumkitparser.cc177
-rw-r--r--src/drumkitparser.h2
-rw-r--r--src/event.cc50
-rw-r--r--src/event.h123
-rw-r--r--src/instrument.cc17
-rw-r--r--src/instrument.h59
-rw-r--r--src/instrumentparser.cc219
-rw-r--r--src/instrumentparser.h (renamed from src/audioinputenginejackmidi.h)45
-rw-r--r--src/jackclient.cc260
-rw-r--r--src/jackclient.h75
-rw-r--r--src/path.cc (renamed from src/audioinputenginemidifile.cc)29
-rw-r--r--src/path.h (renamed from src/cli.h)17
-rw-r--r--src/sample.cc11
-rw-r--r--src/sample.h7
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(&params);
- // 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*/
diff --git a/src/cli.h b/src/path.h
index a5c42be..bdad0a5 100644
--- a/src/cli.h
+++ b/src/path.h
@@ -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;
};