From 41a6b0ebb6f71032c5a8e69e6aa8c813657224d7 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Mon, 27 Jul 2015 19:36:28 +0200 Subject: Add free-wheel mode to LV2 and DrumGizmo class. --- lv2/drumgizmo.ttl | 47 +++++++++++++++++++++++++++++------------------ lv2/lv2.cc | 35 ++++++++++++++++++++++++++--------- lv2/lv2_instance.h | 2 ++ src/cachemanager.cc | 9 ++++++++- src/cachemanager.h | 9 +++++++++ src/drumgizmo.cc | 11 +++++++++++ src/drumgizmo.h | 3 +++ 7 files changed, 88 insertions(+), 28 deletions(-) diff --git a/lv2/drumgizmo.ttl b/lv2/drumgizmo.ttl index 23345f3..6ce3e91 100644 --- a/lv2/drumgizmo.ttl +++ b/lv2/drumgizmo.ttl @@ -37,108 +37,119 @@ lv2:optionalFeature ; lv2:optionalFeature ; lv2:extensionData state:interface ; -lv2:port [ + lv2:port [ + a lv2:InputPort, lv2:ControlPort ; + lv2:index 0 ; + lv2:symbol "lv2_freewheel" ; + lv2:name "Freewheel" ; + lv2:default 0.0 ; + lv2:minimum 0.0 ; + lv2:maximum 1.0 ; + lv2:designation ; + lv2:portProperty lv2:toggled ; + lv2:portProperty epp:hasStrictBounds; + ] , [ a atom:AtomPort , lv2:InputPort; atom:bufferType atom:Sequence ; atom:supports ; - lv2:index 0 ; + lv2:index 1 ; lv2:symbol "control" ; lv2:name "Control" ] , [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 1 ; + lv2:index 2 ; lv2:symbol "out1" ; lv2:name "Out1" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 2 ; + lv2:index 3 ; lv2:symbol "out2" ; lv2:name "Out2" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 3 ; + lv2:index 4 ; lv2:symbol "out3" ; lv2:name "Out3" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 4 ; + lv2:index 5 ; lv2:symbol "out4" ; lv2:name "Out4" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 5 ; + lv2:index 6 ; lv2:symbol "out5" ; lv2:name "Out5" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 6 ; + lv2:index 7 ; lv2:symbol "out6" ; lv2:name "Out6" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 7 ; + lv2:index 8 ; lv2:symbol "out7" ; lv2:name "Out7" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 8 ; + lv2:index 9 ; lv2:symbol "out8" ; lv2:name "Out8" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 9 ; + lv2:index 10 ; lv2:symbol "out9" ; lv2:name "Out9" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 10 ; + lv2:index 11 ; lv2:symbol "out10" ; lv2:name "Out10" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 11 ; + lv2:index 12 ; lv2:symbol "out11" ; lv2:name "Out11" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 12 ; + lv2:index 13 ; lv2:symbol "out12" ; lv2:name "Out12" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 13 ; + lv2:index 14 ; lv2:symbol "out13" ; lv2:name "Out13" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 14 ; + lv2:index 15 ; lv2:symbol "out14" ; lv2:name "Out14" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 15 ; + lv2:index 16 ; lv2:symbol "out15" ; lv2:name "Out15" ], [ a lv2:AudioPort , lv2:OutputPort ; - lv2:index 16 ; + lv2:index 17 ; lv2:symbol "out16" ; lv2:name "Out16" ] . diff --git a/lv2/lv2.cc b/lv2/lv2.cc index 687f989..9722fad 100644 --- a/lv2/lv2.cc +++ b/lv2/lv2.cc @@ -35,6 +35,12 @@ #include +enum { + FREE_WHEEL_PORT = 0, + MIDI_PORT, + AUDIO_PORT_BASE +}; + #define DRUMGIZMO_URI "http://drumgizmo.org/lv2" #define NS_DG DRUMGIZMO_URI "/atom#" @@ -125,6 +131,9 @@ LV2_Handle instantiate(const struct _LV2_Descriptor *descriptor, { DGLV2 *dglv2 = new DGLV2; + dglv2->free_wheel_port = NULL; // Not assigned + dglv2->pos = 0; // Start from the beginning + dglv2->map = NULL; for (int i = 0 ; features[i] ; i++) { if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) { @@ -150,13 +159,18 @@ void connect_port(LV2_Handle instance, uint32_t port, void *data_location) { DGLV2 *dglv2 = (DGLV2 *)instance; - if(port == 0) {// MIDI in + if(port == FREE_WHEEL_PORT) { + dglv2->free_wheel_port = (float*)data_location; + } + + if(port == MIDI_PORT) { // MIDI in dglv2->in->eventPort = (LV2_Atom_Sequence*)data_location; - } else {// Audio Port - if(port - 1 < NUM_OUTPUTS) { - dglv2->out->outputPorts[port - 1].samples = (sample_t*)data_location; - dglv2->out->outputPorts[port - 1].size = 0; - } + } + + if(port >= AUDIO_PORT_BASE) { // Audio Port + uint32_t audio_port = port - AUDIO_PORT_BASE; + dglv2->out->outputPorts[audio_port].samples = (sample_t*)data_location; + dglv2->out->outputPorts[audio_port].size = 0; } } @@ -169,16 +183,19 @@ void activate(LV2_Handle instance) void run(LV2_Handle instance, uint32_t sample_count) { - static size_t pos = 0; DGLV2 *dglv2 = (DGLV2 *)instance; + if(dglv2->free_wheel_port) { + dglv2->dg->setFreeWheel(*dglv2->free_wheel_port); + } + if(dglv2->buffer_size != sample_count) { dglv2->buffer_size = sample_count; dglv2->dg->setFrameSize(sample_count); } - dglv2->dg->run(pos, dglv2->buffer, sample_count); + dglv2->dg->run(dglv2->pos, dglv2->buffer, sample_count); - pos += sample_count; + dglv2->pos += sample_count; } void deactivate(LV2_Handle instance) diff --git a/lv2/lv2_instance.h b/lv2/lv2_instance.h index e050e22..0ce98bb 100644 --- a/lv2/lv2_instance.h +++ b/lv2/lv2_instance.h @@ -43,6 +43,8 @@ typedef struct { sample_t *buffer; size_t buffer_size; LV2_URID_Map* map; + float* free_wheel_port; + size_t pos; } DGLV2; #endif/*__DRUMGIZMO_LV2_INSTANCE_H__*/ diff --git a/src/cachemanager.cc b/src/cachemanager.cc index dc4b3e7..4cc1fa5 100644 --- a/src/cachemanager.cc +++ b/src/cachemanager.cc @@ -321,6 +321,14 @@ void CacheManager::setFrameSize(size_t framesize) this->framesize = framesize; } +void CacheManager::setAsyncMode(bool async) +{ + // TODO: Clean out read queue. + // TODO: Block until reader thread is idle, otherwise we might screw up the + // buffers...? + threaded = async; +} + void CacheManager::handleLoadNextEvent(cevent_t &e) { assert(files.find(e.afile->filename) != files.end()); @@ -355,7 +363,6 @@ void CacheManager::handleCloseEvent(cevent_t &e) } } - void CacheManager::handleEvent(cevent_t &e) { switch(e.cmd) { diff --git a/src/cachemanager.h b/src/cachemanager.h index 4fe813e..1660ecf 100644 --- a/src/cachemanager.h +++ b/src/cachemanager.h @@ -130,8 +130,17 @@ public: */ void close(cacheid_t id); + /** + * Set internal framesize used when iterating through cache buffers. + */ void setFrameSize(size_t framesize); + /** + * Control reader thread. + * Set to true to make reading happen threaded, false to do all reading sync. + */ + void setAsyncMode(bool async); + ///! Internal thread main method - needs to be public. void thread_main(); diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index 528b542..5348324 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -51,6 +51,7 @@ DrumGizmo::DrumGizmo(AudioOutputEngine *o, AudioInputEngine *i) , oe(o) , ie(i) , framesize(0) + , freewheel(false) { is_stopping = false; cacheManager.init(1000, true); // start thread @@ -189,6 +190,16 @@ void DrumGizmo::setFrameSize(size_t framesize) } } +void DrumGizmo::setFreeWheel(bool freewheel) +{ + // Freewheel = true means that we are bouncing and therefore running faster + // than realtime. + if(freewheel != this->freewheel) { + this->freewheel = freewheel; + cacheManager.setAsyncMode(!freewheel); + } +} + bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples) { setFrameSize(nsamples); diff --git a/src/drumgizmo.h b/src/drumgizmo.h index 807e1e0..240ae9f 100644 --- a/src/drumgizmo.h +++ b/src/drumgizmo.h @@ -77,6 +77,8 @@ public: void setFrameSize(size_t framesize); + void setFreeWheel(bool freewheel); + private: DrumKitLoader loader; @@ -99,4 +101,5 @@ private: DrumKit kit; size_t framesize; + bool freewheel; }; -- cgit v1.2.3