fluid-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[fluid-dev] More on GLIB dependency.


From: Carlo Bramini
Subject: [fluid-dev] More on GLIB dependency.
Date: Sun, 31 Dec 2017 15:21:49 +0100 (CET)

Hello,

Nowadays, the differences between the sources into main repository and the ones 
of my FluidSynth build without dependencies to GLIB are much less than the past.

I decided to post this message for resuming my results.
At the time of writing, FluidSynth has a good abstraction of the resources, so 
it is almost possible to switch between the two environment by replacing these 
files with others modified:

CMakeList.txt
src/config.cmake
src/utils/fluid_sys.c
src/utils/fluid_sys.h
src/utils/fluidsynth_priv.c

and adding these new ones:

src/utils/fluid_sys_win32.c
src/utils/fluid_sys_glib.c
src/utils/fluid_sys_posix.c
src/utils/fluid_sys_atomic.c

with the functions that you could imagine.
fluid_sys_atomic.c implements atomic access by using a mutex object and it 
could be used in case that the feature is not directly available.
Win32 and GLIB have it, POSIX has not, so fluid_sys_posix.c is the only source 
to use it at the moment.

fluid_sys.c provides timers, BSD network sockets, logs, profiling and high 
level input/output stream functions (gets, printf, etc).
The other usual functions are provided by the newly added files.

The key of implementation for the layer between the operating system and 
FluidSynth is the fluid_sys_object_t structure.

typedef enum {
    FLUID_TYPE_NULL = 0,
    FLUID_TYPE_MUTEX,
    FLUID_TYPE_THREAD,
    FLUID_TYPE_SOCKET,
    FLUID_TYPE_ISTREAM,
    FLUID_TYPE_OSTREAM,
    FLUID_TYPE_ICONSOLE,
    FLUID_TYPE_OCONSOLE,

    FLUID_TYPE_MAX
} fluid_type;

typedef struct fluid_sys_object_t {
    fluid_type type;
    void      *priv;
} fluid_sys_object_t;

The "type" member of the fluid_sys_object_t can assume one of the values of the 
'fluid_type' enum, so it can address a mutex, a thread or other things with the 
purpose that you could imagine by reading the name assigned to that value. The 
"*priv" member will point to some private data and its meaning will vary 
depending on the target OS.

For example, the mutex object is declared as an alias of fluid_sys_object_t:

typedef fluid_sys_object_t fluid_mutex_t;

Some helper functions are declared, for example:

void _fluid_mutex_lock(fluid_mutex_t *);

And, for minimizing the impact to the sources, the usual macros used in the 
sources are declared to something like:

#define fluid_mutex_lock(_m)        _fluid_mutex_lock(&(_m))

I also did a second branch with functions instead of macros.
In this way, pieces of code like this:

fluid_mutex_lock(mutex);
<blablabla>
fluid_mutex_unlock(mutex);

needs to be fixed to:

fluid_mutex_lock(&mutex);
<blablabla>
fluid_mutex_unlock(&mutex);

Not too much difficult afterall, only 7 files need this fix:

Fluid_cmd.c
fluid_midi_router.c
fluid_seq.c
fluid_defsfont.c
fluid_event.c
fluid_synth.c
fluid_settings.c

Since these functions are not exported as public API, it just depends on what 
people would like to see.

Perhaps my new handling of streams and files through the fluid_sys_object_t may 
be found useful also in the current code. Few functions have been added for 
streams and it is interesting to notice how some pieces of code are simplified. 
Some of these functions are:

fluid_istream_t fluid_istream_open(const char *fname);
void fluid_istream_close(fluid_istream_t istream);

int fluid_istream_read(fluid_istream_t in, void *ptr, unsigned int size);
int fluid_ostream_write(fluid_ostream_t in, void *ptr, unsigned int size);

For example, this is how the fluid_source looks now in my sources:

int fluid_source(fluid_cmd_handler_t* handler, const char *filename)
{
  fluid_istream_t file;
  fluid_shell_t shell;
  int result;

  file = fluid_istream_open(filename);
  if (file == NULL)
    return -1;

  fluid_shell_init(&shell, NULL, handler, file, fluid_get_stdout());
  result = (fluid_shell_run(&shell) == FLUID_THREAD_RETURN_VALUE) ? 0 : -1;
  fluid_istream_close(file);

  return result;
}

Using these functions and eventually expanding them seems also to open the door 
to other solutions, for example receiving shell commands or midi events also 
from a pipe, an MS Windows mailslot, an UNIX socket, a physical UART port, 
without changing the remaining code.

I hope that you find my message interesting.
Sincerely.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]