annotate AppCore.mm @ 15:e45c3e631d20

View fiddling
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Thu, 17 Jan 2013 13:01:19 +0000
parents 346807b47860
children ae4d2c3ce5e0
rev   line source
rt300@9 1 /*
rt300@9 2 * Copyright (c) 2011 Dan Wilcox <danomatika@gmail.com>
rt300@9 3 *
rt300@9 4 * BSD Simplified License.
rt300@9 5 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
rt300@9 6 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
rt300@9 7 *
rt300@9 8 * See https://github.com/danomatika/ofxPd for documentation
rt300@9 9 *
rt300@9 10 */
rt300@9 11 #include "AppCore.h"
rt300@9 12
rt300@9 13 //--------------------------------------------------------------
rt300@9 14 void AppCore::setup(const int numOutChannels, const int numInChannels,
rt300@9 15 const int sampleRate, const int ticksPerBuffer) {
rt300@9 16
rt300@9 17 ofSetFrameRate(60);
rt300@9 18 ofSetVerticalSync(true);
rt300@9 19 //ofSetLogLevel(OF_LOG_VERBOSE);
rt300@9 20
rt300@9 21 // double check where we are ...
rt300@9 22 cout << ofFilePath::getCurrentWorkingDirectory() << endl;
rt300@9 23
rt300@9 24 if(!pd.init(numOutChannels, numInChannels, sampleRate, ticksPerBuffer)) {
rt300@9 25 ofLog(OF_LOG_ERROR, "Could not init pd");
rt300@9 26 OF_EXIT_APP(1);
rt300@9 27 }
rt300@9 28
rt300@9 29 midiChan = 1; // midi channels are 1-16
rt300@9 30
rt300@9 31 // subscribe to receive source names
rt300@9 32 pd.subscribe("toOF");
rt300@9 33 pd.subscribe("env");
rt300@9 34
rt300@9 35 // add message receiver, disables polling (see processEvents)
rt300@9 36 pd.addReceiver(*this); // automatically receives from all subscribed sources
rt300@9 37 pd.ignore(*this, "env"); // don't receive from "env"
rt300@9 38 //pd.ignore(*this); // ignore all sources
rt300@9 39 //pd.receive(*this, "toOF"); // receive only from "toOF"
rt300@9 40
rt300@9 41 // add midi receiver
rt300@9 42 pd.addMidiReceiver(*this); // automatically receives from all channels
rt300@9 43 //pd.ignoreMidi(*this, 1); // ignore midi channel 1
rt300@9 44 //pd.ignoreMidi(*this); // ignore all channels
rt300@9 45 //pd.receiveMidi(*this, 1); // receive only from channel 1
rt300@9 46
rt300@9 47 // add the data/pd folder to the search path
rt300@9 48 pd.addToSearchPath("pd");
rt300@9 49
rt300@9 50 // audio processing on
rt300@9 51 pd.start();
rt300@9 52
rt300@9 53 // open patch
rt300@9 54 Patch patch = pd.openPatch("mytest.pd");
rt300@9 55 cout << patch << endl;
rt300@9 56
rt300@9 57
rt300@9 58 }
rt300@9 59
rt300@9 60 //--------------------------------------------------------------
rt300@9 61 void AppCore::update() {
rt300@9 62 ofBackground(100, 100, 100);
rt300@9 63
rt300@9 64 // update scope array from pd
rt300@9 65 pd.readArray("scope", scopeArray);
rt300@9 66 }
rt300@9 67
rt300@9 68 //--------------------------------------------------------------
rt300@9 69 void AppCore::draw() {
rt300@9 70
rt300@9 71 // draw scope
rt300@9 72 ofSetColor(0, 255, 0);
rt300@9 73 ofSetRectMode(OF_RECTMODE_CENTER);
rt300@9 74 float x = 0, y = ofGetHeight()/2;
rt300@9 75 float w = ofGetWidth() / (float) scopeArray.size(), h = ofGetHeight()/2;
rt300@9 76 for(int i = 0; i < scopeArray.size()-1; ++i) {
rt300@9 77 ofLine(x, y+scopeArray[i]*h, x+w, y+scopeArray[i+1]*h);
rt300@9 78 x += w;
rt300@9 79 }
rt300@9 80 }
rt300@9 81
rt300@9 82 //--------------------------------------------------------------
rt300@9 83 void AppCore::exit() {}
rt300@9 84
rt300@9 85 //--------------------------------------------------------------
rt300@9 86 void AppCore::playTone(int pitch) {
rt300@9 87 pd << StartMessage() << "pitch" << pitch << FinishList("tone") << Bang("tone");
rt300@9 88 }
rt300@9 89
rt300@9 90 //--------------------------------------------------------------
rt300@9 91 void AppCore::keyPressed (int key) {
rt300@9 92
rt300@9 93 switch(key) {
rt300@9 94
rt300@9 95 case 'a':
rt300@9 96 playTone(60);
rt300@9 97 break;
rt300@9 98 case 'w':
rt300@9 99 playTone(61);
rt300@9 100 break;
rt300@9 101 case 's':
rt300@9 102 playTone(62);
rt300@9 103 break;
rt300@9 104 case 'e':
rt300@9 105 playTone(63);
rt300@9 106 break;
rt300@9 107 case 'd':
rt300@9 108 playTone(64);
rt300@9 109 break;
rt300@9 110 case 'f':
rt300@9 111 playTone(65);
rt300@9 112 break;
rt300@9 113 case 't':
rt300@9 114 playTone(66);
rt300@9 115 break;
rt300@9 116 case 'g':
rt300@9 117 playTone(67);
rt300@9 118 break;
rt300@9 119 case 'y':
rt300@9 120 playTone(68);
rt300@9 121 break;
rt300@9 122 case 'h':
rt300@9 123 playTone(69);
rt300@9 124 break;
rt300@9 125 case 'u':
rt300@9 126 playTone(70);
rt300@9 127 break;
rt300@9 128 case 'j':
rt300@9 129 playTone(71);
rt300@9 130 break;
rt300@9 131 case 'k':
rt300@9 132 playTone(72);
rt300@9 133 break;
rt300@9 134
rt300@9 135 case ' ':
rt300@9 136 if(pd.isReceiving(*this, "env")) {
rt300@9 137 pd.ignore(*this, "env");
rt300@9 138 cout << "ignoring env" << endl;
rt300@9 139 }
rt300@9 140 else {
rt300@9 141 pd.receive(*this, "env");
rt300@9 142 cout << "receiving from env" << endl;
rt300@9 143 }
rt300@9 144 break;
rt300@9 145
rt300@9 146 default:
rt300@9 147 break;
rt300@9 148 }
rt300@9 149 }
rt300@9 150
rt300@9 151 //--------------------------------------------------------------
rt300@9 152 void AppCore::audioReceived(float * input, int bufferSize, int nChannels) {
rt300@9 153 pd.audioIn(input, bufferSize, nChannels);
rt300@9 154 }
rt300@9 155
rt300@9 156 //--------------------------------------------------------------
rt300@9 157 void AppCore::audioRequested(float * output, int bufferSize, int nChannels) {
rt300@9 158 pd.audioOut(output, bufferSize, nChannels);
rt300@9 159 }
rt300@9 160
rt300@9 161 //--------------------------------------------------------------
rt300@9 162 void AppCore::print(const std::string& message) {
rt300@9 163 cout << message << endl;
rt300@9 164 }
rt300@9 165
rt300@9 166 //--------------------------------------------------------------
rt300@9 167 void AppCore::receiveBang(const std::string& dest) {
rt300@9 168 cout << "OF: bang " << dest << endl;
rt300@9 169 }
rt300@9 170
rt300@9 171 void AppCore::receiveFloat(const std::string& dest, float value) {
rt300@9 172 cout << "OF: float " << dest << ": " << value << endl;
rt300@9 173 }
rt300@9 174
rt300@9 175 void AppCore::receiveSymbol(const std::string& dest, const std::string& symbol) {
rt300@9 176 cout << "OF: symbol " << dest << ": " << symbol << endl;
rt300@9 177 }
rt300@9 178
rt300@9 179 void AppCore::receiveList(const std::string& dest, const List& list) {
rt300@9 180 cout << "OF: list " << dest << ": ";
rt300@9 181
rt300@9 182 // step through the list
rt300@9 183 for(int i = 0; i < list.len(); ++i) {
rt300@9 184 if(list.isFloat(i))
rt300@9 185 cout << list.getFloat(i) << " ";
rt300@9 186 else if(list.isSymbol(i))
rt300@9 187 cout << list.getSymbol(i) << " ";
rt300@9 188 }
rt300@9 189
rt300@9 190 // you can also use the built in toString function or simply stream it out
rt300@9 191 // cout << list.toString();
rt300@9 192 // cout << list;
rt300@9 193
rt300@9 194 // print an OSC-style type string
rt300@9 195 cout << list.types() << endl;
rt300@9 196 }
rt300@9 197
rt300@9 198 void AppCore::receiveMessage(const std::string& dest, const std::string& msg, const List& list) {
rt300@9 199 cout << "OF: message " << dest << ": " << msg << " " << list.toString() << list.types() << endl;
rt300@9 200 }
rt300@9 201
rt300@9 202 //--------------------------------------------------------------
rt300@9 203 void AppCore::receiveNoteOn(const int channel, const int pitch, const int velocity) {
rt300@9 204 cout << "OF MIDI: note on: " << channel << " " << pitch << " " << velocity << endl;
rt300@9 205 }
rt300@9 206
rt300@9 207 void AppCore::receiveControlChange(const int channel, const int controller, const int value) {
rt300@9 208 cout << "OF MIDI: control change: " << channel << " " << controller << " " << value << endl;
rt300@9 209 }
rt300@9 210
rt300@9 211 // note: pgm nums are 1-128 to match pd
rt300@9 212 void AppCore::receiveProgramChange(const int channel, const int value) {
rt300@9 213 cout << "OF MIDI: program change: " << channel << " " << value << endl;
rt300@9 214 }
rt300@9 215
rt300@9 216 void AppCore::receivePitchBend(const int channel, const int value) {
rt300@9 217 cout << "OF MIDI: pitch bend: " << channel << " " << value << endl;
rt300@9 218 }
rt300@9 219
rt300@9 220 void AppCore::receiveAftertouch(const int channel, const int value) {
rt300@9 221 cout << "OF MIDI: aftertouch: " << channel << " " << value << endl;
rt300@9 222 }
rt300@9 223
rt300@9 224 void AppCore::receivePolyAftertouch(const int channel, const int pitch, const int value) {
rt300@9 225 cout << "OF MIDI: poly aftertouch: " << channel << " " << pitch << " " << value << endl;
rt300@9 226 }
rt300@9 227
rt300@9 228 // note: pd adds +2 to the port num, so sending to port 3 in pd to [midiout],
rt300@9 229 // shows up at port 1 in ofxPd
rt300@9 230 void AppCore::receiveMidiByte(const int port, const int byte) {
rt300@9 231 cout << "OF MIDI: midi byte: " << port << " " << byte << endl;
rt300@9 232 }
rt300@9 233
rt300@9 234 //--------------------------------------------------------------
rt300@9 235 void AppCore::processEvents() {
rt300@9 236
rt300@9 237 cout << "Number of waiting messages: " << pd.numMessages() << endl;
rt300@9 238
rt300@9 239 while(pd.numMessages() > 0) {
rt300@9 240 Message& msg = pd.nextMessage();
rt300@9 241
rt300@9 242 switch(msg.type) {
rt300@9 243
rt300@9 244 case pd::PRINT:
rt300@9 245 cout << "OF: " << msg.symbol << endl;
rt300@9 246 break;
rt300@9 247
rt300@9 248 // events
rt300@9 249 case pd::BANG:
rt300@9 250 cout << "OF: bang " << msg.dest << endl;
rt300@9 251 break;
rt300@9 252 case pd::FLOAT:
rt300@9 253 cout << "OF: float " << msg.dest << ": " << msg.num << endl;
rt300@9 254 break;
rt300@9 255 case pd::SYMBOL:
rt300@9 256 cout << "OF: symbol " << msg.dest << ": " << msg.symbol << endl;
rt300@9 257 break;
rt300@9 258 case pd::LIST:
rt300@9 259 cout << "OF: list " << msg.list << msg.list.types() << endl;
rt300@9 260 break;
rt300@9 261 case pd::MESSAGE:
rt300@9 262 cout << "OF: message " << msg.dest << ": " << msg.symbol << " "
rt300@9 263 << msg.list << msg.list.types() << endl;
rt300@9 264 break;
rt300@9 265
rt300@9 266 // midi
rt300@9 267 case pd::NOTE_ON:
rt300@9 268 cout << "OF MIDI: note on: " << msg.channel << " "
rt300@9 269 << msg.pitch << " " << msg.velocity << endl;
rt300@9 270 break;
rt300@9 271 case pd::CONTROL_CHANGE:
rt300@9 272 cout << "OF MIDI: control change: " << msg.channel
rt300@9 273 << " " << msg.controller << " " << msg.value << endl;
rt300@9 274 break;
rt300@9 275 case pd::PROGRAM_CHANGE:
rt300@9 276 cout << "OF MIDI: program change: " << msg.channel << " "
rt300@9 277 << msg.value << endl;
rt300@9 278 break;
rt300@9 279 case pd::PITCH_BEND:
rt300@9 280 cout << "OF MIDI: pitch bend: " << msg.channel << " "
rt300@9 281 << msg.value << endl;
rt300@9 282 break;
rt300@9 283 case pd::AFTERTOUCH:
rt300@9 284 cout << "OF MIDI: aftertouch: " << msg.channel << " "
rt300@9 285 << msg.value << endl;
rt300@9 286 break;
rt300@9 287 case pd::POLY_AFTERTOUCH:
rt300@9 288 cout << "OF MIDI: poly aftertouch: " << msg.channel << " "
rt300@9 289 << msg.pitch << " " << msg.value << endl;
rt300@9 290 break;
rt300@9 291 case pd::BYTE:
rt300@9 292 cout << "OF MIDI: midi byte: " << msg.port << " 0x"
rt300@9 293 << hex << (int) msg.byte << dec << endl;
rt300@9 294 break;
rt300@9 295
rt300@9 296 case pd::NONE:
rt300@9 297 cout << "OF: NONE ... empty message" << endl;
rt300@9 298 break;
rt300@9 299 }
rt300@9 300 }
rt300@9 301 }