设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2116|回复: 17

[讨论] 【关于Audio模块】有没有可能让它更智能一些?

[复制链接]

Lv5.捕梦者

梦石
16
星屑
6946
在线时间
245 小时
注册时间
2020-12-4
帖子
306

极短23获奖极短22获奖

发表于 2022-8-2 13:26:01 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 纯属小虫 于 2022-8-20 21:56 编辑

玩了很多华丽的画面效果之后,却发现自己在音乐方面的研究还是一片空白
甚至连简单的【改变音乐正在播放的时刻】都做不到

按下F1,搜索Audio,查看模块方法:

Audio 模块方法


可以发现,这个远古的老小可爱,只给了【播放】【停止】【淡出】三个指令
看来不是我不会拖动播放滑块,而是它没给啊!
(好吧,自己菜不能怪工具......)

一直想要做一个效果:
在BGM不更换的情况下,进入战斗或脱离战斗,地图BGM或战斗BGM能够从上次结束的位置继续播放
这样一来,在频繁战斗的情况下,就不会被两首BGM的开头疯狂洗脑了(有一种听起床铃的既视感)
如果BGM比较长的话,每次都从头播放...甚至游戏结束了都没听到过这首BGM之后的旋律,实在是尴尬...

这里想了一个实现这个效果的逻辑:
1、战斗开始时,记录当前【地图BGM】名称,当前【地图BGM】时刻
2、战斗开始时,播放【战斗BGM】,如果【战斗BGM】与被记录的【战斗BGM】名称相同,则从被记录的【战斗BGM】时刻开始播放
3、战斗结束时,记录【战斗BGM】名称,当前【战斗BGM】时刻
4、战斗结束时,播放【地图BGM】,如果【地图BGM】与被记录的【地图BGM】名称相同,则从被记录的【地图BGM】时刻开始播放

具体在脚本中实现方法如下:(该脚本已经作废)
拟写效果代码


可见,如果能够有 【获取当前播放BGM的时刻】 和 【将播放的BGM时刻移动至】 这两个Audio的方法的话,可能就可以实现这种效果了

害...可是要怎么解析Audio模块并为其添加新的方法呢...
欢迎各位大佬前来讨论




2022.08.20
可喜可贺! 制作出来一个能够实现上述功能的实例了!

工程范例:(附件太大没法上传)
链接:https://pan.baidu.com/s/1v1twJ6TkkNdSd41rzxc0yg?pwd=6666
提取码:6666
--来自百度网盘超级会员V6的分享

实际运用的实例脚本

API插件(需要搭配dll使用!)


音频拓展dll.zip (731.14 KB, 下载次数: 9)

评分

参与人数 1+1 收起 理由
89444640 + 1 塞糖

查看全部评分

Lv5.捕梦者

梦石
0
星屑
24057
在线时间
4983 小时
注册时间
2016-3-8
帖子
1613
发表于 2022-8-2 13:34:59 | 显示全部楼层
本帖最后由 alexncf125 于 2022-8-8 13:47 编辑

Audio.bgm_play(filename[, volume[, pitch[, pos]]])
开始播放 BGM。依次指定文件名、音量、音调和起始位置。
起始位置  只对 ogg 和 wav 有效。

Audio.bgm_pos
获取 BGM 的播放位置。只对 ogg 和 wav 有效。无效时返回 0。

点评

感激涕零!不过ogg、wav... TAT得批量转格式了!  发表于 2022-8-2 21:33
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23963
在线时间
3338 小时
注册时间
2011-7-8
帖子
3925

开拓者

发表于 2022-8-2 15:07:14 | 显示全部楼层
好的,马上在新runtime里加上这个功能

点评

很nice 我常用的都是MP3和wav ^.^  发表于 2022-8-3 10:16
mid不行,MP3应该可以  发表于 2022-8-2 22:23
如果还能对ogg wav之外的音频有效,那可谓普天同庆~  发表于 2022-8-2 22:10
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
6483
在线时间
119 小时
注册时间
2020-1-8
帖子
234
发表于 2022-8-19 18:20:12 | 显示全部楼层
RUBY 代码复制
  1. #=begin
  2. # fmod很强,API很多,但我对音频不了解,也不太关注,通常玩游戏都是静音的
  3. # 所以只写了很基(简)本(陋)的功能
  4.  
  5. # 文件格式为官方原文的网页翻译
  6. # - 支持内置超过 20 种音频格式
  7. # FMOD Core API 具有本机/内置代码,以支持许多开箱即用的文件格式。
  8. # 默认支持 WAV、MP3 和 Ogg Vorbis,但也支持更多模糊格式,如 AIFF、FLAC 等。
  9. # 包括使用实时音序器实时回放的音序格式。MIDI/MOD/S3M/XM/IT 就是这些例子。
  10.  
  11. # 尽管F12不会直接报错,但内存泄漏了,具体屏蔽F12方法论坛搜索
  12.  
  13. module FmodLite
  14.   # fmodLite.dll依赖的dll
  15.   # 方法1:预先手动LoadLibrary,fmod.dll可存放目录自由
  16.   Win32API.new('kernel32', 'LoadLibrary', 'P', 'L').call("fmod.dll")
  17.   # 方法2:fmod.dll与Game.exe同目录,可注释上一行代码
  18.  
  19.  
  20.   #—————————————————————————————————
  21.   # 适用于BGM/BGS,和 RMXP Audio 一样,窗口非激活也继续播放音频
  22.   # bug:API并没有太多的参数检查
  23.   # 基本:首先创建系统
  24.   #         创建单元(每个都是独立的,该音频持续期间保留该单元字符串)
  25.   #           api操作该单元
  26.   #             需手动结束该单元
  27.   #       最后释放系统(基本就是结束游戏了)
  28.   #—————————————————————————————————
  29.   dll = "fmodLite.dll"
  30.  
  31.   # 【系统相关】
  32.   # ◆创建系统
  33.   # 参数1:系统指针,至少4字节字符串;
  34.   # 参数2:Fmod的范围[0, 4095],可以理解为同时播放的单元数目;
  35.   Init  = Win32API.new(dll, 'fmod_init', 'PL', 'L')
  36.   # ◆释放系统
  37.   Close = Win32API.new(dll, 'fmod_close', 'V', 'V')
  38.  
  39.   # 【单元相关】
  40.   # ◆创建并播放
  41.   # 参数1:音频文件名;
  42.   # 参数2:节拍,100为正常;
  43.   # 参数3:音量,100为正常;
  44.   # 参数4:播放位置,单位毫秒,如果需要“音量淡入”,设为负值(0写为-1);
  45.   # 参数5:循环标志,0不循环,非0循环;
  46.   # 参数6:单元指针,个人定义的结构,至少12字节字符串;
  47.   Play = Win32API.new(dll, 'fmod_play', 'PLLLLP', 'L')
  48.   # ◆结束
  49.   # 参数1:单元指针,传其字符串即可;
  50.   Stop = Win32API.new(dll, 'fmod_stop', 'P', 'L')
  51.   # ◆淡出
  52.   # 参数1:单元指针,传其字符串即可;
  53.   # 参数2:淡出时间,单位毫秒;
  54.   Fade = Win32API.new(dll, 'fmod_fade', 'PL', 'L')
  55.   # ◆获取播放的时间位置,单位毫秒
  56.   # 参数1:单元指针,传其字符串即可;
  57.   Pos  = Win32API.new(dll, 'fmod_pos', 'P', 'L')
  58.  
  59.  
  60.   # 创建fmod_system
  61.   PPSys = "\0" * 4
  62.   Init.call(PPSys, 32)
  63.   PPSys.freeze
  64.  
  65.   #————————
  66.   # 读取RTP目录
  67.   #————————
  68.   ini, section, rtp_flag = "Game.ini", "[Game]", "RTP"
  69.   get_section, rtps = false, []
  70.  
  71.   File.open(ini).each_line do |line|
  72.     line.chop!
  73.     next if line.empty?
  74.     if line == section
  75.       get_section = true
  76.       next
  77.     end
  78.     next if get_section == false
  79.     rtps << line.split("=")[1] if line.include?(rtp_flag)
  80.   end
  81.  
  82.   rtps.uniq!
  83.   RTP = []
  84.   rtps.each do |i|
  85.     if i != nil
  86.       if i == "Standard"
  87.  
  88.         dll = "Advapi32.dll"
  89.         regOpenKeyExA = Win32API.new(dll, 'RegOpenKeyExA', 'LPLLP', 'L')
  90.         regCloseKey = Win32API.new(dll, 'RegCloseKey', 'L', 'L')
  91.         regQueryValueExA = Win32API.new(dll, 'RegQueryValueExA', 'LPLLPP', 'L')
  92.  
  93. sub_key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\RPGXP.exe"
  94.  
  95.         buf = "\0" * 4
  96.         # HKEY_LOCAL_MACHINE = 0x8000_0002
  97.         # KEY_READ  = 0x20019
  98.         regOpenKeyExA.call(0x8000_0002, sub_key, 0, 0x20019, buf)
  99.  
  100.         hKey = buf.unpack('L')[0]        
  101.         regQueryValueExA.call(hKey, nil, 0, 0, nil, buf)
  102.         path = "\0" * buf.unpack('L')[0]
  103.         regQueryValueExA.call(hKey, nil, 0, 0, path, buf)
  104.         regCloseKey.call(hKey)
  105.  
  106.         RTP << (File.dirname(path.chop!).gsub("\\", "/") << "/RGSS/Standard")
  107.       else
  108.         RTP << i if File.directory?(i)
  109.       end
  110.     end
  111.   end
  112.  
  113.   module_function
  114.  
  115.   # filename 是指相对路径 如 "Audio/BGM/abc"
  116.   # 编辑器保存的音乐文件名没有扩展名……( ̄_ ̄|||)
  117.  
  118.   def find_rtp_file(filename)
  119.     RTP.each do |path|
  120.       name = Dir["#{File.join(path, filename)}.**"][0]
  121.       return name if name != nil
  122.     end
  123.     return
  124.   end
  125.  
  126.   def get_file(filename)
  127.     name = Dir["#{filename}.**"][0]
  128.     name ||= find_rtp_file(filename)
  129.   end   
  130. end
  131.  
  132.  
  133. END {FmodLite::Close.call()}
  134.  
  135.  
  136. # 简单示例,这部分就自由发挥吧
  137. class << Audio
  138.  
  139.   @@bgm = "\0" * 12
  140.   @@bgm_file_name = ""
  141.  
  142.   def bgm_play(filename, volume = 100, pitch = 100, pos = 0, loop = 1)
  143.  
  144.     if filename == @@bgm_file_name
  145.       return
  146.     else
  147.       self.bgm_stop
  148.     end
  149.  
  150.     if (name = FmodLite.get_file(filename)) == nil
  151.       self.bgm_stop
  152.       return
  153.     end
  154.  
  155.     @@bgm_file_name = filename
  156.     FmodLite::Play.call(name, volume, pitch, pos, loop, @@bgm)
  157.   end
  158.  
  159.   def bgm_stop
  160.     return if @@bgm_file_name.empty?
  161.     FmodLite::Stop.call(@@bgm)
  162.     @@bgm_file_name = ""
  163.   end
  164.  
  165.   def bgm_fade(ms)
  166.     return if @@bgm_file_name.empty?
  167.     FmodLite::Fade.call(@@bgm, ms)
  168.   end
  169.  
  170.   def bgm_pos
  171.     return if @@bgm_file_name.empty?
  172.     FmodLite::Pos.call(@@bgm)
  173.   end
  174. end
  175. #=end

dll.zip

711.58 KB, 下载次数: 8

fmod.dll和fmodLite.dll

点评

不过好像有一个小瑕疵,就是播放ME的时候,不会像原RGSS那样暂停BGM  发表于 2022-8-20 14:55
好强大,居然支持这么多种音频,回头试试效果!  发表于 2022-8-19 18:59

评分

参与人数 2+2 收起 理由
89444640 + 1 精品文章
纯属小虫 + 1 塞糖

查看全部评分

回复 支持 1 反对 0

使用道具 举报

Lv5.捕梦者

梦石
16
星屑
6946
在线时间
245 小时
注册时间
2020-12-4
帖子
306

极短23获奖极短22获奖

 楼主| 发表于 2022-8-19 20:09:43 | 显示全部楼层
RPGzh500223 发表于 2022-8-19 18:20
#=begin
# fmod很强,API很多,但我对音频不了解,也不太关注,通常玩游戏都是静音的
# 所以只写了很基(简) ...

试了下,确实很强大!!!

MP3文件成功从中间开始播放
不过,有没有什么方法能够获取【当前播放的BGM的名称】以及【当前BGM所播放到的时刻】?

点评

感谢感谢!!!!!!!我要成功了!  发表于 2022-8-20 13:26
FmodLite::Pos就是当前播放时刻啊,至于名称你传参时保存一下不就行了吗,参考示例中@@bgm_file_name ……  发表于 2022-8-19 20:50
回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
16
星屑
6946
在线时间
245 小时
注册时间
2020-12-4
帖子
306

极短23获奖极短22获奖

 楼主| 发表于 2022-8-20 13:41:11 | 显示全部楼层
可喜可贺!!! 多亏了 RPGzh500223 的 API插件,终于实现了期待了一个月的效果!

具体的脚本和实现方法放在楼顶了

BGM在地图与战斗之间能够承接播放!
工程范例:(附件太大,没法上传,用百度链接了!)
链接:https://pan.baidu.com/s/1GBWJX_wgmr-Y6TP4sohXgQ?pwd=6666
提取码:6666
--来自百度网盘超级会员V6的分享

因为测试的场景太少,可能会有BUG,不过能用!
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
6483
在线时间
119 小时
注册时间
2020-1-8
帖子
234
发表于 2022-8-20 18:52:07 | 显示全部楼层
RUBY 代码复制
  1. module FmodLite
  2.   # ◆延迟以播放另一个音效
  3.   # 参数1:音效文件名;
  4.   # 参数2:节拍;
  5.   # 参数3:音量;
  6.   # 参数4:该音效的单元指针;
  7.   # 参数5:被延迟播放的单元指针;
  8.   PlayDelay = Win32API.new(dll, 'fmod_play_delay', 'PLLPP', 'L')
  9. end


没打算写成完整的Audio……前面就写明了适用于BGM/BGS
勉强模拟BGM时延迟以播放ME

fmodLite.zip

4.23 KB, 下载次数: 8

fmodLite.dll

点评

感谢!!!成功实现了!  发表于 2022-8-20 21:49

评分

参与人数 1+1 收起 理由
纯属小虫 + 1 塞糖

查看全部评分

回复 支持 反对

使用道具 举报

Lv5.捕梦者

梦石
0
星屑
33043
在线时间
10470 小时
注册时间
2009-3-15
帖子
4756
发表于 2022-8-20 21:03:48 | 显示全部楼层
本帖最后由 soulsaga 于 2022-8-21 10:20 编辑

用了第三方音频脚本F1设定关BGM等都没效了..

点评

想关bgm直接把音量变成0也行?  发表于 2022-8-22 21:58
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-3-29 16:14

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表