2021/08/15(日) [n年前の日記]
#1 [dxruby] bassrbをfiddleを使って動くように修正してみた
_一昨日
、
_昨日
に続けて作業。
DXRuby 利用時、ogg サウンドファイルの再生に利用できるライブラリ bassrb (Bass.rb) を、今時のRuby (3.0.x 等)でも動かせるように fiddle を使って処理するように修正してみた。ライセンスは、オリジナル版に倣って Public Domain ってことで。
_Bass.rb (fiddle使用版。動作には bass.dll が必要)
Ruby 1.8, 1.9 で動かす場合はオリジナル版の処理を通って、Ruby 2.0 以降で動かす場合は fiddle を使って処理するようにしてある。
最新版の bass.dll は、以下から入手できる。
_Un4seen Developments - 2MIDI / BASS / MID2XM / MO3 / XM-EXE / XMPlay
以下の環境で動かして、ogg が再生できることを確認できた。一応、最新版の bass.dll 2.4.16.3 (2021/07/21) をダウンロードして動作確認した。
DXRuby + Bass.rb を利用して ogg を Stream 再生する使用例は以下。ruby ogg_play_stream_bassrb.rb で実行できる。DXRuby のウインドウが開いて、キー入力に応じて再生テストができる。
_ogg_play_stream_bassrb.rb
_loop_bgm.ogg
DXRuby + Bass.rb を利用して ogg を Sample 再生する使用例は以下。ruby ogg_play_sample_bassrb.rb で実行できる。
_ogg_play_sample_bassrb.rb
_jingle.ogg
一応、関連ファイルを全部まとめて zip にして置いておきます。
_ogg_play_with_baserb_20210818.zip
_ogg_play_with_baserb_20210815.zip
ちなみに、bass.dll は、Vox.dll と違って、ogg のループ再生もちゃんと鳴らしてくれる。Vox.dll で再生するとループする時に変な聞こえ方になるけれど、bass.dll は滑らかに(?)ループする。
ただ、bass.dll の商用利用はライセンス料がかかるので注意…。無料で公開する何かしらに添付して使う分にはライセンス料はかからないけれど、おそらく同人ソフトを作って販売する、といった場合にはライセンス料を払うことになるのではないかなと…。たぶん。
DXRuby 利用時、ogg サウンドファイルの再生に利用できるライブラリ bassrb (Bass.rb) を、今時のRuby (3.0.x 等)でも動かせるように fiddle を使って処理するように修正してみた。ライセンスは、オリジナル版に倣って Public Domain ってことで。
_Bass.rb (fiddle使用版。動作には bass.dll が必要)
Ruby 1.8, 1.9 で動かす場合はオリジナル版の処理を通って、Ruby 2.0 以降で動かす場合は fiddle を使って処理するようにしてある。
最新版の bass.dll は、以下から入手できる。
_Un4seen Developments - 2MIDI / BASS / MID2XM / MO3 / XM-EXE / XMPlay
以下の環境で動かして、ogg が再生できることを確認できた。一応、最新版の bass.dll 2.4.16.3 (2021/07/21) をダウンロードして動作確認した。
- Windows10 x64 21H1 and
- bass.dll 2.4.16.3 (2021/07/21)
- 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)
DXRuby + Bass.rb を利用して ogg を Stream 再生する使用例は以下。ruby ogg_play_stream_bassrb.rb で実行できる。DXRuby のウインドウが開いて、キー入力に応じて再生テストができる。
_ogg_play_stream_bassrb.rb
_loop_bgm.ogg
DXRuby + Bass.rb を利用して ogg を Sample 再生する使用例は以下。ruby ogg_play_sample_bassrb.rb で実行できる。
_ogg_play_sample_bassrb.rb
_jingle.ogg
一応、関連ファイルを全部まとめて zip にして置いておきます。
_ogg_play_with_baserb_20210818.zip
ちなみに、bass.dll は、Vox.dll と違って、ogg のループ再生もちゃんと鳴らしてくれる。Vox.dll で再生するとループする時に変な聞こえ方になるけれど、bass.dll は滑らかに(?)ループする。
ただ、bass.dll の商用利用はライセンス料がかかるので注意…。無料で公開する何かしらに添付して使う分にはライセンス料はかからないけれど、おそらく同人ソフトを作って販売する、といった場合にはライセンス料を払うことになるのではないかなと…。たぶん。
◎ 2021/08/18追記。 :
Bass.rb の一部の記述でバグってたので修正。
[ ツッコむ ]
#2 [ruby] Ruby の fiddle がDLLをロードしてくれない
Ruby の fiddle が DLL をロードしてくれない問題に遭遇して悩んでいたり。コレってバグなの? それとも仕様なの?
◎ 経緯。 :
Ruby でサウンドファイルを再生できるらしい、sfml-audio-fiddle という拡張ライブラリを見かけて、試用してみたいと思ったのですけど。
_sfml-audio-fiddleの紹介 - Qiita
_sfml-audio-fiddle | RubyGems.org | コミュニティのGemホスティングサービス
_bggd/sfml-audio-fiddle: fiddle(ruby's FFI) binding for SFML2 Audio functions.
_CSFML (SFML / Download / Bindings)
Windows10 x64 21H1 + Ruby 2.6.8 x86, 2.7.4 x86, 3.0.2 x86 上で動作確認。gem でインストール。
しかし、require "sfml/audio" しただけでエラーが出てしまって。csfml-audio-2.dll 2.5.1 は、Rubyスクリプトと同じ場所に置いてある状態。
これが Ruby 2.3.3 x86 上なら、require "sfml/audio" してもエラーが出ない…。今時の Ruby (2.6.8, 2.7.4, 3.0.2) ではエラーが出る。
どうして今時の Ruby + fiddle は、カレントディレクトリに置いてある DLL がロードできないのだろうと…。セキュリティ関係の何かであえて読み込めない仕様にしてあるとか?
_sfml-audio-fiddleの紹介 - Qiita
_sfml-audio-fiddle | RubyGems.org | コミュニティのGemホスティングサービス
_bggd/sfml-audio-fiddle: fiddle(ruby's FFI) binding for SFML2 Audio functions.
_CSFML (SFML / Download / Bindings)
Windows10 x64 21H1 + Ruby 2.6.8 x86, 2.7.4 x86, 3.0.2 x86 上で動作確認。gem でインストール。
gem install sfml-audio-fiddle
しかし、require "sfml/audio" しただけでエラーが出てしまって。csfml-audio-2.dll 2.5.1 は、Rubyスクリプトと同じ場所に置いてある状態。
これが Ruby 2.3.3 x86 上なら、require "sfml/audio" してもエラーが出ない…。今時の Ruby (2.6.8, 2.7.4, 3.0.2) ではエラーが出る。
どうして今時の Ruby + fiddle は、カレントディレクトリに置いてある DLL がロードできないのだろうと…。セキュリティ関係の何かであえて読み込めない仕様にしてあるとか?
◎ 関連してるかもしれない情報をメモ。 :
環境変数 RUBY_DLL_PATH とか、関数 add_dll_directory が関係するかも、みたいな話も見かけたのでメモ。
_Windows の Ruby の fiddle で lib○○.dll が読み込めない時、何をチェックすればよいでしょうか? - スタック・オーバーフロー
_How can I load Windows DLL files with Ruby fiddle? - Stack Overflow
_For gem developers - oneclick/rubyinstaller2 Wiki
_Windows の Ruby の fiddle で lib○○.dll が読み込めない時、何をチェックすればよいでしょうか? - スタック・オーバーフロー
_How can I load Windows DLL files with Ruby fiddle? - Stack Overflow
_For gem developers - oneclick/rubyinstaller2 Wiki
◎ 色々試してみた。 :
Windows版の Ruby において、DLLを検索するパスは、環境変数PATHとは一致してないらしい…。一応、DLL検索パスを変更する手もあるらしいけど…。
方法その1。RubyInstaller::Runtime.add_dll_directory() を使うことで、DLLの検索パスを追加できるらしいので試してみた。
_01_require_sfml_audio.rb
方法その2。Windows API の SetDllDirectory() を使ってDLLの検索パスを指定することもできるらしい。これも試してみた。
_02_require_sfml_audio2.rb
方法その3。sfml-audio-fiddle の audio.rb をカレントディレクトリにコピーして、dlload のあたりで絶対パスを指定するように修正して試してみたりもした。
_03_require_sfml_audio3.rb
_sfmlaudio.rb
しかし、どの方法でもエラーが出る…。
方法その1。RubyInstaller::Runtime.add_dll_directory() を使うことで、DLLの検索パスを追加できるらしいので試してみた。
_01_require_sfml_audio.rb
puts "env RUBY_DLL_PATH = #{ENV["RUBY_DLL_PATH"]}" my_dll_dir_path = File.expand_path("..", __FILE__) puts "my_dll_dir_path = #{my_dll_dir_path}" RubyInstaller::Runtime.add_dll_directory(my_dll_dir_path) require "sfml/audio"
方法その2。Windows API の SetDllDirectory() を使ってDLLの検索パスを指定することもできるらしい。これも試してみた。
_02_require_sfml_audio2.rb
require 'fiddle/import' require 'fiddle/types' module WinAPI extend Fiddle::Importer dlload 'kernel32.dll' include Fiddle::Win32Types extern 'int SetDllDirectory(LPCSTR)' end my_dll_dir_path = File.expand_path("..", __FILE__) WinAPI.SetDllDirectory(my_dll_dir_path) require "sfml/audio"
方法その3。sfml-audio-fiddle の audio.rb をカレントディレクトリにコピーして、dlload のあたりで絶対パスを指定するように修正して試してみたりもした。
_03_require_sfml_audio3.rb
require_relative "sfmlaudio"
_sfmlaudio.rb
しかし、どの方法でもエラーが出る…。
◎ CSFMLのバージョンも関係していたらしい。 :
Ruby 2.3.3 ではエラーが出なかったから、てっきり CSFML の .dll のバージョンは合っているのだろうと思い込んでいたけど、試しに色々変えてみたらバージョンによってエラーが出たり出なかったりすることに気づいた。
利用できるDLLのバージョンと、利用できないDLLのバージョンがあるっぽいな…。
ただ、前述の方法でDLL検索パスを変更しないと、どのみちエラーが出る…。
- CSFML 2.0 32bit (csfml-audio-2.dll, libsndfile-1.dll, openal32.dll) : エラーが出ない。
- CSFML 2.1 32bit (csfml-audio-2.dll, libsndfile-1.dll, openal32.dll) : エラーが出ない。
- CSFML 2.2 32bit (csfml-audio-2.dll, libsndfile-1.dll, openal32.dll) : エラーが出る。
- CSFML 2.5.1 32bit (csfml-audio-2.dll) : エラーが出る。
利用できるDLLのバージョンと、利用できないDLLのバージョンがあるっぽいな…。
ただ、前述の方法でDLL検索パスを変更しないと、どのみちエラーが出る…。
[ ツッコむ ]
以上、1 日分です。