2007年09月06日

DirectSoundとVSTエフェクト

最近忙しくてあんまり音楽的な活動が出来ていないのだが、本文を頑張らなくても比較的長い記事になりそうなメモを残していく。

ASIOやVSTなどの規格ではオーディオデータは各チャンネルごとに分かれて配列として格納する(LLLLRRRRのような構造)のだが、従来のマルチメディア入出力では左右チャンネルのデータがストライプ状に並んでおり(LRLRLRLRLRのような構造)、ASIO以外で入力したオーディオデータにVSTエフェクトをかけようと思った場合、一旦データを並び替えなければいけなくなる。
普段 Delphi を使ってコーディングしている私は MiniHost で有名な TobyBear で配布されているコンポーネントを使おうと思ったのだが、それ用のコンバートルーチンは標準で用意されていなかったので DASIOConvert.pas の処理を参考にステレオ用のコンバート処理を書いてみた。

const
MinSmall : Single = 1/$8000;
MaxSmall : Single = $7FFF;

procedure ToInt16LSB_x87_forDS_2ch(target1: psingle; target2: psingle; frames: longint; source: pointer );
asm
push ebx

mov ebx, source
fld MinSmall //for speed
@Start:
fild [ebx].word
fmul st(0),st(1)
fstp [eax].single;
add ebx, 2

fild [ebx].word
fmul st(0),st(1)
fstp [edx].single;
add ebx, 2

add eax, 4
add edx, 4

loop @Start
ffree st(0)

pop ebx
end;

procedure FromInt16LSB_x87_forDS_2ch(source1: psingle; source2: psingle; frames: longint; target: pointer );
asm
push ebx

mov ebx, target
fld MaxSmall // move to register for speed
@Start: // Samplecount already in ecx!
fld [eax].single;
fmul st(0),st(1)
fistp word ptr [ebx]
add ebx, 2

fld [edx].single;
fmul st(0),st(1)
fistp word ptr [ebx]
add ebx, 2

add eax, 4
add edx, 4

loop @start
ffree st(0) // free after loop has finished

pop ebx
end;

引数を増やすしかなく ebx を退避させないといけなくなったのは残念なところだけど、2回呼ぶよりはマシなんじゃないかなと思うので(速度テストはしてない)、取り合えずこれで行く事に。

誰かの参考になれば幸い。
posted by oov at 21:36| Comment(0) | TrackBack(0) | プログラム | このブログの読者になる | 更新情報をチェックする
この記事へのコメント

この記事へのトラックバック