CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

AdditiveInstrument.cpp
Go to the documentation of this file.
1 ///
2 /// AdditiveInstrument.h -- Sum-of-sines synthesis instrument class.
3 /// See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 ///
5
6 /// Accessors
7 /// "du", set_duration_f
8 /// "am", set_amplitude_f
9 /// "fr", set_frequency_f
10 /// "po", set_position_f
11 /// "at", set_attack_f -- amplitude envelope ADSR
12 /// "de", set_decay_f
13 /// "su", set_sustain_f
14 /// "re", set_release_f
15 /// "pt", set_partial_f
16 /// "ps", set_partials_f
17 ///
18 /// OSC note formats (4 or 8 arguments):
19 /// dur, ampl, c_fr, pos
20 /// dur, ampl, c_fr, pos, att, dec, sus, rel
21
22 #include "AdditiveInstrument.h"
23
24 using namespace csl;
25
26 // The constructor initializes the DSP graph's UGens
27
28 AdditiveInstrument::AdditiveInstrument() : // initializers for the UGens
29 Instrument(),
30 mSOS(16, 0.75), // SumOfSines init, 16 partials @ 1/f
31 mAEnv(0.25, 0.03, 0.06, 0.5, 0.15), // set up standard ADSR (1/4-sec duration)
32 mPanner(mSOS, 0.0) { // init the panner
33 this->init();
34 }
35
36 AdditiveInstrument::AdditiveInstrument(SumOfSines & sos) : // initializers for the UGens
37 Instrument(),
38 mSOS(sos), // SumOfSines init, 16 partials @ 1/f
39 mAEnv(0.25, 0.03, 0.06, 0.5, 0.15), // set up standard ADSR (1/4-sec duration)
40 mPanner(mSOS, 0.0) { // init the panner
41 this->init();
42 }
43
44 AdditiveInstrument::AdditiveInstrument(unsigned numHarms, float noise) : // initializers for the UGens
45 Instrument(),
46 mSOS(numHarms, noise), // SumOfSines init, numHarms partials @ 1/f
47 mAEnv(0.25, 0.03, 0.06, 0.5, 0.15), // set up standard ADSR (1/4-sec duration)
48 mPanner(mSOS, 0.0) { // init the panner
49 this->init();
50 }
51
52 AdditiveInstrument::AdditiveInstrument(SHARCSpectrum & spect) :
53 Instrument(),
54 mSOS(spect), // SumOfSines init, 16 partials @ 1/f
55 mAEnv(0.25, 0.03, 0.06, 0.5, 0.15), // set up standard ADSR (1/4-sec duration)
56 mPanner(mSOS, 0.0) { // init the panner
57 this->init();
58 }
59
60 // setup instance
61
62 void AdditiveInstrument::init() {
63 mSOS.setScale(mAEnv); // plug in the envelope
64 mNumChannels = 2;
65 mName = "SumOfSines"; // set graph's name
66 mGraph = & mPanner; // store the root of the graph as the inst var _graph
67 mUGens["Osc"] = & mSOS; // add ugens that can be monitored to the map
68 mUGens["A env"] = & mAEnv;
69 mUGens["Pos"] = & mPanner;
70 mEnvelopes.push_back(& mAEnv); // list envelopes for retrigger
71 // set up accessor vector
72 mAccessors.push_back(new Accessor("du", set_duration_f, CSL_FLOAT_TYPE));
73 mAccessors.push_back(new Accessor("am", set_amplitude_f, CSL_FLOAT_TYPE));
74 mAccessors.push_back(new Accessor("fr", set_frequency_f, CSL_FLOAT_TYPE));
75 mAccessors.push_back(new Accessor("po", set_position_f, CSL_FLOAT_TYPE));
76 mAccessors.push_back(new Accessor("at", set_attack_f, CSL_FLOAT_TYPE));
77 mAccessors.push_back(new Accessor("de", set_decay_f, CSL_FLOAT_TYPE));
78 mAccessors.push_back(new Accessor("su", set_sustain_f, CSL_FLOAT_TYPE));
79 mAccessors.push_back(new Accessor("re", set_release_f, CSL_FLOAT_TYPE));
80 mAccessors.push_back(new Accessor("pt", set_partial_f, CSL_FLOAT_TYPE));
81 mAccessors.push_back(new Accessor("ps", set_partials_f, CSL_FLOAT_TYPE));
82 }
83
84 // copy constructor
85
86 AdditiveInstrument::AdditiveInstrument(AdditiveInstrument& in) :
87 Instrument(in),
88 mAEnv(in.mAEnv),
89 mSOS(in.mSOS),
90 mPanner(in.mPanner) { }
91
92 // The destructor frees the stuff we allocated
93
94 AdditiveInstrument::~AdditiveInstrument() { }
95
96 // Plug function for use by OSC setter methods
97
98 void AdditiveInstrument::setParameter(unsigned selector, int argc, void **argv, const char *types) {
99 if (argc == 1) {
100 float d = * (float *) argv[0];
101 if (types[0] == 'i')
102 d = (float) (* (int *) argv[0]);
103 float s;
104 if (types[0] == 'i')
105 d = (float) (* (int *) argv[0]);
106 if (argc > 1) {
107 s = * (float *) argv[1];
108 if (types[1] == 'i')
109 s = (float) (* (int *) argv[1]);
110 }
111 // logMsg("Set %d SOS params to (%s)\n", argc, types);
112 switch (selector) { // switch on which parameter is being set
113 case set_duration_f:
114 mAEnv.setDuration(d); break;
115 case set_amplitude_f:
116 mAEnv.setScale(d); break;
117 case set_frequency_f:
118 mSOS.setFrequency(d); break;
119 case set_position_f:
120 mPanner.setPosition(d); break;
121 case set_attack_f:
122 mAEnv.setAttack(d); break;
123 case set_decay_f:
124 mAEnv.setDecay(d); break;
125 case set_sustain_f:
126 mAEnv.setSustain(d); break;
127 case set_release_f:
128 mAEnv.setRelease(d); break;
129 case set_partial_f:
130 mSOS.addPartial(d, s); break;
131 default:
132 logMsg(kLogError, "Unknown selector in AdditiveInstrument set_parameter selector: %d\n", selector);
133 }
134 } else { // multiple args
135 if (selector == set_partials_f) {
136 logMsg("Set %d SOS partials to (%s)\n", argc, types);
137 mSOS.addPartials(argc, argv);
138 } else {
139 logMsg(kLogError, "Unknown multi-arg (%d) setter in AdditiveInstrument: %s\n", argc, types);
140 }
141 }
142 }
143
144 /// OSC note formats (4 or 8 arguments):
145 /// dur, ampl, c_fr, pos
146 /// dur, ampl, c_fr, pos, att, dec, sus, rel
147
148 void AdditiveInstrument::playOSC(int argc, void **argv, const char *types) {
149 float ** fargs = (float **) argv;
150 unsigned nargs;
151
152 // if (strcmp(types, "ffff") == 0)
153 if (argc == 4)
154 nargs = 4;
155 // else if (strcmp(types, "ffffffff") == 0)
156 else if (argc == 8)
157 nargs = 8;
158 else {
159 logMsg(kLogError, "Invalid type string in OSC message, expected \"ff...ff\" got \"%s\"\n", types);
160 return;
161 }
162 printf("\tAdd: d %5.2f a %5.2f f %7.1f p %5.2f\n",
163 *fargs[0], *fargs[1], *fargs[2], *fargs[3]);
164 mAEnv.setDuration(*fargs[0]);
165 mAEnv.scaleValues(*fargs[1]);
166 mSOS.setFrequency(*fargs[2]);
167 mPanner.setPosition(*fargs[3]);
168 if (nargs == 8) {
169 printf("\t\ta %g d %g s %g r %g\t\ta %g d %g s %g r %g\n", fargs[6], fargs[7], fargs[8], fargs[9], fargs[10], fargs[11], fargs[12], fargs[13]);
170 mAEnv.setAttack(*fargs[4]);
171 mAEnv.setDecay(*fargs[5]);
172 mAEnv.setSustain(*fargs[6]);
173 mAEnv.setRelease(*fargs[7]);
174 }
175 this->play();
176 }
177
178 // Play a note specifying all parameters
179
180 void AdditiveInstrument::playNote(float dur, float ampl, float c_fr, float pos, float att, float dec, float sus, float rel) {
181 mAEnv.setDuration(dur);
182 mAEnv.scaleValues(ampl);
183 mSOS.setFrequency(c_fr);
184 mPanner.setPosition(pos);
185 mAEnv.setAttack(att);
186 mAEnv.setDecay(dec);
187 mAEnv.setSustain(sus);
188 mAEnv.setRelease(rel);
189 this->play();
190 }
191
192
193 void AdditiveInstrument::playMIDI(float dur, int chan, int key, int vel) {
194 mAEnv.setDuration(dur);
195 mAEnv.scaleValues(sqrtf((float) vel / 128.0f));
196 mSOS.setFrequency(keyToFreq(key));
197 this->play();
198 }