From aee60a34138d06c329f29f007c76306ee546319d Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Sat, 15 Aug 2026 10:51:30 +0300
Subject: [PATCH] timidity: move load_sbk() stuff from song load to
Timidity_Init() time
Timidity_SetSoundfont() now loads the specified file, therefore its
result should be checked before calling Timidity_Init(). If loading
the font fails, the font won't be set in the library.
---
src/decoder_timidity.c | 4 ++-
src/timidity/sndfont.c | 66 +++++++++++++++++++----------------------
src/timidity/sndfont.h | 6 +++-
src/timidity/timidity.c | 18 ++++++++---
src/timidity/timidity.h | 4 ++-
5 files changed, 55 insertions(+), 43 deletions(-)
diff --git a/src/decoder_timidity.c b/src/decoder_timidity.c
index edde28e9..4abb71e0 100644
--- a/src/decoder_timidity.c
+++ b/src/decoder_timidity.c
@@ -48,7 +48,9 @@ static bool SDLCALL TIMIDITY_init(void)
{
const char *sf2 = SDL_getenv("TIMIDITY_SOUNDFONT");
if (sf2) {
- Timidity_SetSoundfont(sf2); // user override, no cfg
+ if (Timidity_SetSoundfont(sf2) < 0) { // user override, no cfg
+ return false;
+ }
}
const char *cfg = SDL_getenv("TIMIDITY_CFG"); // see if the user had one.
diff --git a/src/timidity/sndfont.c b/src/timidity/sndfont.c
index e0f1ccf0..74239392 100644
--- a/src/timidity/sndfont.c
+++ b/src/timidity/sndfont.c
@@ -27,8 +27,6 @@
* compile flags
*----------------------------------------------------------------*/
-/*#define SF_CLOSE_EACH_FILE*/
-
/*#define SF_SUPPRESS_ENVELOPE*/
/*#define SF_SUPPRESS_TREMOLO*/
/*#define SF_SUPPRESS_VIBRATO*/
@@ -124,6 +122,7 @@ static void calc_filterQ(Layer *lay, SFInfo *sf, SampleList *sp);
static SFInsts sfrec;
+static SFInfo sfinfo;
static SFExclude *sfexclude;
static SFOrder *sforder;
@@ -132,11 +131,8 @@ static const int cutoff_allowed = 0;
#endif
-int init_soundfont(MidiSong *song, const char *fname, int order)
+int init_sbk(const char *fname)
{
- static SFInfo sfinfo;
- int i;
-
SNDDBG(("init soundfonts `%s'\n", fname));
SDL_memset(&sfinfo, 0, sizeof(sfinfo));
@@ -145,13 +141,38 @@ int init_soundfont(MidiSong *song, const char *fname, int order)
SNDDBG(("can't open soundfont file %s\n", fname));
return -1;
}
+
sfrec.fname = SDL_strdup(fname);
- if (!sfrec.fname) goto nomem;
+ if (!sfrec.fname) goto fail;
+
if (load_sbk(sfrec.io, &sfinfo) < 0) {
SNDDBG(("%s: bad soundfont file\n", fname));
goto fail;
}
+ return 0;
+
+fail:
+ end_sbk();
+ return -1;
+}
+
+void end_sbk(void)
+{
+ if (sfrec.io) {
+ SDL_CloseIO(sfrec.io);
+ sfrec.io = NULL;
+ }
+ SDL_free(sfrec.fname);
+ sfrec.fname = NULL;
+ free_sbk(&sfinfo);
+ SDL_memset(&sfinfo, 0, sizeof(sfinfo));
+}
+
+int init_soundfont(MidiSong *song, int order)
+{
+ int i;
+
for (i = 0; i < sfinfo.nrpresets - 1; i++) {
int bank = sfinfo.presethdr[i].bank;
int preset = sfinfo.presethdr[i].preset;
@@ -181,20 +202,9 @@ int init_soundfont(MidiSong *song, const char *fname, int order)
sfrec.samplepos = sfinfo.samplepos;
sfrec.samplesize = sfinfo.samplesize;
- free_sbk(&sfinfo);
-
-#ifdef SF_CLOSE_EACH_FILE
- SDL_CloseIO(sfrec.io);
- sfrec.io = NULL;
-#endif
return 0;
nomem:
song->oom = 1;
-fail: SDL_CloseIO(sfrec.io);
- sfrec.io = NULL;
- SDL_free(sfrec.fname);
- sfrec.fname = NULL;
- free_sbk(&sfinfo);
return -1;
}
@@ -213,13 +223,6 @@ void end_soundfont(void)
{
InstList *ip, *next;
- if (sfrec.io) {
- SDL_CloseIO(sfrec.io);
- sfrec.io = NULL;
- }
- SDL_free(sfrec.fname);
- sfrec.fname = NULL;
-
for (ip = sfrec.instlist; ip; ip = next) {
next = ip->next;
free_sample(ip);
@@ -241,12 +244,8 @@ Instrument *load_soundfont(MidiSong *song, int order, int bank, int preset, int
Instrument *inst = NULL;
if (sfrec.io == NULL) {
- if (sfrec.fname == NULL)
- return NULL;
- if ((sfrec.io = timi_openfile(sfrec.fname)) == NULL) {
- SNDDBG(("can't open soundfont file %s\n", sfrec.fname));
- return NULL;
- }
+ SNDDBG(("NULL soundfont file pointer\n"));
+ return NULL;
}
for (ip = sfrec.instlist; ip; ip = ip->next) {
@@ -258,11 +257,6 @@ Instrument *load_soundfont(MidiSong *song, int order, int bank, int preset, int
if (ip && ip->samples)
inst = load_from_file(song, &sfrec, ip);
-#ifdef SF_CLOSE_EACH_FILE
- SDL_CloseIO(sfrec.io);
- sfrec.io = NULL;
-#endif
-
return inst;
}
diff --git a/src/timidity/sndfont.h b/src/timidity/sndfont.h
index f3a1615b..8f1ca952 100644
--- a/src/timidity/sndfont.h
+++ b/src/timidity/sndfont.h
@@ -10,13 +10,17 @@
#ifndef TIMIDITY_SNDFONT_H /* sndfont.h: soundfont loader public api */
#define TIMIDITY_SNDFONT_H
+#define init_sbk TIMI_NAMESPACE(init_sbk)
+#define end_sbk TIMI_NAMESPACE(end_sbk)
#define init_soundfont TIMI_NAMESPACE(init_soundfont)
#define end_soundfont TIMI_NAMESPACE(end_soundfont)
#define load_soundfont TIMI_NAMESPACE(load_soundfont)
#define exclude_soundfont TIMI_NAMESPACE(exclude_soundfont)
#define order_soundfont TIMI_NAMESPACE(order_soundfont)
-int init_soundfont(MidiSong *song, const char *fname, int order);
+int init_sbk(const char *fname);
+void end_sbk(void);
+int init_soundfont(MidiSong *song, int order);
void end_soundfont(void);
Instrument *load_soundfont(MidiSong *song, int order, int bank, int preset, int keynote);
int exclude_soundfont(int bank, int preset, int keynote);
diff --git a/src/timidity/timidity.c b/src/timidity/timidity.c
index a29ee70e..892b5ff3 100644
--- a/src/timidity/timidity.c
+++ b/src/timidity/timidity.c
@@ -309,11 +309,11 @@ static int read_config_file(const char *name, int rcf_count)
SNDDBG(("%s: line %d: Ignoring multiple \"soundfont\" directives.\n", name, line));
}
else {
- sf_file=SDL_strdup(w[1]);
- if (!sf_file) goto fail;
+ if (Timidity_SetSoundfont(w[1]) < 0) goto fail;
for (j = 2; j < words; j++) {
if (!(cp = SDL_strchr(w[j], '='))) {
SNDDBG(("%s: line %d: bad patch option %s\n", name, line, w[j]));
+ end_sbk();
goto fail;
}
*cp++=0;
@@ -321,6 +321,7 @@ static int read_config_file(const char *name, int rcf_count)
k = SDL_atoi(cp);
if (k < 0 || (*cp < '0' || *cp > '9')) {
SNDDBG(("%s: line %d: order must be a digit", name, line));
+ end_sbk();
goto fail;
}
sf_order = k;
@@ -564,10 +565,18 @@ int Timidity_Init(const char *config_file)
int Timidity_SetSoundfont(const char *file)
{
+ if (sf_file) { /* just in case ... */
+ end_sbk();
+ SDL_free(sf_file);
+ sf_file = NULL;
+ }
if (file) {
char *fname = SDL_strdup(file);
if (!fname) return -1;
- SDL_free(sf_file);
+ if (init_sbk(file) < 0) {
+ SDL_free(fname);
+ return -1;
+ }
sf_file = fname;
}
return 0;
@@ -677,7 +686,7 @@ static void do_song_load(SDL_IOStream *io, const SDL_AudioSpec *audio, MidiSong
song->default_program = DEFAULT_PROGRAM;
if (sf_file) {
- if (init_soundfont(song, sf_file, sf_order) < 0)
+ if (init_soundfont(song, sf_order) < 0)
goto fail;
}
@@ -760,6 +769,7 @@ void Timidity_Exit(void)
}
end_soundfont();
+ end_sbk();
SDL_free(sf_file);
sf_file = NULL;
sf_order = 0;
diff --git a/src/timidity/timidity.h b/src/timidity/timidity.h
index 5d0145a4..1f416952 100644
--- a/src/timidity/timidity.h
+++ b/src/timidity/timidity.h
@@ -157,7 +157,9 @@ typedef struct {
extern int Timidity_Init(const char *config_file);
extern int Timidity_Init_NoConfig(void);
-/* Set the full path of a soundfont (sf2) to use. Must be called before Timidity_Init().
+/* Set the full path of a soundfont (sf2) to use, and do a preliminary load of
+ * the specified file: MUST BE called before Timidity_Init(). If loading fails
+ * the soundfont will NOT be set.
* If a soundfont is set, config file will not be parsed by Timidity_Init(). */
extern int Timidity_SetSoundfont(const char *sf2_file);
extern void Timidity_SetVolume(MidiSong *song, int volume);