#!ruby # -*- mode: ruby; coding: utf-8 -*- # Last updated: <2021/08/18 09:01:09 +0900> # Rubyからbass.dllを使うラッパ bass.rb ver 0.0.1b =begin # it worked. # Windows10 x64 21H1 and # Ruby 1.8.7 p330 x86 (i386-mswin32) # Ruby 1.9.3 p551 x86 (i386-mingw32) # Ruby 2.3.3 p222 x86 (i386-mingw32) # Ruby 2.6.8 p205 x86 (i386-mingw32) # Ruby 2.7.4 p191 x86 (i386-mingw32) # Ruby 3.0.2 p107 x86 (i386-mingw32) == Stream再生とパン変更のサンプル require "dxruby" Bass.init(Window.hWnd) s = Bass.loadStream("test.ogg") s.play(:loop=>true) pan = 0.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 s.setFade(0, 1000) if Input.keyPush?(K_Z) s.setFade(1, 1000) if Input.keyPush?(K_C) break if Input.keyPush?(K_ESCAPE) end s.free Bass.free == Sample再生のサンプル Sampleはデータを全てメモリ内に読み込んでデコードします。 BGMにMP3やOGGを使う場合は、Streamをオススメします。 Sampleはplayするとチャンネル番号が返ってきて、 その番号を使って再生中の音のパンや音量を変更することができます。 StremもSampleも、playの引数に:loop=>trueを指定するとループします。 :panでパン設定、:volumeで音量設定もできます。 :fadevolumeでフェード目標音量、:fadetimeでフェード時間の設定ができます。 require "dxruby" Bass.init(Window.hWnd) s = Bass.loadSample("test.wav") ch = s.play(:loop=>true, :volume=>1.0) 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) s.setFade(ch, 0, 1000) if Input.keyPush?(K_Z) s.setFade(ch, 1, 1000) if Input.keyPush?(K_C) break if Input.keyPush?(K_ESCAPE) end s.free Bass.free 各種bassの機能については今後、気が向いたときに追加していきます。 =end if RUBY_VERSION.to_f >= 2.0 # Ruby 2.0 or later require "fiddle/import" require "fiddle/types" module Bass bassdllpath = format("%s/%s", File.expand_path("..", __FILE__), "bass.dll") extend Fiddle::Importer dlload bassdllpath include Fiddle::Win32Types # 構造体やポインタを扱うものは使い方に注意。 # 定義が間違っている可能性もあるので使うときは確認すること。 extern "int BASS_SetConfig(int, int)" extern "int BASS_GetConfig(int)" extern "int BASS_SetConfigPtr(int, void*)" extern "void *BASS_GetConfigPtr(int)" extern "int BASS_GetVersion(void)" extern "int BASS_ErrorGetCode(void)" extern "int BASS_GetDeviceInfo(int, void*)" extern "int BASS_Init(int, int, int, int, void*)" extern "int BASS_Free(void)" extern "int BASS_SetDevice(int)" extern "int BASS_GetDevice(void)" extern "int BASS_GetInfo(void*)" extern "int BASS_Start(void)" extern "int BASS_Stop(void)" extern "int BASS_Pause(void)" extern "int BASS_IsStarted(void)" extern "int BASS_Update(int)" extern "float BASS_GetCPU(void)" extern "int BASS_SetVolume(float)" extern "float BASS_GetVolume(void)" extern "void *BASS_GetDSoundObject(int)" extern "int BASS_PluginLoad(char *, int)" extern "int BASS_PluginFree(int)" extern "void *BASS_PluginGetInfo(int)" extern "int BASS_Set3DFactors(float, float, float)" extern "int BASS_Get3DFactors(float*, float*, float*)" extern "int BASS_Set3DPosition(void*, void*, void*, void*)" extern "int BASS_Get3DPosition(void*, void*, void*, void*)" extern "void BASS_Apply3D(void)" # extern 'int BASS_SetEAXParameters(int, int, int, int)' # extern 'int BASS_GetEAXParameters(void*, void*, void*, void*)' extern "int BASS_SampleLoad(int, void*, uint64_t, int, int, int)" extern "int BASS_SampleCreate(int, int, int, int, int)" extern "int BASS_SampleFree(int)" extern "int BASS_SampleSetData(int, void*)" extern "int BASS_SampleGetData(int, void*)" extern "int BASS_SampleGetInfo(int, void*)" extern "int BASS_SampleSetInfo(int, void*)" extern "int BASS_SampleGetChannel(int, int)" extern "int BASS_SampleGetChannels(int, void*)" extern "int BASS_SampleStop(int)" extern "int BASS_StreamCreate(int, int, int, void*, void*)" extern "int BASS_StreamCreateFile(int, void*, uint64_t, uint64_t, int)" extern "int BASS_StreamCreateURL(void*, int, int, void*, void*)" extern "int BASS_StreamCreateFileUser(int, int, void*, void*)" extern "int BASS_StreamFree(int)" extern "uint64_t BASS_StreamGetFilePosition(int, int)" extern "int BASS_StreamPutData(int, void*, int)" extern "int BASS_StreamPutFileData(int, void*, int)" extern "int BASS_MusicLoad(int, void*, uint64_t, int, int, int)" extern "int BASS_MusicFree(int)" extern "int BASS_RecordGetDeviceInfo(int, void*)" extern "int BASS_RecordInit(int)" extern "int BASS_RecordFree(void)" extern "int BASS_RecordSetDevice(int)" extern "int BASS_RecordGetDevice(void)" extern "int BASS_RecordGetInfo(void*)" extern "void *BASS_RecordGetInputName(int)" extern "int BASS_RecordSetInput(int, int, float)" extern "int BASS_RecordGetInput(int, float*)" extern "int BASS_RecordStart(int, int, int, void*, void*)" extern "double BASS_ChannelBytes2Seconds(int, uint64_t)" extern "uint64_t BASS_ChannelSeconds2Bytes(int, double)" extern "int BASS_ChannelGetDevice(int)" extern "int BASS_ChannelSetDevice(int, int)" extern "int BASS_ChannelIsActive(int)" extern "int BASS_ChannelGetInfo(int, void*)" extern "char *BASS_ChannelGetTags(int, int)" extern "int BASS_ChannelFlags(int, int, int)" extern "int BASS_ChannelLock(int, int)" extern "int BASS_ChannelFree(int)" extern "int BASS_ChannelPlay(int, int)" extern "int BASS_ChannelStop(int)" extern "int BASS_ChannelPause(int)" extern "int BASS_ChannelUpdate(int, int)" extern "int BASS_ChannelSetAttribute(int, int, float)" extern "int BASS_ChannelGetAttribute(int, int, float*)" extern "int BASS_ChannelSlideAttribute(int, int, float, int)" extern "int BASS_ChannelIsSliding(int, int)" extern "int BASS_ChannelSetAttributeEx(int, int, void*, int)" extern "int BASS_ChannelGetAttributeEx(int, int, void*, int)" extern "int BASS_ChannelSet3DAttributes(int, int, float, float, int, int, float)" extern "int BASS_ChannelGet3DAttributes(int, int*, float*, float*, int*, int*, float*)" extern "int BASS_ChannelSet3DPosition(int, void*, void*, void*)" extern "int BASS_ChannelGet3DPosition(int, void*, void*, void*)" extern "uint64_t BASS_ChannelGetLength(int, int)" extern "int BASS_ChannelSetPosition(int, uint64_t, int)" extern "uint64_t BASS_ChannelGetPosition(int, int)" extern "int BASS_ChannelGetLevel(int)" extern "int BASS_ChannelGetLevelEx(int, float*, float, int)" extern "int BASS_ChannelGetData(int, void*, int)" extern "int BASS_ChannelSetSync(int, int, uint64_t, void*, void*)" extern "int BASS_ChannelRemoveSync(int, int)" extern "int BASS_ChannelSetLink(int, int)" extern "int BASS_ChannelRemoveLink(int, int)" extern "int BASS_ChannelSetDSP(int, void*, void*, int)" extern "int BASS_ChannelRemoveDSP(int, int)" extern "int BASS_ChannelSetFX(int, int, int)" extern "int BASS_ChannelRemoveFX(int, int)" extern "int BASS_FXSetParameters(int, void*)" extern "int BASS_FXGetParameters(int, void*)" extern "int BASS_FXSetPriority(int, int)" extern "int BASS_FXReset(int)" # bass.dll error code 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", } def self.err raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode()]}") end # Init bass.dll def self.init(hWnd, samplerate = 44100) if (BASS_GetVersion() >> 16) != 0x0204 raise("Only bass.dll version 2.4 is supported.") end err if BASS_Init(-1, samplerate, 0, hWnd, nil) == 0 end # Free bass.dll def self.free err if BASS_Free() == 0 end # Load sample def self.loadSample(filename, max = 1) return Sample.new(filename, max) end # Load stream def self.loadStream(filename) return Stream.new(filename) end # Set sample global volume (0 - 10000 (integer)) def self.sampleVolume=(vol) ::Bass.err if BASS_SetConfig(4, vol) == 0 end # Get sample global volume (0 - 10000 (integer)) def self.sampleVolume vol = BASS_GetConfig(4) ::Bass.err if vol == -1 return vol end # Set stream global volume (0 - 10000 (integer)) def self.streamVolume=(vol) ::Bass.err if BASS_SetConfig(5, vol) == 0 end # Get stream global volume (0 - 10000 (integer)) def self.streamVolume vol = BASS_GetConfig(5) ::Bass.err if vol == -1 return vol end #なんだかうまく動かないのでコメントにしとく # # Bassベースボリューム取得(0.0~1.0float) # def self.volume # vol = BASS_GetVolume.call # ::Bass.err if vol == -1 # return [vol].pack("I").unpack("f")[0] # end # Sample class class Sample def initialize(filename, max = 1) @handle = ::Bass.BASS_SampleLoad(0, filename, 0, 0, max, 0x20000) ::Bass.err if @handle == 0 end # free sample def free ::Bass.err if ::Bass.BASS_SampleFree(@handle) == 0 end def get_float(v) return ([v].pack("f").unpack("f")[0]) end # play (option :loop, :pan, :volume, :fadevolume) def play(option = {}) ch = ::Bass.BASS_SampleGetChannel(@handle, 0) ::Bass.err if ch == 0 if option[:loop] ::Bass.err if ::Bass.BASS_ChannelFlags(ch, 4, 4) == -1 end self.setPan(ch, option[:pan]) if option[:pan] self.setVolume(ch, option[:volume]) if option[:volume] self.setFade(ch, option[:fadevolume], option[:fadetime]) if (option[:fadevolume] and option[:fadetime]) ::Bass.err if ::Bass.BASS_ChannelPlay(ch, 0) == 0 return ch end # Set pan (pan value : -1.0(left) - 1.0(right) (float)) def setPan(ch, pan) ::Bass.err if ::Bass.BASS_ChannelSetAttribute(ch, 3, self.get_float(pan)) == 0 end # Set volume (volume value : 0.0 - 1.0 (float)) def setVolume(ch, v) ::Bass.err if ::Bass.BASS_ChannelSetAttribute(ch, 2, self.get_float(v)) == 0 end # Set fade (volume value : 0.0 - 1.0 (float), time : msec) def setFade(ch, v, t) ::Bass.err if ::Bass.BASS_ChannelSlideAttribute(ch, 2, self.get_float(v), t) == 0 end # stop def stop(ch = nil) if ch == nil ::Bass.err if ::Bass.BASS_SampleStop(@handle) == 0 else ::Bass.err if ::Bass.BASS_ChannelStop(ch) == 0 end end end # Stream class class Stream def initialize(filename) @ch = ::Bass.BASS_StreamCreateFile(0, filename, 0, 0, 0) ::Bass.err if @ch == 0 end # free def free ::Bass.err if ::Bass.BASS_StreamFree(@ch) == 0 end def get_float(v) return ([v].pack("f").unpack("f")[0]) end # play def play(option = {}) if option[:loop] ::Bass.err if ::Bass.BASS_ChannelFlags(@ch, 4, 4) == -1 end if option[:pan] self.pan = (option[:pan]) end if option[:volume] self.volume = (option[:volume]) end if option[:fadevolume] and option[:fadetime] self.setFade(option[:fadevolume], option[:fadetime]) end ::Bass.err if ::Bass.BASS_ChannelPlay(@ch, 0) == 0 end # Set pan (pan value : -1.0(left) - 1.0(right) (float)) def pan=(pan) ::Bass.err if ::Bass.BASS_ChannelSetAttribute(@ch, 3, self.get_float(pan)) == 0 end # Set volume (volume value : 0.0 - 1.0 (float)) def volume=(v) ::Bass.err if ::Bass.BASS_ChannelSetAttribute(@ch, 2, self.get_float(v)) == 0 end # Set fade (volume value : 0.0 - 1.0 (float), time : msec) def setFade(v, t) ::Bass.err if ::Bass.BASS_ChannelSlideAttribute(@ch, 2, self.get_float(v), t) == 0 end # stop (pause) def stop ::Bass.err if ::Bass.BASS_ChannelStop(@ch) == 0 end end end else # Ruby 1.8, 1.9 require "Win32API" module Bass # 構造体やポインタを扱うものは使い方に注意。 # 定義が間違っている可能性もあるので使うときは確認すること。 BASS_SetConfig = Win32API.new("bass", "BASS_SetConfig", "II", "I") BASS_GetConfig = Win32API.new("bass", "BASS_GetConfig", "I", "I") BASS_SetConfigPtr = Win32API.new("bass", "BASS_SetConfigPtr", "IP", "I") BASS_GetConfigPtr = Win32API.new("bass", "BASS_GetConfigPtr", "I", "P") BASS_GetVersion = Win32API.new("bass", "BASS_GetVersion", "", "I") BASS_ErrorGetCode = Win32API.new("bass", "BASS_ErrorGetCode", "", "I") BASS_GetDeviceInfo = Win32API.new("bass", "BASS_GetDeviceInfo", "IP", "I") BASS_Init = Win32API.new("bass", "BASS_Init", "IIIIP", "I") BASS_SetDevice = Win32API.new("bass", "BASS_SetDevice", "I", "I") BASS_GetDevice = Win32API.new("bass", "BASS_GetDevice", "", "I") BASS_Free = Win32API.new("bass", "BASS_Free", "", "I") BASS_GetDSoundObject = Win32API.new("bass", "BASS_GetDSoundObject", "I", "P") BASS_GetInfo = Win32API.new("bass", "BASS_GetInfo", "P", "I") BASS_Update = Win32API.new("bass", "BASS_Update", "I", "I") BASS_GetCPU = Win32API.new("bass", "BASS_GetCPU", "", "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_PluginLoad = Win32API.new("bass", "BASS_PluginLoad", "PI", "I") BASS_PluginFree = Win32API.new("bass", "BASS_PluginFree", "I", "I") BASS_PluginGetInfo = Win32API.new("bass", "BASS_PluginGetInfo", "I", "P") BASS_Set3DFactors = Win32API.new("bass", "BASS_Set3DFactors", "III", "I") BASS_Get3DFactors = Win32API.new("bass", "BASS_Get3DFactors", "PPP", "I") BASS_Set3DPosition = Win32API.new("bass", "BASS_Set3DPosition", "PPPP", "I") BASS_Get3DPosition = Win32API.new("bass", "BASS_Get3DPosition", "PPPP", "I") BASS_Apply3D = Win32API.new("bass", "BASS_Apply3D", "", "I") BASS_SetEAXParameters = Win32API.new("bass", "BASS_SetEAXParameters", "IIII", "I") BASS_GetEAXParameters = Win32API.new("bass", "BASS_GetEAXParameters", "PPPP", "I") BASS_MusicLoad = Win32API.new("bass", "BASS_MusicLoad", "IPIIIII", "I") BASS_MusicFree = Win32API.new("bass", "BASS_MusicFree", "I", "I") BASS_SampleLoad = Win32API.new("bass", "BASS_SampleLoad", "IPIIIII", "I") BASS_SampleCreate = Win32API.new("bass", "BASS_SampleCreate", "IIIII", "I") BASS_SampleFree = Win32API.new("bass", "BASS_SampleFree", "I", "I") BASS_SampleSetData = Win32API.new("bass", "BASS_SampleSetData", "IP", "I") BASS_SampleGetData = Win32API.new("bass", "BASS_SampleGetData", "IP", "I") BASS_SampleGetInfo = Win32API.new("bass", "BASS_SampleGetInfo", "IP", "I") BASS_SampleSetInfo = Win32API.new("bass", "BASS_SampleSetInfo", "IP", "I") BASS_SampleGetChannel = Win32API.new("bass", "BASS_SampleGetChannel", "II", "I") BASS_SampleGetChannels = Win32API.new("bass", "BASS_SampleGetChannels", "IP", "I") BASS_SampleStop = Win32API.new("bass", "BASS_SampleStop", "I", "I") BASS_StreamCreate = Win32API.new("bass", "BASS_StreamCreate", "IIIPP", "I") BASS_StreamCreateFile = Win32API.new("bass", "BASS_StreamCreateFile", "IPIIIII", "I") BASS_StreamCreateURL = Win32API.new("bass", "BASS_StreamCreateURL", "PIIPP", "I") BASS_StreamCreateFileUser = Win32API.new("bass", "BASS_StreamCreateFileUser", "IIPP", "I") BASS_StreamFree = Win32API.new("bass", "BASS_StreamFree", "I", "I") BASS_StreamGetFilePosition = Win32API.new("bass", "BASS_StreamGetFilePosition", "II", "I") BASS_StreamPutData = Win32API.new("bass", "BASS_StreamPutData", "IPI", "I") BASS_StreamPutFileData = Win32API.new("bass", "BASS_StreamPutFileData", "IPI", "I") BASS_RecordGetDeviceInfo = Win32API.new("bass", "BASS_RecordGetDeviceInfo", "IP", "I") BASS_RecordInit = Win32API.new("bass", "BASS_RecordInit", "I", "I") BASS_RecordSetDevice = Win32API.new("bass", "BASS_RecordSetDevice", "I", "I") BASS_RecordGetDevice = Win32API.new("bass", "BASS_RecordGetDevice", "", "I") BASS_RecordFree = Win32API.new("bass", "BASS_RecordFree", "", "I") BASS_RecordGetInfo = Win32API.new("bass", "BASS_RecordGetInfo", "P", "I") BASS_RecordGetInputName = Win32API.new("bass", "BASS_RecordGetInputName", "I", "P") BASS_RecordSetInput = Win32API.new("bass", "BASS_RecordSetInput", "III", "I") BASS_RecordGetInput = Win32API.new("bass", "BASS_RecordGetInput", "IP", "I") BASS_RecordStart = Win32API.new("bass", "BASS_RecordStart", "IIIPP", "I") BASS_ChannelBytes2Seconds = Win32API.new("bass", "BASS_ChannelBytes2Seconds", "III", "I") BASS_ChannelSeconds2Bytes = Win32API.new("bass", "BASS_ChannelSeconds2Bytes", "II", "I") BASS_ChannelGetDevice = Win32API.new("bass", "BASS_ChannelGetDevice", "I", "I") BASS_ChannelSetDevice = Win32API.new("bass", "BASS_ChannelSetDevice", "II", "I") BASS_ChannelIsActive = Win32API.new("bass", "BASS_ChannelIsActive", "I", "I") BASS_ChannelGetInfo = Win32API.new("bass", "BASS_ChannelGetInfo", "IP", "I") BASS_ChannelGetTags = Win32API.new("bass", "BASS_ChannelGetTags", "II", "P") BASS_ChannelFlags = Win32API.new("bass", "BASS_ChannelFlags", "III", "I") BASS_ChannelUpdate = Win32API.new("bass", "BASS_ChannelUpdate", "II", "I") BASS_ChannelLock = Win32API.new("bass", "BASS_ChannelLock", "II", "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_ChannelGetAttribute = Win32API.new("bass", "BASS_ChannelGetAttribute", "IIP", "I") BASS_ChannelSlideAttribute = Win32API.new("bass", "BASS_ChannelSlideAttribute", "IIII", "I") BASS_ChannelIsSliding = Win32API.new("bass", "BASS_ChannelIsSliding", "II", "I") BASS_ChannelSet3DAttributes = Win32API.new("bass", "BASS_ChannelSet3DAttributes", "IIIIIII", "I") BASS_ChannelGet3DAttributes = Win32API.new("bass", "BASS_ChannelGet3DAttributes", "IPPPPPP", "I") BASS_ChannelSet3DPosition = Win32API.new("bass", "BASS_ChannelSet3DPosition", "IPPP", "I") BASS_ChannelGet3DPosition = Win32API.new("bass", "BASS_ChannelGet3DPosition", "IPPP", "I") BASS_ChannelGetLength = Win32API.new("bass", "BASS_ChannelGetLength", "II", "I") BASS_ChannelSetPosition = Win32API.new("bass", "BASS_ChannelSetPosition", "IIII", "I") BASS_ChannelGetPosition = Win32API.new("bass", "BASS_ChannelGetPosition", "II", "I") BASS_ChannelGetLevel = Win32API.new("bass", "BASS_ChannelGetLevel", "I", "I") BASS_ChannelGetData = Win32API.new("bass", "BASS_ChannelGetData", "IPI", "I") BASS_ChannelSetSync = Win32API.new("bass", "BASS_ChannelSetSync", "IIIIPP", "I") BASS_ChannelRemoveSync = Win32API.new("bass", "BASS_ChannelRemoveSync", "II", "I") BASS_ChannelSetDSP = Win32API.new("bass", "BASS_ChannelSetDSP", "IPPI", "I") BASS_ChannelRemoveDSP = Win32API.new("bass", "BASS_ChannelRemoveDSP", "II", "I") BASS_ChannelSetLink = Win32API.new("bass", "BASS_ChannelSetLink", "II", "I") BASS_ChannelRemoveLink = Win32API.new("bass", "BASS_ChannelRemoveLink", "II", "I") BASS_ChannelSetFX = Win32API.new("bass", "BASS_ChannelSetFX", "III", "I") BASS_ChannelRemoveFX = Win32API.new("bass", "BASS_ChannelRemoveFX", "II", "I") BASS_FXSetParameters = Win32API.new("bass", "BASS_FXSetParameters", "IP", "I") BASS_FXGetParameters = Win32API.new("bass", "BASS_FXGetParameters", "IP", "I") BASS_FXReset = Win32API.new("bass", "BASS_FXReset", "I", "I") # bass.dll error code 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", } def self.err raise("BASS_ERROR_#{Errmsg[BASS_ErrorGetCode.call]}") end # Init bass.dll def self.init(hWnd, samplerate = 44100) if (BASS_GetVersion.call >> 16) != 0x0204 raise("Only bass.dll version 2.4 is supported.") end err if BASS_Init.call(-1, samplerate, 0, hWnd, nil) == 0 end # Free bass.dll def self.free err if BASS_Free.call == 0 end # Load sample def self.loadSample(filename, max = 1) return Sample.new(filename, max) end # Load stream def self.loadStream(filename) return Stream.new(filename) end # Set sample global volume (0 - 10000 (integer)) def self.sampleVolume=(vol) ::Bass.err if BASS_SetConfig.call(4, vol) == 0 end # Get sample global volume (0 - 10000 (integer)) def self.sampleVolume vol = BASS_GetConfig.call(4) ::Bass.err if vol == -1 return vol end # Set stream global volume (0 - 10000 (integer)) def self.streamVolume=(vol) ::Bass.err if BASS_SetConfig.call(5, vol) == 0 end # Get stream global volume (0 - 10000 (integer)) def self.streamVolume vol = BASS_GetConfig.call(5) ::Bass.err if vol == -1 return vol end #なんだかうまく動かないのでコメントにしとく # # Bassベースボリューム取得(0.0~1.0float) # def self.volume # vol = BASS_GetVolume.call # ::Bass.err if vol == -1 # return [vol].pack("I").unpack("f")[0] # end # Sample class class Sample def initialize(filename, max = 1) @handle = BASS_SampleLoad.call(0, filename, 0, 0, 0, max, 0x20000) ::Bass.err if @handle == 0 end # free sample def free ::Bass.err if BASS_SampleFree.call(@handle) == 0 end # play (option :loop, :pan, :volume, :fadevolume) def play(option = {}) ch = BASS_SampleGetChannel.call(@handle, 0) ::Bass.err if ch == 0 if option[:loop] ::Bass.err if BASS_ChannelFlags.call(ch, 4, 4) == -1 end if option[:pan] ::Bass.err if BASS_ChannelSetAttribute.call(ch, 3, [option[:pan]].pack("f").unpack("I")[0]) == -1 end if option[:volume] ::Bass.err if BASS_ChannelSetAttribute.call(ch, 2, [option[:volume]].pack("f").unpack("I")[0]) == -1 end if option[:fadevolume] and option[:fadetime] ::Bass.err if BASS_ChannelSlideAttribute.call(ch, 2, [option[:fadevolume]].pack("f").unpack("I")[0], option[:fadetime]) == -1 end ::Bass.err if BASS_ChannelPlay.call(ch, 0) == 0 return ch end # Set pan (pan value : -1.0(left) - 1.0(right) (float)) def setPan(ch, pan) ::Bass.err if BASS_ChannelSetAttribute.call(ch, 3, [pan].pack("f").unpack("I")[0]) == -1 end # Set volume (volume value : 0.0 - 1.0 (float)) def setVolume(ch, v) ::Bass.err if BASS_ChannelSetAttribute.call(ch, 2, [v].pack("f").unpack("I")[0]) == -1 end # Set fade (volume value : 0.0 - 1.0 (float), time : msec) def setFade(ch, v, t) ::Bass.err if BASS_ChannelSlideAttribute.call(ch, 2, [v].pack("f").unpack("I")[0], t) == -1 end # stop def stop(ch = nil) if ch == nil ::Bass.err if BASS_SampleStop.call(@handle) == 0 else ::Bass.err if BASS_ChannelStop.call(ch) == 0 end end end # Stream class class Stream def initialize(filename) @ch = BASS_StreamCreateFile.call(0, filename, 0, 0, 0, 0, 0) ::Bass.err if @ch == 0 end # free def free ::Bass.err if BASS_StreamFree.call(@ch) == 0 end # play def play(option = {}) if option[:loop] ::Bass.err if BASS_ChannelFlags.call(@ch, 4, 4) == -1 end if option[:pan] ::Bass.err if BASS_ChannelSetAttribute.call(@ch, 3, [option[:pan]].pack("f").unpack("I")[0]) == -1 end if option[:volume] ::Bass.err if BASS_ChannelSetAttribute.call(@ch, 2, [option[:volume]].pack("f").unpack("I")[0]) == -1 end if option[:fadevolume] and option[:fadetime] ::Bass.err if BASS_ChannelSlideAttribute.call(@ch, 2, [fadevolume].pack("f").unpack("I")[0], fadetime) == -1 end ::Bass.err if BASS_ChannelPlay.call(@ch, 0) == 0 end # Set pan (pan value : -1.0(left) - 1.0(right) (float)) def pan=(pan) ::Bass.err if BASS_ChannelSetAttribute.call(@ch, 3, [pan].pack("f").unpack("I")[0]) == -1 end # Set volume (volume value : 0.0 - 1.0 (float)) def volume=(v) ::Bass.err if BASS_ChannelSetAttribute.call(@ch, 2, [v].pack("f").unpack("I")[0]) == -1 end # Set fade (volume value : 0.0 - 1.0 (float), time : msec) def setFade(v, t) ::Bass.err if BASS_ChannelSlideAttribute.call(@ch, 2, [v].pack("f").unpack("I")[0], t) == 0 end # stop (pause) def stop ::Bass.err if BASS_ChannelStop.call(@ch) == 0 end end end end