summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2017-04-14 20:39:32 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2017-04-15 08:57:35 +0200
commit8b3506186e5c9c810bcbe4a4206874d9fd4dfe9b (patch)
treef27d5d1bcdd1f560de35f418bdf9333d32fff387
parent87e0b9b288c0157544cfcefb63015a319507698a (diff)
Add chunk size control to the audio cache engine.
-rw-r--r--src/audiocache.cc29
-rw-r--r--src/audiocache.h10
-rw-r--r--src/drumgizmo.cc2
-rw-r--r--src/drumkitloader.cc6
-rw-r--r--src/drumkitloader.h4
5 files changed, 37 insertions, 14 deletions
diff --git a/src/audiocache.cc b/src/audiocache.cc
index 7d80ae9..aecb208 100644
--- a/src/audiocache.cc
+++ b/src/audiocache.cc
@@ -35,8 +35,6 @@
#include "audiocachefile.h"
-#define CHUNKSIZE(x) (x * CHUNK_MULTIPLIER)
-
AudioCache::AudioCache(Settings& settings)
: settings(settings)
{
@@ -137,7 +135,7 @@ sample_t* AudioCache::open(const AudioFile& file,
if(c.back == nullptr)
{
- c.back = new sample_t[CHUNKSIZE(framesize)];
+ c.back = new sample_t[chunk_size];
}
event_handler.pushLoadNextEvent(c.afile, c.channel, c.pos,
@@ -184,7 +182,7 @@ sample_t* AudioCache::next(cacheid_t id, std::size_t& size)
{
// We are playing from cache:
- if(c.localpos < CHUNKSIZE(framesize))
+ if(c.localpos < chunk_size)
{
sample_t* s = c.front + c.localpos;
c.localpos += framesize;
@@ -206,7 +204,7 @@ sample_t* AudioCache::next(cacheid_t id, std::size_t& size)
// Next time we go here we have already read the first frame.
c.localpos = framesize;
- c.pos += CHUNKSIZE(framesize);
+ c.pos += chunk_size;
// Does the file have remaining unread samples?
assert(c.afile); // Assert that we have an audio file.
@@ -215,7 +213,7 @@ sample_t* AudioCache::next(cacheid_t id, std::size_t& size)
// Do we have a back buffer to read into?
if(c.back == nullptr)
{
- c.back = new sample_t[CHUNKSIZE(framesize)];
+ c.back = new sample_t[chunk_size];
}
event_handler.pushLoadNextEvent(c.afile, c.channel, c.pos,
@@ -273,8 +271,6 @@ void AudioCache::setFrameSize(std::size_t framesize)
}
this->framesize = framesize;
-
- event_handler.setChunkSize(CHUNKSIZE(framesize));
}
std::size_t AudioCache::getFrameSize() const
@@ -282,6 +278,23 @@ std::size_t AudioCache::getFrameSize() const
return framesize;
}
+void AudioCache::updateChunkSize(std::size_t output_channels)
+{
+ // Make sure we won't get out-of-range chunk sizes.
+ std::size_t disk_cache_chunk_size =
+ std::max(settings.disk_cache_chunk_size.load(), std::size_t(512u * 1024u));
+ output_channels = std::max(output_channels, std::size_t(1u));
+
+ // 1MB pr. chunk divided over 16 channels, 4 bytes pr. sample.
+ const auto ideal_chunk_size =
+ disk_cache_chunk_size / output_channels / sizeof(sample_t);
+
+ // Chunk size must match a whole number of frames.
+ chunk_size = (ideal_chunk_size / framesize) * framesize;
+
+ event_handler.setChunkSize(chunk_size);
+}
+
void AudioCache::setAsyncMode(bool async)
{
event_handler.setThreaded(async);
diff --git a/src/audiocache.h b/src/audiocache.h
index 475f1aa..54abcf7 100644
--- a/src/audiocache.h
+++ b/src/audiocache.h
@@ -38,9 +38,8 @@
#include "audiocacheeventhandler.h"
#include "settings.h"
-#define CHUNK_MULTIPLIER 16
-
-class AudioCache {
+class AudioCache
+{
public:
AudioCache(Settings& settings);
@@ -92,6 +91,10 @@ public:
void setFrameSize(std::size_t framesize);
std::size_t getFrameSize() const;
+ //! Signal the AudioCache sub-system to set it's internals according to the
+ //! chunk size parameter from Settings.
+ void updateChunkSize(std::size_t output_channels);
+
//! Control/get reader threaded mode.
//! True means reading happening threaded, false means all reading done
//! synchronious.
@@ -102,6 +105,7 @@ private:
std::size_t framesize{0};
sample_t* nodata{nullptr};
std::size_t nodata_framesize{0};
+ std::size_t chunk_size{0};
AudioCacheIDManager id_manager;
AudioCacheEventHandler event_handler{id_manager};
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index 2b4007d..592fa20 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -42,7 +42,7 @@
DrumGizmo::DrumGizmo(Settings& settings,
AudioOutputEngine& o, AudioInputEngine& i)
- : loader(settings, kit, i, resamplers, rand)
+ : loader(settings, kit, i, resamplers, rand, audio_cache)
, oe(o)
, ie(i)
, audio_cache(settings)
diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc
index 8ec47a5..e4d34f2 100644
--- a/src/drumkitloader.cc
+++ b/src/drumkitloader.cc
@@ -37,13 +37,15 @@
DrumKitLoader::DrumKitLoader(Settings& settings, DrumKit& kit,
AudioInputEngine& ie,
Resamplers& resamplers,
- Random& rand)
+ Random& rand,
+ AudioCache& audio_cache)
: settings(settings)
, getter(settings)
, kit(kit)
, ie(ie)
, resamplers(resamplers)
, rand(rand)
+ , audio_cache(audio_cache)
{
}
@@ -193,6 +195,8 @@ void DrumKitLoader::loadKit(DrumKit *kit)
DEBUG(loader, "Queued %d (size: %d) AudioFiles for loading.\n",
(int)settings.number_of_files.load(), (int)load_queue.size());
+ audio_cache.updateChunkSize(kit->channels.size());
+
semaphore.post(); // Start loader loop.
}
diff --git a/src/drumkitloader.h b/src/drumkitloader.h
index c36194c..22fa310 100644
--- a/src/drumkitloader.h
+++ b/src/drumkitloader.h
@@ -39,6 +39,7 @@
#include "audioinputengine.h"
#include "chresampler.h"
#include "memchecker.h"
+#include "audiocache.h"
//! This class is responsible for loading the drumkits in its own thread.
//! All interaction calls are simply modifying queues and not doing any
@@ -50,7 +51,7 @@ class DrumKitLoader
{
public:
DrumKitLoader(Settings& settings, DrumKit& kit, AudioInputEngine& ie,
- Resamplers& resamplers, Random& rand);
+ Resamplers& resamplers, Random& rand, AudioCache& audio_cache);
~DrumKitLoader();
@@ -92,5 +93,6 @@ protected:
Resamplers& resamplers;
MemChecker memchecker;
Random& rand;
+ AudioCache& audio_cache;
std::size_t preload_samples{std::numeric_limits<std::size_t>::max()};
};