1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
#include "PyoClass.h"
/*
** Creates a python interpreter and initialize a pyo server inside it.
** This function must be called, once per Pyo object, before any other
** calls.
**
** arguments:
** nChannels : int, number of in/out channels.
** bufferSize : int, number of samples per buffer.
** sampleRate : int, sample rate frequency.
**
** All arguments should be equal to the host audio settings.
*/
void Pyo::setup(int _nChannels, int _bufferSize, int _sampleRate) {
nChannels = _nChannels;
bufferSize = _bufferSize;
sampleRate = _sampleRate;
interpreter = pyo_new_interpreter(sampleRate, bufferSize, nChannels);
pyoInBuffer = reinterpret_cast<float*>(pyo_get_input_buffer_address(interpreter));
pyoOutBuffer = reinterpret_cast<float*>(pyo_get_output_buffer_address(interpreter));
pyoCallback = reinterpret_cast<callPtr*>(pyo_get_embedded_callback_address(interpreter));
pyoId = pyo_get_server_id(interpreter);
}
/*
** Terminates this object's interpreter.
*/
Pyo::~Pyo() {
pyo_end_interpreter(interpreter);
}
/*
** This function fills pyo's input buffers with new samples. Should be called
** once per process block, inside the host's audioIn function.
**
** arguments:
** *buffer : float *, float pointer pointing to the host's input buffers.
*/
void Pyo::fillin(float *buffer) {
for (int i=0; i<(bufferSize*nChannels); i++) pyoInBuffer[i] = buffer[i];
}
/*
** This function tells pyo to process a buffer of samples and fills the host's
** output buffer with new samples. Should be called once per process block,
** inside the host's audioOut function.
**
** arguments:
** *buffer : float *, float pointer pointing to the host's output buffers.
*/
void Pyo::process(float *buffer) {
pyoCallback(pyoId);
for (int i=0; i<(bufferSize*nChannels); i++) buffer[i] = pyoOutBuffer[i];
}
/*
** Execute a python script "file" in the objectès thread's interpreter.
** An integer "add" is needed to indicate if the pyo server should be
** reboot or not.
**
** arguments:
** file : char *, filename to execute as a python script. The file is first
** searched in the current working directory. If not found,
** the module will try to open it as an absolute path.
** add, int, if positive, the commands in the file will be added to whatever
** is already running in the pyo server. If 0, the server will be
** cleared before executing the file.
**
** returns 0 (no error), 1 (failed to open the file) or 2 (bad code in file).
*/
int Pyo::loadfile(const char *file, int add) {
return pyo_exec_file(interpreter, file, pyoMsg, add);
}
/*
** Sends a numerical value to an existing Sig or SigTo object.
**
** arguments:
** name : const char *, variable name of the object.
** value : float, value to be assigned.
**
** returns 0 (no error) or 1 (bad code in file).
**
** Example:
**
** inside the script file:
**
** freq = SigTo(value=440, time=0.1, init=440)
**
** Inside OpenFrameworks (for a Pyo object named `pyo`):
**
** pyo.value("freq", 880);
*/
int Pyo::value(const char *name, float value) {
sprintf(pyoMsg, "%s.value=%f", name, value);
return pyo_exec_statement(interpreter, pyoMsg, 0);
}
/*
** Sends an array of numerical values to an existing Sig or SigTo object.
**
** arguments:
** name : const char *, variable name of the object.
** value : float *, array of floats.
** len : int, number of elements in the array.
**
** returns 0 (no error) or 1 (bad code in file).
**
** Example:
**
** inside the script file:
**
** freq = SigTo(value=[100,200,300,400], time=0.1, init=[100,200,300,400])
**
** Inside OpenFrameworks (for a Pyo object named `pyo`):
**
** float frequencies[4] = {150, 250, 350, 450};
** pyo.value("freq", frequencies, 4);
*/
int Pyo::value(const char *name, float *value, int len) {
char fchar[32];
sprintf(pyoMsg, "%s.value=[", name);
for (int i=0; i<len; i++) {
sprintf(fchar, "%f,", value[i]);
strcat(pyoMsg, fchar);
}
strcat(pyoMsg, "]");
return pyo_exec_statement(interpreter, pyoMsg, 0);
}
/*
** Sends a numerical value to a Pyo object's attribute.
**
** arguments:
** name : const char *, object name and attribute separated by a dot.
** value : float, value to be assigned.
**
** returns 0 (no error) or 1 (bad code in file).
**
** Example:
**
** inside the script file:
**
** filter = Biquad(input=Noise(0.5), freq=1000, q=4, type=2)
**
** Inside OpenFrameworks (for a Pyo object named `pyo`):
**
** pyo.set("filter.freq", 2000);
*/
int Pyo::set(const char *name, float value) {
sprintf(pyoMsg, "%s=%f", name, value);
return pyo_exec_statement(interpreter, pyoMsg, 0);
}
/*
** Sends an array of numerical values to a Pyo object's attribute.
**
** arguments:
** name : const char *, object name and attribute separated by a dot.
** value : float *, array of floats.
** len : int, number of elements in the array.
**
** returns 0 (no error) or 1 (bad code in file).
**
** Example:
**
** inside the script file:
**
** filters = Biquad(input=Noise(0.5), freq=[250, 500, 1000, 2000], q=5, type=2)
**
** Inside OpenFrameworks (for a Pyo object named `pyo`):
**
** float frequencies[4] = {350, 700, 1400, 2800};
** pyo.set("filters.freq", frequencies, 4);
*/
int Pyo::set(const char *name, float *value, int len) {
char fchar[32];
sprintf(pyoMsg, "%s=[", name);
for (int i=0; i<len; i++) {
sprintf(fchar, "%f,", value[i]);
strcat(pyoMsg, fchar);
}
strcat(pyoMsg, "]");
return pyo_exec_statement(interpreter, pyoMsg, 0);
}
/*
** Executes any raw valid python statement. With this function, one can dynamically
** creates and manipulates audio objects and algorithms.
**
** arguments:
** msg : const char *, pointer to a string containing the statement to execute.
**
** returns 0 (no error) or 1 (bad code in file).
**
** Example (for a Pyo object named `pyo`):
**
** pyo.exec("pits = [0.001, 0.002, 0.003, 0.004]")
** pyo.exec("fr = Rossler(pitch=pits, chaos=0.9, mul=250, add=500)")
** pyo.exec("b = SumOsc(freq=fr, ratio=0.499, index=0.4, mul=0.2).out()")
*/
int Pyo::exec(const char *_msg) {
strcpy(pyoMsg, _msg);
return pyo_exec_statement(interpreter, pyoMsg, 0);
}
/*
** Shutdown and reboot the pyo server while keeping current in/out buffers.
** This will erase audio objects currently active within the server.
**
*/void Pyo::clear() {
pyo_server_reboot(interpreter);
}
|