-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsawgen.m
More file actions
64 lines (50 loc) · 2.16 KB
/
sawgen.m
File metadata and controls
64 lines (50 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
:- module sawgen.
%==============================================================================%
% Generates a sawtooth at a certain frequency for a given number of samples.
:- interface.
%==============================================================================%
:- import_module list.
% Generate the waves in reverse, since it's much faster to prepend to the list,
% and the sinewave is the same forward and backwards.
% generate_sinewave(SamplesPerPeriod, NumSamples, !Wave)
% Generates signed 16-bit samples.
:- pred gen_int(int, int, list(int), list(int)).
:- mode gen_int(in, in, di, uo) is det.
% Generates float samples from 0.0 to 1.0.
:- pred gen_float(int, int, list(float), list(float)).
:- mode gen_float(in, in, di, uo) is det.
%==============================================================================%
:- implementation.
%==============================================================================%
:- import_module float.
:- import_module int.
:- pred prepend(T::di, list(T)::di, list(T)::uo) is det.
prepend(I, ListIn, [I|ListIn]).
:- pragma inline(prepend/3).
% dlerp(TValue, MaxT, From, To, Out)
:- pred dlerp_float(int::in, int::in, float::in, float::in, float::uo) is det.
dlerp_float(T, Max, From, To, Out) :-
LerpVal = float.unchecked_quotient(float.float(T), float.float(Max)),
Out = From + LerpVal*(To - From).
:- pragma inline(dlerp_float/5).
:- pred dlerp_int(int::in, int::in, int::in, int::in, int::uo) is det.
dlerp_int(T, Max, From, To, Out) :-
LerpVal = float.unchecked_quotient(float.float(T), float.float(Max)),
Out = From + floor_to_int(LerpVal*float.float(To - From)).
:- pragma inline(dlerp_int/5).
gen_int(SamplesPerPeriod, NumSamples, !Samples) :-
dlerp_int(NumSamples, SamplesPerPeriod, 0, 0xFFFF, Sample),
prepend(Sample, !Samples),
( NumSamples > 0 ->
gen_int(SamplesPerPeriod, NumSamples - 1, !Samples)
;
true % Pass.
).
gen_float(SamplesPerPeriod, NumSamples, !Samples) :-
dlerp_float(NumSamples, SamplesPerPeriod, 0.0, 1.0, Sample),
prepend(Sample, !Samples),
( NumSamples > 0 ->
gen_float(SamplesPerPeriod, NumSamples - 1, !Samples)
;
true % Pass.
)