Enhancing Non-Diatonic Chord Hue Determination

by Admin 47 views
Enhancing Non-Diatonic Chord Hue Determination

Hey guys! Let's dive into how we can make non-diatonic chords pop visually! The goal here is to refine our method for assigning hues to these chords, so they stand out more distinctly from their diatonic cousins.

Current Pain Points

1. Non-Diatonic Chords Looking Too Similar to Diatonic Ones

Alright, so here's the deal: sometimes, our non-diatonic chords are just too similar in color to the diatonic ones. This can be super confusing visually, especially when you're trying to analyze a progression at a glance.

Example: Think about the Chorus section of Just The Two Of Us in F minor:

  • Fm7 (i, diatonic) → tonic function → hue adjustment 0°
  • Em7 (non-diatonic) → tonic function (default) → hue adjustment 0°

Result: They end up being almost the same color! Not ideal, right? The main issue is that both chords, despite one being non-diatonic, get the same tonic function treatment, resulting in a lack of visual distinction. We need to tweak things, so these chords have their own unique flair.

To address this, we need to consider a broader palette for non-diatonic chords. Instead of defaulting to the tonic function, we can explore options like emphasizing the chord's root note, detecting semitone relationships between chords, or even introducing new harmonic function types specifically for non-diatonic scenarios. By doing so, we'll ensure that each chord's color accurately reflects its unique role in the harmonic landscape.

2. The Current Hue-Determining Logic

Let's peek under the hood at our current color-generating logic. Here’s a snippet from colorGenerator.ts:

const harmonicFunction = getHarmonicFunctionType(chord, key);

switch (harmonicFunction) {
  case 'tonic':       hueAdjustment = 0;   // ±0 degrees
  case 'subdominant': hueAdjustment = 15;  // +15 degrees
  case 'dominant':    hueAdjustment = 30;  // +30 degrees
}

And here’s where things get interesting in harmonicAnalysis.ts:

default:
  // Non-diatonic chord
  return {
    romanNumeral: `${chord.root}`,
    function: 'tonic', // ← Defaults to tonic!
    isDiatonic: false,
  };

Problem: All non-diatonic chords are defaulting to a tonic function (0° hue adjustment). This makes them look too similar to the key color and diatonic tonic chords. Not cool!

To solve this, we need to rethink how we classify these chords. By default assigning them a tonic function, we're essentially muting their unique harmonic flavors. It's like putting everyone in the same outfit – no one stands out! Instead, we should aim to differentiate them based on their specific role in the progression, whether it's a chromatic passing chord, a borrowed chord, or a substitution. This will not only enhance their visual representation but also provide valuable insights into their harmonic function.

Improving the Approach

Special Non-Diatonic Chord Patterns We Want to Highlight

  1. Clichés: These are those sweet, chromatic movements, usually by a half-step.

    • Example: Fm7 → Em7 → Ebm7 (Just The Two Of Us)
    • Example: CM7 → Cm7 → Bbm7
  2. Tritone Substitutions: Swapping out a dominant chord for one a tritone away.

    • Example: C7 replaced by F#7 (Gb7)
    • Harmonic function is dominant, but the hue should be unique.
  3. Secondary Dominants: We're already detecting these, but let's leverage them more for color!

    • Example: V7/ii, V7/V, etc.
    • Currently, they get a dominant function, but we want a more distinct hue shift.
  4. Modal Interchanges: Borrowing chords from parallel keys.

    • Example: iv, ♭VII, ♭VI in a major key.
    • Currently, they get a subdominant function, but they deserve their own hue.

Proposed Improvements

Option A: Detect Semitone Relationships Between Chords

// Cliché detection: If the root note is a semitone away from the previous chord
const previousChord = ...;
const semitoneDistance = Math.abs(getNoteIndex(chord.root) - getNoteIndex(previousChord.root));
if (semitoneDistance === 1 && chord.quality === previousChord.quality) {
  // It's a cliché! Give it a unique hue adjustment (e.g., -15° or +45°)
}

Explanation: This approach involves analyzing the relationship between consecutive chords to identify cliché patterns. By comparing the root notes of adjacent chords, we can detect semitone movements, which are characteristic of clichés. Once a cliché is identified, we can apply a specific hue adjustment to visually distinguish it from other chords. This adjustment could involve shifting the hue by a fixed amount, such as -15° or +45°, to create a distinct visual representation. By highlighting cliché patterns in this way, we can enhance the visual analysis of chord progressions and provide valuable insights into their harmonic structure.

Option B: Directly Reflect the Chord’s Root Note in the Hue

// If it's a non-diatonic chord, use the chord's root note as the base
if (!isDiatonic) {
  const chordRootHue = NOTE_TO_HUE[chord.root];
  const keyHue = NOTE_TO_HUE[key.tonic];
  const hueShift = (chordRootHue - keyHue + 360) % 360;
  // Use a hue that's significantly shifted from the key color
}

Explanation: This strategy emphasizes the individual identity of non-diatonic chords by aligning their hue with their root note. Instead of anchoring the color to the key's tonic, we can derive the hue directly from the chord's root, allowing it to stand out more distinctly. By referencing a predefined mapping of notes to hues, we can assign a unique color to each chord based on its root. This approach not only enhances the visual appeal of non-diatonic chords but also helps to convey their harmonic function more effectively.

Option C: Expand Harmonic Function Types

// Add new harmonic function types
type HarmonicFunctionType =
  | 'tonic'
  | 'subdominant'
  | 'dominant'
  | 'chromatic'      // For clichés
  | 'substitute';    // For tritone substitutions

// Expand the hue adjustment
case 'chromatic':   hueAdjustment = -30;  // Reverse direction
case 'substitute':  hueAdjustment = 180;  // Opposite hue

Explanation: This method involves enriching the harmonic function types to better categorize non-diatonic chords. By introducing new categories such as 'chromatic' for clichés and 'substitute' for tritone substitutions, we can tailor the hue adjustment to reflect the specific harmonic role of each chord. This approach allows for a more nuanced representation of non-diatonic chords, enhancing their visual distinctiveness and providing valuable insights into their harmonic function.

Things to Consider

  • [ ] Should we keep the current hue range constraint (±30°) or ditch it for non-diatonic chords?
  • [ ] How can we differentiate the hues of secondary dominants and tritone substitutions?
  • [ ] Does cliché detection need context (previous and subsequent chords)?
  • [ ] Can hues alone provide enough distinction, given the constraint of no visual markers (like borders)?

Relevant Files

  • src/utils/colorGenerator.ts - generateChordColor() function
  • src/utils/harmonicAnalysis.ts - analyzeHarmonicFunction() function
  • src/types/index.ts - HarmonicFunctionType type definition

Priority

Medium to High (improving musical expressiveness)