Add real-time note detection and NOTEDROP visualization
Implemented musical note detection in AudioAnalyzer, exposing dominant note and strength in AudioFeatures. Updated HUD to display detected note. Added "NOTEDROP" fractal preset that animates detected notes as colored glyphs. Extended bitmap font to support sharps. Increased fractal preset count and adjusted HUD layout.
This commit is contained in:
@@ -168,6 +168,8 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
float bassEnergy = 0f;
|
||||
float midEnergy = 0f;
|
||||
float highEnergy = 0f;
|
||||
float dominantMagnitude = 0f;
|
||||
float dominantFrequency = 0f;
|
||||
|
||||
for (int bin = 1; bin < half; bin++)
|
||||
{
|
||||
@@ -195,6 +197,12 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
{
|
||||
highEnergy += magnitude;
|
||||
}
|
||||
|
||||
if (frequency >= 80f && frequency <= 2000f && magnitude > dominantMagnitude)
|
||||
{
|
||||
dominantMagnitude = magnitude;
|
||||
dominantFrequency = frequency;
|
||||
}
|
||||
}
|
||||
|
||||
float[] spectrum = new float[_spectrumBins];
|
||||
@@ -248,6 +256,9 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
float bpmInstant = CalculateBpm();
|
||||
_smoothedBpm = Smooth(_smoothedBpm, bpmInstant, 0.18f, 0.04f);
|
||||
|
||||
int noteIndex = GetNoteIndexFromFrequency(dominantFrequency);
|
||||
float dominantStrength = Clamp01(dominantMagnitude * 0.02f);
|
||||
|
||||
AudioFeatures features = new()
|
||||
{
|
||||
Level = _smoothedLevel,
|
||||
@@ -256,6 +267,9 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
High = _smoothedHigh,
|
||||
Beat = _smoothedBeat,
|
||||
Bpm = _smoothedBpm,
|
||||
DominantFrequencyHz = dominantFrequency,
|
||||
DetectedNoteIndex = noteIndex,
|
||||
DetectedNoteStrength = dominantStrength,
|
||||
Spectrum = spectrum,
|
||||
TimeSeconds = now
|
||||
};
|
||||
@@ -319,6 +333,38 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
return Math.Clamp(bpm, 40f, 220f);
|
||||
}
|
||||
|
||||
private static int GetNoteIndexFromFrequency(float frequencyHz)
|
||||
{
|
||||
if (frequencyHz <= 0f)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
float midi = 69f + (12f * MathF.Log2(frequencyHz / 440f));
|
||||
int note = ((int)MathF.Round(midi)) % 12;
|
||||
if (note < 0)
|
||||
{
|
||||
note += 12;
|
||||
}
|
||||
|
||||
return note;
|
||||
}
|
||||
|
||||
private static float Clamp01(float value)
|
||||
{
|
||||
if (value < 0f)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
if (value > 1f)
|
||||
{
|
||||
return 1f;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private void ThrowIfDisposed()
|
||||
{
|
||||
if (_disposed)
|
||||
|
||||
Reference in New Issue
Block a user