summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2018-12-27 13:57:43 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2018-12-27 13:57:43 +0100
commit5864285c0b987f97b632d1acfcc7cc49439e985d (patch)
tree98b0647f856131b1889aeed86bd7c421fd1a21a9 /src
parent55e4e6a951ca2b5bb23cdc600c6661e76c70a50a (diff)
Add audio cache for the resampled/channel expanded sounds.
Diffstat (limited to 'src')
-rw-r--r--src/soundplayer.cc123
-rw-r--r--src/soundplayer.h15
2 files changed, 87 insertions, 51 deletions
diff --git a/src/soundplayer.cc b/src/soundplayer.cc
index 2570f31..c170ff2 100644
--- a/src/soundplayer.cc
+++ b/src/soundplayer.cc
@@ -104,72 +104,97 @@ void SoundPlayer::run()
ao_shutdown();
}
-void SoundPlayer::playFile(QString file)
+SoundPlayer::Samples SoundPlayer::getSampleData(QString file)
{
- printf(" - playFile(%s)\n", file.toStdString().c_str());
-
- SNDFILE *fh;
- SF_INFO sf_info;
-
- fh = sf_open(file.toStdString().c_str(), SFM_READ, &sf_info);
- if(!fh)
+ // Not yet in cache. Read it from file
+ if(!cache.contains(file))
{
- printf("Load error '%s'\n", file.toStdString().c_str());
- return;
- }
+ printf("Insert '%s' into cache\n", file.toStdString().data());
+ SNDFILE *fh;
+ SF_INFO sf_info;
- size_t size = sf_info.frames * sf_info.channels;
- float *data = new float[size];
- sf_read_float(fh, data, size);
- sf_close(fh);
+ fh = sf_open(file.toStdString().c_str(), SFM_READ, &sf_info);
+ if(!fh)
+ {
+ printf("Load error '%s'\n", file.toStdString().c_str());
+ return {};
+ }
- if(sf_info.channels != 2)
- {
- float* stereo_data = new float[sf_info.frames * 2];
- for(int i = 0; i < sf_info.frames; ++i)
+ size_t size = sf_info.frames * sf_info.channels;
+ float *data = new float[size];
+ sf_read_float(fh, data, size);
+ sf_close(fh);
+
+ if(sf_info.channels != 2)
{
- int c = 0;
- for(;c < sf_info.channels && c < 2; ++c)
- {
- stereo_data[i * 2 + c] = data[i * sf_info.channels + c];
- }
- int last = c - 1;
- for(;c < 2; ++c)
+ printf("channel convert %d => 2\n", (int)sf_info.channels);
+ float* stereo_data = new float[sf_info.frames * 2];
+ for(int i = 0; i < sf_info.frames; ++i)
{
- stereo_data[i * 2 + c] = data[i * sf_info.channels + last];
+ int c = 0;
+ for(;c < sf_info.channels && c < 2; ++c)
+ {
+ stereo_data[i * 2 + c] = data[i * sf_info.channels + c];
+ }
+ int last = c - 1;
+ for(;c < 2; ++c)
+ {
+ stereo_data[i * 2 + c] = data[i * sf_info.channels + last];
+ }
}
+ delete[] data;
+ data = stereo_data;
+ size = sf_info.frames * 2;
}
- delete[] data;
- data = stereo_data;
- size = sf_info.frames * 2;
- }
- if(sf_info.samplerate != 48000)
- {
- double ratio = 48000.0 / sf_info.samplerate;
- std::size_t resampled_size = sf_info.frames * 2 * ratio;
- float *resampled_data = new float[resampled_size + 1];
+ if(sf_info.samplerate != 48000)
+ {
+ printf("resample %d => 48000\n", (int)sf_info.samplerate);
+ double ratio = 48000.0 / sf_info.samplerate;
+ std::size_t resampled_frames = sf_info.frames * ratio;
+ float *resampled_data = new float[resampled_frames * 2];
+
+ SRC_DATA s{};
+ s.data_in = data;
+ s.input_frames = sf_info.frames;
- SRC_DATA s{};
- s.data_in = data;
- s.input_frames = sf_info.frames;
+ s.data_out = resampled_data;
+ s.output_frames = resampled_frames;
- s.data_out = resampled_data;
- s.output_frames = resampled_size + 1;
+ s.src_ratio = ratio;
- s.src_ratio = ratio;
+ int err = src_simple(&s, SRC_SINC_BEST_QUALITY, 2);
+ if(err)
+ {
+ printf("SRC error: %s\n", src_strerror(err));
+ }
+ delete[] data;
+ data = resampled_data;
+ size = s.output_frames_gen * 2;
+ printf("size: %d\n", (int)size);
+ }
- src_simple(&s, SRC_SINC_BEST_QUALITY, 2);
- delete[] data;
- data = resampled_data;
- size = s.output_frames_gen * 2;
- printf("size: %d\n", (int)size);
+ Samples s;
+ s.data = data;
+ s.size = size;
+ printf(" - %p %d\n", (void*)s.data, (int)s.size);
+ cache.insert(file, s);
}
+ return cache[file];
+}
+
+void SoundPlayer::playFile(QString file)
+{
+ auto samples = getSampleData(file);
+
+ printf(" - playFile(%s) [%p %d]\n", file.toStdString().c_str(),
+ (void*)samples.data, (int)samples.size);
+
QueueItem qi;
- qi.samples = data;
+ qi.samples = samples.data;
qi.pos = 0;
- qi.size = size;
+ qi.size = samples.size;
{
QMutexLocker lock(&mutex);
diff --git a/src/soundplayer.h b/src/soundplayer.h
index 8502e6e..d8ba929 100644
--- a/src/soundplayer.h
+++ b/src/soundplayer.h
@@ -31,13 +31,16 @@
#include <QString>
#include <QList>
#include <QMutex>
+#include <QMap>
+
+#include <cstdlib>
class QueueItem
{
public:
float *samples;
- size_t pos;
- size_t size;
+ std::size_t pos;
+ std::size_t size;
};
class SoundPlayer
@@ -57,4 +60,12 @@ private:
QList<QueueItem> queue;
QList<QueueItem> active;
+
+ struct Samples
+ {
+ float *data;
+ std::size_t size;
+ };
+ Samples getSampleData(QString file);
+ QMap<QString, Samples> cache;
};