summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2015-07-27 19:36:28 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2016-01-20 13:31:09 +0100
commit41a6b0ebb6f71032c5a8e69e6aa8c813657224d7 (patch)
tree92c1fcd62d3b910fced00b51dd79ce302e1c33d7
parent116b8dbef22bf3245bcf6c8195bf8bb8c0ea91d3 (diff)
Add free-wheel mode to LV2 and DrumGizmo class.
-rw-r--r--lv2/drumgizmo.ttl47
-rw-r--r--lv2/lv2.cc35
-rw-r--r--lv2/lv2_instance.h2
-rw-r--r--src/cachemanager.cc9
-rw-r--r--src/cachemanager.h9
-rw-r--r--src/drumgizmo.cc11
-rw-r--r--src/drumgizmo.h3
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 <http://lv2plug.in/ns/ext/uri-map> ;
lv2:optionalFeature <http://lv2plug.in/ns/ext/event> ;
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 <http://lv2plug.in/ns/lv2core#freeWheeling> ;
+ lv2:portProperty lv2:toggled ;
+ lv2:portProperty epp:hasStrictBounds;
+ ] , [
a atom:AtomPort ,
lv2:InputPort;
atom:bufferType atom:Sequence ;
atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ;
- 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 <hugin.hpp>
+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;
};