You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SuperCollider的Pbind中访问Buffer数组的当前Buffer信息?

问题描述

加载了一组包含音频采样的Buffer数组,通过Pbind随机将这些Buffer传递给Synth播放,希望把Pbind的\dur参数设置为当前播放Buffer的时长,但无法在Pbind内部访问当前Buffer的numFrames、sampleRate等属性,尝试过Pkey、Pfset、Plambda均未成功。相关代码如下:

// Synth定义
SynthDef(\player, {
  /*
    play a file from a buffer
    out: the output channel
    bufnum: the buffer to play
  */
  arg out=0, bufnum;
  Out.ar(
    out,
    PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum),  doneAction: Done.freeSelf)) ! 2
  )
}).add;

// Buffer数组加载
path = PathName.new("/path/to/files");
bufferArray = Array.new(100);
path.filesDo({
  arg file;
  bufferArray.add( Buffer.read(s, file.fullPath) );
});

// 问题中的Pbind代码
p = Pbind(
  \buffer, Prand(bufferArray, inf),
  \instrument, \player,
  \bufnum, Pkey(\buffer),
  \dur, (Pkey(\buffer.numFrames) / Pkey(\buffer.sampleRate))
)
解决方法

方法一:用Plambda直接获取Buffer属性

你之前的写法错误在于,Pkey只能引用事件中的键名,无法直接链式访问对象的属性(比如.numFrames)。可以用Plambda捕获当前事件中的\buffer对象,直接计算时长:

p = Pbind(
  \buffer, Prand(bufferArray, inf),
  \instrument, \player,
  \bufnum, Pkey(\buffer),
  \dur, Plambda { |event| 
    // 从事件中取出当前Buffer对象,计算时长
    event[\buffer].numFrames / event[\buffer].sampleRate 
  }
);

方法二:预计算时长数组(更高效)

如果不想每次播放时都计算时长,可以提前把所有Buffer的时长计算好,存在对应数组里,播放时直接随机选取:

// 加载Buffer时同时计算时长
path = PathName.new("/path/to/files");
bufferArray = [];
durationArray = [];
path.filesDo({
  arg file;
  var buf = Buffer.read(s, file.fullPath);
  bufferArray.add(buf);
  // 预计算并存储时长
  durationArray.add(buf.numFrames / buf.sampleRate);
});

// 修改后的Pbind
p = Pbind(
  \buffer, Prand(bufferArray, inf),
  \instrument, \player,
  \bufnum, Pkey(\buffer),
  // 对应选取预计算的时长
  \dur, Prand(durationArray, inf)
);

补充说明

两种方法都能实现需求:方法一适合Buffer可能动态变化的场景,方法二避免了实时计算的开销,更适合固定Buffer集合的场景。另外你的SynthDef已经设置了doneAction: Done.freeSelf,Synth会在播放完毕后自动释放,配合正确的\dur参数,就能实现每个采样播放完毕后再触发下一个的效果。

内容的提问来源于stack exchange,提问作者paulhector

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 17:31:00