Update .gitignore to exclude new build and tool files
Added FodyWeavers.xsd, .dotnet-home/.dotnet, .dotnet-home/.dotnet/TelemetryStorageService, and .nuget to .gitignore to prevent tracking of generated and tool-related files.
This commit is contained in:
@@ -50,6 +50,8 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
private int _stableNoteIndex = -1;
|
||||
private float _stableNoteStrength;
|
||||
private float _lastNoteChangeTimeSeconds;
|
||||
private bool _noteIsActive;
|
||||
private int _activeNoteIndex = -1;
|
||||
|
||||
private Snapshot _latestSnapshot;
|
||||
private bool _disposed;
|
||||
@@ -295,7 +297,7 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
int noteIndex = GetNoteIndexFromFrequency(dominantFrequency);
|
||||
float whistleBoost = GetWhistleBoost(dominantFrequency);
|
||||
float dominantStrength = Clamp01(dominantMagnitude * profile.NoteStrengthGain * (1f + whistleBoost * 0.65f));
|
||||
DetectChord(_chroma, out int chordRoot, out int chordType, out float chordConfidence);
|
||||
DetectChord(_chroma, _smoothedLevel, profile, out int chordRoot, out int chordType, out float chordConfidence);
|
||||
ApplyDetectionStability(
|
||||
now,
|
||||
profile,
|
||||
@@ -309,6 +311,7 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
out int stableChordRoot,
|
||||
out int stableChordType,
|
||||
out float stableChordConfidence);
|
||||
bool noteOnset = DetectNoteOnset(stableNoteIndex, stableNoteStrength, profile);
|
||||
|
||||
AudioFeatures features = new()
|
||||
{
|
||||
@@ -321,6 +324,7 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
DominantFrequencyHz = dominantFrequency,
|
||||
DetectedNoteIndex = stableNoteIndex,
|
||||
DetectedNoteStrength = stableNoteStrength,
|
||||
NoteOnset = noteOnset,
|
||||
DetectedChordRootIndex = stableChordRoot,
|
||||
DetectedChordType = stableChordType,
|
||||
DetectedChordConfidence = stableChordConfidence,
|
||||
@@ -404,8 +408,16 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
return note;
|
||||
}
|
||||
|
||||
private void DetectChord(float[] chroma, out int root, out int type, out float confidence)
|
||||
private void DetectChord(float[] chroma, float level, SensitivityProfile profile, out int root, out int type, out float confidence)
|
||||
{
|
||||
if (level < profile.ChordLevelThreshold)
|
||||
{
|
||||
root = -1;
|
||||
type = -1;
|
||||
confidence = 0f;
|
||||
return;
|
||||
}
|
||||
|
||||
float total = 0f;
|
||||
for (int i = 0; i < chroma.Length; i++)
|
||||
{
|
||||
@@ -463,8 +475,6 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
_lastChordRoot = bestRoot;
|
||||
_lastChordType = bestType;
|
||||
root = bestRoot;
|
||||
type = bestType;
|
||||
confidence = conf;
|
||||
@@ -599,6 +609,41 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
stableChordType = _lastChordType;
|
||||
stableChordConfidence = chordConfidence;
|
||||
}
|
||||
else if (_lastChordRoot >= 0 && (_smoothedLevel <= profile.ChordLevelThreshold || stableNoteStrength <= profile.NoteReleaseThreshold))
|
||||
{
|
||||
// Clear stale chord label when audio falls back to near-silence.
|
||||
if ((now - _lastChordChangeTimeSeconds) >= profile.SwitchHoldSeconds)
|
||||
{
|
||||
_lastChordRoot = -1;
|
||||
_lastChordType = -1;
|
||||
stableChordRoot = -1;
|
||||
stableChordType = -1;
|
||||
stableChordConfidence = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool DetectNoteOnset(int stableNoteIndex, float stableNoteStrength, SensitivityProfile profile)
|
||||
{
|
||||
if (stableNoteIndex >= 0 && stableNoteStrength >= profile.NoteOnsetThreshold)
|
||||
{
|
||||
if (!_noteIsActive || _activeNoteIndex != stableNoteIndex)
|
||||
{
|
||||
_noteIsActive = true;
|
||||
_activeNoteIndex = stableNoteIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_noteIsActive && stableNoteStrength <= profile.NoteReleaseThreshold)
|
||||
{
|
||||
_noteIsActive = false;
|
||||
_activeNoteIndex = -1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private readonly struct SensitivityProfile(
|
||||
@@ -613,7 +658,10 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
float referenceDecay,
|
||||
float switchHoldSeconds,
|
||||
float noteConfidenceThreshold,
|
||||
float chordConfidenceThreshold)
|
||||
float chordConfidenceThreshold,
|
||||
float noteOnsetThreshold,
|
||||
float noteReleaseThreshold,
|
||||
float chordLevelThreshold)
|
||||
{
|
||||
public float LevelGain { get; } = levelGain;
|
||||
public float BassGain { get; } = bassGain;
|
||||
@@ -627,6 +675,9 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
public float SwitchHoldSeconds { get; } = switchHoldSeconds;
|
||||
public float NoteConfidenceThreshold { get; } = noteConfidenceThreshold;
|
||||
public float ChordConfidenceThreshold { get; } = chordConfidenceThreshold;
|
||||
public float NoteOnsetThreshold { get; } = noteOnsetThreshold;
|
||||
public float NoteReleaseThreshold { get; } = noteReleaseThreshold;
|
||||
public float ChordLevelThreshold { get; } = chordLevelThreshold;
|
||||
|
||||
public static SensitivityProfile Microphone { get; } = new(
|
||||
levelGain: 1.20f,
|
||||
@@ -640,7 +691,10 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
referenceDecay: 0.010f,
|
||||
switchHoldSeconds: 0.18f,
|
||||
noteConfidenceThreshold: 0.11f,
|
||||
chordConfidenceThreshold: 0.18f);
|
||||
chordConfidenceThreshold: 0.18f,
|
||||
noteOnsetThreshold: 0.20f,
|
||||
noteReleaseThreshold: 0.08f,
|
||||
chordLevelThreshold: 0.10f);
|
||||
|
||||
public static SensitivityProfile SystemOutput { get; } = new(
|
||||
levelGain: 1.00f,
|
||||
@@ -654,7 +708,10 @@ public sealed class AudioAnalyzer : IDisposable
|
||||
referenceDecay: 0.012f,
|
||||
switchHoldSeconds: 0.18f,
|
||||
noteConfidenceThreshold: 0.12f,
|
||||
chordConfidenceThreshold: 0.14f);
|
||||
chordConfidenceThreshold: 0.14f,
|
||||
noteOnsetThreshold: 0.18f,
|
||||
noteReleaseThreshold: 0.07f,
|
||||
chordLevelThreshold: 0.08f);
|
||||
}
|
||||
|
||||
private void ThrowIfDisposed()
|
||||
|
||||
Reference in New Issue
Block a user