TuttiCodeTuttiCode 指南

歌曲与段落

把一整首歌写成按曲式演奏的段落——前奏、主歌、副歌——每条轨道的音色只写一次。

循环只是把一个想法反复演奏。一首歌则会经过不同的段落:前奏、主歌、副歌、再一遍主歌、尾声。每个段落有自己的声部,而歌曲就是这些段落演奏的顺序,也就是它的曲式。TuttiCode 就这样写歌:每个段落演奏什么写在一个块里,曲式写在一行里,每条轨道的音色只写一次。

代码 是什么
track(name) 歌曲的一条轨道和它的音色:.inst、.fx、.mix、.send
section(name, bars, {track: pattern}) 一个段落演奏的全部内容
form("...") 段落演奏的顺序

和 bus、group 一样,这些是 TuttiDAW 独有的。只在几个周期里变化的循环,用时间与结构里的 arrange 就够了;要写一整首歌,就用段落。

第一首歌

两个段落,各自列出它的轨道演奏什么。没有 form 时,段落按书写顺序演奏,然后歌曲从头再来。

section("verse", 4, {
  drums: s("bd ~ sd ~, hh*8"),
  bass: note("<c2 eb2 g1 bb1>*4").s("sawtooth").lpf(600),
})
section("chorus", 4, {
  drums: s("bd sd bd sd, hh*16"),
  bass: note("<ab1 bb1 c2 c2>*8").s("sawtooth").lpf(900),
})
在 /TuttiCode 中打开

块里的键(drums、bass)就是歌曲的轨道。段落没有列出的轨道在那里不发声。每个模式都从段落的第一小节开始,并在段落内循环,所以一个 4 小节的模式总是和段落一起开始,不管这个段落落在歌曲的哪里。

轨道:音色只写一次

track("bass") 在一行里给轨道设定乐器、效果和混音。段落里就只写音符,所以要改贝斯的音色只需改一行,而不用改每个段落。

track("bass").inst("Drift").mix({vol: -3})
track("keys").inst("Electric").fx("Reverb", {dryWetBalance: 0.3})

section("verse", 4, {
  bass: note("<c2 eb2 g1 bb1>*4"),
})
section("chorus", 4, {
  bass: note("<ab1 bb1 c2 c2>*8"),
  keys: note("<[c3,eb3,g3] [bb2,d3,f3]>"),
})
在 /TuttiCode 中打开

没有用 track(...) 声明的轨道照样会演奏:它的模式用自己的音色(.s(...)),就像第一首歌那样。

曲式:顺序与重复

form("...") 用迷你记谱写出顺序:并排的名字依次演奏,[...] 把它们编成一组,!n 重复,name@n 给那一次出现单独指定小节数。每个程序只有一个 form。

section("intro", 2, {
  drums: s("hh*8"),
})
section("verse", 4, {
  drums: s("bd ~ sd ~, hh*8"),
  bass: note("<c2 eb2 g1 bb1>*4").s("sawtooth").lpf(600),
})
section("chorus", 4, {
  drums: s("bd sd bd sd, hh*16"),
  bass: note("<ab1 bb1 c2 c2>*8").s("sawtooth").lpf(900),
})
section("outro", 4, {
  drums: s("bd ~ ~ ~"),
})
form("intro [verse chorus]!2 outro@2")
在 /TuttiCode 中打开

这会依次演奏前奏、主歌、副歌、主歌、副歌、尾声:共 22 小节,最后一段被截成 2 小节。整个曲式就是程序的循环。其他迷你记谱(*、< >、,)在曲式里没有意义,会被报告出来。

贯穿整首歌的声部

带标签的声部不属于任何段落,所以它贯穿整个曲式演奏——铺底、节拍器、垫在一切之下的持续音。

section("verse", 4, {
  drums: s("bd ~ sd ~, hh*8"),
})
section("chorus", 4, {
  drums: s("bd sd bd sd, hh*16"),
})
form("verse chorus")

pad: note("<[c3,eb3,g3] [ab2,c3,eb3]>").s("sawtooth").lpf(800).slow(2)
在 /TuttiCode 中打开

共用声部,只改某一次出现

const 保存几个段落共同演奏的声部,这样它只写一次。section("verse#2", {...}) 只改第二段主歌:它列出的轨道在那里演奏它的模式,其他轨道保持主歌原来的内容。它可以省略小节数,因为它沿用主歌的长度。

const groove = s("bd ~ sd ~, hh*8")

section("verse", 4, {
  drums: groove,
  bass: note("<c2 eb2 g1 bb1>*4").s("sawtooth").lpf(600),
})
section("chorus", 4, {
  drums: groove.fast(2),
  bass: note("<ab1 bb1 c2 c2>*8").s("sawtooth").lpf(900),
})
section("verse#2", {
  bass: note("<c2 c3 eb2 eb3>*8").s("sawtooth").lpf(600),
})
form("[verse chorus]!2")
在 /TuttiCode 中打开

限制

  • 在 TuttiCode 上一首歌最多演奏 128 小节;更长的曲式只演奏前 128 小节,并会提示。
  • 每个段落都要写小节数,section("verse", 8, {...});只有 name#k 覆盖可以省略。
  • “在 TuttiDAW 中打开”会在录音室里打开这首歌:段落每出现一次,每个音轨就有一个片段,每个段落一个定位点,项目循环覆盖整个曲式。你在那里手动编辑过的片段就归你了,代码不再改动它;点“重新关联”可以把它交还给代码。