Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Consonance Field — 音高を評価する地形

Conchordalの知覚coreであるLandscapeはhabitat busを聴き、log-frequency spaceへ 変換して二つのpotentialを計算します。roughnessはcritical band内の振幅変動による 感覚的不協和、harmonicityはperiodicityとtemplate matchingです。この二つを 組み合わせたConsonance Fieldは、placement、movement、prediction、survivalが 読む、周波数上の評価地形です。

Consonance Fieldはhabitat busから計算されるため、そのbusへ送られたVoiceが ほかのVoiceの読むConsonance Fieldを変形します。presentation busだけへ送られたVoiceは 変形しません。和声はchord chartではなく、このfeedback loopから生まれます。 potential、score、level、mass、densityの関係は VoiceとLandscape — 音と環境のフィードバックを参照してください。

Consonance Fieldへの配置:consonancedissonanceedgegap

Consonance Fieldに応じたPlacementでは、Field内の対象領域を指定します。既定では確率分布から位置を選び、 .peak()を付けると決定的な極値を選びます。

  • consonance — consonanceが高い位置(harmonic center、fusion)。
  • dissonance — consonanceが低い位置(tension、cluster、color)。
  • edge — consonance/dissonanceの境界(metastableな中間)。
  • gap — 空いたregister(空間を埋め、maskingを避ける)。

consonance(root)はroot周辺のharmonic windowを取り、range()で倍音範囲を指定します。 どの配置先にも、絶対周波数の(min_hz, max_hz)範囲を渡せます。

let anchor = harmonic()
    .brain("drone")
    .amp(0.06)
    .sustain()
    .anchor();

let voice = harmonic()
    .amp(0.04)
    .sustain();

section("field placement", || {
    place(anchor, at(110.0));
    wait(1.0);

    place(voice, consonance(110.0).peak().range(1.0, 4.0).count(6).spacing(0.9));
    wait(6.0);
});

追加指定のない配置先は密度分布として扱われます。「無作為だが調和的」なのではなく、 協和のモデルから導かれ、指定範囲内で正規化された分布です。配置は配置後の振る舞いから 独立しています。dissonanceへ入りanchor()でclusterを保持することも、 seek_consonance()で解決へ向かわせることもできます。

let cloud = harmonic().amp(0.035).sustain();

place(cloud, consonance(90.0, 1200.0).count(10).spacing(0.8));
wait(8.0);

配置時の緊張度:tension(τ)

tensionを指定しないConsonance Placementは、通常の方法で実現されます。.peak()なら 最も強いpeakを選び、既定のdensityなら通常のConsonance密度分布を作ります。 tension(τ)は、最大値より一段のfield-scoreへ配置を偏らせます。 τ ∈ [0, 1]がtension degreeで、0は通常の配置を変えず、大きい値ほど弱く metastableなstepを対象にします。指定範囲内の評価値で target = L_max − τ·(L_max − L_min)です。movementにおけるsearch temperatureと 対になる、spawnをどれだけ解決した位置に置くかのdialです。.peak()なら最も近いstepへ 最寄りの段へ固定し、確率分布なら対象値の周辺へ重みを集中させます。

let tense = harmonic().amp(0.035).sustain();

// A metastable step below the strongest peak — placed, not resolved.
place(tense, consonance(110.0, 1200.0).peak().tension(0.4).count(6).spacing(0.8));
wait(6.0);

Consonance Fieldに依存しないPlacementには、対数周波数上で一様なrandom(min_hz, max_hz)と、幾何的な at(hz)line(start_hz, end_hz)があります。

周波数をroot比で名づける

at(hz)line(start_hz, end_hz)は絶対周波数を取ります。標準的な書き方は、 鳴っている一つのrootをHzで名づけ、他のpitchをその比として導くことです。完全5度なら root_hz * 1.5、完全4度ならroot_hz * 4.0/3.0、registerを上げるなら root_hz * 2.0です。比はField自身が読む物理量なので、周波数関係として考えられます。

平均律のdecimal、たとえばD3を表す146.83も動作しますが、12音のsymbol gridを裏口から 持ち込みます。sceneで実際に鳴っているrootの比を優先してください。

let root_hz = 110.0;
let voice = harmonic().amp(0.04).sustain();

place(voice, at(root_hz * 1.5));
wait(2.0);

Consonance movement:seek_consonance

VoiceがConsonance Field上のより良い位置を能動的に探すときはseek_consonance()を使います。 自由な山登り探索と音高推移の初期値を設定します。同じ移動を遅く、または速く 動かしたいときはglide(tau_sec)を使います。

let mover = harmonic()
    .amp(0.045)
    .sustain()
    .seek_consonance()
    .glide(0.35)
    .avoid_neighbors(0.6)
    .global_peaks(8, 70.0)
    .ratio_candidates(5);

place(mover, consonance(80.0, 900.0).count(8));
wait(12.0);

avoid_neighbors(strength)は混雑を避ける反発を加え、移動するVoiceがすべて同じ山へ重なるのを防ぎます。 移動の反対はanchor()です。固定されたVoiceは音高を保ち、ほかのVoiceが読むConsonance Fieldだけを 変形します。at()またはfreq()で指定したVoiceは暗黙に固定されます。

移動の反映方法は発音様式から決まります。持続するVoiceは滑らかに移り、再発音するVoice (pulse()metric()entrained()flow())は発音開始ごとに新しい音高へ snapします。例外が必要ならpitch_apply_mode()を使います。研究scriptには pitch_core()など機構水準のcontrolもありますが、作品ではseek_consonance()glide()を優先してください。

Consonance viabilityとrespawn

consonance_viability(low, high)はconsonance window、recovery(seconds)は最大回復に 要する時間を定義します。適合度の高いVoiceは支えられ、低いVoiceは基準 endurance(seconds)へ近づきます。既定では自分の音響的な痕跡を近似的に除く 環境相対評価です。Consonance Field全体への適合度を問う場合だけviability_scope("total")を使います。

再生成は循環を生態系として閉じます。Voiceが死亡すると、再生成の方針に従って代わりのVoiceが 現れます。respawn_consonance()は、energyで重み付けして選んだliving parentの周辺へ 偏らせながら、field scoreの高いpeakから選びます。respawn_capacity(count)はliving membership上限です。respawn_settle(placement)はpolicy本来のcandidateを置き換えず、 replacementのcandidate poolへそのPlacementを追加します。

let settle = consonance(70.0, 1100.0).spacing(0.8);

let ecology = harmonic()
    .amp(0.04)
    .repeat()
    .pulse(1.5)
    .cycles(3)
    .seek_consonance()
    .glide(0.45)
    .endurance(8.0)
    .recovery(4.0)
    .attack_cost_fraction(0.017)
    .attack_recharge_fraction(0.70)
    .consonance_viability(0.32, 0.82)
    .respawn_consonance()
    .respawn_capacity(14)
    .respawn_settle(settle);

place(ecology, consonance(70.0, 1100.0).count(14));
wait(30.0);

完全なlifecycle/respawn surfaceはAPIリファレンス、articulation、 発音、音高の振る舞い、生存の区別はPopulation — Voiceをまとめる持続単位、 エネルギーと再生成のcycleは VoiceとLandscape — 音と環境のフィードバックを参照してください。

Landscape-awareな音色

Fieldはpitchだけでなく音色も形づくれます。modal() bodyはmode patternを取ります。 landscape_density_modes()はdensity massの強い位置を間隔を空けて決定的に選び、 landscape_peaks_modes()はField levelの強いlocal peakを間隔を空けて選びます。 そのため、bellのpartialをConsonance Fieldがすでにsupportする位置へ置けます。

let shimmer_modes = landscape_density_modes()
    .count(10)
    .range(1.0, 5.5)
    .gamma(1.6)
    .spacing(0.7);

let shimmer = modal()
    .amp(0.025)
    .sustain()
    .seek_consonance()
    .modes(shimmer_modes)
    .brightness(0.7);

place(shimmer, consonance(200.0, 1600.0).count(4));
wait(8.0);

mode patternの生成関数にはharmonic_modes()odd_modes()power_modes(beta)stiff_string_modes(stiffness)custom_modes([ratios])modal_table(name)landscape_density_modes()landscape_peaks_modes()があります。