OpenAL 问题 - 改变源增益

2024-05-02

我最近一直致力于将我的游戏移植到跨平台,并决定使用 OpenAL 作为我的跨平台音频引擎。

我有 16 个“通道”(OpenAL 源),可以同时播放最多 16 个声音。为了播放声音,我切换哪个缓冲区链接到给定的源,并设置增益、源位置等,以便在给定的“通道”(源)中播放声音。

问题是,我注意到我的“增益”设置似乎没有立即生效。例如,如果在给定源中以 0.5 增益播放响亮的“闪电”声音,那么当我稍后以 0.15 增益播放按钮单击声音时,此单击开始时声音太大。然后,每次播放时,音量都会减小,直到第 3 次或第 4 次点击时,听起来像是在正确的 0.15 增益左右。

第一次按钮点击声几乎听不见,而且音量似乎在逐渐增大,直到达到 0.15 增益。

简而言之,“源”似乎会记住以前的增益设置,即使我在同一源中播放新声音之前重置这些设置!这是一个错误吗?或者我对 OpenAL 有什么不明白的地方?如何让它“立即”更改为新的增益/位置设置?

播放声音的相关代码:

[Channel 是 0 到 15 之间的值,soundID 是 gBuffer 数组中的有效索引,stereoPosition 是 -255 到 255 之间的整数,volume 是 0 到 255 之间的值。这是来自一个函数,该函数是我的游戏的包装器用于使用 0-255 之间的值,因此它将这些值转换为正确的 OpenAL 值。]

    // Stop any sound currently playing in this channel ("source")
alSourceStop( gSource[channel] );

    // What sound effect ("buffer") is currently linked with this channel? (Even if not currently playing)
alGetSourcei( gSource[channel], AL_BUFFER, &curBuffer );

    // attach a different buffer (sound effect) to the source (channel) only if it's different than the previously-attached one.
    // (Avoid error code by changing it only if it's different)
if (curBuffer != gBuffer[soundID])  
    alSourcei( gSource[channel], AL_BUFFER, gBuffer[soundID] );

    // Loop the sound?
alSourcei( gSource[channel], AL_LOOPING, (loopType == kLoopForever)  );

    // For OpenAL, we do this BEFORE starting the sound effect, to avoid sudden changes a split second after it starts!
volume = (volume / 2) + 1;  // Convert from 0-255 to 0-128

{
    float sourcePos[3] = {(float)stereoPosition / 50, 0.0, 2.0};

        // Set Source Position
    alSourcefv( gSource[channelNum], AL_POSITION, sourcePos );  // fv = float vector

        // Set source volume
    alSourcef( gSource[channelNum], AL_GAIN, (float)newVolume / 255 );
}

    // Start playing the sound!
alSourcePlay( gSource[channel] );

如果需要的话,我也可以发布设置代码,但没什么特别的。只是打电话

alSourcef( gSource[n], AL_REFERENCE_DISTANCE, 5.0f );

对于每个来源。


我们在设置 ByteOffset 以在样本中查找位置时遇到了同样的问题,现在找到了让它工作的解决方案:

只是总是删除并重新创建源在对其设置任何参数之前。

因此,如果您想更改增益和/或其他参数:

  • OpenAL.AL.DeleteSource(oldSourceID);
  • newSourceId = OpenAL.AL.GenSource();
  • OpenAL.AL.Source(newSourceId , OpenTK.Audio.OpenAL.ALSourcef.Gain, yourVolume);
  • OpenAL.AL.Source(newSourceId , OpenTK.Audio.OpenAL.ALSourcef.xxx, yourOtherParameter);

希望它对你有用,并在 10 年后终于找到解决方法:-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenAL 问题 - 改变源增益 的相关文章

  • android 如何延迟执行

    我正在构建一款具有人工智能功能的安卓棋盘游戏 AI 轮流执行 必须调用一系列操作 然后将无效信息发布到我的自定义视图中进行更新 我需要放慢这些动作的速度 以便用户能够看到人工智能正在轮到它 而不是它一闪而过 我已经尝试过一些类似的事情 tr
  • Objective-C 复制视图

    所以我在这里有一个简短的问题 我有一个视图控制器对象的实例 让我们调用它viewCon1 并且它上面放置了几个子视图 每个子视图都具有独特的属性 让我们称呼他们吧sub1 sub2 and sub3 现在 我以编程方式添加每个子视图 执行以

随机推荐

  • 每次加载解决方案时,所有项目引用都有黄色三角形

    我的所有项目 来自同一解决方案 引用都标有黄色三角形 这些项目都设置为相同的 NET 版本 4 5 1 错误日志说 无法引用项目 CommonLibrary 暂时解决该问题的方法是 删除并重新添加引用 右键单击并选择 添加服务引用 并立即取
  • 如何使用VerQueryValue?

    我有一个 exe 需要从特定 dll 检索版本信息 例如 FileDescription 我的代码已经调用了 GetFileVersionInfoSize 和 GetFileVersionInfo 但我不知道如何应用 VerQueryVal
  • 检查argc的值[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我对传递给程序的 argc 数量有疑
  • 保护客户端 API 的安全

    我正在为基于 JavaScript 的游戏构建服务器端 API 和客户端库 其中必须确保两个非常重要的功能的安全 用户每次游玩都必须扣款 我们必须确保提交的分数是玩家实际获得的分数 解决第一个问题看起来很简单 在每次游戏开始时 我们都会调用
  • Firebase JS 错误:getToken 由于令牌更改而中止

    我收到 Firebase 错误 错误 getToken 由于令牌更改而中止 使用 JavaScript 库运行 Firestore 事务时 错误不会每次都会抛出 而且我找不到模式 我想我已经在某处实现了一些竞争条件 我的应用程序中的用户流程
  • FFmpeg - H264 编码器找不到有效设备并且无法配置编码器

    我尝试使用 H264 编码器进行编码 但是当我这样做时 出现以下错误 h264 v4l2m2m 0x55682d2416c0 Could not find a valid device h264 v4l2m2m 0x55682d2416c0
  • java.lang.NoSuchMethodError:org.glassfish.hk2.api.ServiceLocatorFactory.create

    Error java lang NoSuchMethodError org glassfish hk2 api ServiceLocatorFactory create Ljava lang String Lorg glassfish hk
  • 如果菜单项超过 90 个菜单项的限制,Wordpress 将删除我的菜单项 -

    我想在我的菜单中添加更多项目 我的菜单在 WordPress 菜单 管理 中至少包含 90 个项目 我想添加更多项目 但发现其他项目会自动删除 有什么解决办法吗 很有可能 但不是 100 这是 PHP 限制 而不是 WP 您可以通过查看 p
  • 如何在Conky中实现一个基本的Lua功能?

    我正在尝试向我的 Conky 添加一个函数 该函数打印字符串的长度以用于调试目的 代码位于名为的文件内test lua 非常简单 function test word return string len word end 我这样加载它 在我
  • 此版本的渲染库比您的 ADT 插件版本更新。请更新ADT插件 - 已经更新

    在 Eclipse 上 尽管我使用的是最新的 adt 版本 但我收到此错误 我不确定它是否相关 但这发生在我安装 android m sdk 之后 从这里 https stackoverflow com a 30535515 933050
  • Express.js req.ip 正在返回 ::ffff:127.0.0.1

    我目前正在尝试获取所请求用户的IP 问题是IP正在返回 ffff 127 0 0 1代替127 0 0 1 我尝试使用trusted proxy选项 尽管不使用代理 和req ips是空白的 使用 4 x Express js router
  • 如何使用 Sencha Touch 数据模型读取嵌套 JSON 结构?

    我整个晚上都在试图解决这个问题 但没有成功 我有一个 JSON 结构如下 来自另一个系统 所以我无法更改其结构 parents parent parentId 1 children child childId 1 ch
  • 如何仅使用物理 wsdl 文件生成服务引用

    我多年来一直在创建和使用 Web 服务 并且始终能够使用 Visual Studio 从客户端创建服务引用 我需要使用第三方服务 但他们拒绝打开其安全性 以便我可以查看 wsdl 并进行服务引用 这是一项面向公众的服务 因此我认为不需要这种
  • ruby - 数组元素之间的排列

    我正在使用 ruby 在 Google Sketchup 中编写一个插件 在尝试排列数组中存在的两个数组时遇到了一个真正的问题 所有这些都取决于用户组合 我有一个数组数组 例如 1 lol so 当我们有这样的组合 1 2 3 没关系 它应
  • R:在组上应用函数

    我希望将函数应用于数据框 然后将该函数的结果存储在数据框中的新列中 这是我的数据框 tradeData 的示例 Login AL Diff a 1 0 a 1 0 a 1 0 a 0 1 a 0 0 a 0 0 a 0 0 a 1 1 a
  • 被调用的函数在被调用后如何返回给调用者?

    我读到 当程序进行函数调用时 被调用的函数必须知道如何返回其调用者 我的问题是 被调用的函数如何知道如何返回其调用者 是否有一种机制通过编译器在幕后工作 编译器遵循特定的 调用约定 该约定定义为您所针对的 ABI 的一部分 该调用约定将包括
  • Python - 如何将双引号附加到字符串并存储为新字符串?

    我正在使用 Python 2 6 并且想将双引号附加到字符串并将其存储为新的字符串变量 我不想打印它 但稍后在我的 python 脚本中使用它 例如 a apple b some function a gt b would be equal
  • 选择预先选择多个值的标签 - 在数据库中手动插入的值

    我需要在 select tag 中预先选择多个值 但我在空缺表中 手动 添加空缺 如下所示 我的控制器 def create hr curriculum generic HrCurriculumGeneric new params hr c
  • 为什么线性布局 maxHeight 不起作用?

    这是我的布局 我在线性布局上设置了最大和最小高度 但最大高度似乎不起作用 事实上如果TextView R id testo有很多文本 不会被修剪 如果我设置固定高度 则不会发生这种情况 但我不想设置固定高度 以便在选择溢出屏幕模式时正确调整
  • OpenAL 问题 - 改变源增益

    我最近一直致力于将我的游戏移植到跨平台 并决定使用 OpenAL 作为我的跨平台音频引擎 我有 16 个 通道 OpenAL 源 可以同时播放最多 16 个声音 为了播放声音 我切换哪个缓冲区链接到给定的源 并设置增益 源位置等 以便在给定