timidity / music_timidity.c updates (bug #4896):
authorOzkan Sezer
Tue, 17 Dec 2019 14:56:04 +0300
changeset 108689f446aae9b5
parent 1085 c91c7bce78c6
child 1087 2019adc079cc
timidity / music_timidity.c updates (bug #4896):

* Timidity_init(): Library doesn't care about common timidity.cfg
system locations any more, callers are responsible for it. It now
takes a config_path argument as the full path of timidity.cfg.
If the config file argument contains a parent directory, that will
be added to timidity search path. The config file is supposed to
contain any other dirs that needs to be added to the search path:
therefore no need adding several predefined directory paths to the
search paths either: they are now removed.

* configury: New --with-timidity-cfg=FILE option to set the default
config file of the library.

* music.c, New public apis Mix_SetTimidityCfg and Mix_GetTimidityCfg
Allows the mixer library user to set his own timidity config file.

* music_timidity.c, TIMIDITY_Open(): Calls Timidity_Init() with a
config file parameter now. The config file parameter priority is
like the following:

- TIMIDITY_CFG environment var: highest priority, try nothing else.
- Mix_GetTimidityCfg() result: second priority (set by user of the
mixer library using Mix_SetTimidityCfg()), nothing else is tried.
- If the above two are absent, a few OS-specific predefined config
file paths are tried. If that fails, Timidity_init() called with
a NULL param so that the library's default config file is tried.
CHANGES.txt
configure
configure.in
include/SDL_mixer.h
src/codecs/music_timidity.c
src/codecs/timidity/common.c
src/codecs/timidity/common.h
src/codecs/timidity/options.h
src/codecs/timidity/timidity.c
src/codecs/timidity/timidity.h
src/music.c
     1.1 --- a/CHANGES.txt	Mon Dec 16 10:55:10 2019 +0300
     1.2 +++ b/CHANGES.txt	Tue Dec 17 14:56:04 2019 +0300
     1.3 @@ -1,4 +1,6 @@
     1.4  2.0.5:
     1.5 +Ozkan Sezer - Sun Dec 17 14:56:04 2019
     1.6 + * Timidity improvements. New Mix_SetTimidityCfg() public api.
     1.7  Ozkan Sezer - Sun Dec 08 10:20:40 2019
     1.8   * Improved mp3 tag detection/skipping
     1.9  Ozkan Sezer - Thu Dec 05 01:41:50 2019
     2.1 --- a/configure	Mon Dec 16 10:55:10 2019 +0300
     2.2 +++ b/configure	Tue Dec 17 14:56:04 2019 +0300
     2.3 @@ -904,6 +904,7 @@
     2.4  enable_music_mod_mikmod_shared
     2.5  enable_music_midi
     2.6  enable_music_midi_timidity
     2.7 +with_timidity_cfg
     2.8  enable_music_midi_native
     2.9  enable_music_midi_fluidsynth
    2.10  enable_music_midi_fluidsynth_shared
    2.11 @@ -1615,6 +1616,8 @@
    2.12    --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
    2.13    --with-sdl-prefix=PFX   Prefix where SDL is installed (optional)
    2.14    --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)
    2.15 +  --with-timidity-cfg=FILE
    2.16 +                          Specify full path to timidity.cfg
    2.17  
    2.18  Some influential environment variables:
    2.19    CC          C compiler command
    2.20 @@ -3939,13 +3942,13 @@
    2.21  else
    2.22    lt_cv_nm_interface="BSD nm"
    2.23    echo "int some_variable = 0;" > conftest.$ac_ext
    2.24 -  (eval echo "\"\$as_me:3942: $ac_compile\"" >&5)
    2.25 +  (eval echo "\"\$as_me:3945: $ac_compile\"" >&5)
    2.26    (eval "$ac_compile" 2>conftest.err)
    2.27    cat conftest.err >&5
    2.28 -  (eval echo "\"\$as_me:3945: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
    2.29 +  (eval echo "\"\$as_me:3948: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
    2.30    (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
    2.31    cat conftest.err >&5
    2.32 -  (eval echo "\"\$as_me:3948: output\"" >&5)
    2.33 +  (eval echo "\"\$as_me:3951: output\"" >&5)
    2.34    cat conftest.out >&5
    2.35    if $GREP 'External.*some_variable' conftest.out > /dev/null; then
    2.36      lt_cv_nm_interface="MS dumpbin"
    2.37 @@ -5156,7 +5159,7 @@
    2.38    ;;
    2.39  *-*-irix6*)
    2.40    # Find out which ABI we are using.
    2.41 -  echo '#line 5159 "configure"' > conftest.$ac_ext
    2.42 +  echo '#line 5162 "configure"' > conftest.$ac_ext
    2.43    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
    2.44    (eval $ac_compile) 2>&5
    2.45    ac_status=$?
    2.46 @@ -6986,11 +6989,11 @@
    2.47     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    2.48     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    2.49     -e 's:$: $lt_compiler_flag:'`
    2.50 -   (eval echo "\"\$as_me:6989: $lt_compile\"" >&5)
    2.51 +   (eval echo "\"\$as_me:6992: $lt_compile\"" >&5)
    2.52     (eval "$lt_compile" 2>conftest.err)
    2.53     ac_status=$?
    2.54     cat conftest.err >&5
    2.55 -   echo "$as_me:6993: \$? = $ac_status" >&5
    2.56 +   echo "$as_me:6996: \$? = $ac_status" >&5
    2.57     if (exit $ac_status) && test -s "$ac_outfile"; then
    2.58       # The compiler can only warn and ignore the option if not recognized
    2.59       # So say no if there are warnings other than the usual output.
    2.60 @@ -7325,11 +7328,11 @@
    2.61     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    2.62     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    2.63     -e 's:$: $lt_compiler_flag:'`
    2.64 -   (eval echo "\"\$as_me:7328: $lt_compile\"" >&5)
    2.65 +   (eval echo "\"\$as_me:7331: $lt_compile\"" >&5)
    2.66     (eval "$lt_compile" 2>conftest.err)
    2.67     ac_status=$?
    2.68     cat conftest.err >&5
    2.69 -   echo "$as_me:7332: \$? = $ac_status" >&5
    2.70 +   echo "$as_me:7335: \$? = $ac_status" >&5
    2.71     if (exit $ac_status) && test -s "$ac_outfile"; then
    2.72       # The compiler can only warn and ignore the option if not recognized
    2.73       # So say no if there are warnings other than the usual output.
    2.74 @@ -7430,11 +7433,11 @@
    2.75     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    2.76     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    2.77     -e 's:$: $lt_compiler_flag:'`
    2.78 -   (eval echo "\"\$as_me:7433: $lt_compile\"" >&5)
    2.79 +   (eval echo "\"\$as_me:7436: $lt_compile\"" >&5)
    2.80     (eval "$lt_compile" 2>out/conftest.err)
    2.81     ac_status=$?
    2.82     cat out/conftest.err >&5
    2.83 -   echo "$as_me:7437: \$? = $ac_status" >&5
    2.84 +   echo "$as_me:7440: \$? = $ac_status" >&5
    2.85     if (exit $ac_status) && test -s out/conftest2.$ac_objext
    2.86     then
    2.87       # The compiler can only warn and ignore the option if not recognized
    2.88 @@ -7485,11 +7488,11 @@
    2.89     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    2.90     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    2.91     -e 's:$: $lt_compiler_flag:'`
    2.92 -   (eval echo "\"\$as_me:7488: $lt_compile\"" >&5)
    2.93 +   (eval echo "\"\$as_me:7491: $lt_compile\"" >&5)
    2.94     (eval "$lt_compile" 2>out/conftest.err)
    2.95     ac_status=$?
    2.96     cat out/conftest.err >&5
    2.97 -   echo "$as_me:7492: \$? = $ac_status" >&5
    2.98 +   echo "$as_me:7495: \$? = $ac_status" >&5
    2.99     if (exit $ac_status) && test -s out/conftest2.$ac_objext
   2.100     then
   2.101       # The compiler can only warn and ignore the option if not recognized
   2.102 @@ -9854,7 +9857,7 @@
   2.103    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   2.104    lt_status=$lt_dlunknown
   2.105    cat > conftest.$ac_ext <<_LT_EOF
   2.106 -#line 9857 "configure"
   2.107 +#line 9860 "configure"
   2.108  #include "confdefs.h"
   2.109  
   2.110  #if HAVE_DLFCN_H
   2.111 @@ -9950,7 +9953,7 @@
   2.112    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   2.113    lt_status=$lt_dlunknown
   2.114    cat > conftest.$ac_ext <<_LT_EOF
   2.115 -#line 9953 "configure"
   2.116 +#line 9956 "configure"
   2.117  #include "confdefs.h"
   2.118  
   2.119  #if HAVE_DLFCN_H
   2.120 @@ -12118,6 +12121,16 @@
   2.121      if test x$enable_music_midi_timidity = xyes; then
   2.122          EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MID_TIMIDITY -I\$(srcdir)/src/codecs/timidity"
   2.123          SOURCES="$SOURCES $srcdir/src/codecs/timidity/*.c"
   2.124 +        timidity_cfg=no
   2.125 +
   2.126 +# Check whether --with-timidity-cfg was given.
   2.127 +if test "${with_timidity_cfg+set}" = set; then :
   2.128 +  withval=$with_timidity_cfg; timidity_cfg="$withval"
   2.129 +fi
   2.130 +
   2.131 +        if test x$timidity_cfg != xyes -a x$timidity_cfg != xno; then
   2.132 +                EXTRA_CFLAGS="$EXTRA_CFLAGS -DTIMIDITY_CFG=\\\"$timidity_cfg\\\""
   2.133 +        fi
   2.134      fi
   2.135      # Check whether --enable-music-midi-native was given.
   2.136  if test "${enable_music_midi_native+set}" = set; then :
     3.1 --- a/configure.in	Mon Dec 16 10:55:10 2019 +0300
     3.2 +++ b/configure.in	Tue Dec 17 14:56:04 2019 +0300
     3.3 @@ -361,6 +361,12 @@
     3.4      if test x$enable_music_midi_timidity = xyes; then
     3.5          EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MID_TIMIDITY -I\$(srcdir)/src/codecs/timidity"
     3.6          SOURCES="$SOURCES $srcdir/src/codecs/timidity/*.c"
     3.7 +        timidity_cfg=no
     3.8 +        AC_ARG_WITH([timidity-cfg],
     3.9 +AC_HELP_STRING([--with-timidity-cfg=FILE], [Specify full path to timidity.cfg]), timidity_cfg="$withval", [])
    3.10 +        if test x$timidity_cfg != xyes -a x$timidity_cfg != xno; then
    3.11 +                EXTRA_CFLAGS="$EXTRA_CFLAGS -DTIMIDITY_CFG=\\\"$timidity_cfg\\\""
    3.12 +        fi
    3.13      fi
    3.14      AC_ARG_ENABLE([music-midi-native],
    3.15  AC_HELP_STRING([--enable-music-midi-native], [enable native MIDI music output [[default=yes]]]),
     4.1 --- a/include/SDL_mixer.h	Mon Dec 16 10:55:10 2019 +0300
     4.2 +++ b/include/SDL_mixer.h	Tue Dec 17 14:56:04 2019 +0300
     4.3 @@ -627,6 +627,10 @@
     4.4  extern DECLSPEC const char* SDLCALL Mix_GetSoundFonts(void);
     4.5  extern DECLSPEC int SDLCALL Mix_EachSoundFont(int (SDLCALL *function)(const char*, void*), void *data);
     4.6  
     4.7 +/* Set/Get full path of Timidity config file (e.g. /etc/timidity.cfg) */
     4.8 +extern DECLSPEC int SDLCALL Mix_SetTimidityCfg(const char *path);
     4.9 +extern DECLSPEC const char* SDLCALL Mix_GetTimidityCfg(void);
    4.10 +
    4.11  /* Get the Mix_Chunk currently associated with a mixer channel
    4.12      Returns NULL if it's an invalid channel, or there's no chunk associated.
    4.13  */
     5.1 --- a/src/codecs/music_timidity.c	Mon Dec 16 10:55:10 2019 +0300
     5.2 +++ b/src/codecs/music_timidity.c	Tue Dec 17 14:56:04 2019 +0300
     5.3 @@ -41,10 +41,40 @@
     5.4  static int TIMIDITY_Seek(void *context, double position);
     5.5  static void TIMIDITY_Delete(void *context);
     5.6  
     5.7 +/* Config file should contain any other directory that needs
     5.8 + * to be added to the search path. The library adds the path
     5.9 + * of the config file to its search path, too. */
    5.10 +#if defined(__WIN32__) || defined(__OS2__)
    5.11 +# define TIMIDITY_CFG           "C:\\TIMIDITY\\TIMIDITY.CFG"
    5.12 +#else  /* unix: */
    5.13 +# define TIMIDITY_CFG_ETC       "/etc/timidity.cfg"
    5.14 +# define TIMIDITY_CFG_FREEPATS  "/etc/timidity/freepats.cfg"
    5.15 +#endif
    5.16 +
    5.17  static int TIMIDITY_Open(const SDL_AudioSpec *spec)
    5.18  {
    5.19 +    const char *cfg;
    5.20 +    int rc = -1;
    5.21 +
    5.22      (void) spec;
    5.23 -    return Timidity_Init();
    5.24 +
    5.25 +    cfg = SDL_getenv("TIMIDITY_CFG");
    5.26 +    if(!cfg) cfg = Mix_GetTimidityCfg();
    5.27 +    if (cfg) {
    5.28 +        return Timidity_Init(cfg); /* env or user override: no other tries */
    5.29 +    }
    5.30 +#if defined(TIMIDITY_CFG)
    5.31 +    if (rc < 0) rc = Timidity_Init(TIMIDITY_CFG);
    5.32 +#endif
    5.33 +#if defined(TIMIDITY_CFG_ETC)
    5.34 +    if (rc < 0) rc = Timidity_Init(TIMIDITY_CFG_ETC);
    5.35 +#endif
    5.36 +#if defined(TIMIDITY_CFG_FREEPATS)
    5.37 +    if (rc < 0) rc = Timidity_Init(TIMIDITY_CFG_FREEPATS);
    5.38 +#endif
    5.39 +    if (rc < 0) rc = Timidity_Init(NULL); /* library's default cfg. */
    5.40 +
    5.41 +    return rc;
    5.42  }
    5.43  
    5.44  static void TIMIDITY_Close(void)
     6.1 --- a/src/codecs/timidity/common.c	Mon Dec 16 10:55:10 2019 +0300
     6.2 +++ b/src/codecs/timidity/common.c	Tue Dec 17 14:56:04 2019 +0300
     6.3 @@ -22,6 +22,16 @@
     6.4  #include "options.h"
     6.5  #include "common.h"
     6.6  
     6.7 +#if defined(__WIN32__) || defined(__OS2__)
     6.8 +#define CHAR_DIRSEP '\\'
     6.9 +#define is_dirsep(c) ((c) == '/' || (c) == '\\')
    6.10 +#define is_abspath(p) ((p)[0] == '/' || (p)[0] == '\\' || ((p)[0] && (p)[1] == ':'))
    6.11 +#else /* unix: */
    6.12 +#define CHAR_DIRSEP '/'
    6.13 +#define is_dirsep(c) ((c) == '/')
    6.14 +#define is_abspath(p) ((p)[0] == '/')
    6.15 +#endif
    6.16 +
    6.17  /* The paths in this list will be tried whenever we're reading a file */
    6.18  static PathList *pathlist = NULL; /* This is a linked list */
    6.19  
    6.20 @@ -42,7 +52,7 @@
    6.21    if ((rw = SDL_RWFromFile(name, "rb")))
    6.22      return rw;
    6.23  
    6.24 -  if (name[0] != PATH_SEP)
    6.25 +  if (!is_abspath(name))
    6.26    {
    6.27      char current_filename[1024];
    6.28      PathList *plp = pathlist;
    6.29 @@ -55,9 +65,9 @@
    6.30  	if(l)
    6.31  	  {
    6.32  	    strcpy(current_filename, plp->path);
    6.33 -	    if(current_filename[l - 1] != PATH_SEP)
    6.34 +	    if(!is_dirsep(current_filename[l - 1]))
    6.35  	    {
    6.36 -	      current_filename[l] = PATH_SEP;
    6.37 +	      current_filename[l] = CHAR_DIRSEP;
    6.38  	      current_filename[l + 1] = '\0';
    6.39  	    }
    6.40  	  }
    6.41 @@ -88,21 +98,21 @@
    6.42  }
    6.43  
    6.44  /* This adds a directory to the path list */
    6.45 -void add_to_pathlist(const char *s)
    6.46 +void add_to_pathlist(const char *s, size_t l)
    6.47  {
    6.48    PathList *plp = safe_malloc(sizeof(PathList));
    6.49  
    6.50    if (plp == NULL)
    6.51        return;
    6.52  
    6.53 -  plp->path = safe_malloc(strlen(s) + 1);
    6.54 +  plp->path = safe_malloc(l + 1);
    6.55    if (plp->path == NULL)
    6.56    {
    6.57 -      free(plp);
    6.58 +      free (plp);
    6.59        return;
    6.60    }
    6.61 -
    6.62 -  strcpy(plp->path, s);
    6.63 +  strncpy(plp->path, s, l);
    6.64 +  plp->path[l] = 0;
    6.65    plp->next = pathlist;
    6.66    pathlist = plp;
    6.67  }
     7.1 --- a/src/codecs/timidity/common.h	Mon Dec 16 10:55:10 2019 +0300
     7.2 +++ b/src/codecs/timidity/common.h	Tue Dec 17 14:56:04 2019 +0300
     7.3 @@ -15,6 +15,6 @@
     7.4  } PathList;
     7.5  
     7.6  extern SDL_RWops *open_file(const char *name);
     7.7 -extern void add_to_pathlist(const char *s);
     7.8 +extern void add_to_pathlist(const char *s, size_t len);
     7.9  extern void *safe_malloc(size_t count);
    7.10  extern void free_pathlist(void);
     8.1 --- a/src/codecs/timidity/options.h	Mon Dec 16 10:55:10 2019 +0300
     8.2 +++ b/src/codecs/timidity/options.h	Tue Dec 17 14:56:04 2019 +0300
     8.3 @@ -71,17 +71,8 @@
     8.4  
     8.5  /* You could specify a complete path, e.g. "/etc/timidity.cfg", and
     8.6     then specify the library directory in the configuration file. */
     8.7 -#define CONFIG_FILE	"timidity.cfg"
     8.8 -#define CONFIG_FILE_ETC "/etc/timidity.cfg"
     8.9 -#define CONFIG_FILE_ETC_TIMIDITY_FREEPATS "/etc/timidity/freepats.cfg"
    8.10 -
    8.11 -#if defined(__WIN32__) || defined(__OS2__)
    8.12 -#define DEFAULT_PATH	"C:\\TIMIDITY"
    8.13 -#else
    8.14 -#define DEFAULT_PATH	"/etc/timidity"
    8.15 -#define DEFAULT_PATH1	"/usr/share/timidity"
    8.16 -#define DEFAULT_PATH2	"/usr/local/share/timidity"
    8.17 -#define DEFAULT_PATH3	"/usr/local/lib/timidity"
    8.18 +#ifndef TIMIDITY_CFG
    8.19 +#define TIMIDITY_CFG "timidity.cfg"
    8.20  #endif
    8.21  
    8.22  /* These affect general volume */
    8.23 @@ -107,11 +98,4 @@
    8.24    #define PI 3.14159265358979323846
    8.25  #endif
    8.26  
    8.27 -/* The path separator (D.M.) */
    8.28 -#if defined(__WIN32__) || defined(__OS2__)
    8.29 -#  define PATH_SEP '\\'
    8.30 -#else
    8.31 -#  define PATH_SEP '/'
    8.32 -#endif
    8.33 -
    8.34  #define SNDDBG(X)
     9.1 --- a/src/codecs/timidity/timidity.c	Mon Dec 16 10:55:10 2019 +0300
     9.2 +++ b/src/codecs/timidity/timidity.c	Tue Dec 17 14:56:04 2019 +0300
     9.3 @@ -203,7 +203,7 @@
     9.4  	goto fail;
     9.5        }
     9.6        for (i=1; i<words; i++)
     9.7 -	add_to_pathlist(w[i]);
     9.8 +	add_to_pathlist(w[i], strlen(w[i]));
     9.9      }
    9.10      else if (!strcmp(w[0], "source"))
    9.11      {
    9.12 @@ -398,7 +398,7 @@
    9.13    return -2;
    9.14  }
    9.15  
    9.16 -int Timidity_Init_NoConfig()
    9.17 +int Timidity_Init_NoConfig(void)
    9.18  {
    9.19    /* Allocate memory for the standard tonebank and drumset */
    9.20    master_tonebank[0] = safe_malloc(sizeof(ToneBank));
    9.21 @@ -414,40 +414,25 @@
    9.22    return 0;
    9.23  }
    9.24  
    9.25 -int Timidity_Init()
    9.26 +int Timidity_Init(const char *config_file)
    9.27  {
    9.28 -  const char *env = SDL_getenv("TIMIDITY_CFG");
    9.29 -
    9.30 -  /* !!! FIXME: This may be ugly, but slightly less so than requiring the
    9.31 -   *            default search path to have only one element. I think.
    9.32 -   *
    9.33 -   *            We only need to include the likely locations for the config
    9.34 -   *            file itself since that file should contain any other directory
    9.35 -   *            that needs to be added to the search path.
    9.36 -   */
    9.37 -#ifdef DEFAULT_PATH
    9.38 -    add_to_pathlist(DEFAULT_PATH);
    9.39 -#endif
    9.40 -#ifdef DEFAULT_PATH1
    9.41 -    add_to_pathlist(DEFAULT_PATH1);
    9.42 -#endif
    9.43 -#ifdef DEFAULT_PATH2
    9.44 -    add_to_pathlist(DEFAULT_PATH2);
    9.45 -#endif
    9.46 -#ifdef DEFAULT_PATH3
    9.47 -    add_to_pathlist(DEFAULT_PATH3);
    9.48 -#endif
    9.49 +  const char *p;
    9.50  
    9.51    Timidity_Init_NoConfig();
    9.52  
    9.53 -  if (!env || read_config_file(env)<0) {
    9.54 -    if (read_config_file(CONFIG_FILE)<0) {
    9.55 -      if (read_config_file(CONFIG_FILE_ETC)<0) {
    9.56 -        if (read_config_file(CONFIG_FILE_ETC_TIMIDITY_FREEPATS)<0) {
    9.57 -          return(-1);
    9.58 -        }
    9.59 -      }
    9.60 -    }
    9.61 +  if (config_file == NULL || *config_file == '\0')
    9.62 +      config_file = TIMIDITY_CFG;
    9.63 +
    9.64 +  p = strrchr(config_file, '/');
    9.65 +#if defined(__WIN32__)||defined(__OS2__)
    9.66 +  if (!p) p = strrchr(config_file, '\\');
    9.67 +#endif
    9.68 +  if (p != NULL)
    9.69 +    add_to_pathlist(config_file, p - config_file + 1);
    9.70 +
    9.71 +  if (read_config_file(config_file) < 0) {
    9.72 +      Timidity_Exit();
    9.73 +      return -1;
    9.74    }
    9.75    return 0;
    9.76  }
    10.1 --- a/src/codecs/timidity/timidity.h	Mon Dec 16 10:55:10 2019 +0300
    10.2 +++ b/src/codecs/timidity/timidity.h	Tue Dec 17 14:56:04 2019 +0300
    10.3 @@ -146,7 +146,7 @@
    10.4  
    10.5  /* Some of these are not defined in timidity.c but are here for convenience */
    10.6  
    10.7 -extern int Timidity_Init(void);
    10.8 +extern int Timidity_Init(const char *config_file);
    10.9  extern int Timidity_Init_NoConfig(void);
   10.10  extern void Timidity_SetVolume(MidiSong *song, int volume);
   10.11  extern int Timidity_PlaySome(MidiSong *song, void *stream, Sint32 len);
    11.1 --- a/src/music.c	Mon Dec 16 10:55:10 2019 +0300
    11.2 +++ b/src/music.c	Tue Dec 17 14:56:04 2019 +0300
    11.3 @@ -77,6 +77,9 @@
    11.4  /* Semicolon-separated SoundFont paths */
    11.5  static char* soundfont_paths = NULL;
    11.6  
    11.7 +/* full path of timidity config file */
    11.8 +static char* timidity_cfg = NULL;
    11.9 +
   11.10  /* Interfaces for the various music interfaces, ordered by priority */
   11.11  static Mix_MusicInterface *s_music_interfaces[] =
   11.12  {
   11.13 @@ -1047,6 +1050,28 @@
   11.14      }
   11.15  }
   11.16  
   11.17 +int Mix_SetTimidityCfg(const char *path)
   11.18 +{
   11.19 +    if (timidity_cfg) {
   11.20 +        SDL_free(timidity_cfg);
   11.21 +        timidity_cfg = NULL;
   11.22 +    }
   11.23 +
   11.24 +    if (path && *path) {
   11.25 +        if (!(timidity_cfg = SDL_strdup(path))) {
   11.26 +            Mix_SetError("Insufficient memory to set Timidity cfg file");
   11.27 +            return 0;
   11.28 +        }
   11.29 +    }
   11.30 +
   11.31 +    return 1;
   11.32 +}
   11.33 +
   11.34 +const char* Mix_GetTimidityCfg(void)
   11.35 +{
   11.36 +    return timidity_cfg;
   11.37 +}
   11.38 +
   11.39  int Mix_SetSoundFonts(const char *paths)
   11.40  {
   11.41      if (soundfont_paths) {