【C/C++】ProcessingのプログラムをopenFrameworks,Cinder用に書き換える Part13
Audio Input FFT
[環境]
Processing 1.5.1
openFrameworks 0.07
Cinder 0.8.3

[Processing]
[openFrameworks]
testApp.h
[Cinder]
[確認事項]
・openFrameworks
openFrameworksではAudio入力(ofSoundStream)に対するFFTの関数が実装されていないので ofxFftアドオンを使用
http://ofxaddons.com/repos/383
[環境]
Processing 1.5.1
openFrameworks 0.07
Cinder 0.8.3

[Processing]
import ddf.minim.*;
import ddf.minim.analysis.*;
Minim minim;
AudioInput in;
FFT fft;
static final int BUFFER_SIZE = 1024;
void setup() {
size(512, 200);
frameRate(60);
smooth();
minim = new Minim(this);
in = minim.getLineIn(Minim.STEREO, BUFFER_SIZE);
fft = new FFT(in.bufferSize(), in.sampleRate());
}
void draw() {
background(0);
stroke(255);
int bandCount = 512;
float ht = 1000.0f;
fft.forward(in.mix);
for(int i=0; i < bandCount; i++){
float barY = fft.getBand(i) / bandCount * ht;
line(i, height, i, height - barY);
}
}
[openFrameworks]
testApp.h
#pragma once
#include "ofMain.h"
#include "ofxFft.h"
#define BUFFER_SIZE 1024
class testApp : public ofBaseApp {
public:
void setup();
void audioReceived(float* input, int bufferSize, int nChannels);
void draw();
ofxFft* fft;
float* audioInput;
float* fftOutput;
};
testApp.cpp
#include "testApp.h"
void testApp::setup() {
fft = ofxFft::create(BUFFER_SIZE, OF_FFT_WINDOW_RECTANGULAR, OF_FFT_FFTW);
audioInput = new float[BUFFER_SIZE];
fftOutput = new float[fft->getBinSize()];
ofSoundStreamSetup(0, 1, this, 44100, BUFFER_SIZE, 4);
ofBackground(0, 0, 0);
ofSetColor(255, 255, 255);
ofSetFrameRate(60);
}
void testApp::draw() {
float ht = 1000.0f;
int binSize = fft->getBinSize();
for (int i=0; i < binSize; i++) {
float barY = fftOutput[i] * ht;
ofLine(i, ofGetHeight(), i, ofGetHeight()-barY);
}
}
void testApp::audioReceived(float* input, int bufferSize, int nChannels) {
memcpy(audioInput, input, sizeof(float) *bufferSize);
fft->setSignal(audioInput);
memcpy(fftOutput, fft->getAmplitude(), sizeof(float) *fft->getBinSize());
}
main.cpp
#include "ofMain.h"
#include "testApp.h"
#include "ofAppGlutWindow.h"
int main() {
ofAppGlutWindow window;
ofSetupOpenGL(&window, 512, 200, OF_WINDOW);
ofRunApp(new testApp());
}
[Cinder]
#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/audio/FftProcessor.h"
#include "cinder/audio/Input.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class POC013App : public AppBasic {
public:
void prepareSettings(Settings *settings);
void setup();
void update();
void draw();
void drawFft();
audio::Input mInput;
std::shared_ptr<float> mFftDataRef;
audio::PcmBuffer32fRef mPcmBuffer;
};
void POC013App::prepareSettings(Settings *settings){
settings->setWindowSize(512, 200);
settings->setFrameRate(60);
}
void POC013App::setup(){
mInput = audio::Input();
mInput.start();
}
void POC013App::update() {
mPcmBuffer = mInput.getPcmBuffer();
if(!mPcmBuffer) {
return;
}
uint16_t bandCount = 512;
mFftDataRef = audio::calculateFft( mPcmBuffer->getChannelData( audio::CHANNEL_FRONT_LEFT ), bandCount );
}
void POC013App::draw(){
gl::clear(Color(0.0f, 0.0f, 0.0f));
glPushMatrix();
glTranslatef(0.0f, 0.0f, 0.0f);
drawFft();
glPopMatrix();
}
void POC013App::drawFft(){
uint16_t bandCount = 512;
float ht = 1000.0f;
if(!mFftDataRef) {
return;
}
float *fftBuffer = mFftDataRef.get();
for (int i=0; i < (bandCount); i++) {
gl::color(Color(1.0f,1.0f,1.0f));
glLineWidth(1);
float barY = fftBuffer[i] / bandCount * ht;
gl::drawLine(Vec2f(i,getWindowHeight()), Vec2f(i,getWindowHeight()-barY));
}
}
CINDER_APP_BASIC( POC013App, RendererGl )
[確認事項]
・openFrameworks
openFrameworksではAudio入力(ofSoundStream)に対するFFTの関数が実装されていないので ofxFftアドオンを使用
http://ofxaddons.com/repos/383
【C/C++】ProcessingのプログラムをopenFrameworks,Cinder用に書き換える Part12
webカメラの出力とpixelの操作
[環境]
Processing 1.5.1
openFrameworks 0.07
Cinder 0.8.3
[Processing]
[openFrameworks]
testApp.h
[Cinder]
[確認事項]
・Cinder
Pixelの操作はSurface::Iter
Rectの座標は左上右下でとる
[環境]
Processing 1.5.1
openFrameworks 0.07
Cinder 0.8.3
[Processing]
import processing.video.*;
Capture cam;
int camWidth = 320;
int camHeight = 240;
void setup() {
size(640, 240);
cam = new Capture(this, camWidth, camHeight,30);
frameRate(30);
}
void draw() {
if (cam.available() == true) {
cam.read();
image(cam, 0, 0);
loadPixels();
cam.loadPixels();
for(int i = 0; i < width; i += 20){
for(int j = 0; j < height; j += 20){
color c = pixels[j * width + i];
fill(c);
stroke(255);
rect(i+320, j, 20, 20);
}
}
cam.updatePixels();
}
}
[openFrameworks]
testApp.h
#pragma once
#include "ofMain.h"
class testApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
ofVideoGrabber cam;
int camWidth;
int camHeight;
};
testApp.cpp
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
camWidth = 320;
camHeight = 240;
cam.initGrabber(camWidth,camHeight);
ofSetFrameRate(30);
}
//--------------------------------------------------------------
void testApp::update(){
cam.grabFrame();
}
//--------------------------------------------------------------
void testApp::draw(){
ofSetColor(0xffffff);
cam.draw(0,0);
unsigned char *pixels = cam.getPixels();
for (int i = 0; i < camWidth; i += 20){
for (int j = 0; j < camHeight; j += 20){
int r = pixels[j*camWidth*3+i*3];
int g = pixels[j*camWidth*3+i*3+1];
int b = pixels[j*camWidth*3+i*3+2];
ofSetColor(r, g, b);
ofFill();
ofRect(i+320, j, 20, 20);
ofNoFill();
ofSetColor(255, 255, 255);
ofRect(i+320, j, 20, 20);
}
}
}
//--------------------------------------------------------------
void testApp::keyPressed (int key){}
//--------------------------------------------------------------
void testApp::keyReleased(int key){}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h){}
//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){}
//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){}
main.cpp
#include "ofMain.h"
#include "testApp.h"
#include "ofAppGlutWindow.h"
int main( ){
ofAppGlutWindow window;
ofSetupOpenGL(&window, 640, 240, OF_WINDOW);
ofRunApp( new testApp());
}
[Cinder]
#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/Texture.h"
#include "cinder/Capture.h"
#include "cinder/Surface.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class POC012App : public AppBasic {
public:
void prepareSettings(Settings *settings);
void setup();
void update();
void draw();
Capture mCapture;
Surface mSurface;
gl::Texture mTexture;
int camWidth;
int camHeight;
float dataR[320][240];
float dataG[320][240];
float dataB[320][240];
};
void POC012App::prepareSettings(Settings *settings){
settings->setWindowSize(640,240);
settings->setFrameRate(30.0f);
camWidth = 320;
camHeight = 240;
}
void POC012App::setup(){
try{
mCapture = Capture(camWidth, camHeight);
mCapture.start();
}catch( ... ){
console() << "Failed to initialize capture" << endl;
exit(1);
}
}
void POC012App::update(){
if(mCapture && mCapture.checkNewFrame()){
mTexture = gl::Texture(mCapture.getSurface());
mSurface = mCapture.getSurface();
Surface::Iter iter = mSurface.getIter();
int i = 0;
while(iter.line()) {
int j = 0;
while(iter.pixel()) {
dataR[j][i] = (float) iter.r();
dataG[j][i] = (float) iter.g();
dataB[j][i] = (float) iter.b();
j++;
}
i++;
}
}
}
void POC012App::draw(){
gl::clear(Color(0.0f, 0.0f, 0.0f));
if(mTexture){
glPushMatrix();
gl::color(Colorf(1.0f,1.0f,1.0f));
gl::draw(mTexture);
glPopMatrix();
}
glPushMatrix();
gl::translate(Vec2f(320.0f,0.0f));
for (int x = 0; x<=camWidth; x+=20) {
for (int y = 0; y<=camHeight; y+=20) {
gl::color(Colorf(dataR[x][y]/255.0f, dataG[x][y]/255.0f, dataB[x][y]/255.0f));
gl::drawSolidRect(Rectf(x, y, x+20.0f, y+20.0f));
gl::color(Colorf(1.0f,1.0f,1.0f));
gl::drawStrokedRect(Rectf(x, y, x+20.0f, y+20.0f));
}
}
glPopMatrix();
}
CINDER_APP_BASIC( POC012App, RendererGl )
[確認事項]
・Cinder
Pixelの操作はSurface::Iter
Rectの座標は左上右下でとる
【Lisp】Mac emacs slime "Lisp connection closed unexpectedly"
MacのLisp(sbcl) + emacs + slimeの環境下でquicklispからインストールしたcl-glutやlispbuilder-sdl等をコンパイル/ロードした場合
Lisp connection closed unexpectedly: connection broken by remote peer
となってswankが切断されてしまう。
[解決方法]
ユーザのトップディレクトリに.swank.lispを作成し以下を入力
[参照]
http://sourceforge.net/mailarchive/forum.php?forum_name=sbcl-help&thread_name=loom.20110901T014455-156%40post.gmane.org
(eval-when (:compile-toplevel :load-toplevel :execute)
(require :cl-glut)
(require :lispbuilder-sdl))
Lisp connection closed unexpectedly: connection broken by remote peer
となってswankが切断されてしまう。
[解決方法]
ユーザのトップディレクトリに.swank.lispを作成し以下を入力
(setf swank:*communication-style* :fd-handler)
[参照]
http://sourceforge.net/mailarchive/forum.php?forum_name=sbcl-help&thread_name=loom.20110901T014455-156%40post.gmane.org
【C/C++】ProcessingのプログラムをopenFrameworks,Cinder用に書き換える Part11
オーディオ入力 (Audio Input)
[環境]
Processing 1.5.1
openFrameworks 0.07
Cinder 0.8.3
[Processing]
[openFrameworks]
testApp.h
[Cinder]
[確認事項]
オーディオストリームの読み込み
・Processing
minimを使用
Minim minim;
AudioInput in; minim = new Minim(this); in = minim.getLineIn(Minim.STEREO, bufferSize);
・openFrameworks
ofSoundStreamを使用
ofSoundStream soundStream;
soundStream.setup(this, 0, 2, 44100, bufferSize, 4);
・Cinder
audio::Inputを使用
audio::Input mInput;
mInput = audio::Input();
mInput.start();
[環境]
Processing 1.5.1
openFrameworks 0.07
Cinder 0.8.3
[Processing]
import ddf.minim.*;
Minim minim;
AudioInput in;
int bufferSize = 512;
float amp = 50;
void setup(){
size(400,400,P2D);
smooth();
minim = new Minim(this);
in = minim.getLineIn(Minim.STEREO, bufferSize);
}
void draw(){
background(0);
stroke(255);
for(int i = 0; i < in.bufferSize() - 1; i++){
line(i, 150+in.left.get(i)*amp, i+1, 150+in.left.get(i+1)*amp);
line(i, 250+in.right.get(i)*amp, i+1, 250+in.right.get(i+1)*amp);
}
}
void stop(){
in.close();
minim.stop();
super.stop();
}
void keyPressed() {
if(key == 's'){
in = minim.getLineIn(Minim.STEREO, bufferSize);
}
if(key == 'e'){
in.close();
}
}
[openFrameworks]
testApp.h
#pragma once
#include "ofMain.h"
class testApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
void audioIn(float * input, int bufferSize, int nChannels);
int bufferSize;
float amp;
vector <float> lAudio;
vector <float> rAudio;
ofSoundStream soundStream;
};
testApp.cpp
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
ofSetVerticalSync(true);
ofBackground(0, 0, 0);
ofSetColor(255, 255, 255);
ofSetLineWidth(1);
bufferSize = 512;
amp = 50;
soundStream.setup(this, 0, 2, 44100, bufferSize, 4);
lAudio.assign(bufferSize, 0.0);
rAudio.assign(bufferSize, 0.0);
}
//--------------------------------------------------------------
void testApp::update(){
}
//--------------------------------------------------------------
void testApp::draw(){
for (int i=0; i < lAudio.size(); i++) {
ofLine(i, 150+lAudio[i]*amp, i+1, 150+lAudio[i+1]*amp);
}
for (int i=0; i < rAudio.size(); i++) {
ofLine(i, 250+rAudio[i]*amp, i+1, 250+rAudio[i+1]*amp);
}
}
void testApp::audioIn(float *input, int bufferSize, int nChannels){
for (int i = 0; i < bufferSize; i++){
lAudio[i] = input[i*2];
rAudio[i] = input[i*2+1];
}
}
//--------------------------------------------------------------
void testApp::keyPressed(int key){
if(key == 's'){
soundStream.start();
}
if(key == 'e'){
soundStream.stop();
}
}
//--------------------------------------------------------------
void testApp::keyReleased(int key){}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h){}
//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){}
//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){}
main.cpp
#include "ofMain.h"
#include "testApp.h"
#include "ofAppGlutWindow.h"
int main( ){
ofAppGlutWindow window;
ofSetupOpenGL(&window, 400, 400, OF_WINDOW);
ofRunApp( new testApp());
}
[Cinder]
#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/audio/Input.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class POC011App : public AppBasic {
public:
void prepareSettings(Settings *settings);
void setup();
void update();
void draw();
void keyDown(KeyEvent e);
audio::Input mInput;
audio::PcmBuffer32fRef mPcmBuffer;
audio::Buffer32fRef leftBuffer;
audio::Buffer32fRef rightBuffer;
int bufferSize;
float amp;
};
void POC011App::prepareSettings(Settings *settings){
settings->setWindowSize(400, 400);
}
void POC011App::setup(){
bufferSize = 512;
amp = 50;
mInput = audio::Input();
mInput.start();
}
void POC011App::update(){
mPcmBuffer = mInput.getPcmBuffer();
if(!mPcmBuffer){
return;
}
}
void POC011App::draw(){
if(!mPcmBuffer){
return;
}
gl::clear( Color( 0, 0, 0 ) );
leftBuffer = mPcmBuffer->getChannelData(audio::CHANNEL_FRONT_LEFT);
rightBuffer = mPcmBuffer->getChannelData( audio::CHANNEL_FRONT_RIGHT );
gl::color(Color(1.0f, 1.0f, 1.0f));
for(int i = 0, c = 0; i < bufferSize-1; i++, c++){
gl::drawLine(Vec2f(i, 150+leftBuffer->mData[i]*amp), Vec2f(i+1, 150+leftBuffer->mData[i+1]*amp));
gl::drawLine(Vec2f(i, 250+rightBuffer->mData[i]*amp), Vec2f(i+1, 250+rightBuffer->mData[i+1]*amp));
}
}
void POC011App::keyDown(KeyEvent e){
if (e.getChar() == 's') {
mInput.start();
}
if (e.getChar() == 'e') {
mInput.stop();
}
}
CINDER_APP_BASIC( POC011App, RendererGl )
[確認事項]
オーディオストリームの読み込み
・Processing
minimを使用
Minim minim;
AudioInput in; minim = new Minim(this); in = minim.getLineIn(Minim.STEREO, bufferSize);
・openFrameworks
ofSoundStreamを使用
ofSoundStream soundStream;
soundStream.setup(this, 0, 2, 44100, bufferSize, 4);
・Cinder
audio::Inputを使用
audio::Input mInput;
mInput = audio::Input();
mInput.start();
【C/C++】ProcessingのプログラムをopenFrameworks,Cinder用に書き換える Part10
動画の再生
[環境]
Processing 1.5.1
openFrameworks 0.07
Cinder 0.8.3
[Processing]
[openFrameworks]
testApp.h
[Cinder]
[確認事項]
Processing
動画を一時停止した場合speed(0.0)を行わないと音声が停止しない。
Cinder
ロードした動画をテクスチャに貼って出力
[環境]
Processing 1.5.1
openFrameworks 0.07
Cinder 0.8.3
[Processing]
import processing.video.*;
Movie myMovie;
boolean isPaused;
void setup() {
size(400,400,P2D);
background(0);
myMovie = new Movie(this, "fingers.mov");
myMovie.loop();
imageMode(CENTER);
isPaused = false;
}
void movieEvent(Movie m) {
m.read();
}
void draw() {
image(myMovie, width/2, height/2);
}
void keyPressed(){
if(key == 'p'){
if(isPaused == false){
myMovie.pause();
myMovie.speed(0.0);
isPaused = true;
}else{
myMovie.play();
myMovie.speed(1.0);
isPaused = false;
}
}
}
[openFrameworks]
testApp.h
#pragma once
#include "ofMain.h"
class testApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
ofVideoPlayer myMovie;
};
testApp.cpp
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
ofBackground(0, 0, 0);
ofSetRectMode(OF_RECTMODE_CENTER);
myMovie.loadMovie("fingers.mov");
myMovie.play();
}
//--------------------------------------------------------------
void testApp::update(){
myMovie.idleMovie();
}
//--------------------------------------------------------------
void testApp::draw(){
myMovie.draw(ofGetWidth()/2,ofGetHeight()/2);
}
//--------------------------------------------------------------
void testApp::keyPressed(int key){
if (key == 'p') {
if(myMovie.isPaused() == false){
myMovie.setPaused(true);
}else {
myMovie.setPaused(false);
}
}
}
//--------------------------------------------------------------
void testApp::keyReleased(int key){}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h){}
//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){}
//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){}
main.cpp
#include "ofMain.h"
#include "testApp.h"
#include "ofAppGlutWindow.h"
int main( ){
ofAppGlutWindow window;
ofSetupOpenGL(&window, 400, 400, OF_WINDOW);
ofRunApp( new testApp());
}
[Cinder]
#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/Texture.h"
#include "cinder/qtime/QuickTime.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class POC010App : public AppBasic {
public:
void prepareSettings(Settings *settings);
void setup();
void update();
void draw();
void keyDown(KeyEvent e);
gl::Texture mFrameTexture;
qtime::MovieGl myMovie;
};
void POC010App:: prepareSettings(Settings *settings){
settings->setWindowSize(400,400);
}
void POC010App::setup(){
myMovie = qtime::MovieGl(loadResource("fingers.mov"));
myMovie.setLoop();
myMovie.play();
}
void POC010App::update(){
mFrameTexture = myMovie.getTexture();
}
void POC010App::draw(){
gl::clear(Color(0, 0, 0));
if(mFrameTexture) {
Rectf centeredRect = Rectf(mFrameTexture.getBounds()).getCenteredFit(getWindowBounds(), false);
gl::draw(mFrameTexture, centeredRect);
}
}
void POC010App::keyDown(KeyEvent e){
if(e.getChar() == 'p'){
(myMovie.isPlaying()) ? myMovie.stop() : myMovie.play();
}
}
CINDER_APP_BASIC( POC010App, RendererGl )
[確認事項]
Processing
動画を一時停止した場合speed(0.0)を行わないと音声が停止しない。
Cinder
ロードした動画をテクスチャに貼って出力





