-*- outline -*-

* 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/Guile, Snd/Gauche, 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 the Scheme, 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 Scheme,
Ruby and Forth.

** make-fcomb, fcomb?, and fcomb

These are the examples from sndscm.html.

*** (make-fcomb (:scaler 0.0) (:size 1) (:a0 0.0) (:a1 0.0))
*** make_fcomb(:scaler, 0.0, :size, 1, :a0, 0.0, :a1, 0.0)
*** make-fcomb ( :scaler 0.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                  set_mus_scaler(gen, scl)
*** mus-scaler ( gen -- scl )   set-mus-scaler ( gen scl -- scl )

Show the scaler value, settable.

** fm-violin

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

*** (:startime 0.0)			    :startime, 0.0,
*** (:duration 1.0)			    :duration, 1.0,
*** (:frequency 440.0)			    :frequency, 440.0,
*** (:amplitude 0.5)			    :amplitude, 0.5,
*** (:fm-index 1.0)			    :fm_index, 1.0,
*** (:amp-env '(0 0 25 1 75 1 100 0))	    :amp_env, [0, 0, 25, 1, 75, 1, 100, 0],
*** (:periodic-vibrato-rate 5.0)	    :periodic_vibrato_rate, 5.0,
*** (:periodic-vibrato-amplitude 0.0025)    :periodic_vibrato_amplitude, 0.0025,
*** (:random-vibrato-rate 16.0)		    :random_vibrato_rate, 16.0,
*** (:random-vibrato-amplitude 0.005)	    :random_vibrato_amplitude, 0.005,
*** (:noise-freq 1000.0)		    :noise_freq, 1000.0,
*** (:noise-amount 0.0)			    :noise_amount, 0.0,
*** (:ind-noise-freq 10.0)		    :ind_noise_freq, 10.0,
*** (:ind-noise-amount 0.0)		    :ind_noise_amount, 0.0,
*** (:amp-noise-freq 20.0)		    :amp_noise_freq, 20.0,
*** (:amp-noise-amount 0.0)		    :amp_noise_amount, 0.0,
*** (:gliss-env '(0 0 100 0))		    :gliss_env, [0, 0, 100, 0],
*** (:glissando-amount 0.0)		    :glissando_amount, 0.0,
*** (:fm1-env '(0 1 25 0.4 75 0.6 100 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))   :fm2_env, [0, 1, 25, 0.4, 75, 0.6, 100, 0],
*** (:fm3-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)			    :fm1_rat 1.0,
*** (:fm2-rat 3.0)			    :fm2_rat 3.0,
*** (:fm3-rat 4.0)			    :fm3_rat 4.0,
*** (:fm1-index 0.0)			    :fm1_index, 0.0,
*** (:fm2-index 0.0)			    :fm2_index, 0.0,
*** (:fm3-index 0.0)			    :fm3_index, 0.0,
*** (:base 1.0)				    :base, 1.0,
*** (:degree 0.0)			    :degree, 0.0,
*** (:distance 1.0)			    :distance, 1.0,
*** (:reverb-amount 0.01)		    :reverb_amount, 0.01,
*** (:index-type 1 [0 = cello, 1 = violin]) :index_type, 1, [0 = cello, 1 = violin]
*** (:no-waveshaping #f)                    :no_waveshaping, false

** jc-reverb

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

*** (:startime 0.0)           		    :startime, 0.0,
*** (:duration #f)	      		    :duration, nil,
*** (:low-pass #f)	      		    :low_pass, false,
*** (:volume 1.0) 	      		    :volume, 1.0,
*** (:double #f)  	      		    :double, false,
*** (:delay1 0.013)	      		    :delay1, 0.013,
*** (:delay2 0.011)	      		    :delay2, 0.011,
*** (:delay3 0.015)	      		    :delay3, 0.015,
*** (:delay4 0.017)	      		    :delay4, 0.017,
*** (:amp-env #f) 	      		    :amp_env, nil,

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

** nrev

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

*** (:startime 0.0)           		    :startime, 0.0,
*** (:duration #f)	      		    :duration, nil,
*** (:reverb-factor 1.09)     		    :reverb_factor, 1.09,
*** (:lp-coeff 0.7)	      		    :lp_coeff, 0.7,
*** (:lp-out-coeff 0.85)      		    :lp_out_coeff, 0.85,
*** (:output-scale 1.0)	      		    :output_scale, 1.0,
*** (:amp-env '(0 1 1 1))     		    :amp-env, [0, 1, 1, 1],
*** (:volume 1.0)	      		    :volume, 1.0,

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

** freeverb

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

*** (:startime 0.0)	      		    :startime, 0.0,
*** (:duration #f)	      		    :duration, nil,
*** (:room-decay 0.5)	      		    :room_decay, 0.5,
*** (:damping 0.5)	      		    :damping, 0.5,
*** (:global 0.3)	      		    :global, 0.3,
*** (:predelay 0.03)	      		    :predelay, 0.03,
*** (:output-gain 1.0)	      		    :output_gain, 1.0,
*** (:output-mixer #f)	      		    :output_mixer, nil,
*** (:scale-room-decay 0.28)  		    :scale_room_decay, 0.28,
*** (:offset-room-decay 0.7)  		    :offset_room_decay, 0.7,
*** (:combtuning                            :combtuning,
***  '(1116 1188 1277 1356 1422 1491 1557 1617))
***                                          [1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617],
*** (:allpasstuning '(556 441 341 225))     :allpasstuning, [556, 441, 341, 225]
*** (:scale-damping 0.4)      		    :scale_damping, 0.4,
*** (:stereo-spread 23.0)     		    :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(Float scaler, int size, Float a0, Float a1);

** int mus_fcomb_p(mus_any *ptr);

** Float mus_fcomb(mus_any *ptr, Float input, Float ignored);

** Float mus_fcomb_1(mus_any *ptr, Float input);

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

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

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

** off_t ins_freeverb(Float start, Float dur, Float room_decay, Float damping, Float global,
	    Float predelay, Float output_gain, Float scale_room_decay,
	    Float offset_room_decay, Float scale_damping, Float stereo_spread,
	    int *combtuning, int comb_len, int *allpasstuning, int all_len,
	    mus_any *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 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

** Guile	

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/gnu/lib., you can add
it by:

	(csh) setenv LD_LIBRARY_PATH /usr/gnu/lib:${LD_LIBRARY_PATH}

	(sh)  LD_LIBRARY_PATH=/usr/gnu/lib:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH

In Snd/Guile one can add to the ~/.snd(_guile) init file:

(if (provided? 'snd)
    (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")))))
    (begin
      (if (not (provided? 'sndlib)) (load-extension "libsndlib" "Init_sndlib"))
      (if (not (provided? 'sndins)) (load-extension "libsndins" "Init_sndins"))))

** Gauche

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

    cd ${compile_sndlib_dir}
    make
    install -c sndlib.so ${prefix}/lib/gauche/site/0.8.7/i686-socrates-freebsd5.1/
    cd sndins
    make
    install -c sndins.so ${prefix}/lib/gauche/site/0.8.7/i686-socrates-freebsd5.1/

In Snd/Gauche one can add to the ~/.snd(_gauche) init file:

    (if (not (provided? 'sndlib))
        (dynamic-load "sndlib" :init-function "Init_sndlib" :export-symbols #t))
    (if (not (provided? 'sndins))
        (dynamic-load "sndins" :init-function "Init_sndins" :export-symbols #t))

** Ruby

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

    cd ${compile_sndlib_dir}
    make
    install -c sndlib.so ${prefix}/lib/ruby/site_ruby/1.9/i686-freebsd5.1/
    cd sndins
    make
    install -c sndins.so ${prefix}/lib/ruby/site_ruby/1.9/i686-freebsd5.1/

So 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:

    cd ${compile_sndlib_dir}
    make
    fth --verbose --no-init --eval "install sndlib.so"
    cd sndins
    make
    fth --verbose --no-init --eval "install sndins.so"

These lines install the libraries in $(prefix)/lib/fth where FTH will
look for so-libs at first.

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 and 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-2/clm-example.clm into Scheme,
Ruby, and Forth as a test case.

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

** Scheme (Guile, Gauche)

You can load the *.scm scripts into Snd.  If you have compiled and
installed the Scheme 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 [ -s ]

The default outfile is agn.rbm.  A different outfile name may end
in *.rbm.  The option -s 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 [ -s ]

The default outfile is agn.fsm.  A different outfile name should end
in *.fsm.  The option -s 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
