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; }; |