RSS Twitter Facebook


« 2006年07月 | 2006年12月のアーカイブ | 2007年01月 »

2006/12/31

おおみそかじゃん


もう正月を迎えてしまいそうだが、プログラム書いてる。
モジュラーシンセでパッチをペチペチできるようなのにしたいのだが、やりかけてみると色々難しいところがあるねぇ。適当に接続したらそれなりに音はでるけどコントローラのレンジとか変化のカーブが感覚的にフィットしなくて今一な感じ。
例えばLFOの出力とEGの出力が同じレンジで動いているとLFOの方が効きが強すぎるのだな。しかし専用の端子なんかを付けちゃうと結局接続の自由度がなくなってモジュラーの意味がない・・・。

取りあえず、モジュレーション系をマトリックスにしたような接続済みのシンセを一個作ってみるか、という感じでトーンダウン。

こんな感じになる予定。


posted by g200kg : 10:59 PM : PermaLink

2006/12/26

信号系と制御系


そんな感じでモジュール間の接続を処理するとして、やっぱり問題はパフォーマンスなのだ。理想は全てのPin間の接続に従って毎サンプルの処理をしたいのだが、さすがにできそうもないので、信号系の接続と制御系の接続を別処理する事にする。

OSCからVCF、VCAへと流れる音信号の本線が信号系で、その他のCV、EG、LFOなどのモジュレーション系の信号が制御系だ。信号系はサンプル毎の処理で、制御系は1msec毎に処理する事にする。48KHzサンプルだと48サンプル毎に一回制御系の信号を処理する感じだ。本当は信号系の処理を基本にして制御系の処理を間引く程度でなんとかしたいのだが、やってみるとそれでも厳しい。しょがないので、信号系のPinにバッファを持たせて制御系の処理、つまり1msec単位でモジュール毎の処理を回していく。

class ControlInPin {
 ControlOutPin *in;
public:
 void Connect(ControlOutPin *opin);
};
class ControlOutPin {
 float fValue[kNumPoly];
public:
 ・
 ・
};
class SignalInPin {
 SignalOutPin *in;
public:
 void Connect(SignalOutPin *opin);
};
class SignalOutPin {
 float fValue[kBlockSize][kNumPoly];
public:
 ・
 ・
};

ちなみに作りたいのはポリフォニックシンセなので、各PinはkNumPoly分のチャンネルを持たせる事にする。なんだか結構重たくなりそうなのだ。ふにゃふにゃ。InPinとかOutPinとかSignalPinとかControlPinとか、クラスを継承していきたいと思わなくもないが、そうすると欠点はコードの総量が見えづらくなるのだよな。「あれ、この処理はなんでこんなに重いのだ?」みたいなのが実はずっと親の方に原因があったりするとはまるので、その辺は調整しつつ。

posted by g200kg : 1:20 AM : PermaLink

2006/12/21

Pin


InPin,OutPin の方はというとやっぱりPinっていう基底クラスがあってInPin, OutPin を派生するというのが、教科書的なやり方だろうな。 Pinはそれぞれ現在の値を持っていて、Set(float) Get(float) なんてメソドで扱えて、Connect(Pin *) なんていうメソドがあってPin間を接続するような感じ? 接続はInPin からOutPinに向けてだけ、とかでも良いかな?

class Pin {
public:
 float Get(void);
void Set(float);
};
class InPin : Pin {
public:
 bool Connect(OutPin*);
};
class OutPin : Pin {
};

で、値(float fVale とするか)をどこに置くかだけど、基底クラスにSet() Get()があるんで

class Pin {
 float fValue;
public:
 float Get(void) { return fValue; }
 void Set(fValue f) { fValue=f; }
};

てしたいな。で、InPinは信号処理のメソド( Process() とか?)で接続先のPinから現在値をコピーする?それともInPinは接続先Pin へのポインタを持っていてそこから直接持ってくる? 

綺麗なのは最初の方だけどパフォーマンスがどうかな? でもInPinにポインタを持つなら fValueなんて基底クラスにあるのは無駄じゃ。OutPinにだけあればいいや。でもそれだとGet() Set() も基底クラスにいらないな。 てか InPInにSet()はいらんだろ。ち、基底クラスが無駄じゃん。

なんて事を妄想しながら深みにはまるのだ。 実際の所、VST作るならパフォーマンス優先で考えたい。InPin と OutPinには基底クラスはなくてもいいのだ。

class InPin {
 OutPin *in;
public:
 float Get(void) { return in->Get(); }
 void Connect(OutPin*opin) { in=opin; }
};
class OutPin {
 float fValue;
public:
 float Get(void) { return fValue; }
 void Set(float f) { fValue=f; }
};

接続されてないInPinの事とかは今は考えない...

posted by g200kg : 12:43 AM : PermaLink

2006/12/20


まあそんなわけで、ここしばらくはプログラム系のディープな話でも書いてみようかと思っている。
モジュラーシンセをソフトウェアで実現しようとした時にどんな構造にすれば良いのか、という所なのだが、C++のクラスにしようとすると、元々各機能のモジュールの組み合わせで出来ているものなので、そういう分割になるのだね。

More... ""

posted by g200kg : 12:30 AM : PermaLink

2006/12/17

復活


さて、随分長い間放置してしまったのだが・・・
ぼちぼち活動するかな・・・と。

とにかくBBSはスパムで埋まってしまったので取りあえず書き込みは
できなくした。困ったもんだね。

で、何をしたいかと言うと、またVSTでも作ってみようかと思っている。
数年前、ProtoPSGを作り始めた時、内部をモジュラーシンセ構造にしよう
としたのだが、パフォーマンスが出なくて途中で方針変更したのだった。
今にして思えば、モジュラー化するのならもっと良い方法があったなぁ、
て感じなのだ。

なんていうかね、モジュラーシンセって、OSCとかVCAとかVCFとかモジュール
があって、それぞれ入出力端子があって、相互に接続されて・・・っていうのが
とてもオブジェクト志向的にはまりすぎていて、クラス構造なんか考えてると
ついついこう上から下までしゅばじゅばっと、楽しくできてしまったりするのだが、
パフォーマンスの事を考えると、その裏側でどろどろしたチューニングの仕方を
考慮しなきゃならんのだな。

てなわけで、目標はモジュラーシンセという事にしてみるのだ。

(さて、このモチベーションははたして維持できるのか!?)

posted by g200kg : 9:04 PM : PermaLink


« 2006年07月 | 2006年12月のアーカイブ | 2007年01月 »

g200kg