ref: f1d9f73efeabbe6629d0d0e0eebdf19a0ec90b86
parent: bf574519e601202c3a9d27a74f345921277eed39
parent: 05d006c48418aadfb684394dd93588ae062396e5
author: Bernhard Schelling <14200249+schellingb@users.noreply.github.com>
date: Sun Nov 14 20:36:50 EST 2021
Merge pull request #65 from ell1e/tsf-copy-new Add "tsf_copy" function for linked copies (rebased from #1)
--- a/tsf.h
+++ b/tsf.h
@@ -89,6 +89,12 @@
// Generic SoundFont loading method using the stream structure above
TSFDEF tsf* tsf_load(struct tsf_stream* stream);
+// Copy a tsf instance from an existing one, use tsf_close to close it as well.
+// All copied tsf instances and their original instance are linked, and share the underlying soundfont.
+// This allows loading a soundfont only once, but using it for multiple independent playbacks.
+// (This function isn't thread-safe without locking.)
+TSFDEF tsf* tsf_copy(tsf* f);
+
// Free the memory related to this tsf instance
TSFDEF void tsf_close(tsf* f);
@@ -313,6 +319,7 @@
enum TSFOutputMode outputmode;
float outSampleRate;
float globalGainDB;
+ int* refCount;
};
#ifndef TSF_NO_STDIO
@@ -1265,6 +1272,9 @@
res->presets = (struct tsf_preset*)TSF_MALLOC(res->presetNum * sizeof(struct tsf_preset));
res->fontSamples = fontSamples;
res->outSampleRate = 44100.0f;
+ res->outputSampleSize = 0;
+ res->refCount = (int*)TSF_MALLOC(sizeof(int));
+ *res->refCount = 1;
fontSamples = TSF_NULL; //don't free below
tsf_load_presets(res, &hydra, fontSampleCount);
}
@@ -1275,17 +1285,40 @@
return res;
}
+TSFDEF tsf* tsf_copy(tsf* f)
+{
+ if (!f)
+ return TSF_NULL;
+
+ tsf* res = TSF_NULL;
+
+ res = (tsf*)TSF_MALLOC(sizeof(tsf));
+ memcpy(res, f, sizeof(tsf));
+ res->voices = TSF_NULL;
+ res->voiceNum = 0;
+ res->channels = TSF_NULL;
+ res->outputSamples = TSF_NULL;
+ res->outputSampleSize = 0;
+ ++(*res->refCount);
+
+ return res;
+}
+
TSFDEF void tsf_close(tsf* f)
{
struct tsf_preset *preset, *presetEnd;
if (!f) return;
- for (preset = f->presets, presetEnd = preset + f->presetNum; preset != presetEnd; preset++)
- TSF_FREE(preset->regions);
- TSF_FREE(f->presets);
- TSF_FREE(f->fontSamples);
+ if (--(*f->refCount) == 0)
+ {
+ for (preset = f->presets, presetEnd = preset + f->presetNum; preset != presetEnd; preset++)
+ TSF_FREE(preset->regions);
+ TSF_FREE(f->presets);
+ TSF_FREE(f->fontSamples);
+ TSF_FREE(f->refCount);
+ }
+ TSF_FREE(f->outputSamples);
TSF_FREE(f->voices);
if (f->channels) { TSF_FREE(f->channels->channels); TSF_FREE(f->channels); }
- TSF_FREE(f->outputSamples);
TSF_FREE(f);
}