`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 之间有啥区别吗