mieki256's diary



2021/08/16(月) [n年前の日記]

#1 [ruby] Ruby の sfml-audio-fiddle が動かない

Rubyでogg再生ができるらしい拡張ライブラリ、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.

環境は以下。

インストール方法。 :

念のためにインストール方法をメモしておく。

gem でインストールできる。
gem install sfml-audio-fiddle

動作には CSFML の DLL も必要。以下のサイトから入手する。32bit版と64bit版があるので、使ってる Ruby に合わせる。

_CSFML (SFML / Download / Bindings)
_SFML/CSFML: Official binding of SFML for C

zipをダウンロードして解凍。

bin/ の中に入っている .dll を、スクリプトと同じ場所に置くらしい。
  • csfml-audio-2.dll
  • openal32.dll
  • libsndfile-1.dll ... 解説ページには記載が無いが、ファイル名からして必要になりそうな…。

requireしただけでエラーを出す問題。 :

require "sfml/audio" をしてから使うライブラリだけど、require しただけでエラーを出してしまう。

> irb

irb(main):001:0> RUBY_VERSION
=> "2.6.8"

irb(main):002:0> require "sfml/audio"
Traceback (most recent call last):
        21: from C:/Ruby/Ruby26-x86/bin/irb:23:in `<main>'
        20: from C:/Ruby/Ruby26-x86/bin/irb:23:in `load'
        19: from C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/irb-1.3.6/exe/irb:11:in `<top (required)>'
         2: from (irb):2:in `<main>'
         1: from C:/Ruby/Ruby26-x86/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:85:in `require'
C:/Ruby/Ruby26-x86/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:85:in `require': cannot load such file -- sfml/audio (LoadError)
        30: from C:/Ruby/Ruby26-x86/bin/irb:23:in `<main>'
        29: from C:/Ruby/Ruby26-x86/bin/irb:23:in `load'
        28: from C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/irb-1.3.6/exe/irb:11:in `<top (required)>'
        11: from (irb):2:in `<main>'
        10: from C:/Ruby/Ruby26-x86/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:149:in `require'
         9: from C:/Ruby/Ruby26-x86/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:160:in `rescue in require'
         8: from C:/Ruby/Ruby26-x86/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:160:in `require'
         7: from C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:4:in `<top (required)>'
         6: from C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:6:in `<module:SFMLImporter>'
         5: from C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle/import.rb:77:in `dlload'
         4: from C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle/import.rb:77:in `collect'
         3: from C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle/import.rb:87:in `block in dlload'
         2: from C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle.rb:47:in `dlopen'
         1: from C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle.rb:47:in `new'
C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle.rb:47:in `initialize': No such file or directory (Fiddle::DLError)
        28: from C:/Ruby/Ruby26-x86/bin/irb:23:in `<main>'
        27: from C:/Ruby/Ruby26-x86/bin/irb:23:in `load'
        26: from C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/irb-1.3.6/exe/irb:11:in `<top (required)>'
         9: from (irb):2:in `<main>'
         8: from C:/Ruby/Ruby26-x86/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:149:in `require'
         7: from C:/Ruby/Ruby26-x86/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:160:in `rescue in require'
         6: from C:/Ruby/Ruby26-x86/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:160:in `require'
         5: from C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:4:in `<top (required)>'
         4: from C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:6:in `<module:SFMLImporter>'
         3: from C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle/import.rb:77:in `dlload'
         2: from C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle/import.rb:77:in `collect'
         1: from C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle/import.rb:86:in `block in dlload'
C:/Ruby/Ruby26-x86/lib/ruby/2.6.0/fiddle/import.rb:89:in `rescue in block in dlload': can't load csfml-audio-2 (Fiddle::DLError)
irb(main):003:0>

問題点は2つありそう。

一つは、DLL検索パスの問題。どうやら今時の Ruby の fiddle は、スクリプトが置いてあるディレクトリ/カレントディレクトリに置いてある .dll を探してくれない感じで…。Ruby 2.3.3 ならエラーが出ないけど、Ruby 2.6 以降はエラーになる。

もう一つは、CSFML の .dll のバージョンによってエラーが出る問題。DLL検索パスの問題を解決した状況下で試すと、以下のような結果になった。
  • CSFML 2.0, 2.1 の .dll は、require した際にエラーを出さなかった。
  • CSFML 2.2, 2.3, 2.4, 2.5.1 の .dll はエラーを出した。
利用できる CSFML のバージョンが限定されている気配がする。

DLL検索パスの問題は、以下のような記述をすることで解決できそう。

一つは、RubyInstaller::Runtime.add_dll_directory() を使ってDLL検索パスを指定する方法。
my_dll_dir_path = File.expand_path("..", __FILE__)
RubyInstaller::Runtime.add_dll_directory(my_dll_dir_path)

require "sfml/audio"

一つは、kernel32.dll の SetDllDirectory() を使ってDLL検索パスを指定する方法。
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"

あるいは、そもそも、ruby.exe が置いてある場所(C:\Ruby\bin\ 等)に関連DLLをコピーすることでもエラーは出なくなる。

ただ、こういう対策をしても、CSFML 2.2 以降の .dll を使うとエラーが出るのだけど…。

サウンドファイルを再生するとクラッシュする問題。 :

前述のDLL検索パスの問題を対策して require が通るようになったとしても、サウンドファイルを再生すると、再生が終わったタイミングで Segmentation fault が出てしまう。

例えば、以下のようなスクリプトを実行してみると…。

_04_ogg_play_music.rb
begin
  
  require 'sfml/audio'
  
rescue => e
  
  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'
  
end

music = SFML::Music.new("loop_bgm.ogg")
puts "Song length : #{music.get_duration} sec"
music.play
while music.get_status == :playing
  puts "playing"
  sleep 1
end

_loop_bgm.ogg

実行すると、再生が終わったあたりのタイミングで Segmentation fault になる。

C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:41: [BUG] Segmentation fault
ruby 2.6.8p205 (2021-07-07 revision 67951) [i386-mingw32]

-- Control frame information -----------------------------------------------
c:0004 p:---- s:0018 e:000017 CFUNC  :call
c:0003 p:0018 s:0013 e:000012 METHOD C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:41
c:0002 p:0013 s:0007 e:000006 BLOCK  C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:154 [FINISH]
c:0001 p:0000 s:0003 E:001d48 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:154:in `block in dtor'
C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:41:in `sfMusic_stop'
C:/Ruby/Ruby26-x86/lib/ruby/gems/2.6.0/gems/sfml-audio-fiddle-0.1.0/lib/sfml/audio.rb:41:in `call'

-- C level backtrace information -------------------------------------------
C:\Windows\SYSTEM32\ntdll.dll(NtWaitForSingleObject+0xc) [0x76ff29dc]
C:\Windows\System32\KERNELBASE.dll(WaitForSingleObject+0x12) [0x75031072]
C:\Ruby\Ruby26-x86\bin\msvcrt-ruby260.dll(rb_vm_bugreport+0x301) [0x665407a1]
C:\Windows\SYSTEM32\ntdll.dll(RtlCaptureStackContext+0x1bc43) [0x77024883]

-- Other runtime information -----------------------------------------------

* Loaded script: 04_ogg_play_music.rb
...
_stderr04.txt(全てのエラーメッセージ)

Music ではなく SoundBuffer を使ってみても…。

_05_ogg_play_soundbuffer.rb
begin
  
  require 'sfml/audio'
  
rescue => e
  
  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'
  
end

buffer = SFML::SoundBuffer.new 'loop_bgm.ogg'
sound = SFML::Sound.new buffer
sound.play
sleep buffer.get_duration + 1

結果は同じ。再生が終わったタイミングで Segmentation fault になる。

_stderr05.txt

Ruby 2.3.3, 2.6.8, 2.7.4, 3.0.2、どのバージョンで試しても Segmentation fault になる…。

雑感。 :

Ruby の fiddle を使うことで、Ruby のバージョンが変わるたびにバイナリをビルドしなくても済むメリットがありそう、などと思ってたけど、そもそも正常動作してくれないのではなあ、みたいな…。

#2 [anime][neta] HDDレコーダの空き容量が厳しい

HDDレコーダの電源を入れたら「録画できる空き容量が無くなりました」とメッセージが。厳しい。

仕方ないので、未視聴のまま溜め込んでた「東京リベンジャーズ」アニメ版の数話分を、見ないまま削除。かつ、録画予約も削除。

余談と言うか独り言。

件の作品は、アニメ版も人気があるとか、実写映画版はヒットしてるとか聞いたので、フツーに考えたらここまで見といて視聴を打ち切るのはアレだろうけど…。実によくできてるアニメだと思うし…。ただ、そもそも個人的に、不良だの珍走団だのが主人公の漫画やアニメって大嫌いで…。自分、校内暴力が吹き荒れてた時期に中学時代を送る羽目になった世代なので、あの手の人種は目にするのも嫌で嫌で…。アイツラ、リアルに母校の校舎を全焼させたりしてたから…。

それでも、放送されてるアニメはできる限り見ておかねばという奇妙な義務感とか、あるいは、キャラ設定なんてどうでもよくなるぐらい途中から面白くなったら勿体無いとか、そんな理由でここまで見てきたけど、それでもやっぱり見るのが苦痛で苦痛で…。自然と視聴も後回しになって、結局数話溜まって、HDDレコの空き容量確保しなきゃいけないからここは我慢してとにかく流そう的にBGV扱い+早見再生で無理矢理どうにか消化してる感じだったので…。これじゃMだよ。これでも頑張ったよね、俺。もうゴールしてもいいよね。みたいな。そのくらい嫌いなんですよ…不良や珍走団が主人公の作品って…。いやまあ、ちゃんと作ってあるアニメだよなと感心しながらチラ見してたんですけど…。

大体にして、途中で1回上手くいった感じになったのにまだ続くあたり、さては原作の人気が出て連載を引き延ばすための展開を用意したのかなと邪推しちゃったりもして…。もうつきあってらんねーよ。DBやワンピースを目指してだらだらずるずるといつまでも続けてればいいさ、てな感じの妙にやさぐれた気分になってきたりもして…。

そんな感じで、ここまで見てきたのに最後まで見れなくて残念という気持ちと、あの手のキャラをもう見なくて済むからこれでせいせいしたわい的な気持ちが入り混じった、ちょっと複雑な気分…。まあ、録画するための空き容量が無いんだから仕方ない…。どうしようもない…。今時のアニメの放送本数が多過ぎるんや…。いや、全部見ようと頑張っちゃうからおかしなことになるんだけど。

それにしても、ああいう展開の話がウケるなら、例えば「夏への扉」も一般層にウケるのでは、と思ってたら、そういう実写映画が…。そっちは全然ウケてないようで不思議。一体何が明暗を分けたのか…。

以上、1 日分です。

過去ログ表示

Prev - 2021/08 - Next
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project