2021/08/18(水) [n年前の日記]
#1 [dxruby][ruby] DXRubyでogg再生するためにvAudio.dllのラッパーを書いてみた
Windows版 Ruby + DXRuby で ogg再生するために、vAudio.dll のラッパーを書いてみたので、アップロードしてみる。
ogg, mp3, wav等を再生できるDLL、vAudio.dll は、以下から入手できる。現時点では、vAudio-3.0.2.zip を入手可能。解凍すると、中に vAudio.dll が入ってるのでソレを使う。
_vAudioの詳細情報 : Vector ソフトを探す!
vAudio.dll を Ruby から使うためのラッパー、VAudio.rb は以下。
_VAudio.rb
一応、関連ファイルを全部zipにまとめて置いておきます。
_vaudiorb_20210818.zip
ogg, mp3, wav等を再生できるDLL、vAudio.dll は、以下から入手できる。現時点では、vAudio-3.0.2.zip を入手可能。解凍すると、中に vAudio.dll が入ってるのでソレを使う。
_vAudioの詳細情報 : Vector ソフトを探す!
vAudio.dll を Ruby から使うためのラッパー、VAudio.rb は以下。
_VAudio.rb
一応、関連ファイルを全部zipにまとめて置いておきます。
_vaudiorb_20210818.zip
◎ 概要。 :
_readme.md
から抜粋。
vAuido.dll + VAudio.rb と、voxrb (Vox.dll)、bassrb (bass.dll)、Ayame/Ruby (Ayame.dll) を比較した場合のメリットは以下になります。
逆に、デメリットは以下になります。
- vAudio.dll を使うと、ogg, mp3, wav等を再生できます。
- vAudio.dll + VAudio.rb を使うと、Windows版 Ruby で ogg や mp3 を再生できます。
- Ruby の fiddle を使って、vAudio.dll の機能を呼び出しています。
- DXRuby と組み合わせて使うことを前提にして作成しました。
vAuido.dll + VAudio.rb と、voxrb (Vox.dll)、bassrb (bass.dll)、Ayame/Ruby (Ayame.dll) を比較した場合のメリットは以下になります。
- Vox.dll と違って、ちゃんとループ再生される。
- bass.dll と違って、商用利用時もライセンス料がかからない。
- Ayame/Ruby と違って、Rubyのバージョンが変わるたびにビルドし直さなくても動く。
- ループポイントの指定ができるので、イントロ+ループ部分で構成されたサウンドデータをループ再生できる。
逆に、デメリットは以下になります。
- 扱える波形サウンドデータは、44.1kHz, 16bit, 2ch(ステレオ) (CD音質) のみ。
◎ 動作確認環境。 :
- Windows10 x64 21H1
- Ruby 2.3.3 p222 [i386-mingw32] + DXRuby 1.4.6 x86
- Ruby 2.6.8 p205 [i386-mingw32] + DXRuby 1.4.7 x86
- Ruby 2.7.4 p191 [i386-mingw32] + DXRuby 1.4.7 x86
- Ruby 3.0.2 p107 [i386-mingw32] + DXRuby 1.4.7 x86
- vAudio.dll 3.0.2
◎ 使い方。 :
使い方は、vAudio.dll と VAudio.rb を、利用したいスクリプトと同じフォルダに置いて、以下のような感じで使う。
_01_play_stream.rb
テストに使った ogg は以下。
_loop_bgm.ogg
もっと色々な機能(パン変更、音量変更、ループポイントの指定等)を使ったサンプルは以下。
_03_play_stream2.rb
_01_play_stream.rb
require "dxruby" require_relative "VAudio" VAudio.init(Window.hWnd) # init vAudio s = VAudio.loadStream("loop_bgm.ogg") # load ogg s.setRepeat(true) # loop enable s.play Window.loop do break if Input.keyPush?(K_ESCAPE) end s.free VAudio.free
テストに使った ogg は以下。
_loop_bgm.ogg
もっと色々な機能(パン変更、音量変更、ループポイントの指定等)を使ったサンプルは以下。
_03_play_stream2.rb
◎ ライセンスについて。 :
自分(mieki256)が書いた VAudio.rb については、Public Domain / CC0 ってことで。
vAudio.dll は、フリーウェアとの記述があった。以下、vAudioHelp.chm から引用。
vAudio.dll は、フリーウェアとの記述があった。以下、vAudioHelp.chm から引用。
使用制限など
vAudioはフリーウェアです。
vAudio.dll自体を商品として売るような行為や著作権を侵害するような行為は禁止とします。
その他は特に制限はありません。
趣味でも商用でも使ってください。
著作権表示など
vAudioの著作権はHolyWingsが保持しています。
vAudio自体に著作権の表示義務はありませんが、
vAudioを使用してOgg Vorbis、MP3、FLAC形式のファイルを再生する場合は
以下の著作権表示を配布するテキストファイル等に含めてください。
--------------------------------------------------------------------------------
vAudio.dll incudes the mpglib, libogg , libvorbis and libFlac.
mpglib Copyright(c) 2004 Michael Hipp.
libogg Copyright (c) 2002, Xiph.org Foundation.
libvorbis Copyright (c) 2002-2008 Xiph.org Foundation.
libFlac Copyright (c) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson
Thanks for creating the useful library!
◎ 雑感。 :
とりあえず、これで、今時の Ruby (2.6.x, 2.7.x, 3.0.x, 32bit版) + DXRuby でも、oggを再生可能になったかなと…。fiddle を使って機能を呼び出しているから、Ruby のバージョンが違ってもビルドし直さなくて済むだろうし、ラッパーはRubyスクリプトだから、不具合が出た場合も改造は容易のはず…。
vAudio.dll の作者様、ありがとう…。
vAudio.dll の作者様、ありがとう…。
◎ 余談。ポインタを使って戻り値を得るソレ。 :
C言語の関数は、複数の戻り値を得ることができないので、もし、複数の戻り値が欲しいなら、一般的には、ポインタを引数として渡して、そのポインタを使って値を入れて取得する、といったことをするわけだけど。
例えば、以下のような感じで…。
Ruby の fiddle を使って、そういう形の戻り値を得るにはどうしたらいいのか悩んでしまった。
ググってみたら、以下のページで解説されてた。ありがたや。
_参照先を更新する関数をPython/Rubyのffiで扱うには - ローファイ日記
Fiddle::Pointer.malloc() を使ってデータ型に対応したサイズの領域を確保、かつ、ポインタを得て、それを引数として渡して、unpack() で目的のデータ型に変換して取得すればいいらしい。
ただ、配列として得られるので、実際は以下のような書き方になるのかなと。
こんな感じの書き方で、一応それらしく動いてるように見えたので、これで合ってるっぽい。たぶん。
それにしても、Ruby の fiddle の使用例がググってみてもなかなか出てこない。Google の検索精度が悪化してるのか、それとも fiddle を使った事例が少ないのか…。
例えば、以下のような感じで…。
BOOL vAudioGetVolume( int AudioHandle , double* pVolume );pVolume が double型のポインタで…。この関数を呼ぶと、処理の成功失敗を BOOL で返してきつつ、現在のボリューム値は pVolume に入れて戻ってくる。みたいな。
Ruby の fiddle を使って、そういう形の戻り値を得るにはどうしたらいいのか悩んでしまった。
ググってみたら、以下のページで解説されてた。ありがたや。
_参照先を更新する関数をPython/Rubyのffiで扱うには - ローファイ日記
i = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT) p CLib.update_int(i) p i[0, i.size].unpack("i!")
Fiddle::Pointer.malloc() を使ってデータ型に対応したサイズの領域を確保、かつ、ポインタを得て、それを引数として渡して、unpack() で目的のデータ型に変換して取得すればいいらしい。
ただ、配列として得られるので、実際は以下のような書き方になるのかなと。
v = i[0, i.size].unpack("i!")[0]
こんな感じの書き方で、一応それらしく動いてるように見えたので、これで合ってるっぽい。たぶん。
それにしても、Ruby の fiddle の使用例がググってみてもなかなか出てこない。Google の検索精度が悪化してるのか、それとも fiddle を使った事例が少ないのか…。
[ ツッコむ ]
以上です。