`xtratim` 和覆盖 p3 之间有啥区别吗?

Posted

技术标签:

【中文标题】`xtratim` 和覆盖 p3 之间有啥区别吗?【英文标题】:Is there any difference between `xtratim` and overriding p3?`xtratim` 和覆盖 p3 之间有什么区别吗? 【发布时间】:2020-02-16 06:40:18 【问题描述】:

根据参考 csound 手册,在编写响应 MIDI 的乐器时,应该使用 xtratim(或隐含使用它的操作码,例如 madsr),因为事先不知道键/音符的持续时间(对于现场表演)。

但是,我还在external example 中指出,可以从乐器代码中覆盖 p3(乐谱音符长度)。那么,这样做和使用xtratim 有什么区别吗?

【问题讨论】:

【参考方案1】:

是的,当音符关闭时,具有释放段的 xtratim 和 -r 操作码将触发额外的释放时间。 p3 将只是“开启”时间的持续时间值。

例如,如果您运行以下命令:

instr S1
  p3 = 2
  asig = oscili(0.25, 440)
  asig *= linsegr(1, .1, 1, 4, 0)
  out(asig, asig)
endin
schedule("S1", 0, 0.1)
    调度调用将 p3 设置为 0.1 秒 仪器将 p3 重新定义为 2 秒 仪器运行 2 秒,之后由于 linsegr 释放值有 4 秒释放时间

一般来说,覆盖 p3 应谨慎使用,但在某些情况下很有用,例如确保为仪器提供最少的时间。 xtratim 或 -r 操作码的发布时间可能更适用于大多数用例。

【讨论】:

【参考方案2】:

由于xtratim 在额外的时间内获得了 i-arg,我希望更改 p3 会更灵活,但实际上并非如此......

对于初学者,p3 被视为 i-var,即它只能在初始传递时分配,所以类似于

instr 1
if p3 < 9 then
  p3 = p3 + 1 ; runs only once
  printk 0.1, p3
endif
endin

如果从分数调用,只会运行三秒钟

i1 0 2

这是意料之中的事。另一方面,调用reinit 以[重新]运行初始化阶段的以下hack 确实多次更新p3,但是这对音符播放时间的影响为零,即只有第一个( "real init") 改变了实际的音符持续时间...... perf-time reinits,同时改变从乐器读取的 p3,对音符播放持续时间没有任何影响,即

top:
p3  = p3 + 1
printk 0.1, p3
if p3 < 9 then
  reinit top
endif

仍然以相同的分数播放 3 秒(即使我确保 Csound 运行足够长的时间),即:

i1 0 2
e 10

尽管 printk 确实将 p3 显示为使用后一种仪器达到值 9...

至于xtratim,它根本不会改变 p3,正如 Steven' Yi 的回答正确指出的那样,“额外时间”是在此之外实现的。

查看 xtratim 的源代码,实际上可以通过多次调用 xtratim 来延长“额外时间”,值不断增加,但不能缩短......

int32_t xtratim(CSOUND *csound, XTRADUR *p)

    IGN(csound);
    int32_t *xtra = &(p->h.insdshead->xtratim);
    int32_t tim = (int32_t)(*p->extradur * p->h.insdshead->ekr);
    if (*xtra < tim)  /* gab-a5 revised */
      *xtra = tim;
    return OK;

有了这些信息,我尝试了

ixtr = 0
top:
ixtr += 1
xtratim ixtr
print ixtr
if ixtr < 8 then
  reinit top
endif

你瞧,后面的 hack 确实有效,即后面的代码实际上使用之前的分数将乐器/音符的播放时间延长到 10 秒。因此,与破解 p3 不同,可以在演奏时从乐器内部以编程方式扩展音符,随心所欲。

对于那些好奇的人,xtratim 甚至在播放(实际释放)时间(正确地)生效,即使在释放已被断言之后调用,即即使从“释放段”,例如

xtratim 1
kflag release
kdone init 0
if (kflag == 1) && (kdone == 0)  then
  kdone = 1
  reinit more
  more:
  xtratim 4
endif

将额外提供 4 秒的播放时间。鉴于此,我不确定在 perf 期间忽略 p3 更新是错误还是“设计使然”。

【讨论】:

一般来说,如果你想延长持续时间,你可能想使用负 p3。这会将仪器实例置于保持状态,直到您执行某些操作来关闭仪器。这更像是你想要做的吗,按住一个音符,直到你发出信号关闭它?

以上是关于`xtratim` 和覆盖 p3 之间有啥区别吗?的主要内容,如果未能解决你的问题,请参考以下文章

RenderPartial 和 RenderPage 之间有啥区别吗? [复制]

激活函数和传递函数之间有啥区别吗?

Observable 和 Future.get 之间有啥区别吗

where 子句和使用关联对象来提高性能之间有啥区别吗

Activityname.this() 和 this 之间有啥区别吗?

[,] 2d 数组和 [][] 数组之间有啥功能区别吗? [复制]