NET OwnChordDetect API Reference

Advanced musical chord detection and analysis library with support for real-time and file-based processing. Features key detection, extended chord recognition, and configurable detection modes.

Key Features Real-time chord detection, automatic key detection, extended chord support (9th, 11th, 13th), key-aware note naming, and configurable detection sensitivity.

Overview

OwnChordDetect provides comprehensive chord detection capabilities:

Main API - ChordDetect

The main entry point for chord detection functionality.

ChordDetect Static Class
public static class ChordDetect
{
    // File-based chord detection with key and tempo detection
    public static (List<TimedChord>, MusicalKey, int) DetectFromFile(
        string audioFile,
        float intervalSecond = 1.0f);
    
    // Real-time chord detection from note list
    public static (string chord, float stability) DetectRealtime(
        List<Note> notes,
        DetectionMode mode = DetectionMode.Optimized,
        int buffersize = 5);
}

DetectFromFile

Analyzes an audio file and returns timed chord progression with key and tempo.

Parameter Type Description
audioFile string Path to the audio file to analyze
intervalSecond float Analysis window size in seconds (default: 1.0f)
Returns Description
List<TimedChord> List of detected chords with timing information
MusicalKey Detected musical key of the song
int Detected tempo in BPM

DetectRealtime

Processes a list of notes for real-time chord detection with stability tracking.

Parameter Type Description
notes List<Note> List of notes to analyze
mode DetectionMode Detection mode to use (default: Optimized)
buffersize int Buffer size for stability analysis (default: 5)

Chord Detectors

Various chord detector implementations for different use cases.

ChordDetector (Base)

Core chord detection engine with multiple detection modes.

ChordDetector Constructor
public class ChordDetector
{
    public ChordDetector(
        DetectionMode mode = DetectionMode.Basic,
        float confidenceThreshold = 0.7f,
        float ambiguityThreshold = 0.0f,
        int bufferSize = 0);
    
    // Main detection methods
    public (string chord, float confidence) DetectChord(List<Note> notes);
    public ChordAnalysis AnalyzeChord(List<Note> notes);
    public (string chord, float stability) ProcessNotes(List<Note> newNotes);
    
    // Key management
    public MusicalKey DetectKeyFromNotes(List<Note> notes);
    public void SetKey(MusicalKey key);
}

BaseChordDetector

Basic chord detection for triads and simple chords.

BaseChordDetector
public class BaseChordDetector : ChordDetector
{
    public BaseChordDetector(float confidenceThreshold = 0.7f)
        : base(DetectionMode.Basic, confidenceThreshold) { }
}

ExtendedChordDetector

Extended chord detection including 7th, 9th, 11th, 13th chords.

ExtendedChordDetector
public class ExtendedChordDetector : ChordDetector
{
    public ExtendedChordDetector(float confidenceThreshold = 0.6f)
        : base(DetectionMode.Extended, confidenceThreshold) { }
}

OptimizedChordDetector

Optimized detection with ambiguity analysis and alternative suggestions.

OptimizedChordDetector
public class OptimizedChordDetector : ChordDetector
{
    public OptimizedChordDetector(
        float confidenceThreshold = 0.6f,
        float ambiguityThreshold = 0.1f)
        : base(DetectionMode.Optimized, confidenceThreshold, ambiguityThreshold) { }
    
    public (string chord, float confidence, bool isAmbiguous, string[] alternatives) 
        DetectChordAdvanced(List<Note> notes);
}

KeyAwareChordDetector

Key-aware detection with appropriate note naming (sharps vs flats).

KeyAwareChordDetector
public class KeyAwareChordDetector : ChordDetector
{
    public KeyAwareChordDetector(
        float confidenceThreshold = 0.6f,
        float ambiguityThreshold = 0.0f)
        : base(DetectionMode.KeyAware, confidenceThreshold, ambiguityThreshold) { }
}

RealTimeChordDetector

Real-time chord detector with stability tracking for continuous analysis.

RealTimeChordDetector
public class RealTimeChordDetector
{
    public RealTimeChordDetector(
        int bufferSize = 5,
        DetectionMode mode = DetectionMode.Optimized);
    
    public (string chord, float stability) ProcessNotes(List<Note> newNotes);
}

Analysis Classes

SongChordAnalyzer

Analyzes complete songs and extracts timed chord progressions with key awareness.

SongChordAnalyzer
public class SongChordAnalyzer
{
    public SongChordAnalyzer(
        float windowSize = 1.0f,
        float hopSize = 0.5f,
        float minimumChordDuration = 0.8f,
        float confidence = 0.6f);
    
    public MusicalKey? DetectedKey { get; }
    
    public List<TimedChord> AnalyzeSong(List<Note> songNotes);
    public List<TimedChord> AnalyzeSongInKey(List<Note> songNotes, MusicalKey key);
}
Parameter Description Default
windowSize Analysis window size in seconds 1.0f
hopSize Step size between windows in seconds 0.5f
minimumChordDuration Minimum chord duration to include in results 0.8f
confidence Minimum confidence threshold 0.6f

TimedChord

Represents a detected chord with timing information.

TimedChord Class
public class TimedChord
{
    public float StartTime { get; }      // Start time in seconds
    public float EndTime { get; }        // End time in seconds
    public string ChordName { get; }     // Chord name (e.g., "Cm7")
    public float Confidence { get; }     // Detection confidence (0.0 to 1.0)
    public string[] Notes { get; }       // Note names in the chord
    
    public override string ToString();
}

ChordAnalysis

Detailed chord analysis result with ambiguity detection.

ChordAnalysis Class
public class ChordAnalysis
{
    public string ChordName { get; }      // Detected chord name
    public float Confidence { get; }      // Confidence level (0.0 to 1.0)
    public string Explanation { get; }    // Detailed explanation
    public string[] NoteNames { get; }    // Notes forming the chord
    public bool IsAmbiguous { get; set; } // Whether detection is ambiguous
    public string[] Alternatives { get; set; } // Alternative chord names
    public int[] PitchClasses { get; set; }    // Pitch classes used
    public float[] Chromagram { get; set; }    // Chromagram data
    
    public override string ToString();
}

Core Classes

MusicalKey

Represents a musical key with signature and note naming preferences.

MusicalKey Class
public class MusicalKey
{
    public string KeyName { get; }              // Key name (e.g., "C", "F#", "Bb")
    public bool IsMajor { get; }                // Major (true) or Minor (false)
    public int Sharps { get; }                  // Number of sharps (0-7)
    public int Flats { get; }                   // Number of flats (0-7)
    public string[] PreferredNoteNames { get; } // Note naming preference
    
    public override string ToString(); // Returns "KeyName major/minor"
}

KeyDetector

Detects musical key using the Krumhansl-Schmuckler algorithm.

KeyDetector Class
public class KeyDetector
{
    public MusicalKey DetectKey(List<Note> notes);
}

ChordTemplates

Manages chord templates and note name conversion with key-aware naming.

ChordTemplates Static Class
public static class ChordTemplates
{
    // Get note name for pitch class with key context
    public static string GetNoteName(int pitchClass, MusicalKey? key = null);
    
    // Create chord template from pitch classes
    public static float[] CreateTemplate(int[] pitchClasses);
    
    // Create all chord templates with key-aware naming
    public static Dictionary<string, float[]> CreateAllTemplates(
        MusicalKey? key = null,
        bool includeExtended = true);
}

Detection Modes

Different detection modes for various use cases.

DetectionMode Enum
public enum DetectionMode
{
    Basic,      // Basic triads and simple chords only
    Extended,   // Includes 7th, 9th, 11th, 13th chords
    Optimized,  // Extended + ambiguity analysis
    KeyAware    // Optimized + key-aware note naming
}
Mode Chord Types Features Use Case
Basic Major, Minor, 7th, maj7, m7 Fast, simple Simple songs, quick analysis
Extended Basic + sus2/4, dim, aug, add9, 6th, 9th, 11th, 13th Comprehensive chord set Complex songs, jazz
Optimized All extended chords Ambiguity detection, alternatives Professional analysis
KeyAware All extended chords Optimized + key-aware naming Music theory applications

Supported Chord Types

Type Suffix Example Intervals
Major (none) C 0, 4, 7
Minor m Cm 0, 3, 7
Dominant 7th 7 C7 0, 4, 7, 10
Major 7th maj7 Cmaj7 0, 4, 7, 11
Minor 7th m7 Cm7 0, 3, 7, 10
Suspended 2nd sus2 Csus2 0, 2, 7
Suspended 4th sus4 Csus4 0, 5, 7
Diminished dim Cdim 0, 3, 6
Augmented aug Caug 0, 4, 8
Add 9 add9 Cadd9 0, 4, 7, 2
6th 6 C6 0, 4, 7, 9
Minor 6th m6 Cm6 0, 3, 7, 9
9th 9 C9 0, 4, 7, 10, 2
Minor 9th m9 Cm9 0, 3, 7, 10, 2
Major 9th maj9 Cmaj9 0, 4, 7, 11, 2
11th 11 C11 0, 4, 7, 10, 2, 5
Minor 11th m11 Cm11 0, 3, 7, 10, 2, 5
13th 13 C13 0, 4, 7, 10, 2, 9
Minor 13th m13 Cm13 0, 3, 7, 10, 2, 9

Usage Examples

File-Based Analysis

Example: Analyze Audio File
using OwnaudioNET.Features.OwnChordDetect;

// Detect chords from audio file
var (chords, key, tempo) = ChordDetect.DetectFromFile(
    audioFile: "song.mp3",
    intervalSecond: 1.0f
);

Console.WriteLine($"Detected key: {key}");
Console.WriteLine($"Detected tempo: {tempo} BPM");
Console.WriteLine($"Found {chords.Count} chords:");

foreach (var chord in chords)
{
    Console.WriteLine($"  {chord.StartTime:F1}s - {chord.EndTime:F1}s: " +
                     $"{chord.ChordName} (confidence: {chord.Confidence:F2})");
    Console.WriteLine($"    Notes: {string.Join(", ", chord.Notes)}");
}

Real-Time Detection

Example: Real-Time Chord Detection
using OwnaudioNET.Features.OwnChordDetect;
using OwnaudioNET.Features.OwnChordDetect.Detectors;

// Initialize real-time detector
var detector = new RealTimeChordDetector(
    bufferSize: 5,
    mode: DetectionMode.Optimized
);

// Process incoming notes
List<Note> currentNotes = GetCurrentNotes(); // Your note input

var (chord, stability) = detector.ProcessNotes(currentNotes);

Console.WriteLine($"Current chord: {chord}");
Console.WriteLine($"Stability: {stability:P1}");

// Alternative using static method
var (chord2, stability2) = ChordDetect.DetectRealtime(
    currentNotes,
    DetectionMode.Optimized,
    buffersize: 5
);

Custom Analysis with SongChordAnalyzer

Example: Custom Song Analysis
using OwnaudioNET.Features.OwnChordDetect.Analysis;

// Create analyzer with custom parameters
var analyzer = new SongChordAnalyzer(
    windowSize: 1.0f,           // 1 second windows
    hopSize: 0.5f,              // 0.5 second steps
    minimumChordDuration: 1.0f, // Min 1 second chords
    confidence: 0.90f           // 90% confidence threshold
);

// Analyze song (auto-detect key)
List<Note> songNotes = GetNotesFromAudio(); // Your note extraction
var chords = analyzer.AnalyzeSong(songNotes);

Console.WriteLine($"Detected key: {analyzer.DetectedKey}");

// Or analyze with specified key
var key = new MusicalKey("F#", true, 6, 0, sharpNoteNames);
var chordsInKey = analyzer.AnalyzeSongInKey(songNotes, key);

Advanced Chord Detection

Example: Advanced Detection with Alternatives
using OwnaudioNET.Features.OwnChordDetect.Detectors;

// Use optimized detector with ambiguity detection
var detector = new OptimizedChordDetector(
    confidenceThreshold: 0.6f,
    ambiguityThreshold: 0.1f
);

List<Note> notes = GetNotes();
var (chord, confidence, isAmbiguous, alternatives) = 
    detector.DetectChordAdvanced(notes);

Console.WriteLine($"Detected: {chord} (confidence: {confidence:F2})");

if (isAmbiguous)
{
    Console.WriteLine("Ambiguous detection!");
    Console.WriteLine($"Alternatives: {string.Join(", ", alternatives)}");
}

// Get detailed analysis
var analysis = detector.AnalyzeChord(notes);
Console.WriteLine(analysis.ToString());

Key Detection

Example: Standalone Key Detection
using OwnaudioNET.Features.OwnChordDetect.Core;

// Create key detector
var keyDetector = new KeyDetector();

// Detect key from notes
List<Note> notes = GetNotesFromSong();
var key = keyDetector.DetectKey(notes);

Console.WriteLine($"Detected key: {key.KeyName} {(key.IsMajor ? "major" : "minor")}");
Console.WriteLine($"Sharps: {key.Sharps}, Flats: {key.Flats}");
Console.WriteLine($"Preferred notes: {string.Join(", ", key.PreferredNoteNames)}");

// Use key for chord detection
var detector = new KeyAwareChordDetector();
detector.SetKey(key);
var (chord, confidence) = detector.DetectChord(notes);

Custom Chord Templates

Example: Working with Chord Templates
using OwnaudioNET.Features.OwnChordDetect.Core;

// Get note name with key context
var key = new MusicalKey("Bb", true, 0, 2, flatNoteNames);
string noteName = ChordTemplates.GetNoteName(10, key); // Returns "Bb"

// Create custom chord template
int[] pitchClasses = { 0, 4, 7 }; // Major triad
float[] template = ChordTemplates.CreateTemplate(pitchClasses);

// Get all chord templates for a key
var templates = ChordTemplates.CreateAllTemplates(
    key: key,
    includeExtended: true
);

Console.WriteLine($"Generated {templates.Count} chord templates");
foreach (var kvp in templates.Take(10))
{
    Console.WriteLine($"{kvp.Key}: {string.Join(", ", kvp.Value.Select(v => v.ToString("F2")))}");
}
Performance Tips For real-time applications, use DetectionMode.Optimized with appropriate buffer size. For analysis of complete songs, use SongChordAnalyzer with suitable window and hop sizes. Lower confidence thresholds detect more chords but may increase false positives.
Note Recognition Required OwnChordDetect requires musical notes (pitch + timing) as input. Use the included note detection from DetectFromFile or implement your own note extraction for custom audio sources.

Configuration Guidelines

Parameter Low Value Default High Value Effect
confidenceThreshold 0.4f 0.6f - 0.7f 0.9f Lower = more detections, higher = stricter
ambiguityThreshold 0.05f 0.1f 0.2f Lower = more alternatives suggested
windowSize 0.5f 1.0f 2.0f Smaller = more responsive, larger = more stable
hopSize 0.25f 0.5f 1.0f Smaller = finer resolution, more processing
minimumChordDuration 0.5f 0.8f - 1.0f 2.0f Filters out short/transient chords
bufferSize 3 5 10 Real-time stability (higher = more stable)

Related Documentation