【问题标题】:Scaling of integer values (from float)整数值的缩放(从浮点数)
【发布时间】:2011-01-27 14:56:12
【问题描述】:

我正在设计一个 VST 音频插件,它需要从输入信号中提取幅度数据,以用于 midi 域中的速度设置。

基本上,我将收到 0-1(float) 之间的值,需要将它们转换为 0-127 int。

目前的过程是将浮点值乘以 100,得到 +3 位小数的整数,即 103.4567685 或 005.6778787282

然后我将使用 floor() 函数将浮点数舍入为整数。

但是,这将使我的值介于 0-100 之间;但是,我需要将这些缩放到 0-127。

任何关于如何实现这一点的建议将不胜感激。

【问题讨论】:

    标签: c++ floating-point int scale midi


    【解决方案1】:

    如果您采用此处提出的一些建议并乘以 127,您会发现 127 在您的输出中并没有很好地表示。也许这对你来说不是问题,但有一个小小的改变会产生很大的不同。

    您可能认为四舍五入会有所帮助,但事实并非如此。 127 处的值数量仍将仅为其他值的一半,现在 0 处的值数量也将是平均值的一半。

    正确的公式:

    int amplitude = static_cast<int>(value * (128-epsilon)); // where epsilon is a very small floating point value
    

    【讨论】:

    • 你不能在不告诉可怜的 OP 如何获得 epsilon 的情况下给出这样的建议!
    • 100 对他来说似乎是可以接受的,所以 127 可能是/曾经是,但他可能没有想到或注意到这一点!
    • @TonyK,epsilon 的确切值对于大多数现实世界的应用程序来说并不是非常重要。您可以使用来自limits.hFLT_EPSILON 或来自limitsnumeric_limits&lt;float&gt;::epsilon(),或者只是一个任意小的数字。我不会使用numeric_limits&lt;double&gt;::epsilon(),因为它只对 1.0 的值有效,对于 128.0 来说太小了。
    • 你没有解决我的问题。 (请参阅我的回答以了解一些常识。)
    【解决方案2】:

    正确的做法是:

    int amplitude = 128 * value ;
    if (amplitude == 128) amplitude = 127 ;
    

    【讨论】:

    • TonyK 是对的。原因是 64 是 MIDI 的中心值,在 MIDI 设备中的实现通常使用上述方法。
    【解决方案3】:

    范围转换并不是那么简单。在缩放整数范围的情况下 [-n; n] 浮动,使用简单乘法的幼稚方法会产生这样的效果,即逆映射可能不会映射到原始值。假设您有整数范围内所有数字的集合,以及浮点范围内相同大小的集合,那么朴素映射不是双射的。

    http://kaba.hilvi.org/programming/range/index.htm有一篇关于这个和示例代码的好论文,关于如何实现单调和排序保留映射

    【讨论】:

      【解决方案4】:

      只需将您的值乘以 127 并将其转换为 int[0,1]*127 =&gt; [0,127]

      【讨论】:

      • -1:这不会正确映射所有值 - 参见例如TonyK 的答案或 Mark R 的答案以获得更好的解决方案
      【解决方案5】:

      我想我一定错过了什么。为什么不乘以 127.0 而不是 100?

      【讨论】:

      • 哦,是的。我没有想到。我觉得自己像个傻瓜
      【解决方案6】:

      我使用这种有效的变通方法,在 round() 函数的帮助下覆盖所有值。

      输出 = 圆形 (ampiezza * 127.5 + 127.5)

      ampiezza 是一个有符号浮点数,范围从 -1 到 +1 输出是一个 8 位整数

      输出范围从 0 到 255,居中在 127 和 128 之间

      希望这会有所帮助。

      【讨论】:

        【解决方案7】:

        在使用floor()之前将结果值乘以1.27?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-11-05
          • 1970-01-01
          • 2016-11-06
          • 1970-01-01
          • 2018-10-09
          • 2021-04-18
          • 1970-01-01
          相关资源
          最近更新 更多