Re: hello world in BSE



On Wed, 22 Sep 2004, [iso-8859-5] °àâñÜ ¿ÞßÞÒ wrote:

> Hello, I would like to learn how to create the smallest BSE program
> possible (like a command-line player for bse files with a glib main
> loop).

the easiest way to do that is probably in scheme:

;; play argc/argv contents as bse files
(define (bse-shell-auto-play)
  (bse-server-register-blocking bse-server-register-core-plugins #f)
  (bse-server-register-blocking bse-server-register-scripts #f)
  (bse-server-register-blocking bse-server-register-ladspa-plugins #f)
  (map (lambda (file)
         (let ((project (bse-server-use-new-project bse-server file))
               (blimp "*"))
           (bse-project-restore-from-file project file)
           (bse-project-play project)
           (display file)
           (display ": -")
           (while (bse-project-is-playing project)
                  (usleep 250000)
                  (display #\backspace)
                  (display blimp)
                  (if (string=? blimp "*")
                      (set! blimp "o")
                      (set! blimp "*")))
           (bse-project-stop project)
           (bse-item-unuse project)
           (display #\backspace)
           (display "done.")
           (newline)
           ))
       (cdr (command-line))))

so the simplest program to play a .bse file given on the command
line to bsesh is:
(bse-shell-auto-play)

> Preferably without threading, i.e. it should not require threads-
> enter, etc.

BSE has a hard dependancy on threading at this point. internally, there
are at least the BSE Core thread which communicates with the user program,
the sequencer thread and the synthesis thread.
there user program however doesn't have to worry about that. it communicates
iwth the core thread only, and it doesn so, through an extra glue layer
provided by SFI. at this point, we have three more or less functional
language bindings for BSE:
* the scheme binding. this binding only uses the sfi_glue* functions provided
  by SFI to communicate with the core thread. it queries BSE for all available
  procedures and then defines scheme functions for all of them. the set of
  functions is documented in man bse-procs. beast supports invokation of
  scripts at the GUI, e.g. in the /Tools/ menu, or the context menu of the
  piano roll, these are what the scheme binding is mainly used for.
* the C binding. this binding is generated by the IDL compiler sfidl, it
  parses an IDL file, describing all procedures supplied by BSE at compile time
  and generates a static binding consisting of C functions which internally
  use sfi_glue* calls to actually communicate with the BSE core thread.
  documentation for the C functions and structures is given in bse-procs and
  bse-structs. all of the GUI code in beast uses the C binding to communicate
  with BSE.
* the C++ binding. in theory, it should work like the C binding, just define
  object methods instead of functions. in practice, i don't know what it's
  current state is, and how good it's maintained. stefan is responsible for
  that.

> This is required to test... (deep breath)
> ...the C# bindings for BSE! And I've got a small subset ready already!

yeah, that's on my TODO list as well, has a couple hundred items above
it though ;)
i can't say i'd recommend writing a language binding to anyone except stefan
and me at this point, but if you really want to do this, you'll need to
implement something like sfidl-clientc*.cc to generate your binding.

> I'm also having a problem dynamically loading the methods:
> register_core_plugins
> register_scripts
> register_ladspa_plugins
> Are they renamed somehow in .so? The runtime just says:
>
> Unhandled Exception: System.EntryPointNotFoundException:
> register_core_plugins
> in <0x00053> (wrapper managed-to-native)
> Bse.Server:register_core_plugins (intptr)

i don't know the C# runtime. however BSE doesn't provide functions
named e.g. "register_core_plugins". what you can do is call a BSE
procedure manually like this (provided you have a server handle):
  sfi_glue_vcall_void ("BseServer+register-core-plugins", 'p', bse_server_object, 0);
this code is taken from bswgenapi.c and was generated by sfidl --client-c.

> Also: what are .proc files for: I guess they're for autogeneration of
> scheme bindings?

due to the project being slowly ported to C++ (at least the BSE part), there
are two way currently to implement a BSE procedure. a BSE procedure differs
from an ordinary C function, in that it is callable from outside the BSE
core thread, i.e. from the user program (which may call none of the ordinary
BSE functions). the original way in pure C to define a procedure is to
use the GObject property system in conjunction with function pointers.
because it was so tedious to use manually, i wrote a small perl script,
that parses .proc files adds some tedious glue code and generates readily
compilable .c files (simplified):

METHOD (BseServer, register-core-plugins) {
  HELP  = "Register core plugins.";
  IN    = g_param_spec_object ("server", BSE_TYPE_SERVER, G_PARAM_READWRITE);
}
BODY (BseProcedureClass *proc,
      const GValue      *in_values,
      GValue            *out_values)
{
  /* extract parameter values */
  BseServer *server = g_value_get_object (in_values++);
  SfiRing *ring;
  /* check parameters */
  if (!BSE_IS_SERVER (server))
    return BSE_ERROR_PROC_PARAM_INVAL;
  bse_server_register_plugins (server);
  return BSE_ERROR_NONE;
}

where bse_server_register_plugins() would be an internal BSE function
that can not be called from the user program. the majority of the procedures
as listed in bse-procs are stil limplemented in .proc files.

the second and new way to implement procedures is with IDL files and C++:
--- IDL ---
namespace Bse {
Int  source_get_mix_freq   (Source          obj);
};
--- C++ ---
namespace Bse {
namespace Procedure {
Int
source_get_mix_freq::exec (BseSource *self)
{
  if (!self)
    throw std::runtime_error ("invalid arguments");
  return BSE_SOURCE_PREPARED (self) ? bse_engine_sample_freq() : 0;
}
} // Procedure
} // Bse

(modulo some magic registration macro ;)

we hope to have -at some point- all of the core ported to C++, so we can
get rid of stuff like the .proc files. (we started out with the C++ migration
in summer 2002).


> Regards,
> Artem.
>

---
ciaoTJ




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