-*- 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 and Snd/Ruby.  They are not so fast as the
ffi-lisp versions, at least not on my machine, but they run much
faster than the Scheme or Ruby 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!

* Instruments

The following generator and instruments are accessible from Guile or
Ruby.

** 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)

Returns a new fcomb generator.

*** (fcomb? gen)
*** fcomb?(gen)

Tests if gen is an fcomb generator.

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

Returns the next value of the fcomb generator gen.

*** (mus-describe gen)
*** gen.to_s

Shows the inspect string of the fcomb gen.

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

Shows length of delay line.

*** (mus-scaler gen) (set! (mus-scaler gen) val)
*** gen.scaler       set_mus_scaler(gen, val)

Shows the scaler value, settable.

** fm-violin

*** (: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,
*** (:reverb-amount 0.01)		    :reverb_amount, 0.01,
*** (:index-type 1 [0 = cello, 1 = violin]) :index_type, 1, [0 = cello, 1 = violin]
*** (:degree 0.0)			    :degree, 0.0,
*** (:distance 1.0)			    :distance, 1.0,
*** (:degrees 0.0)			    :degrees, 0.0,
*** (:no-waveshaping #f)                    :no_waveshaping, false

** jc-reverb

*** (: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,
*** (:verbose *clm-verbose*)   		    :verbose, $rbm_verbose

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

** nrev

*** (: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,
*** (:verbose *clm-verbose*)   		    :verbose, $rbm_verbose

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

** freeverb

*** (: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,
*** (:verbose *clm-verbose*)   		    :verbose, $rbm_verbose

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

* Installation

After running `configure' and `make' in the normal sndlib directory
you can cd to sndins and run

    make
    make install (as root)

The library path should be in your LD_LIBRARY_PATH, e.g. if you have
installed the library in /usr/gnu/lib.:

	(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 you can add the line

	(load-extension "libsndins" "init_sndins")

in your ~/.snd init file or wherever you need it if the library is
installed in a proper directory.

I set symlinks from libsndlib.so and libsndins.so to the ruby library
path, i.e.

ln -s $(prefix)/lib/libsndlib.so $(prefix)/lib/ruby/site_ruby/1.9/i686-freebsd5.1/sndlib.so
ln -s $(prefix)/lib/libsndins.so $(prefix)/lib/ruby/site_ruby/1.9/i686-freebsd5.1/sndins.so

So in Snd/Ruby one can add the line

      	require "sndlib"
	require "sndins"

in ~/.snd init.

* Samples

The four scripts in sndins/samples may run outside in a shell and
inside Snd too.  If you have compiled and installed the Guile sndlib
and sndins libraries, you can type

	./agn.scm [ outfile.clm ]
	./fmviolin.scm [ -s ]

The default outfile is agn.clm (or agn.rbm in Ruby).  A different
outfile name should end in *.clm (or in *.rbm). The option -s can be
everything, its only meaning is to choose the (short-example), without
an option (long-example) is chosen.

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

        ./agn.rb [ outfile.rbm ]
        ./fmviolin.rb [ -s ]

The options are like above.

You can set some variables in fmviolin.* to change the channels,
srate, reverb function etc.

** agn.scm, agn.rb

Translation of clm-2/clm-example.clm into Guile and Ruby as a test
case.

** fmviolin.scm, fmviolin.rb

Translation of clm-2/fmviolin.clm into Guile and Ruby as a test case.

** ws_s.scm

Simple with-sound for running the Guile examples outside Snd.

* Emacs Fontifying for c-, scheme-, snd-guile-, and lisp-mode

The following font variables and functions are set in my .emacs file.

(setq c-font-lock-extra-types
      (append '("Float" "XEN" "mus_any" "mus_xen") c-font-lock-extra-types))

(font-lock-add-keywords
 'scheme-mode
 '(("(\\(definstrument\\|run\\)\\>\\s-*(?\\(\\sw+\\)?"
    (1 font-lock-keyword-face)
    (2 (cond ((match-beginning 1) font-lock-function-name-face)
	     ((match-beginning 2) font-lock-variable-name-face)
	     (t font-lock-type-face))
       nil t))))

(font-lock-add-keywords
 'snd-guile-mode
 '(("(\\(definstrument\\|run\\)\\>\\s-*(?\\(\\sw+\\)?"
    (1 font-lock-keyword-face)
    (2 (cond ((match-beginning 1) font-lock-function-name-face)
	     ((match-beginning 2) font-lock-variable-name-face)
	     (t font-lock-type-face))
       nil t))))

(font-lock-add-keywords
 'lisp-mode
 '(("(\\(def[p]?instrument\\|def-optkey-fun\\|run\\|let\\*?\\)\\>\\s-*(?\\(\\sw+\\)?"
    (1 font-lock-keyword-face)
    (2 (cond ((match-beginning 1) font-lock-function-name-face)
	     ((match-beginning 2) font-lock-variable-name-face)
	     (t font-lock-type-face))
       nil t))))

* README ends here
