bass.rbプロトタイプ
ちょっとデカいが(゚ε゚)キニシナイ!!
bass.dllは、un4seenさまのサイト、
http://www.un4seen.com/
の一番上にダウンロードリンクがある。
#!ruby -Ks # Rubyからbass.dllを使うラッパ bass.rb ver 0.0.1α require 'Win32API' module Bass # 構造体やポインタを扱うものは使い方に注意。 # 定義が間違っている可能性もあるので使うときは確認すること。 BASS_GetVersion = Win32API.new("bass", "BASS_GetVersion", "", "I") BASS_ErrorGetCode = Win32API.new("bass", "BASS_ErrorGetCode", "", "I") BASS_Init = Win32API.new("bass", "BASS_Init", "IIIIP", "I") BASS_Free = Win32API.new("bass", "BASS_Free", "", "I") BASS_Start = Win32API.new("bass", "BASS_Start", "", "I") BASS_Stop = Win32API.new("bass", "BASS_Stop", "", "I") BASS_Pause = Win32API.new("bass", "BASS_Pause", "", "I") BASS_SetVolume = Win32API.new("bass", "BASS_SetVolume", "I", "I") BASS_GetVolume = Win32API.new("bass", "BASS_GetVolume", "", "I") BASS_SampleLoad = Win32API.new("bass", "BASS_SampleLoad", "IPIIIII", "I") BASS_SampleFree = Win32API.new("bass", "BASS_SampleFree", "I", "I") BASS_SampleGetChannel = Win32API.new("bass", "BASS_SampleGetChannel", "II", "I") BASS_SampleStop = Win32API.new("bass", "BASS_SampleStop", "I", "I") BASS_StreamCreateFile = Win32API.new("bass", "BASS_StreamCreateFile", "IPIIIII", "I") BASS_StreamFree = Win32API.new("bass", "BASS_StreamFree", "I", "I") BASS_ChannelFlags = Win32API.new("bass", "BASS_ChannelFlags", "III", "I") BASS_ChannelPlay = Win32API.new("bass", "BASS_ChannelPlay", "II", "I") BASS_ChannelStop = Win32API.new("bass", "BASS_ChannelStop", "I", "I") BASS_ChannelPause = Win32API.new("bass", "BASS_ChannelPause", "I", "I") BASS_ChannelSetAttribute = Win32API.new("bass", "BASS_ChannelSetAttribute", "III", "I") BASS_ChannelSlideAttribute = Win32API.new("bass", "BASS_ChannelSlideAttribute", "IIII", "I") BASS_ChannelIsSliding = Win32API.new("bass", "BASS_ChannelIsSliding", "II", "I") # bass.dllのエラーコード Errmsg = { 1=>"MEM",2=>"FILEOPEN",3=>"DRIVER",4=>"BUFLOST",5=>"HANDLE",6=>"FORMAT",7=>"POSITION",8=>"INIT", 9=>"START",14=>"ALREADY",18=>"NOCHAN",19=>"ILLTYPE",20=>"ILLPARAM",21=>"NO3D",22=>"NOEAX",23=>"DEVICE", 24=>"NOPLAY",25=>"FREQ",27=>"NOTFILE",29=>"NOHW",31=>"EMPTY",32=>"NONET",33=>"CREATE",34=>"NOFX", 37=>"NOTAVAIL",38=>"DECODE",39=>"DX",40=>"TIMEOUT",41=>"FILEFORM",42=>"SPEAKER",43=>"VERSION",44=>"CODEC", 45=>"ENDED",-1=>" UNKNOWN" } # bass.dll初期化 def self.init(hWnd, samplerate = 44100) if (BASS_GetVersion.call >> 16) != 0x0204 then raise("bass.dllバージョン2.4系以外には対応しておりません") end if BASS_Init.call(-1, samplerate, 0, hWnd, nil) == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # bass.dll解放 def self.free if BASS_Free.call == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # sampleロード def self.loadSample(filename, max = 1) return Sample.new(filename, max) end # streamロード def self.loadStream(filename) return Stream.new(filename) end # Sampleを表すクラス class Sample def initialize(filename, max = 1) @handle = BASS_SampleLoad.call(0, filename, 0, 0, 0, max, 0x20000) if @handle == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # 解放 def free if BASS_SampleFree.call(@handle) == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # 再生 def play(option = {}) ch = BASS_SampleGetChannel.call(@handle, 0) if ch == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end if option[:loop] then if BASS_ChannelFlags.call(ch, 4, 4) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end if option[:pan] then if BASS_ChannelSetAttribute.call(ch, 3, [option[:pan]].pack("f").unpack("I")[0]) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end if option[:volume] then if BASS_ChannelSetAttribute.call(ch, 2, [option[:volume]].pack("f").unpack("I")[0]) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end if BASS_ChannelPlay.call(ch, 0) == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end return ch end # 再生中のchのパン変更。-1.0(左)〜1.0(右)。float型で。 def setPan(ch, pan) if BASS_ChannelSetAttribute.call(ch, 3, [pan].pack("f").unpack("I")[0]) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # 再生中のchのボリューム変更。0〜1まで、float型で。 def setVolume(ch, v) if BASS_ChannelSetAttribute.call(ch, 2, [v].pack("f").unpack("I")[0]) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # ch停止 def stop(ch = nil) if ch == nil then if BASS_SampleStop.call(@handle) == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end else if BASS_ChannelStop.call(ch) == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end end end # Streamを表すクラス class Stream def initialize(filename) @ch = BASS_StreamCreateFile.call(0, filename, 0, 0, 0, 0, 0) if @ch == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # 解放 def free if BASS_StreamFree.call(@ch) == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # 再生 def play(option = {}) if option[:loop] then if BASS_ChannelFlags.call(@ch, 4, 4) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end if option[:pan] then if BASS_ChannelSetAttribute.call(@ch, 3, [option[:pan]].pack("f").unpack("I")[0]) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end if option[:volume] then if BASS_ChannelSetAttribute.call(@ch, 2, [option[:volume]].pack("f").unpack("I")[0]) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end if BASS_ChannelPlay.call(@ch, 0) == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # パン変更。-1.0(左)〜1.0(右)。float型で。 def pan=(pan) if BASS_ChannelSetAttribute.call(@ch, 3, [pan].pack("f").unpack("I")[0]) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # ボリューム変更。0〜1まで、float型で。 def volume=(v) if BASS_ChannelSetAttribute.call(@ch, 2, [v].pack("f").unpack("I")[0]) == -1 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end # 停止 def stop if BASS_ChannelStop.call(@ch) == 0 then raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end end end end #Stream再生とパン変更のサンプル 要DXRuby1.0.4 #require "dxruby" #Bass.init(Window.hWnd) #s = Bass.loadStream("test.ogg") #s.play(:loop=>true) #pan = 0 # #Window.loop do # pan += Input.x * 0.02 # pan = -1.0 if pan < -1.0 # pan = 1.0 if pan > 1.0 # s.pan=pan # # break if Input.keyPush?(K_ESCAPE) #end #s.free #Bass.free #Sample再生のサンプル 要DXRuby1.0.4 #Sampleはデータを全てメモリ内に読み込んでデコードします。 #BGMにMP3やOGGを使う場合は、Streamをオススメします。 #Sampleはplayするとチャンネル番号が返ってきて、 #その番号を使って再生中の音のパンや音量を変更することができます。 #StremもSampleも、playの引数に:loop=>trueを指定するとループします。 #:panでパン設定、:volumeで音量設定もできます。 #require "dxruby" #Bass.init(Window.hWnd) #s = Bass.loadSample("test2.wav") #ch = s.play(:loop=>true) #pan = 0 # #Window.loop do # pan += Input.x * 0.02 # pan = -1.0 if pan < -1.0 # pan = 1.0 if pan > 1.0 # s.setPan(ch, pan) # # break if Input.keyPush?(K_ESCAPE) #end # #s.free #Bass.free #bassの各種機能については今後、気が向いたときに追加していきます。
とりあえずSampleとStreamの再生、ボリューム、パンの設定のみ。
DXRuby1.0.4が必要で、まだリリースしていないのだがそんなことは(゚ε゚)キニシナイ!!
動かしてみたい人はSVNリポジトリのtrunkから引っこ抜いておくれ。1.8限定でバイナリ置いてあるから。