11/04: #8
11/04: てすと
10/31: つづき2

ピクセルつったらオートマトン。
一次元セルオートマトンやってみた。
Stringの.atで返ってくるのがCharってのに気付くのに無駄に時間を取られた。
オートマトンのルールは例のrewriteStringで実現。
string = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxa";
rules= [
"a>a>a" -> "x",
"a>a>x" -> "x",
"a>x>a" -> "x",
"a>x>x" -> "a",
"x>a>a" -> "a",
"x>a>x" -> "a",
"x>x>a" -> "a",
"x>x>x" -> "x",
]//rule 30
string = string.rewriteString(rules)
こんかんじで”>”でつなぐと文脈判断も可能rewriteStringベンーリ。
10/26: スパコ+データロガーのつづき
ほったらかしといたスパコ+データロガーのつづき。今度、多摩美でMAKE Meeting、その後11月にはPlacardとあるのでネタ作り。
rssでタンブラーの画像ひぱってきて32pxの画像をプロットできるようになった。rssと画像処理はPythonで、データロガーのドライブ部分をスパコで書いてる。てかスパコ使う必要性はいまんとこ特にない。Pythonだけで書いた方がもっと解像度細かくしてプロットできる..。
まあゆくゆくオーディオビジュアルな感じにするのでシーケンスをスパコで書いとくのはいいかなと。 rssパーサめんどい。
07/08: モータドライバとか
新作を作っててモータの制御用にFS70SMJ−06を買ってみた。(作品中ではペルチェ素子のスイッチングに使う予定だけど)
感想としては、これはいい。TAMIYAのロボコン用のDCモータをマイコンからなんなく回せる。大容量だから発熱とかもぜんぜん気にならない。パワーMOSFETってスイッチング速度も速いらしいしパルス制御とかもいけそうね。
でもステッピングモーターとかだとこれ一個ってわけにはいかないしな、なんかいいモータードライバ無いかなー。
やっぱ自作でHブリッジ回路組めってことかなー。
感想としては、これはいい。TAMIYAのロボコン用のDCモータをマイコンからなんなく回せる。大容量だから発熱とかもぜんぜん気にならない。パワーMOSFETってスイッチング速度も速いらしいしパルス制御とかもいけそうね。
でもステッピングモーターとかだとこれ一個ってわけにはいかないしな、なんかいいモータードライバ無いかなー。
やっぱ自作でHブリッジ回路組めってことかなー。
07/03: FFTとか3
#この記事は4月頃書かれたものを再投稿したものです。
前のエントリで正変換と逆変換の間に関数を入れるのにpvcalcと言うのを紹介したが、
他にも2つのchainを処理できるpvcalc2や、関数内でindex(bin数)を利用できるpvcollectがある。pvcollectが便利そう。
UnpackFFT
UnpackFFTはFFTの吐いたchainの中身をDemand rateのストリームで吐き出す。
UnpackFFT(chain, numFrames, frombin, tobin)
これもfrombin, tobin引数によって必要なbin数を指定できる。
出てくる数値はDemand rateのストリームなのでこれにDemand UGenで処理を加えることができる。
出てくるストリームはリアルパートとイマジナリパートが分かれていないので、そこは適せん自分で分ける式を書く。
(あとpvcalcやpvcollectも関数内でDemand UGenで処理を加える事ができる。つまりDemand UGenはサンプル毎に処理ができるってこと。?これってなんかスパコの時間概念って実は結構フレキシブルなんじゃないだろかと思ってしまう。もししたらChuckみたいにサンプルレベルの波形処理も別に普通のことなのかもしれない。このへん後で調べたい)
あとヘルプに注意があるように今の時点でDemand UGenは32のインプットしか処理できないのでbin数はfrombin, tobinでそれ以内に抑えなければいけないようだ。
以下ヘルプから
(
s.boot.doWhenBooted{
~fftsize = 1024;
b = Buffer.alloc(s, ~fftsize, 1);
c = Buffer.read(s,"sounds/a11wlk01.wav");
}
)
// ポストウィンドにMagnitude、Phaseとストリームをポストする
(
x = {
var sig, chain, unp;
sig = SinOsc.ar;
sig = PlayBuf.ar(1, c, BufRateScale.kr(c), loop: 1);
chain = FFT(b, sig);
// frombin と tobin 引数で必要なbinを制限
unp = UnpackFFT(chain, b.numFrames, frombin: 0, tobin: 4);
// アンパックしてDemand rateに
// 時点でDemand UGenは32のインプットしか処理できない
//なのでbin数はfrombin, tobinでそれ以内に抑える
Demand.kr(chain>=0, 0, unp).collect{|anunp, index|
anunp.poll(chain>=0, if(index % 2 == 0, "Magnitude", "Phase")+(index/2).floor);
};
(sig*0.1).dup;
}.play(s);
)
x.free;
またDemand rateのFFTデータをchainバッファに束ねて戻すPackFFTもある。
前のエントリで正変換と逆変換の間に関数を入れるのにpvcalcと言うのを紹介したが、
他にも2つのchainを処理できるpvcalc2や、関数内でindex(bin数)を利用できるpvcollectがある。pvcollectが便利そう。
UnpackFFT
UnpackFFTはFFTの吐いたchainの中身をDemand rateのストリームで吐き出す。
UnpackFFT(chain, numFrames, frombin, tobin)
これもfrombin, tobin引数によって必要なbin数を指定できる。
出てくる数値はDemand rateのストリームなのでこれにDemand UGenで処理を加えることができる。
出てくるストリームはリアルパートとイマジナリパートが分かれていないので、そこは適せん自分で分ける式を書く。
(あとpvcalcやpvcollectも関数内でDemand UGenで処理を加える事ができる。つまりDemand UGenはサンプル毎に処理ができるってこと。?これってなんかスパコの時間概念って実は結構フレキシブルなんじゃないだろかと思ってしまう。もししたらChuckみたいにサンプルレベルの波形処理も別に普通のことなのかもしれない。このへん後で調べたい)
あとヘルプに注意があるように今の時点でDemand UGenは32のインプットしか処理できないのでbin数はfrombin, tobinでそれ以内に抑えなければいけないようだ。
以下ヘルプから
(
s.boot.doWhenBooted{
~fftsize = 1024;
b = Buffer.alloc(s, ~fftsize, 1);
c = Buffer.read(s,"sounds/a11wlk01.wav");
}
)
// ポストウィンドにMagnitude、Phaseとストリームをポストする
(
x = {
var sig, chain, unp;
sig = SinOsc.ar;
sig = PlayBuf.ar(1, c, BufRateScale.kr(c), loop: 1);
chain = FFT(b, sig);
// frombin と tobin 引数で必要なbinを制限
unp = UnpackFFT(chain, b.numFrames, frombin: 0, tobin: 4);
// アンパックしてDemand rateに
// 時点でDemand UGenは32のインプットしか処理できない
//なのでbin数はfrombin, tobinでそれ以内に抑える
Demand.kr(chain>=0, 0, unp).collect{|anunp, index|
anunp.poll(chain>=0, if(index % 2 == 0, "Magnitude", "Phase")+(index/2).floor);
};
(sig*0.1).dup;
}.play(s);
)
x.free;
またDemand rateのFFTデータをchainバッファに束ねて戻すPackFFTもある。
07/03: FFTとか2
#この記事は4月頃書かれたものを再投稿したものです。
正変換後なんらかの操作を加えて逆変換してオーディオシグナルを再現したい時、
間の処理を支援してくれるPV UGens(Phase Vocoder UGens)が用意されている。
[例] PV_BrickWall
PV_BrickWallは指定したn次高調波(bins)でカットオフ(といってもbin数を指定できない)
(2つ目の引数には周波数ではなく-1,1のbipolar)
b = Buffer.alloc(s,2048,1);
(
SynthDef("help-brick", { arg out=0, bufnum=0;
var in, chain;
in = WhiteNoise.ar(0.2);
chain = FFT(bufnum, in);
chain = PV_BrickWall(chain, SinOsc.kr(0.1));
Out.ar(out, IFFT(chain));
}).play(s,[out, 0, bufnum, b]);
)
ここでFFTででてきた成分を(chainと表現しいてる)としてPV UGen->逆変換と順番に代入して最終的にオーディオ波形に出力している。
バッファを二つ用意しなければいけないPV UGenもあるので注意。
pvcalc pvcalc2 pvcollect
PV_はプラグイン化されC++で実装されているが、SCLangでも自分で関数を設けて成分を操作できる。
pvcalcはFFTででてきたchainに対して配列操作のようにプロセスを加えられる。
シンンタクスは
chain.pvcalc(numFrames, function, frombin, tobin, zeroothers)
numFrames:
バッファのフレーム数
function:
加える処理。
リアルパートとイマジナリーパートが出てくるのでそれぞれ振幅(mags)、位相(phases)成分として関数内で利用できる。
frombin:
tobin:
from - to で操作するのが第n次高調波(bins)なのか指定できる
zeroothers:
1だと指定していないレンジのbinを無視する
[例] 振幅成分、位相成分のそれぞれ0~250のbinをすべてシャッフルしてから逆変換
(
s.boot.doWhenBooted{
b = Buffer.alloc(s, 1024, 1);
c = Buffer.read(s,"sounds/a11wlk01.wav");
}
)
(
x = {
var in, chain, v;
in = PlayBuf.ar(1, c, BufRateScale.kr(c), loop: 1);
chain = FFT(b, in);
chain = chain.pvcalc(b.numFrames, {|mags, phases|
[mags.scramble, phases.scramble]; //振幅成分、位相成分のbinそれぞれをすべてシャッフル
}, frombin: 0, tobin: 250, zeroothers: 0);
Out.ar(0, 0.5 * IFFT(chain).dup);
}.play(s);
)
x.free;
追記:
FFTで用意するバッファは例えば1024でもバッファにはリアルパート、イマジナリパートと書き込まれるので窓のサンプル数は512になる。
なので分解能の倍のバッファを用意しなくてはいけない。
正変換後なんらかの操作を加えて逆変換してオーディオシグナルを再現したい時、
間の処理を支援してくれるPV UGens(Phase Vocoder UGens)が用意されている。
[例] PV_BrickWall
PV_BrickWallは指定したn次高調波(bins)でカットオフ(といってもbin数を指定できない)
(2つ目の引数には周波数ではなく-1,1のbipolar)
b = Buffer.alloc(s,2048,1);
(
SynthDef("help-brick", { arg out=0, bufnum=0;
var in, chain;
in = WhiteNoise.ar(0.2);
chain = FFT(bufnum, in);
chain = PV_BrickWall(chain, SinOsc.kr(0.1));
Out.ar(out, IFFT(chain));
}).play(s,[out, 0, bufnum, b]);
)
ここでFFTででてきた成分を(chainと表現しいてる)としてPV UGen->逆変換と順番に代入して最終的にオーディオ波形に出力している。
バッファを二つ用意しなければいけないPV UGenもあるので注意。
pvcalc pvcalc2 pvcollect
PV_はプラグイン化されC++で実装されているが、SCLangでも自分で関数を設けて成分を操作できる。
pvcalcはFFTででてきたchainに対して配列操作のようにプロセスを加えられる。
シンンタクスは
chain.pvcalc(numFrames, function, frombin, tobin, zeroothers)
numFrames:
バッファのフレーム数
function:
加える処理。
リアルパートとイマジナリーパートが出てくるのでそれぞれ振幅(mags)、位相(phases)成分として関数内で利用できる。
frombin:
tobin:
from - to で操作するのが第n次高調波(bins)なのか指定できる
zeroothers:
1だと指定していないレンジのbinを無視する
[例] 振幅成分、位相成分のそれぞれ0~250のbinをすべてシャッフルしてから逆変換
(
s.boot.doWhenBooted{
b = Buffer.alloc(s, 1024, 1);
c = Buffer.read(s,"sounds/a11wlk01.wav");
}
)
(
x = {
var in, chain, v;
in = PlayBuf.ar(1, c, BufRateScale.kr(c), loop: 1);
chain = FFT(b, in);
chain = chain.pvcalc(b.numFrames, {|mags, phases|
[mags.scramble, phases.scramble]; //振幅成分、位相成分のbinそれぞれをすべてシャッフル
}, frombin: 0, tobin: 250, zeroothers: 0);
Out.ar(0, 0.5 * IFFT(chain).dup);
}.play(s);
)
x.free;
追記:
FFTで用意するバッファは例えば1024でもバッファにはリアルパート、イマジナリパートと書き込まれるので窓のサンプル数は512になる。
なので分解能の倍のバッファを用意しなくてはいけない。
07/03: FFTとか
#この記事は4月頃書かれたものを再投稿したものです。
FFT出来無いとか馬鹿にされた(マジむかつく)のでFFTの事をちょっと。
スパコにもフーリエ変換、正変換FFT逆変換IFFTのクラスが用意されている。
FFT
FFTクラスはデカルト座標で配列をずらっと吐いてくるのでその配列を操作する事でスペクトル解析、フィルタリングなど各操作をする。
出てくる配列はこんな感じ。order: DC, nyquist, real 1f, imag 1f, real 2f, imag 2f, ... real (N-1)f, imag (N-1)f
また窓の種類が選べてrectangular、Welch、Hannの三つ。デフォルトではWelch。(レクトアングルとハニングはわかるけど、ウェルチとはどんな窓なんですか?)
またIFFTに突っ込む前にデータ変換するためのPV UGensというクラス郡も用意されていて、各種比較、演算オンセット・ディテクトなどいろいろある。
詳しくは FFT Overview.html
では一つヘルプから例を、
周波数成分をプロットしてグラフを見る。スペクトルアナライズ。
b = Buffer.alloc(s,1024);
a = { FFT(b, LFSaw.ar(400)); 0.0 }.play;
(
b.getn(0, 1024, { arg buf;
var z, x;
z = buf.clump(2).flop;
z = [Signal.newFrom(z[0]), Signal.newFrom(z[1])];
x = Complex(z[0], z[1]);
{x.magnitude.plot}.defer
})
)
a.free; b.free;
[説明]
b = Buffer.alloc(s,1024);
//FFTデータを書き込むバッファが必要。
z = buf.clump(2).flop;
//clumpしてflopすると奇数、偶数つまり振幅成分と位相成分のデータ配列に分ける(clump(2)はサイズが2のセルを配列の先頭から順番に作っていく、結果2DArrayになる。flopは2DArrayの行と列をひっくり返す)
z = [Signal.newFrom(z[0]), Signal.newFrom(z[1])];
//newFromは別の配列から新たに配列を作る(でもこれzの要素をまたzの要素に入れ子にして意味あるんかなこれ)
x = Complex(z[0], z[1]);
//パワースペクトルを対数表示するのでComplexを使って
x.magnitude.plot
//実部と虚部から距離を取って最後にプロット
こんな感じのグラフが出た。

追記:
ウェルチ窓についてSignal.htmlヘルプにグラフ見るコードが。
Signal.welchWindow(1024).plot;


上がハニングで下がウェルチ。なるほどね。
追記2:
スパコのFFTでは窓かけやオーバーラップを自動でやってくれていて、
オーバーラップの深度はFFTの引数"hop"で0~ 1のunipolarでこれは0~100のパーセンテージ。
wintypeが窓の種類で -1 rectangular, 0 Welch, 1 Hannとなっている。
FFT.new(buffer, input, hop, wintype, active)
FFT出来無いとか馬鹿にされた(マジむかつく)のでFFTの事をちょっと。
スパコにもフーリエ変換、正変換FFT逆変換IFFTのクラスが用意されている。
FFT
FFTクラスはデカルト座標で配列をずらっと吐いてくるのでその配列を操作する事でスペクトル解析、フィルタリングなど各操作をする。
出てくる配列はこんな感じ。order: DC, nyquist, real 1f, imag 1f, real 2f, imag 2f, ... real (N-1)f, imag (N-1)f
また窓の種類が選べてrectangular、Welch、Hannの三つ。デフォルトではWelch。(レクトアングルとハニングはわかるけど、ウェルチとはどんな窓なんですか?)
またIFFTに突っ込む前にデータ変換するためのPV UGensというクラス郡も用意されていて、各種比較、演算オンセット・ディテクトなどいろいろある。
詳しくは FFT Overview.html
では一つヘルプから例を、
周波数成分をプロットしてグラフを見る。スペクトルアナライズ。
b = Buffer.alloc(s,1024);
a = { FFT(b, LFSaw.ar(400)); 0.0 }.play;
(
b.getn(0, 1024, { arg buf;
var z, x;
z = buf.clump(2).flop;
z = [Signal.newFrom(z[0]), Signal.newFrom(z[1])];
x = Complex(z[0], z[1]);
{x.magnitude.plot}.defer
})
)
a.free; b.free;
[説明]
b = Buffer.alloc(s,1024);
//FFTデータを書き込むバッファが必要。
z = buf.clump(2).flop;
//clumpしてflopすると奇数、偶数つまり振幅成分と位相成分のデータ配列に分ける(clump(2)はサイズが2のセルを配列の先頭から順番に作っていく、結果2DArrayになる。flopは2DArrayの行と列をひっくり返す)
z = [Signal.newFrom(z[0]), Signal.newFrom(z[1])];
//newFromは別の配列から新たに配列を作る(でもこれzの要素をまたzの要素に入れ子にして意味あるんかなこれ)
x = Complex(z[0], z[1]);
//パワースペクトルを対数表示するのでComplexを使って
x.magnitude.plot
//実部と虚部から距離を取って最後にプロット
こんな感じのグラフが出た。

追記:
ウェルチ窓についてSignal.htmlヘルプにグラフ見るコードが。
Signal.welchWindow(1024).plot;


上がハニングで下がウェルチ。なるほどね。
追記2:
スパコのFFTでは窓かけやオーバーラップを自動でやってくれていて、
オーバーラップの深度はFFTの引数"hop"で0~ 1のunipolarでこれは0~100のパーセンテージ。
wintypeが窓の種類で -1 rectangular, 0 Welch, 1 Hannとなっている。
FFT.new(buffer, input, hop, wintype, active)
07/03: Boarduino
#この記事は5月頃に書かれたものを再度投稿した物です。

韓国でのワークショップでBoarduinoをつかったのでそれに関するメモ。
BoArduinoはArduinoのクローンでATmega168チップを使っているのでArduino Dicimilaボードと同じ用に動作する。Arduinoより少し安い。
スパコではquarksにarduinoライブラリがあるのでこれを使うと便利。
SimpleMessageSystemって言うArdino側のファームウエアのためにかかれているので、今回これを使用した。
最初Firmataというわりとスタンダードらしいファームを焼いたが、挙動がおかしいのであきらめる。
簡単なデジタルreadがやりたかったんだけど、手持ちに抵抗が無かったのでちゃんとしたスイッチ回路が組めない事に気付く。
チップ側でどうにかならないかなーと思っていたら..あった。
本来ならちゃんとアクティブハイ、ローの回路を組まなきゃ行けないんだけど、そこを省くためにチップ側でI/Oピンを常にハイかローを書き込んであげるという技。なんて言うんだか忘れたけど(チャタリング防止?ちがうか)、そいうのがあるらしい。
で、ファーム側で44行目からのreadpins()を少し修正
void readpins(){ // Read pins (analog or digital)
switch (messageGetChar()) { // Gets the next word as a character
case 'd': // READ digital pins
messageSendChar('d'); // Echo what is being read
for (char i=2;i<14;i++) {
pinMode(i, INPUT); //ここ
analogWrite(i, 0); //毎ループI/Oピンにlowを書き込む
messageSendInt(digitalRead(i)); // Read pins 2 to 13
}
messageEnd(); // Terminate the message being sent
break; // Break from the switch
case 'a': // READ analog pins
messageSendChar('a'); // Echo what is being read
for (char i=0;i<6;i++) {
messageSendInt(analogRead(i)); // Read pins 0 to 5
}
messageEnd(); // Terminate the message being sent
}
}
これでok
スパコ側はArdino.scdのヘルプを参考に
p = ArduinoSMS("/dev/tty.usbserial-A6004uzj", 9600); // was 9600 (changed by thor)
(
p.action = { |... msg|
msg.postln;
};
)
// read digital pins
(
t=Task( {
inf.do {
p.send($r, $d); //here is comunication with BoArduino
0.025.wait;//適せんsleepをさせて
}
}).play;
)
t.stop;
あれ、でもこれよくかんがえたらなぜかanalogWriteしてる。
でも動作はokなんだよな、なんでだろ?わけわからん。

韓国でのワークショップでBoarduinoをつかったのでそれに関するメモ。
BoArduinoはArduinoのクローンでATmega168チップを使っているのでArduino Dicimilaボードと同じ用に動作する。Arduinoより少し安い。
スパコではquarksにarduinoライブラリがあるのでこれを使うと便利。
SimpleMessageSystemって言うArdino側のファームウエアのためにかかれているので、今回これを使用した。
最初Firmataというわりとスタンダードらしいファームを焼いたが、挙動がおかしいのであきらめる。
簡単なデジタルreadがやりたかったんだけど、手持ちに抵抗が無かったのでちゃんとしたスイッチ回路が組めない事に気付く。
チップ側でどうにかならないかなーと思っていたら..あった。
本来ならちゃんとアクティブハイ、ローの回路を組まなきゃ行けないんだけど、そこを省くためにチップ側でI/Oピンを常にハイかローを書き込んであげるという技。なんて言うんだか忘れたけど(チャタリング防止?ちがうか)、そいうのがあるらしい。
で、ファーム側で44行目からのreadpins()を少し修正
void readpins(){ // Read pins (analog or digital)
switch (messageGetChar()) { // Gets the next word as a character
case 'd': // READ digital pins
messageSendChar('d'); // Echo what is being read
for (char i=2;i<14;i++) {
pinMode(i, INPUT); //ここ
analogWrite(i, 0); //毎ループI/Oピンにlowを書き込む
messageSendInt(digitalRead(i)); // Read pins 2 to 13
}
messageEnd(); // Terminate the message being sent
break; // Break from the switch
case 'a': // READ analog pins
messageSendChar('a'); // Echo what is being read
for (char i=0;i<6;i++) {
messageSendInt(analogRead(i)); // Read pins 0 to 5
}
messageEnd(); // Terminate the message being sent
}
}
これでok
スパコ側はArdino.scdのヘルプを参考に
p = ArduinoSMS("/dev/tty.usbserial-A6004uzj", 9600); // was 9600 (changed by thor)
(
p.action = { |... msg|
msg.postln;
};
)
// read digital pins
(
t=Task( {
inf.do {
p.send($r, $d); //here is comunication with BoArduino
0.025.wait;//適せんsleepをさせて
}
}).play;
)
t.stop;
あれ、でもこれよくかんがえたらなぜかanalogWriteしてる。
でも動作はokなんだよな、なんでだろ?わけわからん。
02/15: SCStreamingLive
去る2007年12月自分が所属する学校でコンピュータ音楽やってる人の集まりic2007と言うのがありました。
そこでスパコでストリーミングセッションを行ったのでその事後報告と言うかまとめ。
何をやったかと言うとスパコが立ち上がっているサーバにみんなでシンセやコマンドを送り合い、それをサーバ内でルーティング、ストリ−ミング配信でセッションライブをすると言うもの。
詳しくはここの導入ページ。
演奏者も同じストリーミングを聴きながら演奏するのではっきり言って目隠しで次の音を決める感じ。コマンドを送ってから音が鳴るまでのラグが1−2秒あって、それもまた面白かった。
さらにセカンドライフやってる友達がいて、ライブ中ストリーミングがセカンドライフ内でも共有されてて何人かのリスナーがそこで聴いてたとか..。けっこうわけわかんない事になってたらしい。
スパコの面白いところは何度も言うようだけどやっぱりサーバクライアントという構造だと思う。UDPを介してOSCでコマンドを送り合ってる。これは他のDSPソフトには見られないユニークなところ。今回のライブはサーバがリモートでも演奏可能でしかも複数人数でも行けるってことが証明されたいい企画だったと思います。
スパコのサーバは今でも立ち上がっていていつでも演奏可能な状態です。ストリーミング配信プレイリスト(m3u)につなげば今なっている音が聞けます。試してみてください。(無音と言う事は何もシンセがなっていないと言う事です)
もう既に場は出来上がっているので、またセッションライブをやるのもいいかなと思います。(でもぶっ続けで音が鳴っているのも面白いな)、何か面白いアイデアが浮かんだら教えてください。是非なにか活用しましょう。
とにかくスパコは単なるソフトシンセでは無い、いろんな可能性があるなぁと思いました。
1,2
next>
そこでスパコでストリーミングセッションを行ったのでその事後報告と言うかまとめ。
何をやったかと言うとスパコが立ち上がっているサーバにみんなでシンセやコマンドを送り合い、それをサーバ内でルーティング、ストリ−ミング配信でセッションライブをすると言うもの。
詳しくはここの導入ページ。
演奏者も同じストリーミングを聴きながら演奏するのではっきり言って目隠しで次の音を決める感じ。コマンドを送ってから音が鳴るまでのラグが1−2秒あって、それもまた面白かった。
さらにセカンドライフやってる友達がいて、ライブ中ストリーミングがセカンドライフ内でも共有されてて何人かのリスナーがそこで聴いてたとか..。けっこうわけわかんない事になってたらしい。
スパコの面白いところは何度も言うようだけどやっぱりサーバクライアントという構造だと思う。UDPを介してOSCでコマンドを送り合ってる。これは他のDSPソフトには見られないユニークなところ。今回のライブはサーバがリモートでも演奏可能でしかも複数人数でも行けるってことが証明されたいい企画だったと思います。
スパコのサーバは今でも立ち上がっていていつでも演奏可能な状態です。ストリーミング配信プレイリスト(m3u)につなげば今なっている音が聞けます。試してみてください。(無音と言う事は何もシンセがなっていないと言う事です)
もう既に場は出来上がっているので、またセッションライブをやるのもいいかなと思います。(でもぶっ続けで音が鳴っているのも面白いな)、何か面白いアイデアが浮かんだら教えてください。是非なにか活用しましょう。
とにかくスパコは単なるソフトシンセでは無い、いろんな可能性があるなぁと思いました。