summaryrefslogtreecommitdiff
path: root/plugins/ZamSFZ/Sfz.cpp
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2017-11-29 20:45:58 +1100
committerDamien Zammit <damien@zamaudio.com>2017-11-29 20:45:58 +1100
commit89635316558a1128bc1a0b399ad5cd7817e74553 (patch)
tree2de3ba3b6e0b95b9be172f00557297f2a30762b4 /plugins/ZamSFZ/Sfz.cpp
parente8868b75437ee83d7f012581cc72de0ae4261c2e (diff)
ZamSFZ: Resample sfz samples when host samplerate mismatches sfz
Diffstat (limited to 'plugins/ZamSFZ/Sfz.cpp')
-rw-r--r--plugins/ZamSFZ/Sfz.cpp62
1 files changed, 56 insertions, 6 deletions
diff --git a/plugins/ZamSFZ/Sfz.cpp b/plugins/ZamSFZ/Sfz.cpp
index eddc5fd..5630ae5 100644
--- a/plugins/ZamSFZ/Sfz.cpp
+++ b/plugins/ZamSFZ/Sfz.cpp
@@ -2,7 +2,6 @@
#include <iostream>
#include <fstream>
#include <string>
-#define BLOCK_SIZE 512
void Sfz::remapvelocityranges(::sfz::Instrument *inst)
{
@@ -95,8 +94,55 @@ void Sfz::remapvelocityranges(::sfz::Instrument *inst)
}
}
-void Sfz::readsamples(SNDFILE *infile,
- int channels, int note, int layer)
+void Sfz::readsamples_resample(SNDFILE *infile, SF_INFO *sfinfo, int note, int layer, int target_rate)
+{
+ float buf[sfinfo->channels * BLOCK_SIZE];
+ float tmpbuf_pre[2][MAX_SAMPLES] = {0.f};
+ float tmpbuf_post[2][MAX_SAMPLES] = {0.f};
+ SRC_DATA src;
+ int k, m, readcount, i;
+ int maxch = std::min(sfinfo->channels, 2);
+
+ // Read samples in blocks to a flat buffer
+ i = 0;
+ while (i < MAX_SAMPLES && (readcount = sf_readf_float (infile, buf, BLOCK_SIZE)) > 0) {
+ for (k = 0 ; k < readcount ; k++) {
+ for (m = 0; m < maxch; m++) {
+ tmpbuf_pre[m][i+k] = buf[k*sfinfo->channels + m];
+ }
+ }
+ i += readcount;
+ }
+
+ // Resample...
+ src.data_in = &tmpbuf_pre[0][0];
+ src.data_out = &tmpbuf_post[0][0];
+ src.input_frames = MAX_SAMPLES;
+ src.output_frames = MAX_SAMPLES;
+ src.src_ratio = (double)target_rate / (double)sfinfo->samplerate;
+ if (!src_simple(&src, CONVERTER_TYPE, 1)) {
+ // Write left samples out to sample buffer
+ for (i = 0; i < src.output_frames_gen; i++) {
+ sample[note][layer][0][i] = tmpbuf_post[0][i];
+ }
+ }
+
+ if (maxch == 2) {
+ src.data_in = &tmpbuf_pre[1][0];
+ src.data_out = &tmpbuf_post[1][0];
+ src.input_frames = MAX_SAMPLES;
+ src.output_frames = MAX_SAMPLES;
+ src.src_ratio = (double)target_rate / (double)sfinfo->samplerate;
+ if (!src_simple(&src, CONVERTER_TYPE, 1)) {
+ // Write right samples out to sample buffer
+ for (i = 0; i < src.output_frames_gen; i++) {
+ sample[note][layer][1][i] = tmpbuf_post[1][i];
+ }
+ }
+ }
+}
+
+void Sfz::readsamples(SNDFILE *infile, int channels, int note, int layer)
{
float buf[channels*BLOCK_SIZE];
int k, m, readcount, i;
@@ -104,7 +150,7 @@ void Sfz::readsamples(SNDFILE *infile,
i = 0;
while (i < MAX_SAMPLES && (readcount = sf_readf_float (infile, buf, BLOCK_SIZE)) > 0) {
for (k = 0 ; k < readcount ; k++) {
- for (m = 0 ; m < channels ; m++) {
+ for (m = 0; m < std::min(channels, 2); m++) {
sample[note][layer][m][i+k] = buf[k*channels + m];
}
}
@@ -138,7 +184,7 @@ void Sfz::clearsamples()
}
}
-void Sfz::loadsamples(std::string path, std::string filename)
+void Sfz::loadsamples(std::string path, std::string filename, int target_rate)
{
int note, i, j, k, key;
::sfz::SFZParser sfzfile;
@@ -175,8 +221,12 @@ void Sfz::loadsamples(std::string path, std::string filename)
puts (sf_strerror (NULL));
printf("File: %s\n",fullsamplepath.c_str());
}
- readsamples (infile, sfinfo.channels, note, layers[note].max);
k = layers[note].max;
+ if ((int)sfinfo.samplerate == target_rate) {
+ readsamples (infile, sfinfo.channels, note, k);
+ } else {
+ readsamples_resample (infile, &sfinfo, note, k, target_rate);
+ }
layers[note].l[k].lovel = sfzinstrument->regions[i]->lovel;
layers[note].l[k].hivel = sfzinstrument->regions[i]->hivel;
layers[note].l[k].lokey = sfzinstrument->regions[i]->lokey;