* Introduction

The C/XEN library `libsndins.so' provides the instrument FM-VIOLIN
and the reverberators JC-REVERB, NREV, and FREEVERB to use them in
longer notelists in Snd/Ruby, or Snd/Forth.  They are not so fast
as Lisp's FFI versions, at least not on my machine, but they run
much faster than Ruby or Forth variants.  In addition I have added
the FCOMB example from sndscm.html which is used in freeverb.

The library is based on Bill Schottstaedt's `xen' and `sndlib'
libraries and the Snd editor itself.  Thank you for these great
music programs and libraries!

* XEN-Instruments

The following generator and instruments are accessible from S7,
Ruby and Forth.

** make-fcomb, fcomb?, and fcomb

These are the examples from sndscm.html.

*** (make-fcomb (:scaler 1.0) (:size 1) (:a0 0.0) (:a1 0.0))
*** make_fcomb(:scaler, 1.0, :size, 1, :a0, 0.0, :a1, 0.0)
*** make-fcomb ( :scaler 1.0 :size 1 :a0 0.0 :a1 0.0 -- gen )

Return a new fcomb generator.

*** (fcomb? gen)
*** fcomb?(gen)
*** fcomb? ( gen -- f )

Test if GEN is an fcomb generator.

*** (fcomb gen (input 0.0))
*** fcomb(gen[, input=0.0])
*** fcomb ( gen input=0.0 -- result )

Return the next value of the fcomb generator GEN.

*** (mus-describe gen)
*** gen.to_s
*** object->string ( gen -- str )

Show the inspect string of the fcomb GEN.

*** (mus-length gen)
*** gen.length
*** mus-length ( gen -- len )

Show length of delay line.

*** (mus-scaler gen)                  (set! (mus-scaler gen) scl)
*** gen.scaler                        gen.scaler = scl
*** mus-scaler ( gen -- scl )         set-mus-scaler ( gen scl -- scl )

Show the scaler value, settable.

*** (mus-xcoeff gen index)            (set! (mus-xcoeff gen index) val)
*** gen.xcoeff(index)                 gen.xcoeff = [index, val]
*** mus-xcoeff ( gen index -- val )   set-mus-xcoeff ( gen index val -- val )

Show the a0/a1 values, settable (index == 0: a0, index == 1: a1)

** fm-violin

Keyword options for fm-violin (v.ins, v.scm, examp.rb, clm-ins.fs).

*** :startime                      0.0
*** :duration                      1.0
*** :frequency                     440.0
*** :amplitude                     0.5
*** :fm-index                      1.0
*** :amp-env                       '( 0 0 25 1 75 1 100 0 )
*** :periodic-vibrato-rate         5.0
*** :periodic-vibrato-amplitude    0.0025
*** :random-vibrato-rate           16.0
*** :random-vibrato-amplitude      0.005
*** :noise-freq                    1000.0
*** :noise-amount                  0.0
*** :ind-noise-freq                10.0
*** :ind-noise-amount              0.0
*** :amp-noise-freq                20.0
*** :amp-noise-amount              0.0
*** :gliss-env                     '( 0 0 100 0 )
*** :glissando-amount              0.0
*** :fm1-env                       '( 0 1 25 0.4 75 0.6 100 0 )
*** :fm2-env                       '( 0 1 25 0.4 75 0.6 100 0 )
*** :fm3-env                       '( 0 1 25 0.4 75 0.6 100 0 )
*** :fm1-rat                       1.0
*** :fm2-rat                       3.0
*** :fm3-rat                       4.0
*** :fm1-index                     #f
*** :fm2-index                     #f
*** :fm3-index                     #f
*** :base                          1.0
*** :degree                        0.0
*** :distance                      1.0
*** :reverb-amount                 0.01
*** :index-type                    'violin ('cello or 'violin)
*** :no-waveshaping                #f

** jc-reverb

Keyword options for jc-reverb (jcrev.ins, jcrev.scm, examp.rb,
clm-ins.fs).

*** :volume     1.0
*** :delay1     0.013
*** :delay2     0.011
*** :delay3     0.015
*** :delay4     0.017
*** :low-pass   #f
*** :doubled    #f
*** :amp-env    #f

If more than one reverb channel exist, the values from them are
collected together before computing the result.

** nrev

Keyword options for nrev (nrev.ins, clm-ins.scm, clm-ins.rb).

*** :reverb-factor   1.09
*** :lp-coeff        0.7
*** :lp-out-coeff    0.85
*** :output-scale    1.0
*** :amp-env         '( 0 1 1 1 )
*** :volume          1.0

If more than one reverb channel exist, the values from them are
collected together before computing the result.

** freeverb

Keyword options for freeverb (freeverb.ins, freeverb.scm, freeverb.rb).

*** :room-decay          0.5
*** :damping             0.5
*** :global              0.3
*** :predelay            0.03
*** :output-gain         1.0
*** :output-mixer        #f
*** :scale-room-decay    0.28
*** :offset-room-decay   0.7
*** :combtuning          '( 1116 1188 1277 1356 1422 1491 1557 1617 )
*** :allpasstuning       '( 556 441 341 225 )
*** :scale-damping       0.4
*** :stereo-spread       23.0

Works with one reverb channel or the same number of reverb channels
like output channels.

* C-Instruments

The following functions are accessible from C.

** mus_any *mus_make_fcomb(mus_float_t scaler, int size, mus_float_t a0, mus_float_t a1);
** int mus_fcomb_p(mus_any *ptr);
** mus_float_t mus_fcomb(mus_any *ptr, mus_float_t input, mus_float_t ignored);

** mus_long_t ins_fm_violin(mus_float_t start,
		       mus_float_t dur,
		       mus_float_t freq,
		       mus_float_t amp,
		       mus_float_t fm_index,
		       mus_float_t *amp_env,
		       int amp_len,
		       mus_float_t periodic_vibrato_rate,
		       mus_float_t periodic_vibrato_amp,
		       mus_float_t random_vibrato_rate,
		       mus_float_t random_vibrato_amp,
		       mus_float_t noise_freq,
		       mus_float_t noise_amount,
		       mus_float_t ind_noise_freq,
		       mus_float_t ind_noise_amount,
		       mus_float_t amp_noise_freq,
		       mus_float_t amp_noise_amount,
		       mus_float_t *gliss_env,
		       int gliss_len,
		       mus_float_t gliss_amount,
		       mus_float_t *fm1_env,
		       int fm1_len,
		       mus_float_t *fm2_env,
		       int fm2_len,
		       mus_float_t *fm3_env,
		       int fm3_len,
		       mus_float_t fm1_rat,
		       mus_float_t fm2_rat,
		       mus_float_t fm3_rat,
		       mus_float_t fm1_index,
		       mus_float_t fm2_index,
		       mus_float_t fm3_index,
		       mus_float_t base,
		       mus_float_t degree,
		       mus_float_t distance,
		       mus_float_t reverb_amount,
		       bool index_type,
		       bool no_waveshaping,
		       mus_any *out,
		       mus_any *rev,
		       mus_interp_t mode);

** mus_long_t ins_jc_reverb(mus_float_t start,
		       mus_float_t dur,
		       mus_float_t volume,
		       bool low_pass,
		       bool doubled,
		       mus_float_t delay1,
		       mus_float_t delay2,
		       mus_float_t delay3,
		       mus_float_t delay4,
		       mus_float_t *amp_env,
		       int amp_len,
		       mus_any *out,
		       mus_any *rev);

** mus_long_t ins_nrev(mus_float_t start,
		  mus_float_t dur,
		  mus_float_t reverb_factor,
		  mus_float_t lp_coeff,
		  mus_float_t lp_out_coeff,
		  mus_float_t output_scale,
		  mus_float_t volume,
		  mus_float_t *amp_env,
		  int amp_len,
		  mus_any *out,
		  mus_any *rev);

** mus_long_t ins_freeverb(mus_float_t start,
		      mus_float_t dur,
		      mus_float_t room_decay,
		      mus_float_t damping,
		      mus_float_t global,
		      mus_float_t predelay,
		      mus_float_t output_gain,
		      mus_float_t scale_room_decay,
		      mus_float_t offset_room_decay,
		      mus_float_t scale_damping,
		      mus_float_t stereo_spread,
		      int *combtuning,
		      int comb_len,
		      int *allpasstuning,
		      int all_len,
		      vct *output_mixer,
		      mus_any *out,
		      mus_any *rev);

* Prerequisite	    

Sndins depends on a configured and compiled, but not necessary
installed, libsndlib.a one directory in the hierarchy above sndins.
Configuring sndlib from sndlib.tar.gz creates a Makefile in
sndlib/sndins, sndlib's mus-config.h is needed as well and the
compiled sndlib/libsndlib.a will be linked in sndlib/sndins/libsndins.*

* Compilation

Running Sndlib's configure script in sndlib path creates sndins/Makefile
from sndins/Makefile.in so we can use the configured variables from
Sndlib.  Then one can cd to sndins and run make.  Again: Sndlib
must be configured before!

    cd sndins
    make

* Installation

** S7

You can install libsndlib.so and libsndins.so to ${prefix}/lib with
the usual `make install' command.  Again: Sndlib must be configured
before!

    cd ${compile_sndlib_dir}
    make
    make install
    cd sndins
    make
    make install

The library path should be in your LD_LIBRARY_PATH, e.g. if you
have installed the library in the unusual path /usr/opt/lib., you
can add it by:

	(csh) setenv LD_LIBRARY_PATH /usr/opt/lib:${LD_LIBRARY_PATH}
	(sh)  LD_LIBRARY_PATH=/usr/opt/lib:${LD_LIBRARY_PATH}
	(sh)  export LD_LIBRARY_PATH

In Snd/S7 one can add to the ~/.snd_s7 init file:

    (begin
      (if (not (provided? 'sndlib))
	  (let ((hsndlib (dlopen "sndlib.so")))
	    (if (string? hsndlib)
		(snd-error (format #f "script needs the sndlib module: ~A" hsndlib))
		(dlinit hsndlib "Init_sndlib"))))
      (if (not (provided? 'sndins))
	  (let ((hsndins (dlopen "sndins.so")))
	    (if (string? hsndins)
		(snd-error (format #f "script needs the sndins module: ~A" hsndins))
		(dlinit hsndins "Init_sndins")))))

** Ruby

You can install sndlib.so and sndins.so in the ruby library path,
e.g.

    (csh) setenv RUBYLIB ${HOME}/share/snd:${HOME}/lib/ruby/site-ruby
    (sh)  RUBYLIB=${HOME}/share/snd:${HOME}/lib/ruby/site-ruby; export RUBYLIB
    cd ${compile_sndlib_dir}
    make
    install -c sndlib.so ~/lib/ruby/site-ruby/
    cd sndins
    make
    install -c sndins.so ~/lib/ruby/site-ruby/

In Snd/Ruby one can add to the ~/.snd_ruby init file:

    require "sndlib"
    require "sndins"

** Forth

Installing so-libs in Forth is possible with these command lines:

    (csh) setenv FTH_FTHPATH ${HOME}/share/fth/site-fth
    (csh) setenv FTH_LIBPATH ${HOME}/lib/fth
    (sh)  FTH_FTHPATH=${HOME}/share/fth/site-fth; export FTH_FTHPATH
    (sh)  FTH_LIBPATH=${HOME}/lib/fth; export FTH_LIBPATH

    cd ${compile_sndlib_dir}
    make
    fth -e "install sndlib.so"
    cd sndins
    make
    fth -e "install sndins.so"

These lines install the libraries in ~/lib/fth, the first user
writeable path in $FTH_LIBPATH.

Then in Snd/Forth one can add to the ~/.snd_forth init file:

    dl-load sndlib Init_sndlib
    dl-load sndins Init_sndins

* Samples

You can load the sample files into Snd, with Ruby and Forth you can
test them in a shell too.  One may set with-sound variables in agn.*
and fmviolin.* files.

The agn.* files are translations of clm/clm-example.clm into S7,
Ruby, and Forth as a test case.

The fmviolin.* files are translations of clm/fmviolin.clm into S7,
Ruby, and Forth as a test case.

** S7

You can load the *.scm scripts into Snd.  If you have compiled and
installed the S7 sndlib and sndins libraries, you can type

    (do-agn)                  ;; agn.scm
    (short-example)           ;; fmviolin.scm
    (long-example)            ;; fmviolin.scm

** Ruby

If you have compiled and installed the Ruby sndlib and sndins
libraries, you can type in a shell

    ./agn.rb [ outfile.rbm ]
    ./fmviolin.rb [ /dev/null ]

The default outfile is agn.rbm.  A different outfile name may end
in *.rbm.  The option /dev/null can be everything, its only meaning
is to choose the short_example, without an option long_example is
chosen.

You can load these scripts into Snd too.

** Forth

If you have compiled and installed the Forth sndlib and sndins
libraries, you can type

    ./agn.fth [ outfile.fsm ]
    ./fmviolin.fth [ /dev/null ]

The default outfile is agn.fsm.  A different outfile name should
end in *.fsm.  The option /dev/null can be everything, its only
meaning is to choose the short-example, without an option long-example
is chosen.

You can load these scripts into Snd too.

* README ends here
