Simple VJ Controller (refine): Resolume + Launchpad + openFrameworks
#include "ofApp.h" | |
#include <regex> | |
const int midiMap[] = { | |
0, 1, 2, 3, 4, 5, 6, 7, | |
16, 17, 18, 19, 20, 21, 22, 23, | |
32, 33, 34, 35, 36, 37, 38, 39, | |
48, 49, 50, 51, 52, 53, 54, 55, | |
64, 65, 66, 67, 68, 69, 70, 71, | |
80, 81, 82, 83, 84, 85, 86, 87, | |
96, 97, 98, 99, 100, 101, 102, 103, | |
112, 113, 114, 115, 116, 117, 118, 119 | |
}; | |
int ledWidth = 8, ledHeight = 8; | |
int ledColor = 63; | |
int ledBuf[64] = {}; // LEDのOn/Offのバッファ | |
int refreshRate = 100; // バッファを送信するまでの時間(ms) | |
int prevTime = 0; | |
const int numeratorMin = 1, numeratorMax = 16; | |
const int denominatorMin = 3, denominatorMax = 18; | |
void ofApp::setup() { | |
ofSetFrameRate(60); | |
// Setup OSC | |
receiver.setup(PORT); | |
sender.setup(HOST, SEND_PORT); | |
// Setup MIDI | |
midiIn.listPorts(); | |
midiIn.openPort("Launchpad"); | |
midiOut.openPort("Launchpad"); | |
midiIn.addListener(this); | |
// Reset LED | |
midiOut.sendControlChange(1, 0, 0); | |
} | |
void ofApp::update() { | |
int time = ofGetElapsedTimeMillis(); | |
if(time - prevTime > refreshRate) { | |
ledRefresh(ledBuf); | |
prevTime = time; | |
} | |
// Recieve OSC message | |
while (receiver.hasWaitingMessages()) { | |
ofxOscMessage m; | |
receiver.getNextMessage(m); | |
string address = m.getAddress(); | |
// レイヤー不透明度を指定するOSCメッセージを受信 | |
std::regex re("/layer([0-9]+)/video/opacity/values"); | |
std::smatch match; | |
if (std::regex_match(address, match, re)) { | |
int x = ofMap(m.getArgAsFloat(0), 0, 1, 0, 7); | |
int y = ofToInt(match[1]) - 1; | |
int set; | |
// 不透明度の値に合わせてLEDを横一列に点灯 | |
for (int i=0; i<ledWidth; i++) { | |
set = i <= x ? ledColor : 0; | |
ledBuf[y*ledWidth+i] = set; | |
} | |
} | |
} | |
} | |
void ofApp::newMidiMessage(ofxMidiMessage& msg) { | |
int x = msg.pitch%16; | |
int y = msg.pitch/16; | |
bool pressed = msg.velocity ? true : false; | |
int set; | |
if (!pressed) return; | |
// Send MIDI to Launchpad | |
for (int i=0; i<ledWidth; i++) { | |
set = i <= x ? ledColor : 0; | |
ledBuf[y*ledWidth+i] = set; | |
} | |
// Send OSC to Resolume | |
int layer = y+1; | |
float opacity = ofMap(x, 0, 7, 0, 1.0); | |
// レイヤー不透明度を指定するOSCメッセージを送信 | |
m.setAddress("/layer"+ofToString(layer)+"/video/opacity/values"); | |
m.addFloatArg(opacity); | |
sender.sendMessage(m); | |
m.clear(); | |
} | |
// 8x8のLEDを全更新する | |
void ofApp::ledRefresh(int data[]) { | |
for(int i=0,size=ledWidth*ledHeight; i<size; i++) { | |
midiOut.sendNoteOn(3, data[i], data[i+1]); | |
i++; | |
} | |
midiOut.sendNoteOn(1, 127, 0); | |
} | |
// LaunchpadのLEDを点灯 | |
void ofApp::ledSet(int x, int y, int set) { | |
midiOut.sendNoteOn(1, midiMap[y*ledHeight+x], set); | |
} |
#pragma once | |
#include "ofMain.h" | |
#include "ofxOsc.h" | |
#include "ofxMidi.h" | |
#define PORT 7001 | |
#define SEND_PORT 7000 | |
#define HOST "localhost" | |
class ofApp : public ofBaseApp, public ofxMidiListener { | |
public: | |
void setup(); | |
void update(); | |
private: | |
ofxOscReceiver receiver; | |
ofxOscSender sender; | |
ofxOscMessage m; | |
ofxMidiIn midiIn; | |
ofxMidiOut midiOut; | |
void newMidiMessage(ofxMidiMessage& msg); | |
void ledRefresh(int data[]); | |
void ledSet(int x, int y, int set); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment