【问题标题】:How to implement an instrument/score pattern in supercollider?如何在超级对撞机中实现仪器/分数模式?
【发布时间】:2012-08-12 06:36:21
【问题描述】:

我已经阅读了一些教程,但似乎没有一个能理解我认为合理的架构:

  1. 有一个或多个Instrument 实例,
  2. 有一个Score 定义了一组Note 对象,
  3. Player 类(可能是函数)将 Note 实例从乐谱路由到乐器,以便制作音乐。

我在这个模式中看到的,但在我目前阅读的示例中没有看到的是 (a) 乐谱和乐器之间的总分离和 (b) 明确的定义(以 a 的形式类和/或 API)的 Note 对象告诉仪器做什么。

他们的内置实用程序是否支持这种类型的操作模式?

这是一种不重要的思考问题的方式吗?

【问题讨论】:

    标签: audio supercollider


    【解决方案1】:

    我还要补充一点,有一组名为Ctk 的扩展(“夸克”),它包装了 SynthDef(到 CtkSynthDef)、音符的概念(到 CtkNote)和乐谱(到 CtkScore)促进实时和非实时工作。我觉得其帮助文件提供的示例(大部分)遵循 OP 建议的架构。 要安装它,请在 SuperCollider 中运行 Quarks.install("Ctk")

    【讨论】:

      【解决方案2】:

      鉴于您已查看示例,我不确定您到底想要什么。奇数位是“完全分离”的要求;通常,乐谱需要对哪些参数与哪些乐器相关做出一些假设——尽管 SynthDef 中有足够的内省方法,程序可以做出有根据的猜测。

      但基本原理图是相当标准的:SynthDef 定义乐器,Collection 及其子类存储数据,Routine 和其他类可以在预定的时间内解释数据结构以制作音乐。

      在底部,我粘贴了一些样板代码,用于使用 SynthDef、Routine 和 Array 对这种结构进行非常简单的类似 c 的方法。使用哪种乐器是在音符生成时任意选择的,“分数”与乐器无关。

      然而,SC 中的惯用方法是使用模式和事件,尤其是 Pbind 类。我个人觉得这些有点限制和冗长,但他们肯定会按照你的要求做。查看“Streams-Patterns-Events”系列帮助文件。

      许多人已经编写了第三方扩展程序,例如 Instr 和 Voicer,以适应他们自己风格的乐谱乐器模型。查看 Quarks 列表还是考虑推出自己的列表?

      s = Server.local.boot;
      s.waitForBoot{ Routine {
      /// in a "real" patch, i'd make these local variables,
      /// but in testing its convenient to use environment variables.
      // var inst, tclock, score, playr, switchr;
      
      // the current instrument
      ~inst = \ding;
      // a fast TempoClock
      ~tclock = TempoClock.new(8);
      
      // two instruments that take the same arguments
      SynthDef.new(\ding, {
          arg dur=0.2, hz=880, out=0, level=0.25, pan=0.0;
          var snd;
          var amp = EnvGen.ar(Env.perc, doneAction:2, timeScale:dur);
          snd = SinOsc.ar(hz) * amp * level;
          Out.ar(out, Pan2.ar(snd, pan));
      }).send(s);
      
      SynthDef.new(\tick, {
          arg dur=0.1, hz=880, out=0, level=0.25, pan=0.0;
          var snd;
          var amp = EnvGen.ar(Env.perc, doneAction:2, timeScale:dur);
          snd = LPF.ar(WhiteNoise.ar, hz) * amp * level;
          Out.ar(out, Pan2.ar(snd, pan));
      }).send(s);
      
      s.sync;
      
      // the "score" is just a nested array of argument values
      // there are also many kinds of associative collections in SC if you prefer
      ~score = [
          // each entry:
          // midi note offset, note duration in seconds, wait time in beats
          [0, 0.4, 2],
          [0, 0.4, 1],
          [7, 0.2, 1],
          [0, 0.2, 1],
          [7, 0.15, 1],
          [10, 0.5, 2],
          [7, 0.1, 1],
          [2, 0.3, 1]
      
      ];
      
      // a routine that plays the score, not knowing which instrument is the target
      ~playr = Routine { var note, hz; inf.do({ arg i;
          // get the next note
          note = ~score.wrapAt(i);
          // interpret scale degree as MIDI note plus offset
          hz = (note[0] + 60).midicps;
          // play the note
          Synth.new(~inst, [\hz, hz, \dur, note[1] ], s);
          // wait
          note[2].wait;
      }); }.play(~tclock);
      
      
      // a routine that randomly switches instruments
      ~switchr = Routine { var note, hz; inf.do({ arg i;
          if(0.2.coin, {
              if(~inst == \ding, {
                  ~inst = \tick;
              }, {
                  ~inst = \ding;
              });
              ~inst.postln;
          });
          // wait
          1.wait;
      }); }.play(~tclock);
      
      }.play; };
      

      【讨论】:

        猜你喜欢
        • 2022-12-11
        • 2013-04-11
        • 2021-01-29
        • 2014-01-17
        • 2014-01-17
        • 2014-01-16
        • 1970-01-01
        • 2013-02-13
        • 2016-04-11
        相关资源
        最近更新 更多