## 2 The Framework
### Registering Opcodes with Csound
This is based on the use of a placement new via a function template, which is used to access the class constructor for an object:

template <typename T, typename... Types> T *constr(T* P, Types... args){  return new(p) T(args...); } As an example, consider an object of type A called obj, which needs to be constructed explicitly, using

A::A(int, float) {... }; To invoke it, we should place the following call in the init() method of our opcode class:

csnd::constr(&obj, 10, 10.f); where the arguments are the variable address, followed by any class constructor parameters. Again, given that the compiler knows that obj is of type A, it resolves the template without the need for an explicit type instantiation. It is also important to note that if the object constructed in this form allocates any resources dynamically, we will need to free these. For this we are required to call the object destructor explicitly by using another function template, defined in CPOF as

template<typename T> void destr(T *p) {  p->T::-T(); } The call to the destructor should be issued at the point where we no longer need the object. For opcodes that run at perf-time, this is normally done in the opcoe deinit() method. For example, to clean up a member variable obj, we implement the following code:

int deinit() {  csnd::destr(&obj);  return OK; }

## 3 The Engine Object

As noted in Section 1.1.1, the Csound API provides a large range of facilities to opcodes through several functions provided in the CSOUND data structure, which is made opaque to CPOF. In fact,since the API is designed to cater for a wider variety of applications beyond extending the language, many of these functions are not designed for use in UGs. For this reason, to provide a clearer interface for opcode programming, CPOF encapsulates the engine into an object that exposes only the relevant methods to the user. All opcodes are run inside the Csound engine, represented by the Csound class (Figure 2). As we have seen above, the Plugin class holds a pointer of this type, which can be used to access the various utility methods provided by the engine. The following are the public methods of the Csound class in each category:

* init_error(): takes a string message and signals an initialisation error. * perf_error(): takes a string message, an instrument instance and signals a performance error. * warning(): warning messages. * message(): information messages. * System parameters:
* sr(): returns engine sampling rate. * _0 dbfs(): returns max amplitude reference. * _A4(): returns A4 pitch reference. * nchnls(): return number of output channels for the engine. * nchnls_i(): same, for input channel numbers. * current_time_samples(): current engine time in samples. * current_time_seconds(): current engine time in seconds. * is_asig(): check for an audio signal argument. * MIDI data access:
* midi_channel(): midi channel assigned to this instrument. * midi_note_num(): midi note number (if the instrument was instantiated with a MIDI. NOTE ON). * midi_note_vel(): same, for velocity. * midi_chn_aftertouch(): channel aftertouch. * midi_chn_polytouch(): polyphonic aftertouch. * midi_chn_ctl(): continuous control value. * midi_chn_pitchend(): pitch bend data. * midi_chn_list(): list of active notes for this channel. * fft_setup(): FFT operation setup. * rfft(): real-to-complex, complex-to-real FFT. * fft(): complex-to-complex FFT. * Memory allocation (Csound-managed heap):
* malloc(): malloc-style memory allocation. * calloc(): calloc-style memory allocation. * realloc(): realloc-style memory allocation. * strdup(): string duplication. * free(): memory deallocation. In addition to these, the Csound class also holds a deinit method registration function template that can be used by opcodes to implement housekeeping tasks. template <typename T> void plugin_deinit(T *p);

This is only required if the Plugin-derived class has allocated extra resources using mechanisms that require explicit clean-up. It is not need in most cases, as we will see in our examples.