Add real-time chord detection and visualization mode

Implemented chroma-based major/minor chord detection in AudioAnalyzer and exposed results in AudioFeatures. Updated HUD to display detected chord names. Added a new "CHORDS" fractal preset that visualizes the current chord with large pixel text, modulated by confidence and beat. Extended pixel font for chord display. Ensured graceful handling when no chord is detected. These changes enhance both analysis and visual feedback for harmonic content.
This commit is contained in:
Michal Vrba
2026-02-13 20:52:02 +01:00
parent 6a1bdfb935
commit 2d535addd0
4 changed files with 188 additions and 7 deletions
+18 -5
View File
@@ -145,7 +145,7 @@ public class Game1 : Game
if (IsPressed(keyboard, Keys.Right))
{
_fractalPresetIndex = Math.Min(20, _fractalPresetIndex + 1);
_fractalPresetIndex = Math.Min(21, _fractalPresetIndex + 1);
}
if (IsPressed(keyboard, Keys.M))
@@ -195,10 +195,11 @@ public class Game1 : Game
_hudFont.DrawText(_spriteBatch, _pixel, "BEAT " + _latestFeatures.Beat.ToString("0.000"), 12, 130, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "BPM " + _latestFeatures.Bpm.ToString("0.0"), 12, 150, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "NOTE " + GetDetectedNoteName(_latestFeatures.DetectedNoteIndex), 12, 170, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "PAUSED " + (_isPaused ? "YES" : "NO"), 12, 190, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "FPS " + _fps, 12, 210, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "QUALITY " + _renderQuality + " 1 2 3", 12, 230, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "F OR F11 FULLSCREEN R RESIZE", 12, 250, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "CHORD " + GetDetectedChordName(_latestFeatures.DetectedChordRootIndex, _latestFeatures.DetectedChordType), 12, 190, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "PAUSED " + (_isPaused ? "YES" : "NO"), 12, 210, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "FPS " + _fps, 12, 230, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "QUALITY " + _renderQuality + " 1 2 3", 12, 250, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "F OR F11 FULLSCREEN R RESIZE", 12, 270, 2, Color.White);
_spriteBatch.End();
}
@@ -249,6 +250,7 @@ public class Game1 : Game
18 => "RIBBON",
19 => "GRAINBARS",
20 => "NOTEDROP",
21 => "CHORDS",
_ => "JULIA"
};
}
@@ -273,6 +275,17 @@ public class Game1 : Game
};
}
private static string GetDetectedChordName(int rootIndex, int chordType)
{
string root = GetDetectedNoteName(rootIndex);
if (root == "-")
{
return "-";
}
return chordType == 1 ? root + " MIN" : root + " MAJ";
}
private void ToggleFullScreen()
{
_graphics.ToggleFullScreen();