【问题标题】:Playing baudio multiple sounds播放多个声音的音频
【发布时间】:2014-03-01 19:42:22
【问题描述】:

我最近发现了很棒的 baudio NodeJS 库。

我有以下代码:

var baudio = require("baudio")
  , b = baudio()
  , tau = 2 * Math.PI
  ;

function playSound (f, duration) {

    console.log(f, duration);

    b.push(function (t) {
        return (square (f) + square (f + 1)) * (t < duration);
        function square (freq) {
            return Math.sin(tau * t * freq) < 0 ? -1 : 1;
        }
    });

    b.play();
}

playSound(440, 2) 将播放 A 键 2 秒。这是对的。如果我再次调用playSound 函数,则不会播放其他声音。

为什么?在播放完第一个或正在播放后,如何播放其他声音?

【问题讨论】:

  • 上面的tau是什么?
  • @Andbdrew 不错。 tau2 * Math.PI

标签: linux node.js audio sox


【解决方案1】:

你的 playSound() 函数应该在几秒钟内接受一个参数t,你可以使用模重放声音。例如,考虑这个 pluck 函数:

return function (t, i) {
  return pluck(t % 0.5, 100, 10, 10);
}

function pluck (t, freq, duration, steps) {
    var n = duration;
    var scalar = Math.max(0, 0.95 - (t * n) / ((t * n) + 1));
    var sum = 0;
    for (var i = 0; i < steps; i++) {
        sum += Math.sin(2 * Math.PI * t * (freq + i * freq));
    }
    return scalar * sum / 6;
}

Use this link to experiment with a live version.

不要在歌曲中使用 setTimeout、setInterval 或其他类型的 IO。由于 baudio 与事件循环的交互方式(它固定它并且系统时间和音乐时间之间没有 1:1 的对应关系),它的性能会很差。

【讨论】:

    【解决方案2】:

    如果你运行playSound(440, 2);,然后定期检查b.t,你会看到2秒后它还在增加,如果你检查topps,你会看到一个 sox 进程仍在进行中。

    事实证明,baudio 几乎是 sox 的包装,这很甜蜜,而 baudio::play method returns a reference to a child process running sox

    因此,无论如何,可能有更好的方法,但您可以通过在 duration 结束时终止进程并在每次调用 playSound 时新建一个新进程来使其工作,例如:

    var baudio = require("baudio");
    
    function square(freq, t) {
        return Math.sin(2 * Math.PI * t * freq) < 0 ? -1 : 1;
    }
    
    function playSound(f, duration) {
    
        var b = baudio();
        b.push(function (t) {
            return (square (f, t) + square (f + 1, t)) * (t < duration);
        });
        var ps = b.play();
    
        setTimeout(function() {
            ps.kill('SIGHUP');
            b.t = 0;
          }
        , duration * 1000);
    
    }
    
    playSound(440, 2);
    

    这在节点 0.8.24 中有效,但在 0.10.26 中效果不佳...不知道为什么

    【讨论】:

    • 以错误结束:events.js:72 throw er; // Unhandled 'error' event ^ Error: read ECONNRESET
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多