バッファからグラフを描く
脳波(Delta, Theta, Alpha, Beta, Gamma)を取得してバッファに格納する
Last updated
脳波(Delta, Theta, Alpha, Beta, Gamma)を取得してバッファに格納する
Last updated
一定の時間データを保持する機構。ここでは、1フレームごとに新しい脳波を取得して、300フレーム(約5秒)前のデータまで保持する。
実行手順
Vieを装着し、Vie StreamでVieに接続
「計測開始(Activate Sensor)」ボタンを押す
「OSC転送(OSC Streaming)」ボタンを押す
「ポート番号」と「デバイス識別子」を確認。(通常はそれぞれ、65001、1)
コードの実行
キーボードの1~5キーで脳波を切り替える
Delta, Theta, Alpha, Beta, Gammaの数値をまとめて保持するクラスを用意する
//脳波格納用のクラス
class BrainWave{
public float delta;
public float theta;
public float alpha;
public float beta;
public float gamma;
BrainWave(){
this.delta =0.0;
this.theta =0.0;
this.alpha =0.0;
this.beta =0.0;
this.gamma =0.0;
}
void set(float d,float t,float a,float b,float g){
this.delta =d;
this.theta =t;
this.alpha =a;
this.beta =b;
this.gamma =g;
}
}
////左と右の脳波を一定時間格納するバッファ、左用と右用
ArrayList<BrainWave> bwBufferLeft = new ArrayList<BrainWave>();
ArrayList<BrainWave> bwBufferRight = new ArrayList<BrainWave>();
//バッファサイズ(300フレーム分のバッファ)
int bwBufferSize = 300;
void setup() {
//中略
//バッファを初期化する
for(int i=0; i<bwBufferSize; i++){
bwBufferLeft.add( new BrainWave() );
bwBufferRight.add( new BrainWave() );
}
}
void draw() {
//中略
//左脳波をバッファに格納
BrainWave bwLeft = new BrainWave();
bwLeft.set(waveLeft[0],waveLeft[1], waveLeft[2], waveLeft[3], waveLeft[4]);
bwBufferLeft.add(bwLeft);
//右脳波をバッファに格納
BrainWave bwRight = new BrainWave();
bwRight.set(waveRight[0],waveRight[1], waveRight[2], waveRight[3], waveRight[4]);
bwBufferRight.add(bwRight);
//バッファサイズが上限に達したら先頭を削除
if(bwBufferLeft.size() > bwBufferSize){
bwBufferLeft.remove(0);
}
if(bwBufferRight.size() > bwBufferSize){
bwBufferRight.remove(0);
}
//中略
}
次のように書くと、(x0,y0)、(x1,y1)、(x2,y2)の各頂点を結ぶ線が描ける。
noFill();
beginShape();
vertex(x0, y0);
vertex(x1, y1);
vertex(x2, y2);
endShape();
void draw() {
//中略
//左のバッファの折れ線グラフ
beginShape();
//バッファの先頭から最後まで格納されているBrainWaveのインスタンスにアクセスして数値を取得
for(int i=0; i<bwBufferLeft.size();i++){
float wave = 0;
if(selectedWaveByKey == 0){
//bwBufferLeft.get(i)で先頭からi番目のBrainWaveインスタンスにアクセス
//bwBufferLeft.get(i).deltaで、インスタンスに保持されているdeltaの数値を取得
wave = bwBufferLeft.get(i).delta;
}
else if(selectedWaveByKey == 1){
wave = bwBufferLeft.get(i).theta;
}
else if(selectedWaveByKey == 2){
wave = bwBufferLeft.get(i).alpha;
}
else if(selectedWaveByKey == 3){
wave = bwBufferLeft.get(i).beta;
}
else if(selectedWaveByKey == 4){
wave = bwBufferLeft.get(i).gamma;
}
//折れ線グラフ上の点(x,y)を計算
float x = 30 + i;
float y = -1 * wave;
//頂点を登録
vertex(x,y);
}
endShape();
//中略
}
void draw() {
//中略
//バッファの描画2:円環グラフ
float centerX = 180;
float centerY = height*0.7;
//左のバッファ
beginShape();
for(int i=0; i<bwBufferLeft.size();i++){
float wave = 0;
if(selectedWaveByKey == 0){
wave = bwBufferLeft.get(i).delta;
}
else if(selectedWaveByKey == 1){
wave = bwBufferLeft.get(i).theta;
}
else if(selectedWaveByKey == 2){
wave = bwBufferLeft.get(i).alpha;
}
else if(selectedWaveByKey == 3){
wave = bwBufferLeft.get(i).beta;
}
else if(selectedWaveByKey == 4){
wave = bwBufferLeft.get(i).gamma;
}
//バッファ内のデータを全て描画するのに4周分とすると
//2.0Pi * 4 / bwBufferSizeで1バッファあたりの角度が求まる。
//取得した数値waveは中心からの距離に対応させ、頂点の座標(x,y)を求める
float x = wave * cos( 8.0*PI/bwBufferSize * i)+centerX;
float y = wave * sin( 8.0*PI/bwBufferSize * i)+centerY;
color cl = unhex(colorHex[selectedWaveByKey]);
//古いバッファ値はアルファが低く(薄く)なるようにする
float alpha = 255.0 * (float)i / (float)bwBufferLeft.size();
//vertex関数の直前に色指定(stroke() or fill())することでその頂点固有の色を指定できる。
stroke(red(cl), green(cl), blue(cl),alpha);
vertex(x,y);
}
endShape();
//中略
}
import oscP5.*;
import netP5.*;
//OSCP5クラスのインスタンス
OscP5 oscP5;
float [] waveLeft = new float[5];
float [] waveRight = new float[5];
//左と右の脳波を一定時間格納するバッファ、左用と右用
ArrayList<BrainWave> bwBufferLeft = new ArrayList<BrainWave>();
ArrayList<BrainWave> bwBufferRight = new ArrayList<BrainWave>();
//バッファサイズ(300フレーム分のバッファ)
int bwBufferSize = 300;
int selectedWaveByKey = 0;
String [] colorHex = {"FF034AA6", "FF72B6F2", "FF73BFB1", "FFF2A30F", "FFF26F63"};
String [] bandName = {"Delta", "Theta", "Alpha", "Beta", "Gamma"};
void setup() {
size(800,600,P2D);
frameRate(60);
//ポートを65001に設定して新規にOSCP5のインスタンスを生成
oscP5 = new OscP5(this,65001);
//バッファを初期化する
for(int i=0; i<bwBufferSize; i++){
bwBufferLeft.add( new BrainWave() );
bwBufferRight.add( new BrainWave() );
}
textSize(15);
}
void draw() {
background(0);
noStroke();
//左脳波をバッファに格納
BrainWave bwLeft = new BrainWave();
bwLeft.set(waveLeft[0],waveLeft[1], waveLeft[2], waveLeft[3], waveLeft[4]);
bwBufferLeft.add(bwLeft);
//右脳波をバッファに格納
BrainWave bwRight = new BrainWave();
bwRight.set(waveRight[0],waveRight[1], waveRight[2], waveRight[3], waveRight[4]);
bwBufferRight.add(bwRight);
//バッファサイズが上限に達したら先頭を削除
if(bwBufferLeft.size() > bwBufferSize){
bwBufferLeft.remove(0);
}
if(bwBufferRight.size() > bwBufferSize){
bwBufferRight.remove(0);
}
//ラベル
fill(255);
text("Left", 30, 30);
text("Right", 430, 30);
//waveLeftの描画
for(int i=0;i<5;i++){
fill(unhex(colorHex[i]));
rect(130, 50+30*i, waveLeft[i], 20);
fill(255);
text(bandName[i], 30, 65+30*i);
text(floor(waveLeft[i])+"%", waveLeft[i]+140, 65+30*i );
}
//waveRightの描画
for(int i=0;i<5;i++){
fill(unhex(colorHex[i]));
rect(530, 50+30*i, waveRight[i], 20);
fill(255);
text(bandName[i], 430, 65+30*i);
text(floor(waveRight[i])+"%", waveRight[i]+540, 65+30*i );
}
//バッファの描画1:折れ線グラフ
pushMatrix();
translate(0,height/2);
//左のバッファ
noFill();
strokeWeight(2);
stroke(50,50,50);
rect(30, -100, bwBufferSize, 100);
stroke(unhex(colorHex[selectedWaveByKey]));
beginShape();
for(int i=0; i<bwBufferLeft.size();i++){
float wave = 0;
if(selectedWaveByKey == 0){
wave = bwBufferLeft.get(i).delta;
}
else if(selectedWaveByKey == 1){
wave = bwBufferLeft.get(i).theta;
}
else if(selectedWaveByKey == 2){
wave = bwBufferLeft.get(i).alpha;
}
else if(selectedWaveByKey == 3){
wave = bwBufferLeft.get(i).beta;
}
else if(selectedWaveByKey == 4){
wave = bwBufferLeft.get(i).gamma;
}
float x = 30 + i;
float y = -1 * wave;
vertex(x,y);
}
endShape();
//右のバッファ
noFill();
strokeWeight(2);
stroke(50,50,50);
rect(430, -100, bwBufferSize, 100);
stroke(unhex(colorHex[selectedWaveByKey]));
beginShape();
for(int i=0; i<bwBufferRight.size();i++){
float wave = 0;
if(selectedWaveByKey == 0){
wave = bwBufferRight.get(i).delta;
}
else if(selectedWaveByKey == 1){
wave = bwBufferRight.get(i).theta;
}
else if(selectedWaveByKey == 2){
wave = bwBufferRight.get(i).alpha;
}
else if(selectedWaveByKey == 3){
wave = bwBufferRight.get(i).beta;
}
else if(selectedWaveByKey == 4){
wave = bwBufferRight.get(i).gamma;
}
float x = 430 + i;
float y = -1 * wave;
vertex(x,y);
}
endShape();
popMatrix();
//バッファの描画2:円環グラフ
float centerX = 180;
float centerY = height*0.7;
//左のバッファ
noFill();
strokeWeight(2);
stroke(50,50,50);
ellipse(centerX,centerY,200,200);
ellipse(centerX,centerY,100,100);
beginShape();
for(int i=0; i<bwBufferLeft.size();i++){
float wave = 0;
if(selectedWaveByKey == 0){
wave = bwBufferLeft.get(i).delta;
}
else if(selectedWaveByKey == 1){
wave = bwBufferLeft.get(i).theta;
}
else if(selectedWaveByKey == 2){
wave = bwBufferLeft.get(i).alpha;
}
else if(selectedWaveByKey == 3){
wave = bwBufferLeft.get(i).beta;
}
else if(selectedWaveByKey == 4){
wave = bwBufferLeft.get(i).gamma;
}
float x = wave * cos( 8.0*PI/bwBufferSize * i)+centerX;
float y = wave * sin( 8.0*PI/bwBufferSize * i)+centerY;
color cl = unhex(colorHex[selectedWaveByKey]);
float alpha = 255.0 * (float)i / (float)bwBufferLeft.size();
stroke(red(cl), green(cl), blue(cl),alpha);
vertex(x,y);
}
endShape();
//右のバッファ
centerX = 590;
noFill();
strokeWeight(2);
stroke(50,50,50);
ellipse(centerX,centerY,200,200);
ellipse(centerX,centerY,100,100);
beginShape();
for(int i=0; i<bwBufferRight.size();i++){
float wave = 0;
if(selectedWaveByKey == 0){
wave = bwBufferRight.get(i).delta;
}
else if(selectedWaveByKey == 1){
wave = bwBufferRight.get(i).theta;
}
else if(selectedWaveByKey == 2){
wave = bwBufferRight.get(i).alpha;
}
else if(selectedWaveByKey == 3){
wave = bwBufferRight.get(i).beta;
}
else if(selectedWaveByKey == 4){
wave = bwBufferRight.get(i).gamma;
}
float x = wave * cos( 8.0*PI/bwBufferSize * i)+centerX;
float y = wave * sin( 8.0*PI/bwBufferSize * i)+centerY;
color cl = unhex(colorHex[selectedWaveByKey]);
float alpha = 255.0 * (float)i / (float)bwBufferRight.size();
stroke(red(cl), green(cl), blue(cl),alpha);
vertex(x,y);
}
endShape();
//インタラクションガイド
fill(255);
text("Press key \"1,2,3,4,5\" to select a wave.",30,height-10);
}
//OSCメッセージを受信した際に実行するイベント
void oscEvent(OscMessage msg) {
if(msg.checkAddrPattern("/wave/L/1")==true) {
for(int i=0;i<5;i++){
waveLeft[i] = msg.get(i).floatValue();
}
}
if(msg.checkAddrPattern("/wave/R/1")==true) {
for(int i=0;i<5;i++){
waveRight[i] = msg.get(i).floatValue();
}
}
}
//脳波格納用のクラス
class BrainWave{
public float delta;
public float theta;
public float alpha;
public float beta;
public float gamma;
BrainWave(){
this.delta =0.0;
this.theta =0.0;
this.alpha =0.0;
this.beta =0.0;
this.gamma =0.0;
}
void set(float d,float t,float a,float b,float g){
this.delta =d;
this.theta =t;
this.alpha =a;
this.beta =b;
this.gamma =g;
}
}
void keyPressed(){
if(key == '1'){
selectedWaveByKey = 0;
}
if(key == '2'){
selectedWaveByKey = 1;
}
if(key == '3'){
selectedWaveByKey = 2;
}
if(key == '4'){
selectedWaveByKey = 3;
}
if(key == '5'){
selectedWaveByKey = 4;
}
}