PageRenderTime 22ms CodeModel.GetById 10ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/examples/sampler.scm

http://github.com/digego/extempore
Lisp | 103 lines | 44 code | 20 blank | 39 comment | 0 complexity | ff7f58036783c0b8aa83d944f9ef2943 MD5 | raw file
  1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2;;
  3;; This example shows how to use the builtin sampler
  4;;
  5;; You will first need to load and compile dsp_library.scm
  6;;
  7;; Then you're OK to go
  8;;
  9;; NOTE [at the moment compiling in a secondary thread is a little
 10;;      [flakey.  I'm working on this so in the mean time you'll
 11;;      [just have to put up with the audio delays while compiling
 12;;
 13
 14
 15;; first find a stereo audio file of some kind (not mp3 or aac)
 16;; ogg wav or aif should all be fine
 17
 18;; then load up a few excerpts from the file
 19;; set-sampler-index takes
 20;; 1st: the instrument to load into (the default sampler is called 'sampler')
 21;; 2nd: the audio file to load from
 22;; 3rd: an index (from 0-127) to load into
 23;;      this should be the base frequency of the sample
 24;;      in other words a middle C sample should be loaded into 60.
 25;; 4th: an offset in samples (frames without channels)
 26;; 5th: a duration or length in samples to read
 27
 28;; first let's just read in at one index
 29;; we'll choose middle C - 60
 30;; make sure your audio file is long enough for the params below!!
 31(set-sampler-index sampler "/tmp/audio.ogg" 60 500000 1000000)
 32
 33;; playing back at 60 should playback without pitch shift
 34(play-note (now) sampler 60 80 100000)
 35
 36;; anything else will pitch shift
 37;; floating point is OK
 38(play-note (now) sampler 67.25 80 100000)
 39
 40;; a loop
 41(define loop
 42  (lambda (beat dur)
 43    (play sampler (random 48 72) 80 dur)
 44    (callback (*metro* (+ beat (* .5 dur))) 'loop
 45	      (+ beat dur)
 46	      dur)))
 47
 48;; start loop
 49(loop (*metro* 'get-beat 4) 1)
 50
 51
 52;; read a directory full of samples
 53;; samples define a midi root i.e. 60.wav (for middle c)
 54;; must be stereo samples of type wav aif or ogg
 55(define-macro (load-sampler sampler path)
 56  `(let ((files (sys:directory-list ,path)))
 57     (for-each (lambda (f)
 58		 (if (regex:match? f "([0-9]*)\.(wav|aif|aiff|ogg)$")		     
 59		     (let ((result (regex:matched f "([0-9]*)\.(wav|aif|aiff|ogg)$")))
 60		       (set-sampler-index ,sampler f
 61		       			  (string->number (cadr result)) 0 0))))
 62	       files)))
 63
 64;; load audio samples
 65;; I'm using piano samples
 66(load-sampler sampler "/home/andrew/Desktop/piano")
 67
 68
 69(define loop2
 70  (lambda (beat dur root)
 71    (play 3 sampler 36 100 dur)
 72    (for-each (lambda (p offset)
 73		(play (+ offset) sampler p 100 dur))
 74	      (pc:make-chord 40 84 7
 75			     (pc:chord root (if (member root '(10 8))
 76						'^7
 77						'-7)))
 78	      '(1/3 1 3/2 1 2 3 13/3))
 79    (callback (*metro* (+ beat (* .5 dur))) 'loop2 (+ beat dur)
 80	      dur
 81	      (if (member root '(0 8))
 82		  (random '(2 7 10))
 83		  (random '(0 8))))))
 84
 85
 86(loop2 (*metro* 'get-beat 4) 4 0)
 87
 88
 89
 90;; make some more samplers
 91(define-sampler sampler2 sampler-note sampler-fx)
 92(define-sampler sampler3 sampler-note sampler-fx)
 93
 94;; add new samplers to dsp
 95(definec:dsp dsp
 96  (lambda (in time chan dat)
 97    (cond ((< chan 2.0) (+ (synth in time chan dat)
 98			   (sampler in time chan dat)
 99			   (sampler2 in time chan dat)
100			   (sampler3 in time chan dat)))
101	  (else 0.0))))
102
103;; load new samplers