Skip to content

Commit 529ee52

Browse files
committed
renamed mysaw to mysaw2
1 parent cd5f7c0 commit 529ee52

File tree

3 files changed

+146
-1
lines changed

3 files changed

+146
-1
lines changed

02b-MySaw/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
set(FILENAME "MySaw.cpp") #specify the .cpp file here
1+
set(FILENAME "MySaw2.cpp") #specify the .cpp file here
22
cmake_minimum_required (VERSION 2.8)
33
get_filename_component(PROJECT ${FILENAME} NAME_WE) #automatically sets project name from the filename
44
# set(PROJECT "my_name") #alternatively set project name manually

02b-MySaw/MySaw2.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#include "SC_PlugIn.hpp"
2+
3+
// InterfaceTable contains pointers to functions in the host (server).
4+
static InterfaceTable *ft;
5+
6+
// declare struct to hold unit generator state
7+
struct MySaw2 : public SCUnit{
8+
9+
// Constructor usually does 3 things.
10+
// 1. set the calculation function.
11+
// 2. initialize the unit generator state variables.
12+
// 3. calculate one sample of output.
13+
public:
14+
MySaw2() {
15+
// 1. set the calculation function.
16+
if (isAudioRateIn(0)) {
17+
// if the frequency argument is audio rate
18+
set_calc_function<MySaw2,&MySaw2::next_a>();
19+
} else {
20+
// if thene frequency argument is control rate (or a scalar).
21+
set_calc_function<MySaw2,&MySaw2::next_k>();
22+
}
23+
24+
// 2. initialize the unit generator state variables.
25+
// initialize a constant for multiplying the frequency
26+
mFreqMul = 2.0 * sampleDur();
27+
// get initial phase of oscillator
28+
mPhase = in0(1);
29+
30+
// 3. calculate one sample of output.
31+
if (isAudioRateIn(0)) {
32+
next_a(1);
33+
} else {
34+
next_k(1);
35+
}
36+
37+
}
38+
39+
private:
40+
double mPhase; // phase of the oscillator, from -1 to 1.
41+
float mFreqMul; // a constant for multiplying frequency
42+
43+
//////////////////////////////////////////////////////////////////
44+
45+
// The calculation function executes once per control period
46+
// which is typically 64 samples.
47+
48+
// calculation function for an audio rate frequency argument
49+
void next_a(int inNumSamples)
50+
{
51+
// get the pointer to the output buffer
52+
float *outBuf = out(0);
53+
54+
// get the pointer to the input buffer
55+
const float *freq = in(0);
56+
57+
// get phase and freqmul constant from struct and store it in a
58+
// local variable.
59+
// The optimizer will cause them to be loaded it into a register.
60+
float freqmul = mFreqMul;
61+
double phase = mPhase;
62+
63+
// perform a loop for the number of samples in the control period.
64+
// If this unit is audio rate then inNumSamples will be 64 or whatever
65+
// the block size is. If this unit is control rate then inNumSamples will
66+
// be 1.
67+
for (int i=0; i < inNumSamples; ++i)
68+
{
69+
// out must be written last for in place operation
70+
float z = phase;
71+
phase += freq[i] * freqmul;
72+
73+
// these if statements wrap the phase a +1 or -1.
74+
if (phase >= 1.f) phase -= 2.f;
75+
else if (phase <= -1.f) phase += 2.f;
76+
77+
// write the output
78+
outBuf[i] = z;
79+
}
80+
81+
// store the phase back to the struct
82+
mPhase = phase;
83+
}
84+
85+
//////////////////////////////////////////////////////////////////
86+
87+
// calculation function for a control rate frequency argument
88+
void next_k(int inNumSamples)
89+
{
90+
// get the pointer to the output buffer
91+
float *outBuf = out(0);
92+
93+
// freq is control rate, so calculate it once.
94+
float freq = in0(0) * mFreqMul;
95+
96+
// get phase from struct and store it in a local variable.
97+
// The optimizer will cause it to be loaded it into a register.
98+
double phase = mPhase;
99+
100+
// since the frequency is not changing then we can simplify the loops
101+
// by separating the cases of positive or negative frequencies.
102+
// This will make them run faster because there is less code inside the loop.
103+
if (freq >= 0.f) {
104+
// positive frequencies
105+
for (int i=0; i < inNumSamples; ++i)
106+
{
107+
outBuf[i] = phase;
108+
phase += freq;
109+
if (phase >= 1.f) phase -= 2.f;
110+
}
111+
} else {
112+
// negative frequencies
113+
for (int i=0; i < inNumSamples; ++i)
114+
{
115+
outBuf[i] = phase;
116+
phase += freq;
117+
if (phase <= -1.f) phase += 2.f;
118+
}
119+
}
120+
121+
// store the phase back to the struct
122+
mPhase = phase;
123+
}
124+
};
125+
126+
// the entry point is called by the host when the plug-in is loaded
127+
PluginLoad(MySaw2UGens)
128+
{
129+
// InterfaceTable *inTable implicitly given as argument to the load function
130+
ft = inTable; // store pointer to InterfaceTable
131+
132+
// registerUnit takes the place of the Define*Unit functions. It automatically checks for the presence of a
133+
// destructor function.
134+
// However, it does not seem to be possible to disable buffer aliasing with the C++ header.
135+
registerUnit<MySaw2>(ft, "MySaw2");
136+
}

02b-MySaw/MySaw2.sc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// without mul and add.
2+
MySaw2 : UGen {
3+
*ar { arg freq = 440.0, iphase = 0.0;
4+
^this.multiNew('audio', freq, iphase)
5+
}
6+
*kr { arg freq = 440.0, iphase = 0.0;
7+
^this.multiNew('control', freq, iphase)
8+
}
9+
}

0 commit comments

Comments
 (0)