FluidSynth / fluidsynth

Software synthesizer based on the SoundFont 2 specifications
https://www.fluidsynth.org
GNU Lesser General Public License v2.1
1.82k stars 254 forks source link

Add ability to have a system-wide configuration file for Windows #1143

Closed daniel-1964 closed 2 years ago

daniel-1964 commented 2 years ago

I want a system-wide configuration file for fluidsynth on Windows

Linux has one on /etc but Windows does not have /etc or similar. My proposal is to place the system-wide configuration file togheter with the fluidsynth executable. I know that only administrator can modify this file, but with a junction you can put it elsewhere.

My solution

If you accept win32 api code in this part of program, the solution is very simple (see patch below).

diff --git a/src/bindings/fluid_cmd.c b/src/bindings/fluid_cmd.c                                                        
index 1d4baaed..b7c9b60f 100644                                                                                         
--- a/src/bindings/fluid_cmd.c                                                                                          
+++ b/src/bindings/fluid_cmd.c                                                                                          
@@ -692,7 +692,22 @@ fluid_get_userconf(char *buf, int len)                                                             
 char *                                                                                                                 
 fluid_get_sysconf(char *buf, int len)                                                                                  
 {                                                                                                                      
-#if defined(WIN32) || defined(MACOS9)                                                                                  
+#if defined(WIN32)                                                                                                     
+    char exePath[MAX_PATH];                                                                                            
+    char *lpFileName;                                                                                                  
+    int requiredLen;                                                                                                   
+    GetModuleFileName(NULL, exePath, MAX_PATH);                                                                        
+    requiredLen = GetFullPathName(exePath, len, buf, &lpFileName);                                                     
+    if(requiredLen >= len)                                                                                             
+    {                                                                                                                  
+        return NULL;                                                                                                   
+    }                                                                                                                  
+    else                                                                                                               
+    {                                                                                                                  
+        strcpy(lpFileName, "fluidsynth.cfg");                                                                          
+        return buf;                                                                                                    
+    }                                                                                                                  
+#elif defined(MACOS9)                                                                                                  
     return NULL;                                                                                                       
 #else                                                                                                                  
     FLUID_SNPRINTF(buf, len, "/etc/fluidsynth.conf");                                                                  

HTH

derselbst commented 2 years ago

The idea of a system-wide config is that no matter where you are on the system and no matter who you are, you get the same config file.

Your proposal is neither a system-wide, nor a user-wide config, as the location of the config depends on the location of the invoking process. This is not acceptable, sry.

daniel-1964 commented 2 years ago

I agree with your definition and it’s like linux do.

On Windows we can either use the Windows directory (not recomended), the c:\programdata directory (but only since Windows 7) or the registry to store the system-wide configuration (to complicated and not portable).

If you want to use the c:\programdata directory you can use a win32 api function to locate it. Note that in Windows normaly, no hard coded path should be in the executable. This also apply for the "c:\soundfonts\default.sf"" hardcoded in fluidsynth.

If your are interrested in this approach, I can search to modify the proposal in ordre to use the appropriate win32 API to locate the c:\programData directory.

Note that jack for Windows for the asio plugin jack-router use my first proposal to place the jack-rooter.ini file together with je jack-rooter.dll.

An other alternative is to reword my proposal by: Provide the ability to have a generic configuration file on a multi-user Windows OS.

And clearly specify: It's no a system-wide approach as for posix-like OS because it's related to the invoked executable.

To be honest my goal it to have something alowing me to have a functioning fluidsynth on a Windows system that my family use. I don't want any body having to configure fluidsynth before playing music of listening midifile. The hardcodec "c:\soundfonts\default.sf2" is the main problem I encountered.

derselbst commented 2 years ago

This also apply for the "c:\soundfonts\default.sf"" hardcoded in fluidsynth.

You probably mean C:\ProgramData\soundfonts\default.sf2, do you? This value can be overridden when building fluidsynth.

I would prefer to go with the %PROGRAMDATA%\fluidsynth solution you proposed, just by simply using getenv() (no need for too much win32 clutter). For Windows Vista and older, fluid_get_sysconf() should just return NULL as before.

If the default.sf2 strikes you so much, I would be open to relocate this into %PROGRAMDATA%\fluidsynth by default.

daniel-1964 commented 2 years ago

Yes, I prefer having default.sf2 into c:\ProgramData\fluidsynth. But it is not so important if we have already a system-wide configuration file.

Finaly the solution invoked yesterday reaches my goal:

I have tested and it works perfectly for my need: all users of my Windows machine can use a configured fluidsynth without having to define a user configuration file. I let in your own the default value for the DEFAULT_SOUNDFONT build option. It can break the configuration for old systems but is better in newer system because it is more compliant with the latest Windows philosophy.

derselbst commented 2 years ago

Ok, thanks. I'll probably adapt your solution later, when I find some time.

derselbst commented 2 years ago

Implemented in 5c38efb8396e116372280d9fcb629eecc29729c4 and will be part of 2.2.9