Changeset 493

Show
Ignore:
Timestamp:
08/02/07 18:39:40 (1 year ago)
Author:
shans
Message:

Refactored envelope and wave code out into new modules

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • ocaml-remix/trunk/Makefile

    r488 r493  
    11ALL: all 
    22 
    3 COMPONENTS = remix time sound transparency layer track 
     3COMPONENTS = remix time sound wave envelope transparency layer track 
    44TESTS = sound_test_sin layer_test_sins track_test_sins 
    55INCLUDES=-I +extlib 
  • ocaml-remix/trunk/layer_test_sins.ml

    r488 r493  
    44let remix = Remix.create 44000 2 120.;; 
    55 
    6 let e = Sound.adsr_envelope (Time.Seconds 0.1) (Time.Seconds 0.4) 0.8 
    7   (Time.Seconds 0.1);; 
     6let e = Envelope.adsr (Time.Seconds 0.1) (Time.Seconds 0.4) 0.8 
     7                                                          (Time.Seconds 0.1);; 
    88 
    9 let a = Sound.apply_envelope e (Sound.sin_wave 30000. (Time.Samples 100));; 
    10 let hi_a = Sound.apply_envelope e (Sound.square_wave 20000. (Time.Samples 50));; 
    11 let e = Sound.apply_envelope e (Sound.tri_wave 20000. (Time.Samples 75));; 
     9let a    = Envelope.apply e (Wave.sin 30000.    (Time.Samples 100));; 
     10let hi_a = Envelope.apply e (Wave.square 20000. (Time.Samples 50));; 
     11let e    = Envelope.apply e (Wave.tri 20000.    (Time.Samples 75));; 
    1212 
    1313let layer = Layer.empty ();; 
    14 Layer.add_sound layer a (Time.Seconds 2.0, Time.Seconds 4.0);; 
     14Layer.add_sound layer a    (Time.Seconds 2.0, Time.Seconds 4.0);; 
    1515Layer.add_sound layer hi_a (Time.Seconds 6.0, Time.Seconds 2.0);; 
    16 Layer.add_sound layer e (Time.Seconds 12.0, Time.Seconds 3.0);; 
     16Layer.add_sound layer e    (Time.Seconds 12.0, Time.Seconds 3.0);; 
    1717 
    1818Layer.print layer;; 
  • ocaml-remix/trunk/sound.ml

    r488 r493  
    55   length *) 
    66type sound = Remix.remix -> Time.extent -> Time.extent -> raw_sound;;  
    7  
    8 type envelope = Remix.remix -> Time.extent -> int -> float;; 
    97 
    108(* note: length applies to raw sounds *) 
     
    4543  Oss.sound_close dev;; 
    4644 
    47 let round_to_int f =  
    48       if f >= 0.  
    49       then int_of_float (f +. 0.5)  
    50       else int_of_float (f -. 0.5) 
    51  
    52 exception AmplitudeTooHigh;; 
    53  
    54 (* sin waves are phased globally so that clicks don't occur between 
    55    adjacent sounds.  Hence we don't need to worry about the extent 
    56    of the sound, only the rendered extent *) 
    57 let sin_generator amp period start channels time = 
    58   let stime = (time + start) / channels * channels in 
    59   let coef = (float_of_int stime) *. 3.142 *. 2. in 
    60   round_to_int (amp *. (sin (coef /. (float_of_int period))));;  
    61  
    62 let square_generator amp period start channels time = 
    63   if (time + start) mod period < period/2 then int_of_float amp else 0;; 
    64  
    65 let tri_generator amp period start channels time = 
    66   let stime = (time + start) / channels * channels in  
    67   int_of_float ( 
    68     float_of_int (stime mod period) /. float_of_int period *. amp);; 
    69  
    70 let wave generator amp period remix sound_extent (start, length) =  
    71   if (amp > 32767. || amp < 0.) then raise AmplitudeTooHigh; 
    72   let raw_period = Time.time_to_raw_samples remix period in 
    73   let raw_length = Time.time_to_raw_samples remix length in 
    74   let raw_start = Time.time_to_raw_samples remix start in 
    75   let channels = Remix.channels remix in 
    76   Array.init raw_length (generator amp raw_period raw_start channels);; 
    77  
    78 let sin_wave = wave sin_generator;; 
    79 let square_wave = wave square_generator;; 
    80 let tri_wave = wave tri_generator;; 
    81  
    82 let adsr_envelope a d s r remix (start, length) pos = 
    83   let a = Time.time_to_raw_samples remix a in 
    84   let d = Time.time_to_raw_samples remix d in 
    85   let r = Time.time_to_raw_samples remix r in 
    86   let raw_length = Time.time_to_raw_samples remix length in 
    87   if pos <= a  
    88   then float_of_int pos /. float_of_int a 
    89   else if pos <= (a + d) 
    90   then 1.0 -. (1.0 -. s) *. float_of_int (pos - a) /. float_of_int d 
    91   else if pos <= raw_length - r 
    92   then s 
    93   else s *. float_of_int (raw_length - pos) /. float_of_int r;; 
    94  
    95 let apply_envelope envelope sound remix sound_extent render_extent = 
    96   let (ss, sl) = Time.extent_to_raw_samples remix sound_extent in 
    97   let (rs, rl) = Time.extent_to_raw_samples remix render_extent in 
    98   let raw_envelope = envelope remix sound_extent in 
    99   let raw_sound = sound remix sound_extent render_extent in 
    100   for i = rs - ss to rs - ss + rl - 1 do ( 
    101     let r = raw_envelope i in 
    102     let pos = i - rs + ss in 
    103     raw_sound.(pos) <- int_of_float (r *. float_of_int raw_sound.(pos)) 
    104   ) done; 
    105   raw_sound;; 
  • ocaml-remix/trunk/sound.mli

    r488 r493  
    99 
    1010val preview : Remix.remix -> sound -> Time.extent -> Time.extent -> unit;; 
    11  
    12 (** construct a sin wave sound of a particular amplitude and period *) 
    13 val sin_wave : float -> Time.time -> sound;; 
    14 val square_wave : float -> Time.time -> sound;; 
    15 val tri_wave : float -> Time.time -> sound;; 
    16  
    17 (** an envelope accepts a remix, an envelope length, and a current position, 
    18     an returns a scaling factor between 0.0 and 1.0 *) 
    19 type envelope = Remix.remix -> Time.extent -> Time.raw_time -> float;; 
    20  
    21 (** an adsr envelope requires an attack time, a decay time, a sustain level, 
    22     and a release time *) 
    23 val adsr_envelope : Time.time -> Time.time -> float -> Time.time ->  
    24                                                                 envelope;; 
    25  
    26 val apply_envelope : envelope -> sound -> sound;; 
  • ocaml-remix/trunk/sound_test_sin.ml

    r492 r493  
    99 
    1010let r = Remix.create 44000 2 120.;; 
    11 let four_second_A = Sound.sin_wave amp period;; 
    12 let envelope = Sound.adsr_envelope (Time.Seconds 0.1) (Time.Seconds 0.4) 0.8 
    13   (Time.Seconds 0.1);; 
     11let four_second_A = Wave.sin amp period;; 
     12let envelope = Envelope.adsr (Time.Seconds 0.1) (Time.Seconds 0.4) 0.8 
     13                                                        (Time.Seconds 0.1);; 
    1414 
    15 let env_a = Sound.apply_envelope envelope four_second_A;; 
     15let env_a = Envelope.apply envelope four_second_A;; 
    1616 
    1717(* 
  • ocaml-remix/trunk/track_test_sins.ml

    r491 r493  
    33 
    44let remix = Remix.create 44000 2 120.;; 
    5 let env = Sound.adsr_envelope (Time.Seconds 0.2) (Time.Seconds 0.6) 0.7  
    6                                     (Time.Seconds 0.1);; 
    7 let a = Sound.sin_wave 30000. (Time.Hertz 440.);; 
    8 let e = Sound.sin_wave 20000. (Time.Hertz 660.);; 
    9 let [a; e] = List.map (Sound.apply_envelope env) [a; e];; 
     5let env = Envelope.adsr (Time.Seconds 0.2) (Time.Seconds 0.6) 0.7  
     6                                                           (Time.Seconds 0.1);; 
     7let a = Wave.sin 30000. (Time.Hertz 440.);; 
     8let e = Wave.sin 20000. (Time.Hertz 660.);; 
     9let [a; e] = List.map (Envelope.apply env) [a; e];; 
    1010 
    1111(* AAAA  AAAA EEEE