summaryrefslogtreecommitdiff
path: root/src/drumgizmo.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/drumgizmo.cc')
-rw-r--r--src/drumgizmo.cc106
1 files changed, 70 insertions, 36 deletions
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index 7ce05ef..8661232 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -46,14 +46,19 @@
#include "nolocale.h"
DrumGizmo::DrumGizmo(AudioOutputEngine *o, AudioInputEngine *i)
- : MessageReceiver(MSGRCV_ENGINE),
- loader(), oe(o), ie(i)
+ : MessageReceiver(MSGRCV_ENGINE)
+ , loader()
+ , oe(o)
+ , ie(i)
+ , framesize(0)
{
is_stopping = false;
+ cacheManager.init(1000, true); // start thread
}
DrumGizmo::~DrumGizmo()
{
+ cacheManager.deinit(); // stop thread
}
bool DrumGizmo::loadkit(std::string file)
@@ -164,8 +169,30 @@ void DrumGizmo::handleMessage(Message *msg)
}
}
+void DrumGizmo::setFrameSize(size_t framesize)
+{
+ // If we are resampling override the frame size.
+ if(resampler[0].ratio() != 1) {
+ framesize = RESAMPLER_INPUT_BUFFER;
+ }
+
+ if(this->framesize != framesize) {
+ printf("New framesize: %d\n", framesize);
+
+ this->framesize = framesize;
+
+ // Update framesize in drumkitloader and cachemanager:
+ loader.setFrameSize(framesize);
+ printf("loader.setFrameSize\n"); fflush(stdout);
+ cacheManager.setFrameSize(framesize);
+ printf("cacheManager.setFrameSize\n"); fflush(stdout);
+ }
+}
+
bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
{
+ setFrameSize(nsamples);
+
// Handle engine messages, at most one in each iteration:
handleMessages(1);
@@ -353,26 +380,6 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
return true;
}
-void DrumGizmo::run(int endpos)
-{
- size_t pos = 0;
- size_t nsamples = oe->getBufferSize();
- sample_t *samples = (sample_t *)malloc(nsamples * sizeof(sample_t));
-
- ie->start();
- oe->start();
-
- while(run(pos, samples, nsamples) == true) {
- pos += nsamples;
- if(endpos != -1 && pos >= (size_t)endpos) break;
- }
-
- ie->stop();
- oe->stop();
-
- free(samples);
-}
-
#ifdef SSE
#define N 8
typedef float vNsf __attribute__ ((vector_size(sizeof(float)*N)));
@@ -381,7 +388,7 @@ typedef float vNsf __attribute__ ((vector_size(sizeof(float)*N)));
void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)
{
std::list< Event* >::iterator i = activeevents[ch].begin();
- while(i != activeevents[ch].end()) {
+ for(; i != activeevents[ch].end(); ++i) {
bool removeevent = false;
Event *event = *i;
@@ -398,43 +405,68 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)
break;
}
+ // Don't handle event now is is scheduled for a future iteration?
+ if(evt->offset > (pos + sz)) {
+ continue;
+ }
+
+ if(evt->cache_id == CACHE_NOID) {
+ size_t initial_chunksize = (pos + sz) - evt->offset;
+ evt->buffer =
+ cacheManager.open(af, initial_chunksize, ch, evt->cache_id);
+ evt->buffer_size = initial_chunksize;
+ }
+
{
MutexAutolock l(af->mutex);
- size_t n = 0;
+ size_t n = 0; // default start point is 0.
+
+ // If we are not at offset 0 in current buffer:
if(evt->offset > (size_t)pos) n = evt->offset - pos;
- size_t end = sz;
+
+ size_t end = sz; // default end point is the end of the buffer.
+
+ // Find the end point intra-buffer
if((evt->t + end - n) > af->size) end = af->size - evt->t + n;
+
+ // This should not be necessary but make absolutely shure that we do
+ // not write over the end of the buffer.
if(end > sz) end = sz;
+ size_t t = 0; // Internal buffer counter
if(evt->rampdown == NO_RAMPDOWN) {
#ifdef SSE
-// DEBUG(drumgizmo,"%d\n", evt->t); fflush(stdout);
- size_t optend = ((end - n) / N) * N + n;
- for(; n < optend; n += N) {
- *(vNsf*)&(s[n]) += *(vNsf*)&(af->data[evt->t]);
- evt->t += N;
- }
+ size_t optend = ((end - n) / N) * N + n;
+ for(; n < optend; n += N) {
+ *(vNsf*)&(s[n]) += *(vNsf*)&(evt->buffer[t]);
+ t += N;
+ }
#endif
for(; n < end; n++) {
- s[n] += af->data[evt->t];
- evt->t++;
+ s[n] += evt->buffer[t];
+ t++;
}
} else { // Ramp down in progress.
for(; n < end && evt->rampdown; n++) {
float scale = (float)evt->rampdown/(float)evt->ramp_start;
- s[n] += af->data[evt->t] * scale;
- evt->t++;
+ s[n] += evt->buffer[t] * scale;
+ t++;
evt->rampdown--;
}
if(evt->rampdown == 0) {
removeevent = true; // Down ramp done. Remove event.
+ cacheManager.close(evt->cache_id);
}
}
+ evt->t += t; // Add internal buffer counter to "global" event counter.
if(evt->t >= af->size) {
removeevent = true;
+ cacheManager.close(evt->cache_id);
+ } else {
+ evt->buffer = cacheManager.next(evt->cache_id, evt->buffer_size);
}
}
@@ -447,7 +479,6 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)
i = activeevents[ch].erase(i);
continue;
}
- i++;
}
}
@@ -468,6 +499,9 @@ void DrumGizmo::setSamplerate(int samplerate)
for(int i = 0; i < MAX_NUM_CHANNELS; i++) {
resampler[i].setup(kit.samplerate(), Conf::samplerate);
}
+ if(resampler[0].ratio() != 1) {
+ setFrameSize(RESAMPLER_INPUT_BUFFER);
+ }
#endif/*WITH_RESAMPLER*/
}