| 1 |
type wave = Volume.volume -> float -> Sound.sound;; |
|---|
| 2 |
|
|---|
| 3 |
(* generator amplitude period start time *) |
|---|
| 4 |
type generator = float -> float -> int -> int -> float;; |
|---|
| 5 |
|
|---|
| 6 |
exception AmplitudeTooHigh;; |
|---|
| 7 |
|
|---|
| 8 |
(* these waves are phased globally so that clicks don't occur between |
|---|
| 9 |
adjacent sounds. Hence we don't need to worry about the extent |
|---|
| 10 |
of the sound, only the rendered extent *) |
|---|
| 11 |
let sin_generator amp period start time = |
|---|
| 12 |
let stime = time + start in |
|---|
| 13 |
let coef = (float_of_int stime) *. 3.142 *. 2. in |
|---|
| 14 |
amp *. (sin (coef /. period));; |
|---|
| 15 |
|
|---|
| 16 |
let square_generator amp period start time = |
|---|
| 17 |
if mod_float (float_of_int (time + start)) period < period/.2. |
|---|
| 18 |
then amp else 0.0;; |
|---|
| 19 |
|
|---|
| 20 |
let tri_generator amp period start time = |
|---|
| 21 |
let stime = time + start in |
|---|
| 22 |
(mod_float (float_of_int stime) period) /. period *. amp;; |
|---|
| 23 |
|
|---|
| 24 |
let generate generator volume rate remix ss (start, length) = |
|---|
| 25 |
let raw_length = Time.time_to_raw_time remix length in |
|---|
| 26 |
let raw_start = Time.time_to_raw_time remix start in |
|---|
| 27 |
let raw_ss = Time.time_to_raw_time remix ss in |
|---|
| 28 |
let period = float_of_int (Remix.samplerate remix) /. rate in |
|---|
| 29 |
let offset = (raw_start - raw_ss) in |
|---|
| 30 |
let channels = Remix.channels remix in |
|---|
| 31 |
let vfunc = fun p -> Volume.amplitude remix volume (p + offset) in |
|---|
| 32 |
let buffer = FB.create raw_length channels in |
|---|
| 33 |
FB.fill buffer (fun p -> generator (vfunc p) period raw_start p); |
|---|
| 34 |
buffer;; |
|---|
| 35 |
|
|---|
| 36 |
let sin = generate sin_generator;; |
|---|
| 37 |
let square = generate square_generator;; |
|---|
| 38 |
let tri = generate tri_generator;; |
|---|
| 39 |
|
|---|
| 40 |
|
|---|