1

我正在学习 SuperCollider 并且在尝试创建用于存储频率的 2D 数组时遇到问题...最初我希望数组为 12 x 9 以便行代表音符(c、d、e、f. ..) 并且列表示八度音阶,例如 f[0,0] = c0 、 f[1,5] = c#5 、 f[2,1] = d1 等。首先,SC 从左到右自动换行通过行,所以这是我的第一个问题(稍后解决)。

主要问题:我尝试嵌套 for() 或 while() 循环以迭代 3 个索引以手动将频率放入数组位置,但失败了。我知道这充满了漏洞。对不起/谢谢。代码如下。

//loading the frequency array with note values
(
f = Array.new(108);
for ( -57,50, { arg n; 
    f.add(440 * (( 2 ** (1/12)) ** (n)) );
} );
)

/* below attempt works, sort of... values in the 
expected 12x9 array are what they're supposed to 
be, but there are extra values, in that the array 
size is larger than expected... e.g. k[0,9] should 
return null, right? Don't want the array values 
to wrap such that the first row is (108) entries 
long!
*/

k = Array2D.fromArray(12,9,f);
k[0,0]; //returns proper entry
k[0,9]; //should be null???
k[0,107]; //shouldn't exist??
k[11,8]; //returns proper entry

/* attempts at manual entry, array size is too 
large after 2nd for() loop is executed and double 
entries exist in the array, which is now bigger 
than it was initialized...
*/

h = Array2D.new(12,9);
for ( 0,8, { arg n; h.put(0,n,f[n]);} );
for ( 0,8, { arg n; h.put(1,n,f[n+12]); } );


//nested iteration attempted 1

(
f = Array.new(108);
for (-57, 50, { arg n;
    f.add(440 * (( 2 ** (1/12) ) ** n) );
} );
q = Array2D.new(12,9);

for (0, 11, { arg i;
    for (0, 8, { arg j;
        for (0, 107, { arg k;
            q.put(0,j,f[k]);
            q[0,j].postln;
        });
    });
});
)


//nested iteration attempt 2

(
for (0, 107, { arg i;
    for (0, 11, { arg j;
        for (0, 8, { arg k;
            q.put(j,k,f[i]);
            q[j,k].postln;
//              k = k+1;
        });
//          j = j+1;
    });
//      i = i+1;
});
)
4

1 回答 1

1

可以像你一样构建你的数组,但是你错过了 SuperCollider 的一些更好的语言特性,这些特性使得表达这样的概念非常简单。

在构造数组时,该collect方法非常有用:

var octaves = (1..7); // array of numbers 1..7
var degrees = (0..11);
var table = octaves.collect {
  |oct|
  degrees.collect {
    |degree|
    // Table value calculation here
  }
}:

table[3][2]; // Octave three, degree two

SuperCollider 也有足够的支持你手动做的各种音符/频率转换 - 没有必要在这里重新发明轮子,看看 Scale 类,以及像 |degreeToFreq| 这样的方法 和 |midiCps|。

于 2019-12-04T09:42:29.737 回答