いらないモノ、ひつようなモノ

書籍、音楽、そして若干のテクノロジー

wrapperコードをコンパイル

swigの生成してくれたruby_interface_wrap.cc, ruby_interface_wrap.hをコンパイルしてオブジェクトを作成する。これもsconsして出てきたコンパイルオプションで実施。これも山ほどwarningが出る。

g++ -o interfaces/ruby_interface_wrap.os -c -fexceptions -Wall -O3 -march=pentium3 \
-fomit-frame-pointer -ffast-math -ftree-vectorize -DLINUX -DPIPES -fPIC \
-DHAVE_LIBSNDFILE=1016 -DHAVE_FLTK -DUSE_DOUBLE -DHAVE_SOCKETS -DHAVE_FCNTL_H \
-DHAVE_UNISTD_H -DHAVE_STDINT_H -DHAVE_SYS_TIME_H -DHAVE_SYS_TYPES_H -DHAVE_TERMIOS_H \
-DHAVE_SOCKETS -DHAVE_DIRENT_H -D__BUILDING_LIBCSOUND -D_CSOUND_RELEASE_ \
-DCS_DEFAULT_PLUGINDIR=\"/usr/local/lib/csound/plugins64\" -I. -IH \
-I/usr/java/jdk1.6.0_02/include -I/usr/local/include -I/usr/include -I/usr/X11R6/include \
-Iinterfaces -I/usr/lib/ruby/1.8/i386-linux/   interfaces/ruby_interface_wrap.cc

ruby_interface_wrap.ccで「dereferencing type-punned pointer will break strict-aliasing rules」という警告が出まくるがとりあえず無視。

ライブラリを作成

これもsconsの結果をほとんど持ってこようと思ったが-o _csdとなっていたものは明らかにpython用のライブラリと名前が被るのでrcsoundにした*1

g++ -o rcsound.so -Wl,-Bdynamic -Wl,-rpath-link,. -shared interfaces/ruby_interface_wrap.os \
-L/usr/local/lib -L/usr/lib -L/usr/lib/ruby/1.8/i386-linux/ -L. -L. -L/usr/local/lib -L. \
-L. -lruby -lstdc++ -lutil -lsndfile -ldl -lm -lpthread -csnd

テストコード

リアルタイム動作をさせることを念頭に、interface/test.pyやinterface/test.luaを斜めに見て作成。サンプルでは-oとdacを分けて引数として与えていたがひとつにしても動く。hw:0,0等の値は各環境に依存する。

#!/bin/env /usr/bin/ruby
require 'rcsound' # automatically Init_rcsoundが動く
csound=Rcsound::Csound.new()

csound.Compile('-d','-m0','-+rtaudio=alsa','-odac:hw:0,0', 'rt.csd')
puts "compile END"
while csound.PerformBuffer()==0
    next
end
csound.Reset()
#Rcsound::csoundDestroy(csound)
  • テストコードのファイルを作るのは、interfaces配下ではなく、先ほどのrcsound.soと同じディレクトリに作成(特にrcsound.soをLD_LIBRARY_PATHのどこかにコピーしたのではない限り。つまりこの例だとソースを展開したディレクトリの最上位でした)。
  • requireを行うとinit_XXXXXという関数が動くのが分かるXXXXXというのは作成したライブラリの名称でこれはruby_interface.iで定義したモジュール名と同一になるべき。例えば以下のようなエラーが出る。
./XXXXX.so: ./XXXXX.so: undefined symbol: Init_XXXXX - ./XXXXX.so (LoadError)
  • 最終行でDestroyを行おうとしたらこの引数の中身はポインタが入るべきなので動かないけどOKだなーとか思っていたら、csoundDestoryというのはCの関数でC++APIではデストラクタから直接呼び出されていることがソースから判明。rubyでは呼ばなくていいのかな?ガベージコレクションの関係があるのみたいなので、それから悩むのかな?

csoundファイル

どこから持ってきたか忘れてしまいましたが、シンプルで結構好きな音だったのでとっといてあったもの(最初のファイル名はfilteredSawとあったような)。オプションが書かれているけどこれはどこまで有効なんだろうか後から考えると不明。

;
; generated by shell function
;
<CsoundSynthesizer>
<CsOptions>
-d -m0 -+rtaudio=alsa -odac:hw:0,0
</CsOptions>
<CsInstruments>
sr = 44100
kr = 44100
ksmps = 1
nchnls = 2

instr 1 
  ilen             =        p3
  ifrq             = cpspch(p4)
  iamp             =        p5

  i_filt_frq_start =        p6  
  i_filt_frq_end   =        p7

  kenv  linen iamp,ilen/5,ilen,ilen/5
  kpan  phasor 1/ilen
  a1    oscil kenv,ifrq       ,9
  a2    oscil kenv,ifrq*0.999 ,9
  a3    oscil kenv,ifrq*1.001 ,9
  k_flt_freq    line i_filt_frq_start,ilen,i_filt_frq_end
  a4=(a1+a2+a3)/3
  aout  reson a4,k_flt_freq,100, 2
  outs aout*kpan , aout*(1-kpan)
endin
</CsInstruments> 
<CsScore>
f9 0 4096 10 1 .5 .333 .25 .2 .167 .1428 .125 .111 .1 .0909 .0833 .0769 .0714 .0667 .0625  ; SAW

i1   0  10 8.04 14000   5000   500
i1   0  10 8.07 14000   5000   500
i1   0  10 8.11 14000   5000   500
i1   0  10 9.02 14000   5000   500
</CsScore>
</CsoundSynthesizer>

*1:この名称がswigのモジュール定義と関連があると知ったのは、テストコードを使って動かなくなったときでした