mieki256's diary



2014/12/24(水) [n年前の日記]

#1 [dxruby] DXRubyとAyameとイントロとループとスレッド

DXRuby は 60FPS でメインループが回っているけど、それより速い周期でループを回す部分を作って、そこでBGMの切り替えをしたら、自然に繋がってるように聞こえないかなと思えてきたので、Ruby の Thread とやらを使って試してみたりして。

_bgmloop2.rb
require 'dxruby'
require_relative 'ayame'

if true
  bgm_intro = Ayame.new('test58intro.ogg')
  bgm_loop = Ayame.new('test58loop.ogg')
  bgm_intro_time = 6.888
else
  bgm_intro = Ayame.new('test59intro.ogg')
  bgm_loop = Ayame.new('test59loop.ogg')
  bgm_intro_time = 13.714
end


bgm_intro.predecode
bgm_loop.predecode

intro_time = 0
bgm_step = 0

# BGM処理用スレッド
t = Thread.new do
  loop do
    case bgm_step
    when 0
      # イントロ再生開始の指示待ち
      nil

    when 1
      # イントロ再生開始
      bgm_intro.play(1, 0)
      intro_time = Time.now.to_f
      bgm_step = 2

    when 2
      # イントロ再生終了待ち
      if intro_time + bgm_intro_time < Time.now.to_f
        # loop BGM 再生開始
        bgm_loop.play(0, 0)
        bgm_step = 3
      end

    when 3
      # loop BGM再生中
      nil

    when 4
      # loop BGM停止
      bgm_loop.stop(1)
      bgm_step = 0

    when 5
      break
    end

    Ayame.update
    sleep(0.001)
  end

  bgm_intro.stop
  bgm_intro.dispose

  bgm_loop.stop
  bgm_loop.dispose
end

fnt = Font.new(24)
Window.loop do
  break if Input.keyPush?(K_ESCAPE)

  if Input.keyPush?(K_Z)
    if bgm_step <= 0
      # BGMを再生していないので、イントロ再生開始
      bgm_step = 1
    elsif bgm_step == 3
      # loop BGM 再生中なので停止する
      bgm_step = 4
    end
  end

  if bgm_step >= 0
    msg = [
      "z : start intro",
      "    intro play start",
      "    intro playing",
      "z : stop loop bgm",
      "    loop BGM stop"
    ]
    Window.drawFont(8, 8, msg[bgm_step], fnt)
  end

end

bgm_step = 5
t.join

試してはみたものの、違いが分からない…。元の ogg の作りがマズいのだろうか。

別スレッド内で Ayame.update を呼んじゃってるけど、これってアリなのかな…。勝手な想像では、おそらく Ayame.update が音の再生開始等の処理も担っていて、となるとメインループ内に Ayame.update を置いておくと再生開始タイミングも 60fps になってしまって意味が無いのではないか、と思って別スレッド内に置いてガンガン呼びまくるようにしてみたのだけど。ちなみにこの状態でも、フェードアウト等の秒数指定は、指定通りに動いてるように聞こえた。

ていうか、メインループ内でBGMを切り替えるやり方も、切り替え時にビミョーにずれてるとは気付かれないのではないか、てな気分になってきたり。何度も聞いてるうちに、よくわからなくなってきた…。

sleepの精度が分からない。 :

Ruby で Thread を使って sleep(秒数) でループを回すソレは、環境によってどうなるか不明という話もあるそうで。

Ruby の sleep() は小数点以下も指定できるので、ミリ秒(ms)単位でもsleepできるように思えるけれど、OSによってsleepできる精度? 分解能? が違ってるそうで。Windows NT の場合、sleep が 10ms の精度?だから、それより小さい値を指定しても意味が無い、という話も見かけた。 しかし、XP、Vista、7、8 とWindowsのバージョンが上がった際に、そのあたり何の変更も無かったのかな、改善されてたりしないのかな、という疑問も。

調べてみたら、Windows の場合、時間を測る仕様は3種類ほどあるらしく。

_QueryPerformanceCounterを実時間計測には使えない - 音宮志久の日々の考え

マルチメディアタイマーとやらを使えば 1ms 単位で測定できるらしいから、もし、Windows版の Ruby がそのあたりを使ってたら、昔と違って 1ms の精度で sleep できたりするのかも、と素人考えで思ったりもしたけど、そのへんの実装に何か変化があったのかどうかも分からない状態で。

ひとまず上のソースで、sleep(0.001) を sleep(0.0005) にしてみたら、CPU使用率が急激に上昇したので、指定値が何かしらの形で反映されてる、ような気もする。

曲データの作り方でも誤魔化せそう。 :

例えばだけど、イントロ部分の最後で、
  • シンバル? クラッシュライド? を「バシャーン(シャンシャンシャン…)」と鳴らしてる上にループ部分を載せてみたり
  • ドラムだけ叩いて「ダダダダダッ、ダンッ…(シーン)…」と意図的に無音部分を作ったり
  • Glitch でテンポを崩したり
等をすれば、繋がりが誤魔化せるんじゃないのか、とも。

以上です。

過去ログ表示

Prev - 2014/12 - 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