CSL  6.0
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  mAEnv(0.25, 0.03, 0.06, 0.5, 0.15), // set up standard ADSR (1/4-sec duration)
31  mSOS(16, 0.75), // SumOfSines init, 16 partials @ 1/f
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  mAEnv(0.25, 0.03, 0.06, 0.5, 0.15), // set up standard ADSR (1/4-sec duration)
39  mSOS(sos), // SumOfSines init, 16 partials @ 1/f
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  mAEnv(0.25, 0.03, 0.06, 0.5, 0.15), // set up standard ADSR (1/4-sec duration)
47  mSOS(numHarms, noise), // SumOfSines init, numHarms partials @ 1/f
48  mPanner(mSOS, 0.0) { // init the panner
49  this->init();
50 }
51 
53  Instrument(),
54  mAEnv(0.25, 0.03, 0.06, 0.5, 0.15), // set up standard ADSR (1/4-sec duration)
55  mSOS(spect), // SumOfSines init, 16 partials @ 1/f
56  mPanner(mSOS, 0.0) { // init the panner
57  this->init();
58 }
59 
60 // setup instance
61 
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 
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 
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 %5.2f d %5.2f s %5.2f r %5.2f\t\ta %5.2f d %5.2f s %5.2f r %5.2f\n",
170  fargs[6], fargs[7], fargs[8], fargs[9], fargs[10], fargs[11], fargs[12], fargs[13]);
171  mAEnv.setAttack(*fargs[4]);
172  mAEnv.setDecay(*fargs[5]);
173  mAEnv.setSustain(*fargs[6]);
174  mAEnv.setRelease(*fargs[7]);
175  }
176  this->play();
177 }
178 
179 // Play a note specifying all parameters
180 
181 void AdditiveInstrument::playNote(float dur, float ampl, float c_fr, float pos, float att, float dec, float sus, float rel) {
182  mAEnv.setDuration(dur);
183  mAEnv.scaleValues(ampl);
184  mSOS.setFrequency(c_fr);
185  mPanner.setPosition(pos);
186  mAEnv.setAttack(att);
187  mAEnv.setDecay(dec);
188  mAEnv.setSustain(sus);
189  mAEnv.setRelease(rel);
190  this->play();
191 }
192 
193 
194 void AdditiveInstrument::playMIDI(float dur, int chan, int key, int vel) {
195  mAEnv.setDuration(dur);
196  mAEnv.scaleValues(sqrtf((float) vel / 128.0f));
198  this->play();
199 }
void logMsg(const char *format,...)
These are the public logging messages.
Definition: CGestalt.cpp:292
Panner mPanner
stereo panner
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
#define set_amplitude_f
Definition: Instrument.h:20
void playOSC(int argc, void **argv, const char *types)
Play functions.
#define set_decay_f
Definition: Instrument.h:26
AdditiveInstrument.
#define set_attack_f
Definition: Instrument.h:25
void setAttack(float attack)
Definition: Envelope.cpp:409
#define set_partial_f
Definition: Instrument.h:48
void setRelease(float release)
Definition: Envelope.cpp:432
UnitGenerator * mGraph
Caches.
Definition: Instrument.h:87
float keyToFreq(unsigned midiKey)
MIDI Conversions.
Definition: CGestalt.cpp:483
void addPartials(unsigned num_p, Partial **pt)
Definition: Oscillator.cpp:490
AccessorVector mAccessors
the accessor vector
Definition: Instrument.h:91
void playMIDI(float dur, int chan, int key, int vel)
virtual void play()
Definition: Instrument.cpp:70
string mName
my name
Definition: Instrument.h:88
void playNote(float dur=1, float ampl=1, float c_fr=110, float pos=0, float att=0.05, float dec=0.05, float sus=0.5, float rel=0.5)
ADSR mAEnv
amplitude envelope
SumOfSines mSOS
sum-of-sine oscillator
#define set_duration_f
Instrument.h – The CSL pluggable instrument class. See the copyright notice and acknowledgment of au...
Definition: Instrument.h:19
unsigned mNumChannels
my "expected" number of output channels
Definition: CSL_Core.h:292
#define set_frequency_f
Definition: Instrument.h:21
void setPosition(UnitGenerator &pan)
Operations.
Definition: Mixer.cpp:279
Instrument class (abstract)
Definition: Instrument.h:56
void addPartial(Partial *pt)
given a SHARC spectrum
Definition: Oscillator.cpp:486
void setParameter(unsigned selector, int argc, void **argv, const char *types)
Plug functions.
void setDuration(float d)
Special accessors.
Definition: Envelope.cpp:385
void setFrequency(UnitGenerator &frequency)
Setter accessors.
Definition: CSL_Core.cpp:981
#define CSL_FLOAT_TYPE
Definition: Accessor.h:14
virtual void scaleValues(float s)
scale values so the max is s
Definition: Envelope.cpp:246
void setSustain(float sustain)
Definition: Envelope.cpp:426
The Accessor class has public data members.
Definition: Accessor.h:22
void setDecay(float decay)
Definition: Envelope.cpp:419
#define set_partials_f
Definition: Instrument.h:49
#define set_sustain_f
Definition: Instrument.h:27
#define set_position_f
Definition: Instrument.h:22
UGenVector mEnvelopes
the vector of envelopes to query or trigger
Definition: Instrument.h:90
void setScale(UnitGenerator &scale)
set the receiver's scale member to a UGen or a float
Definition: CSL_Core.cpp:1039
#define set_release_f
Definition: Instrument.h:28
SHARC spectrum class.
Definition: SHARC.h:76
UGenMap mUGens
the map of ugens in the graph by name
Definition: Instrument.h:89