History

added phasor

Paul Batchelor committed 5 years ago

Commit 31b135e1 parent eba2afb4 files · +155 −0Browse files

Unified · Split

4 files
  1. Makefile +1 −0
  2. algos.org +2 −0
  3. mkdb.janet +1 −0
  4. phasor.org +151 −0
Makefile+1−0
@@ -20,6 +20,7 @@ valp1.c valp1.h \ · 19 unmodified lines
2020 vardelay.c vardelay.h \
2121 oscf.c oscf.h \
2222 bezier.c bezier.h \
23+phasor.c phasor.h \
2324
2425 .SUFFIX: .org .c
2526
algos.org+2−0
@@ -35,3 +35,5 @@ transformation to an normalized ramp signal. · 34 unmodified lines
3535
3636 @!(ref "phsclk")!@ converts a phasor signal into a clock
3737 signal.
38+
39+@!(ref "phasor")!@ generates normalized periodic ramp signal.
mkdb.janet+1−0
@@ -29,6 +29,7 @@ · 28 unmodified lines
2929 (ww-add-link "bezier" "bezier.org")
3030 (ww-add-link "expmap" "expmap.org")
3131 (ww-add-link "phsclk" "phsclk.org")
32+(ww-add-link "phasor" "phasor.org")
3233
3334 # sync and close
3435
phasor.org+151−0
@@ -0,0 +1,151 @@
1+#+TITLE: Phasor
2+* Overview
3+The =phasor= (not to be confused with the phaser audio
4+effect) is a name used to describe a classic signal
5+generator that produces a periodic ramp signal normalized
6+to be in range 0-1, set to move at a specified frequency.
7+Phasors are typically used in the context of table-lookup
8+oscillators such as @!(ref "oscf")!@.
9+
10+The term "phasor" comes from the engineering and physics
11+world, used to describe the complex value of a sinusoid
12+(phase, and amplitude). While not a complex value, the
13+phasor in this computer music context could be the phase
14+component of the phasor.
15+
16+The adoption of the phasor term in the computer music world
17+can be traced back to one of the oldest opcodes in Csound,
18+but the author believes it may go back even further to the
19+MUSICN family of computer music languages. It is noteworthy
20+that the word phasor is six letters, which was the
21+character limit for opcodes in both MUSICN languages and
22+the older versions of Csound. In this context, it is a
23+really nice name to describe this.
24+* Tangled Files
25+Tangles to =phasor.h= and =phasor.c=.
26+
27+If =SK_PHASOR_PRIV= is defined, it exposes the struct
28+=sk_phasor=, otherwise it is opaque.
29+
30+#+NAME: phasor.h
31+#+BEGIN_SRC c :tangle phasor.h
32+#ifndef SK_PHASOR_H
33+#define SK_PHASOR_H
34+
35+#ifndef SKFLT
36+#define SKFLT float
37+#endif
38+
39+<<typedefs>>
40+<<funcdefs>>
41+#ifdef SK_PHASOR_PRIV
42+<<structs>>
43+#endif
44+#endif
45+#+END_SRC
46+
47+#+NAME: phasor.c
48+#+BEGIN_SRC c :tangle phasor.c
49+#define SK_PHASOR_PRIV
50+#include "phasor.h"
51+<<funcs>>
52+#+END_SRC
53+* Struct and initialization
54+The state of phasor is wrapped in a struct
55+called =sk_phasor=, and initialized with =sk_phasor_init=.
56+You'll need the sampling rate, and initial phase.
57+
58+#+NAME: typedefs
59+#+BEGIN_SRC c
60+typedef struct sk_phasor sk_phasor;
61+#+END_SRC
62+
63+In =sk_phasor=, =freq= stores the frequency, =phs= stores
64+the previous phasor value, and =onedsr= is the inverse value
65+of the sampling rate, which is used in order to shave off
66+a traditionally more expensive divide operation.
67+
68+#+NAME: structs
69+#+BEGIN_SRC c
70+struct sk_phasor {
71+ SKFLT freq;
72+ SKFLT phs;
73+ SKFLT onedsr;
74+};
75+#+END_SRC
76+
77+#+NAME: funcdefs
78+#+BEGIN_SRC c
79+void sk_phasor_init(sk_phasor *ph, int sr, SKFLT iphs);
80+#+END_SRC
81+
82+#+NAME: funcs
83+#+BEGIN_SRC c
84+void sk_phasor_init(sk_phasor *ph, int sr, SKFLT iphs)
85+{
86+ ph->phs = iphs;
87+ ph->onedsr = 1.0 / sr;
88+ sk_phasor_freq(ph, 440);
89+}
90+#+END_SRC
91+* Setting the Frequency
92+The frequency of the phasor can be set with
93+=sk_phasor_freq=.
94+
95+#+NAME: funcdefs
96+#+BEGIN_SRC c
97+void sk_phasor_freq(sk_phasor *ph, SKFLT freq);
98+#+END_SRC
99+
100+#+NAME: funcs
101+#+BEGIN_SRC c
102+void sk_phasor_freq(sk_phasor *ph, SKFLT freq)
103+{
104+ ph->freq = freq;
105+}
106+#+END_SRC
107+* Computation
108+A single sample of audio is computed with
109+=sk_phasor_tick=.
110+
111+#+NAME: funcdefs
112+#+BEGIN_SRC c
113+SKFLT sk_phasor_tick(sk_phasor *ph);
114+#+END_SRC
115+
116+The output of the phasor is the current internal phase
117+state before being incremented.
118+
119+The behavior of the phasor is to increment its internal
120+phase by an increment amount, determined by =freq*onedsr=.
121+It is then wrapped to be in range 0 and 1. Instead of
122+using something =fmod= for the wrapping, conditionals
123+and arithmetic are used. In addition to being simpler,
124+this is often a faster approach.
125+
126+#+NAME: funcs
127+#+BEGIN_SRC c
128+SKFLT sk_phasor_tick(sk_phasor *ph)
129+{
130+ SKFLT phs;
131+ SKFLT incr;
132+ SKFLT out;
133+
134+ phs = ph->phs;
135+ incr = ph->freq * ph->onedsr;
136+
137+ out = phs;
138+
139+ phs += incr;
140+
141+ if (phs >= 1.0) {
142+ phs -= 1.0;
143+ } else if (phs < 0.0) {
144+ phs += 1.0;
145+ }
146+
147+ ph->phs = phs;
148+
149+ return out;
150+}
151+#+END_SRC

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t