summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2015-05-22 10:34:21 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2015-05-22 10:34:21 +0200
commitbef1d5542f926a3b942374707dd56041013d35ff (patch)
tree71161b4239db1de08d5a3ee60399a596490f3486
parentacf59a4f960b3e45db566675551b8158b47e1554 (diff)
Added framesize control mechanism to the engine, and made us of it in the cachemanager and drumkitloader.
-rw-r--r--drumgizmo/drumgizmoc.cc19
-rw-r--r--drumgizmo/output/alsa/alsa.cc12
-rw-r--r--lv2/lv2.cc34
-rw-r--r--src/audiooutputengine.h5
-rw-r--r--src/cachemanager.cc51
-rw-r--r--src/cachemanager.h9
-rw-r--r--src/drumgizmo.cc60
-rw-r--r--src/drumgizmo.h21
-rw-r--r--src/drumkitloader.cc12
-rw-r--r--src/drumkitloader.h5
-rw-r--r--vst/drumgizmo_vst.cc1
11 files changed, 140 insertions, 89 deletions
diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc
index d6fea9e..612973f 100644
--- a/drumgizmo/drumgizmoc.cc
+++ b/drumgizmo/drumgizmoc.cc
@@ -322,6 +322,8 @@ int CliMain::run(int argc, char *argv[])
DrumGizmo gizmo(oe, ie);
+ gizmo.setFrameSize(oe->getBufferSize());
+
if(kitfile == "" || !gizmo.loadkit(kitfile)) {
printf("Failed to load \"%s\".\n", kitfile.c_str());
return 1;
@@ -349,7 +351,22 @@ int CliMain::run(int argc, char *argv[])
return 1;
}
- gizmo.run(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(gizmo.run(pos, samples, nsamples) == true) {
+ pos += nsamples;
+ if(endpos != -1 && pos >= (size_t)endpos) break;
+ }
+
+ ie->stop();
+ oe->stop();
+
+ free(samples);
printf("Quit.\n"); fflush(stdout);
diff --git a/drumgizmo/output/alsa/alsa.cc b/drumgizmo/output/alsa/alsa.cc
index dc2ac73..0de3cdb 100644
--- a/drumgizmo/output/alsa/alsa.cc
+++ b/drumgizmo/output/alsa/alsa.cc
@@ -49,6 +49,7 @@ public:
void pre(size_t size);
void run(int channel, sample_t* data, size_t size);
void post(size_t size);
+ size_t bufsize();
size_t samplerate();
private:
@@ -158,6 +159,11 @@ void Alsa::post(size_t size)
snd_pcm_writei(handle, data, size);
}
+size_t Alsa::bufsize()
+{
+ return frames;
+}
+
size_t Alsa::samplerate()
{
return srate;
@@ -217,6 +223,12 @@ extern "C" {
alsa->post(s);
}
+ size_t bufsize(void *h)
+ {
+ Alsa *alsa = (Alsa*)h;
+ return alsa->bufsize();
+ }
+
size_t samplerate(void *h)
{
Alsa *alsa = (Alsa*)h;
diff --git a/lv2/lv2.cc b/lv2/lv2.cc
index d87665d..687f989 100644
--- a/lv2/lv2.cc
+++ b/lv2/lv2.cc
@@ -47,12 +47,11 @@ static DrumGizmo *dg_get_pci(LV2_Handle instance)
return dglv2->dg;
}
-LV2_State_Status
-dg_save(LV2_Handle instance,
- LV2_State_Store_Function store,
- LV2_State_Handle handle,
- uint32_t flags,
- const LV2_Feature *const * features)
+LV2_State_Status dg_save(LV2_Handle instance,
+ LV2_State_Store_Function store,
+ LV2_State_Handle handle,
+ uint32_t flags,
+ const LV2_Feature *const * features)
{
DGLV2 *dglv2 = (DGLV2 *)instance;
@@ -77,12 +76,11 @@ dg_save(LV2_Handle instance,
return LV2_STATE_SUCCESS;
}
-LV2_State_Status
-dg_restore(LV2_Handle instance,
- LV2_State_Retrieve_Function retrieve,
- LV2_State_Handle handle,
- uint32_t flags,
- const LV2_Feature *const * features)
+LV2_State_Status dg_restore(LV2_Handle instance,
+ LV2_State_Retrieve_Function retrieve,
+ LV2_State_Handle handle,
+ uint32_t flags,
+ const LV2_Feature *const * features)
{
DGLV2 *dglv2 = (DGLV2 *)instance;
@@ -148,9 +146,7 @@ LV2_Handle instantiate(const struct _LV2_Descriptor *descriptor,
return (LV2_Handle)dglv2;
}
-void connect_port(LV2_Handle instance,
- uint32_t port,
- void *data_location)
+void connect_port(LV2_Handle instance, uint32_t port, void *data_location)
{
DGLV2 *dglv2 = (DGLV2 *)instance;
@@ -171,12 +167,15 @@ void activate(LV2_Handle instance)
(void)dglv2;
}
-void run(LV2_Handle instance,
- uint32_t sample_count)
+void run(LV2_Handle instance, uint32_t sample_count)
{
static size_t pos = 0;
DGLV2 *dglv2 = (DGLV2 *)instance;
+ if(dglv2->buffer_size != sample_count) {
+ dglv2->buffer_size = sample_count;
+ dglv2->dg->setFrameSize(sample_count);
+ }
dglv2->dg->run(pos, dglv2->buffer, sample_count);
pos += sample_count;
@@ -184,7 +183,6 @@ void run(LV2_Handle instance,
void deactivate(LV2_Handle instance)
{
- // We don't really need to do anything here.
DGLV2 *dglv2 = (DGLV2 *)instance;
dglv2->dg->stop();
}
diff --git a/src/audiooutputengine.h b/src/audiooutputengine.h
index 7f15e49..8b2b768 100644
--- a/src/audiooutputengine.h
+++ b/src/audiooutputengine.h
@@ -50,11 +50,6 @@ public:
// Reimplement this if you wish to use internal buffer directly.
virtual sample_t *getBuffer(int ch) { return NULL; }
-
- /*
- * Overload this method to force engine to use different buffer size.
- */
- virtual size_t getBufferSize() { return 1024; }
};
#endif/*__DRUMGIZMO_AUDIOOUTPUTENGINE_H__*/
diff --git a/src/cachemanager.cc b/src/cachemanager.cc
index 61fdb3e..4053f05 100644
--- a/src/cachemanager.cc
+++ b/src/cachemanager.cc
@@ -28,15 +28,16 @@
#include <string.h>
#include <stdio.h>
+#include <assert.h>
#include <sndfile.h>
#include <hugin.hpp>
-static sample_t nodata[FRAMESIZE];
-
#define BUFFER_SIZE 4092
+#define CHUNKSIZE(x) (x * CHUNK_MULTIPLIER)
+
static size_t readChunk(std::string filename, int filechannel, size_t pos,
size_t num_samples, sample_t* buf)
{
@@ -84,21 +85,22 @@ static size_t readChunk(std::string filename, int filechannel, size_t pos,
return size;
}
-CacheManager::CacheManager() {}
+CacheManager::CacheManager()
+ : framesize(0)
+ , nodata(NULL)
+{
+}
CacheManager::~CacheManager()
{
deinit();
+ delete[] nodata;
}
void CacheManager::init(size_t poolsize, bool threaded)
{
this->threaded = threaded;
- for(size_t i = 0; i < FRAMESIZE; i++) {
- nodata[i] = 0;
- }
-
id2cache.resize(poolsize);
for(size_t i = 0; i < poolsize; i++) {
availableids.push_back(i);
@@ -137,6 +139,7 @@ sample_t *CacheManager::open(AudioFile *file, size_t initial_samples_needed,
}
if(id == CACHE_DUMMYID) {
+ assert(nodata);
return nodata;
}
@@ -145,10 +148,10 @@ sample_t *CacheManager::open(AudioFile *file, size_t initial_samples_needed,
c.channel = channel;
c.pos = initial_samples_needed;
c.localpos = 0;
- c.front = new sample_t[CHUNKSIZE];
- c.back = new sample_t[CHUNKSIZE];
+ c.front = new sample_t[CHUNKSIZE(framesize)];
+ c.back = new sample_t[CHUNKSIZE(framesize)];
- size_t size = CHUNKSIZE;
+ size_t size = CHUNKSIZE(framesize);
if(size > (file->preloadedsize - c.pos)) size = (file->preloadedsize - c.pos);
memcpy(c.front, c.file->data + c.pos, size * sizeof(sample_t));
c.ready = false;
@@ -174,21 +177,22 @@ sample_t *CacheManager::open(AudioFile *file, size_t initial_samples_needed,
sample_t *CacheManager::next(cacheid_t id, size_t &size)
{
- size = FRAMESIZE;
+ size = framesize;
if(id == CACHE_DUMMYID) {
+ assert(nodata);
return nodata;
}
cache_t& c = id2cache[id];
- if(c.localpos < CHUNKSIZE) {
+ if(c.localpos < CHUNKSIZE(framesize)) {
sample_t *s = c.front + c.localpos;
c.localpos += size;
return s;
}
if(!c.ready) {
- printf("#%d: NOT READY!\n", id); // TODO: Count and show in UI?
+ //printf("#%d: NOT READY!\n", id); // TODO: Count and show in UI?
}
// Swap buffers
@@ -198,7 +202,7 @@ sample_t *CacheManager::next(cacheid_t id, size_t &size)
c.localpos = size; // Next time we go here we have already read the first frame.
- c.pos += CHUNKSIZE;
+ c.pos += CHUNKSIZE(framesize);
if(c.pos < c.file->size) {
cevent_t e = createLoadNextEvent(c.file, c.channel, c.pos, c.back);
@@ -220,17 +224,28 @@ void CacheManager::close(cacheid_t id)
pushEvent(e);
}
+void CacheManager::setFrameSize(size_t framesize)
+{
+ this->framesize = framesize;
+ delete[] nodata;
+ nodata = new sample_t[framesize];
+
+ for(size_t i = 0; i < framesize; i++) {
+ nodata[i] = 0;
+ }
+}
+
void CacheManager::handleLoadNextEvent(cevent_t &e)
{
#if 0 // memcpy
- size_t size = CHUNKSIZE;
+ size_t size = CHUNKSIZE(framesize);
if(size > (e.file->size - e.pos)) {
size = (e.file->size - e.pos);
}
memcpy(e.buffer, e.file->data + e.pos, size * sizeof(sample_t));
#elif 1 // diskread
- //memset(e.buffer, 0, CHUNKSIZE * sizeof(sample_t));
- readChunk(e.file->filename, e.channel, e.pos, CHUNKSIZE, e.buffer);
+ //memset(e.buffer, 0, CHUNKSIZE(framesize) * sizeof(sample_t));
+ readChunk(e.file->filename, e.channel, e.pos, CHUNKSIZE(framesize), e.buffer);
#endif
*e.ready = true;
}
@@ -246,7 +261,7 @@ void CacheManager::handleCloseEvent(cevent_t &e)
availableids.push_back(e.id);
}
- // TODO: Count down ref coutner on c.file and close it if 0.
+ // TODO: Count down ref counter on c.file and close it if 0.
}
diff --git a/src/cachemanager.h b/src/cachemanager.h
index f2c0122..d98d66c 100644
--- a/src/cachemanager.h
+++ b/src/cachemanager.h
@@ -41,9 +41,7 @@
#define CACHE_DUMMYID -2
#define CACHE_NOID -1
-#define FRAMESIZE 2048
-#define CHUNKSIZE (FRAMESIZE * 16)
-#define PRELOADSIZE (FRAMESIZE + CHUNKSIZE)
+#define CHUNK_MULTIPLIER 16
class AudioFile;
typedef int cacheid_t;
@@ -131,10 +129,15 @@ public:
*/
void close(cacheid_t id);
+ void setFrameSize(size_t framesize);
+
///! Internal thread main method - needs to be public.
void thread_main();
private:
+ size_t framesize;
+ sample_t *nodata;
+
typedef struct {
AudioFile *file;
size_t channel;
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index fb4f042..8661232 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -46,8 +46,11 @@
#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
@@ -166,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);
@@ -355,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)));
@@ -383,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;
@@ -405,17 +410,12 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)
continue;
}
- size_t buffer_offset = 0;
-
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;
}
- else {
- buffer_offset = evt->offset;
- }
{
MutexAutolock l(af->mutex);
@@ -479,7 +479,6 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)
i = activeevents[ch].erase(i);
continue;
}
- i++;
}
}
@@ -500,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*/
}
diff --git a/src/drumgizmo.h b/src/drumgizmo.h
index a8f007a..4c0740e 100644
--- a/src/drumgizmo.h
+++ b/src/drumgizmo.h
@@ -24,8 +24,7 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#ifndef __DRUMGIZMO_DRUMGIZMO_H__
-#define __DRUMGIZMO_DRUMGIZMO_H__
+#pragma once
#include <string>
#include <list>
@@ -52,6 +51,7 @@
#define MAX_NUM_CHANNELS 64
#define REFSFILE "refs.conf"
+#define RESAMPLER_INPUT_BUFFER 64
class DrumGizmo : public MessageReceiver {
public:
@@ -62,10 +62,6 @@ public:
bool init();
- /**
- * @param endpos number of samples to process, -1 := never stop.
- */
- void run(int endpos);
bool run(size_t pos, sample_t *samples, size_t nsamples);
void stop();
@@ -79,6 +75,8 @@ public:
int samplerate();
void setSamplerate(int samplerate);
+ void setFrameSize(size_t framesize);
+
private:
DrumKitLoader loader;
@@ -92,17 +90,12 @@ private:
CHResampler resampler[MAX_NUM_CHANNELS];
sample_t resampler_output_buffer[MAX_NUM_CHANNELS][4096];
- sample_t resampler_input_buffer[MAX_NUM_CHANNELS][64];
+ sample_t resampler_input_buffer[MAX_NUM_CHANNELS][RESAMPLER_INPUT_BUFFER];
std::map<std::string, AudioFile *> audiofiles;
CacheManager cacheManager;
-
-#ifdef TEST_DRUMGIZMO
-public:
-#endif
DrumKit kit;
-};
-
-#endif/*__DRUMGIZMO_DRUMGIZMO_H__*/
+ size_t framesize;
+};
diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc
index 2b66ae0..413d3f4 100644
--- a/src/drumkitloader.cc
+++ b/src/drumkitloader.cc
@@ -34,6 +34,7 @@
DrumKitLoader::DrumKitLoader()
: semaphore("drumkitloader")
+ , framesize(0)
{
run();
run_semaphore.wait(); // Wait for the thread to actually start.
@@ -64,6 +65,13 @@ void DrumKitLoader::skip()
load_queue.clear();
}
+void DrumKitLoader::setFrameSize(size_t framesize)
+{
+ MutexAutolock l(mutex);
+ this->framesize = framesize;
+ framesize_semaphore.post(); // Signal that the framesize has been set.
+}
+
bool DrumKitLoader::isDone()
{
MutexAutolock l(mutex);
@@ -120,6 +128,8 @@ void DrumKitLoader::thread_main()
run_semaphore.post(); // Signal that the thread has been started.
+ framesize_semaphore.wait(); // Wait until the framesize has been set.
+
while(running) {
size_t size;
{
@@ -137,7 +147,7 @@ void DrumKitLoader::thread_main()
AudioFile *audiofile = load_queue.front();
load_queue.pop_front();
filename = audiofile->filename;
- audiofile->load(PRELOADSIZE);
+ audiofile->load(framesize * CHUNK_MULTIPLIER + framesize);
}
loaded++;
diff --git a/src/drumkitloader.h b/src/drumkitloader.h
index 2c0ea8e..550d885 100644
--- a/src/drumkitloader.h
+++ b/src/drumkitloader.h
@@ -85,15 +85,20 @@ public:
*/
void skip();
+ void setFrameSize(size_t framesize);
+
private:
Semaphore run_semaphore;
Semaphore semaphore;
+ Semaphore framesize_semaphore;
Mutex mutex;
volatile bool running;
std::list<AudioFile*> load_queue;
size_t total_num_audiofiles;
size_t fraction;
size_t loaded;
+
+ size_t framesize;
};
#endif/*__DRUMGIZMO_DRUMKITLOADER_H__*/
diff --git a/vst/drumgizmo_vst.cc b/vst/drumgizmo_vst.cc
index 6aec4f2..1e40852 100644
--- a/vst/drumgizmo_vst.cc
+++ b/vst/drumgizmo_vst.cc
@@ -450,6 +450,7 @@ void DrumGizmoVst::processReplacing(float** inputs, float** outputs,
if(buffer) free(buffer);
buffer_size = sampleFrames;
buffer = (sample_t*)malloc(sizeof(sample_t) * buffer_size);
+ drumgizmo->setFrameSize(buffer_size);
}
drumgizmo->run(pos, buffer, buffer_size);