@leafo/lml 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/music.d.ts CHANGED
@@ -1,108 +1,604 @@
1
+ /**
2
+ * MIDI pitch value for middle C (C4).
3
+ * @example
4
+ * parseNote("C4") === MIDDLE_C_PITCH // true
5
+ */
1
6
  export declare const MIDDLE_C_PITCH = 60;
7
+ /**
8
+ * Number of semitones in an octave.
9
+ */
2
10
  export declare const OCTAVE_SIZE = 12;
11
+ /**
12
+ * Bidirectional mapping between note letters and their semitone offsets from C.
13
+ * Maps both directions: number -> letter name, and letter name -> number.
14
+ * Only includes natural notes (no sharps/flats).
15
+ * @example
16
+ * OFFSETS[0] // "C"
17
+ * OFFSETS["C"] // 0
18
+ * OFFSETS[7] // "G"
19
+ * OFFSETS["G"] // 7
20
+ */
3
21
  export declare const OFFSETS: Record<number | string, string | number>;
22
+ /**
23
+ * Maps semitone offset (from C) to staff line position (0-6).
24
+ * Used for determining vertical placement on sheet music.
25
+ * @example
26
+ * LETTER_OFFSETS[0] // 0 (C)
27
+ * LETTER_OFFSETS[7] // 4 (G)
28
+ */
4
29
  export declare const LETTER_OFFSETS: Record<number, number>;
5
- export declare const NOTE_NAME_OFFSETS: Record<string, number>;
30
+ /**
31
+ * Maps note letter names to staff line position (0-6).
32
+ * C=0, D=1, E=2, F=3, G=4, A=5, B=6.
33
+ * @example
34
+ * NOTE_NAME_OFFSETS["C"] // 0
35
+ * NOTE_NAME_OFFSETS["G"] // 4
36
+ */
37
+ export declare const NOTE_NAME_OFFSETS: {
38
+ readonly C: 0;
39
+ readonly D: 1;
40
+ readonly E: 2;
41
+ readonly F: 3;
42
+ readonly G: 4;
43
+ readonly A: 5;
44
+ readonly B: 6;
45
+ };
46
+ /** Valid note letter names (A through G) */
47
+ export type NoteLetter = keyof typeof NOTE_NAME_OFFSETS;
48
+ /**
49
+ * Converts a MIDI pitch number to a note name string.
50
+ * @param pitch - MIDI pitch number (60 = middle C)
51
+ * @param sharpen - If true, use sharps for accidentals; if false, use flats
52
+ * @returns Note name with octave (e.g., "C4", "F#5", "Bb3")
53
+ * @example
54
+ * noteName(60) // "C4"
55
+ * noteName(61) // "C#4"
56
+ * noteName(61, false) // "Db4"
57
+ */
6
58
  export declare function noteName(pitch: number, sharpen?: boolean): string;
59
+ /**
60
+ * Parses a note string into its MIDI pitch number.
61
+ * @param note - Note string with octave (e.g., "C4", "F#5", "Bb3")
62
+ * @returns MIDI pitch number (60 = middle C)
63
+ * @throws Error if note format is invalid
64
+ * @example
65
+ * parseNote("C4") // 60
66
+ * parseNote("A4") // 69
67
+ * parseNote("C#4") // 61
68
+ */
7
69
  export declare function parseNote(note: string): number;
70
+ /**
71
+ * Calculates the vertical staff position for a note.
72
+ * Used for positioning notes on sheet music.
73
+ * @param note - Note string with octave (e.g., "C4", "G5"); letter must be A-G
74
+ * @returns Staff offset value (higher = higher on staff)
75
+ * @throws Error if note format is invalid; invalid letters yield NaN
76
+ * @example
77
+ * noteStaffOffset("C4") // 28
78
+ * noteStaffOffset("D4") // 29
79
+ */
8
80
  export declare function noteStaffOffset(note: string): number;
81
+ /**
82
+ * Compares two notes ignoring octave (enharmonic comparison).
83
+ * @param a - First note string (with or without octave)
84
+ * @param b - Second note string (with or without octave)
85
+ * @returns True if notes are the same pitch class
86
+ * @example
87
+ * notesSame("C4", "C5") // true (same pitch class)
88
+ * notesSame("C#4", "Db4") // true (enharmonic)
89
+ * notesSame("C4", "D4") // false
90
+ */
9
91
  export declare function notesSame(a: string, b: string): boolean;
92
+ /**
93
+ * Transposes a note by a given interval in semitones.
94
+ * @param note - Note string with octave (e.g., "C4")
95
+ * @param halfSteps - Number of semitones to transpose (positive = up, negative = down)
96
+ * @returns Transposed note string
97
+ * @example
98
+ * addInterval("C4", 2) // "D4" (whole step up)
99
+ * addInterval("C4", 12) // "C5" (octave up)
100
+ * addInterval("C4", -1) // "B3" (half step down)
101
+ */
10
102
  export declare function addInterval(note: string, halfSteps: number): string;
103
+ /**
104
+ * Compares two notes and returns the difference in semitones.
105
+ * @param a - First note string with octave
106
+ * @param b - Second note string with octave
107
+ * @returns 0 if equal, negative if a < b, positive if a > b
108
+ * @example
109
+ * compareNotes("C4", "C4") // 0
110
+ * compareNotes("C4", "D4") // -2
111
+ * compareNotes("D4", "C4") // 2
112
+ */
11
113
  export declare function compareNotes(a: string, b: string): number;
114
+ /**
115
+ * Checks if the first note is lower than the second.
116
+ * @param a - First note string with octave
117
+ * @param b - Second note string with octave
118
+ * @returns True if a is lower than b
119
+ * @example
120
+ * notesLessThan("C4", "D4") // true
121
+ * notesLessThan("C5", "C4") // false
122
+ */
12
123
  export declare function notesLessThan(a: string, b: string): boolean;
124
+ /**
125
+ * Checks if the first note is higher than the second.
126
+ * @param a - First note string with octave
127
+ * @param b - Second note string with octave
128
+ * @returns True if a is higher than b
129
+ * @example
130
+ * notesGreaterThan("D4", "C4") // true
131
+ * notesGreaterThan("C4", "D4") // false
132
+ */
13
133
  export declare function notesGreaterThan(a: string, b: string): boolean;
134
+ /**
135
+ * Represents a musical key signature with a given number of sharps or flats.
136
+ * Positive count = sharps, negative count = flats, zero = C major/A minor.
137
+ * @example
138
+ * const gMajor = new KeySignature(1) // G major (1 sharp)
139
+ * const fMajor = new KeySignature(-1) // F major (1 flat)
140
+ * gMajor.name() // "G"
141
+ * gMajor.accidentalNotes() // ["F"]
142
+ */
14
143
  export declare class KeySignature {
144
+ /** Circle of fifths note names */
15
145
  static FIFTHS: string[];
146
+ /** Natural note names in order of fifths (for accidental calculation) */
16
147
  static FIFTHS_TRUNCATED: string[];
17
148
  private static cache;
149
+ /**
150
+ * Returns all standard key signatures (excludes chromatic).
151
+ * Uses flat spellings for 6 accidentals (Gb instead of F#).
152
+ * @returns Array of KeySignature instances for standard major keys
153
+ */
18
154
  static allKeySignatures(): KeySignature[];
155
+ /**
156
+ * Gets a cached KeySignature instance for the given accidental count.
157
+ * @param count - Number of accidentals (positive = sharps, negative = flats)
158
+ * @returns KeySignature instance, or undefined if count is out of range
159
+ */
19
160
  static forCount(count: number): KeySignature | undefined;
161
+ /** Number of accidentals: positive = sharps, negative = flats, 0 = C major */
20
162
  count: number;
163
+ /**
164
+ * Creates a new KeySignature.
165
+ * @param count - Number of accidentals (positive = sharps, negative = flats)
166
+ */
21
167
  constructor(count: number);
168
+ /** Returns the number of accidentals in this key signature. */
22
169
  getCount(): number;
170
+ /** Returns true if this is a chromatic key signature. */
23
171
  isChromatic(): boolean;
172
+ /** Returns true if this key has sharps. */
24
173
  isSharp(): boolean;
174
+ /** Returns true if this key has flats. */
25
175
  isFlat(): boolean;
176
+ /**
177
+ * Returns the name of the major key (e.g., "G", "F", "Bb").
178
+ * @returns Key name string
179
+ * @example
180
+ * new KeySignature(0).name() // => "C"
181
+ * new KeySignature(1).name() // => "G" (1 sharp)
182
+ * new KeySignature(2).name() // => "D" (2 sharps)
183
+ * new KeySignature(-1).name() // => "F" (1 flat)
184
+ * new KeySignature(-2).name() // => "Bb" (2 flats)
185
+ */
26
186
  name(): string;
187
+ /** Returns the key name as a string. */
27
188
  toString(): string;
189
+ /**
190
+ * Returns the root note for building scales from this key signature.
191
+ * @returns Note name (e.g., "G", "F")
192
+ */
28
193
  scaleRoot(): string;
194
+ /**
195
+ * Returns the default scale for this key signature.
196
+ * @returns A MajorScale rooted on this key
197
+ */
29
198
  defaultScale(): MajorScale;
199
+ /**
200
+ * Converts a note to its enharmonic equivalent that fits this key signature.
201
+ * Sharp keys convert flats to sharps; flat keys convert sharps to flats.
202
+ * @param note - Note string with octave
203
+ * @returns Enharmonic equivalent note string
204
+ * @example
205
+ * new KeySignature(1).enharmonic("Db4") // "C#4" (G major uses sharps)
206
+ * new KeySignature(-1).enharmonic("C#4") // "Db4" (F major uses flats)
207
+ */
30
208
  enharmonic(note: string): string;
209
+ /**
210
+ * Converts a MIDI pitch to a note name with correct enharmonic spelling for this key.
211
+ * Uses sharps for sharp keys and flats for flat keys.
212
+ * @param pitch - MIDI pitch number
213
+ * @returns Note name string with appropriate accidentals for this key
214
+ * @example
215
+ * new KeySignature(1).noteName(61) // => "C#4" (G major uses sharps)
216
+ * new KeySignature(-1).noteName(61) // => "Db4" (F major uses flats)
217
+ * new KeySignature(0).noteName(61) // => "C#4" (C major defaults to sharps)
218
+ */
31
219
  noteName(pitch: number): string;
220
+ /**
221
+ * Returns the note letters that have accidentals in this key.
222
+ * @returns Array of note letters (e.g., ["F"] for G major, ["B", "E"] for Bb major)
223
+ * @example
224
+ * new KeySignature(1).accidentalNotes() // ["F"] (F# in G major)
225
+ * new KeySignature(-2).accidentalNotes() // ["B", "E"] (Bb, Eb)
226
+ */
32
227
  accidentalNotes(): string[];
228
+ /**
229
+ * Converts a note without accidentals to its actual pitch in this key.
230
+ * For example, in G major, "F" becomes "F#".
231
+ * @param note - Note string or MIDI pitch
232
+ * @returns Note string with appropriate accidentals applied
233
+ */
33
234
  unconvertNote(note: string | number): string;
235
+ /**
236
+ * Converts a note with accidentals to its staff spelling in this key.
237
+ * This is the inverse of unconvertNote - it strips accidentals that are
238
+ * implied by the key signature.
239
+ *
240
+ * Note: This only strips # or b accidentals. Notes without accidentals are
241
+ * returned unchanged. To determine if a natural sign is needed (e.g., F
242
+ * natural in D major), use {@link accidentalsForNote} which returns 0 when
243
+ * a natural is required.
244
+ *
245
+ * @param note - Note string with accidentals
246
+ * @returns Note string as it would appear on a staff with this key signature
247
+ * @example
248
+ * // In G major (1 sharp on F):
249
+ * new KeySignature(1).convertNote("F#4") // "F4" (sharp implied by key)
250
+ * new KeySignature(1).convertNote("C#4") // "C#4" (not in key, keep accidental)
251
+ * // In F major (1 flat on B):
252
+ * new KeySignature(-1).convertNote("Bb4") // "B4" (flat implied by key)
253
+ * // Notes without accidentals are unchanged:
254
+ * new KeySignature(2).convertNote("F4") // "F4" (use accidentalsForNote to check if natural needed)
255
+ */
256
+ convertNote(note: string): string;
257
+ /**
258
+ * Determines how many accidentals should display for a note in this key.
259
+ * @param note - Note string or MIDI pitch
260
+ * @returns null if no accidental needed, 0 for natural, 1 for sharp, -1 for flat, etc.
261
+ * @example
262
+ * // In G major (1 sharp on F):
263
+ * new KeySignature(1).accidentalsForNote("F#4") // null (already in key)
264
+ * new KeySignature(1).accidentalsForNote("F4") // 0 (natural needed)
265
+ * new KeySignature(1).accidentalsForNote("C#4") // 1 (sharp not in key)
266
+ */
34
267
  accidentalsForNote(note: string | number): number | null;
268
+ /**
269
+ * Returns the notes that need accidentals within a given pitch range.
270
+ * The returned notes are natural note names at specific octaves.
271
+ * @param min - Minimum note (string or MIDI pitch)
272
+ * @param max - Maximum note (string or MIDI pitch)
273
+ * @returns Array of note strings that need accidentals in this range
274
+ */
35
275
  notesInRange(min: string | number, max: string | number): string[];
36
276
  }
277
+ /**
278
+ * A special key signature for chromatic contexts where all 12 notes are equally valid.
279
+ * Renders as C major (no accidentals in the key signature) but allows all chromatic notes.
280
+ */
37
281
  export declare class ChromaticKeySignature extends KeySignature {
38
282
  constructor();
283
+ /** Returns true (this is always a chromatic key signature). */
39
284
  isChromatic(): boolean;
285
+ /** Returns "Chromatic" as the key name. */
40
286
  name(): string;
287
+ /** Returns "C" as the scale root. */
41
288
  scaleRoot(): string;
289
+ /** Returns a ChromaticScale as the default scale. */
42
290
  defaultScale(): ChromaticScale;
43
291
  }
292
+ /**
293
+ * Base class for musical scales. A scale is defined by a root note and
294
+ * a pattern of intervals (steps) in semitones.
295
+ * @example
296
+ * const cMajor = new MajorScale("C")
297
+ * cMajor.getRange(4, 8) // ["C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5"]
298
+ * cMajor.containsNote("D") // true
299
+ * cMajor.containsNote("Db") // false
300
+ */
44
301
  export declare class Scale {
302
+ /** Root note of the scale (e.g., "C", "G", "Bb") */
45
303
  root: string;
304
+ /** Interval pattern in semitones (e.g., [2,2,1,2,2,2,1] for major) */
46
305
  steps: number[];
306
+ /** True if this is a minor scale (affects enharmonic spelling) */
47
307
  minor: boolean;
308
+ /** True if this is a chromatic scale */
48
309
  chromatic: boolean;
310
+ /**
311
+ * Creates a new Scale.
312
+ * @param root - Root note as string (e.g., "C") or KeySignature
313
+ */
49
314
  constructor(root: string | KeySignature);
315
+ /**
316
+ * Returns all notes in the scale across 8 octaves.
317
+ * @returns Array of note strings covering the full playable range
318
+ */
50
319
  getFullRange(): string[];
320
+ /**
321
+ * Returns scale notes within a pitch range (inclusive).
322
+ * @param min - Minimum note string (e.g., "C3")
323
+ * @param max - Maximum note string (e.g., "C6")
324
+ * @returns Array of scale notes within the range
325
+ */
51
326
  getLooseRange(min: string, max: string): string[];
327
+ /**
328
+ * Returns a range of notes from the scale starting at a given octave.
329
+ * @param octave - Starting octave number
330
+ * @param count - Number of notes to return (default: one octave)
331
+ * @param offset - Scale degree offset (negative = start below root)
332
+ * @returns Array of note strings
333
+ * @example
334
+ * new MajorScale("C").getRange(4, 8) // ["C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5"]
335
+ * new MajorScale("C").getRange(4, 3, 2) // ["E4", "F4", "G4"] (start from 3rd degree)
336
+ */
52
337
  getRange(octave: number, count?: number, offset?: number): string[];
338
+ /**
339
+ * Determines if this scale should use flats for accidentals.
340
+ * Based on the circle of fifths position of the root.
341
+ * @returns True if the scale should use flats
342
+ */
53
343
  isFlat(): boolean;
344
+ /**
345
+ * Checks if a note (any octave) belongs to this scale.
346
+ * @param note - Note string (with or without octave)
347
+ * @returns True if the note is in the scale
348
+ * @example
349
+ * new MajorScale("C").containsNote("D") // true
350
+ * new MajorScale("C").containsNote("Db") // false
351
+ */
54
352
  containsNote(note: string): boolean;
353
+ /**
354
+ * Converts a scale degree number to a note name (without octave).
355
+ * Degrees are 1-indexed: 1 = root, 2 = second, etc.
356
+ * @param degree - Scale degree (1-indexed)
357
+ * @returns Note name string (e.g., "C", "D", "E")
358
+ * @example
359
+ * new MajorScale("C").degreeToName(1) // "C"
360
+ * new MajorScale("C").degreeToName(5) // "G"
361
+ */
55
362
  degreeToName(degree: number): string;
363
+ /**
364
+ * Gets the scale degree of a note.
365
+ * Degrees are 1-indexed: root = 1, second = 2, etc.
366
+ * @param note - Note string (with or without octave)
367
+ * @returns Scale degree number
368
+ * @throws Error if note is not in the scale
369
+ * @example
370
+ * new MajorScale("C").getDegree("C") // 1
371
+ * new MajorScale("C").getDegree("G") // 5
372
+ */
56
373
  getDegree(note: string): number;
374
+ /**
375
+ * Builds chord intervals by stacking thirds from a scale degree.
376
+ * @param degree - Starting scale degree (1-indexed)
377
+ * @param count - Number of intervals to generate (2 = triad, 3 = seventh chord)
378
+ * @returns Array of intervals in semitones
379
+ * @example
380
+ * new MajorScale("C").buildChordSteps(1, 2) // [4, 3] (C major triad intervals)
381
+ * new MajorScale("C").buildChordSteps(2, 2) // [3, 4] (D minor triad intervals)
382
+ */
57
383
  buildChordSteps(degree: number, count: number): number[];
384
+ /**
385
+ * Generates all diatonic chords in this scale.
386
+ * @param noteCount - Number of notes per chord (3 = triads, 4 = seventh chords)
387
+ * @returns Array of Chord instances built on each scale degree
388
+ * @example
389
+ * new MajorScale("C").allChords(3) // [C, Dm, Em, F, G, Am, Bdim]
390
+ */
58
391
  allChords(noteCount?: number): Chord[];
59
392
  }
393
+ /**
394
+ * Major scale with the interval pattern W-W-H-W-W-W-H (whole and half steps).
395
+ * @example
396
+ * new MajorScale("C").getRange(4, 8) // ["C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5"]
397
+ */
60
398
  export declare class MajorScale extends Scale {
61
399
  constructor(root: string | KeySignature);
62
400
  }
401
+ /**
402
+ * Natural minor scale (Aeolian mode) with pattern W-H-W-W-H-W-W.
403
+ * @example
404
+ * new MinorScale("A").getRange(4, 8) // ["A4", "B4", "C5", "D5", "E5", "F5", "G5", "A5"]
405
+ */
63
406
  export declare class MinorScale extends Scale {
64
407
  minor: boolean;
65
408
  constructor(root: string | KeySignature);
66
409
  }
410
+ /**
411
+ * Harmonic minor scale with raised 7th degree.
412
+ * Pattern: W-H-W-W-H-A2-H (A2 = augmented second, 3 semitones).
413
+ */
67
414
  export declare class HarmonicMinorScale extends Scale {
68
415
  minor: boolean;
69
416
  constructor(root: string | KeySignature);
70
417
  }
418
+ /**
419
+ * Ascending melodic minor scale with raised 6th and 7th degrees.
420
+ * Pattern: W-H-W-W-W-W-H.
421
+ */
71
422
  export declare class AscendingMelodicMinorScale extends Scale {
72
423
  minor: boolean;
73
424
  constructor(root: string | KeySignature);
74
425
  }
426
+ /**
427
+ * Major blues scale (6 notes).
428
+ * Notes in C: C, D, Eb, E, G, A.
429
+ */
75
430
  export declare class MajorBluesScale extends Scale {
76
431
  constructor(root: string | KeySignature);
77
432
  }
433
+ /**
434
+ * Minor blues scale (6 notes).
435
+ * Notes in C: C, Eb, F, Gb, G, Bb.
436
+ */
78
437
  export declare class MinorBluesScale extends Scale {
79
438
  minor: boolean;
80
439
  constructor(root: string | KeySignature);
81
440
  }
441
+ /**
442
+ * Chromatic scale containing all 12 semitones.
443
+ */
82
444
  export declare class ChromaticScale extends Scale {
83
445
  chromatic: boolean;
84
446
  constructor(root: string | KeySignature);
85
447
  }
448
+ /**
449
+ * Represents a musical chord as a special kind of scale.
450
+ * Chords are defined by a root note and interval pattern.
451
+ * @example
452
+ * const cMajor = new Chord("C", "M")
453
+ * cMajor.getRange(4, 3) // ["C4", "E4", "G4"]
454
+ * Chord.notes("C4", "m7") // ["C4", "Eb4", "G4", "Bb4"]
455
+ */
86
456
  export declare class Chord extends Scale {
87
- static SHAPES: Record<string, number[]>;
88
- static notes(note: string, chordName: string, inversion?: number, notesCount?: number): string[];
89
- constructor(root: string | KeySignature, intervals: string | number[]);
457
+ /**
458
+ * Predefined chord shapes as interval arrays (in semitones).
459
+ * - M: Major triad [4, 3]
460
+ * - m: Minor triad [3, 4]
461
+ * - dim: Diminished triad [3, 3]
462
+ * - aug: Augmented triad [4, 4]
463
+ * - 7: Dominant 7th [4, 3, 3]
464
+ * - M7: Major 7th [4, 3, 4]
465
+ * - m7: Minor 7th [3, 4, 3]
466
+ * - And more...
467
+ */
468
+ static SHAPES: {
469
+ readonly M: readonly [4, 3];
470
+ readonly m: readonly [3, 4];
471
+ readonly dim: readonly [3, 3];
472
+ readonly dimM7: readonly [3, 3, 5];
473
+ readonly dim7: readonly [3, 3, 3];
474
+ readonly aug: readonly [4, 4];
475
+ readonly augM7: readonly [4, 4, 3];
476
+ readonly M6: readonly [4, 3, 2];
477
+ readonly m6: readonly [3, 4, 2];
478
+ readonly M7: readonly [4, 3, 4];
479
+ readonly "7": readonly [4, 3, 3];
480
+ readonly m7: readonly [3, 4, 3];
481
+ readonly m7b5: readonly [3, 3, 4];
482
+ readonly mM7: readonly [3, 4, 4];
483
+ readonly Q: readonly [5, 5];
484
+ readonly Qb4: readonly [4, 5];
485
+ };
486
+ /**
487
+ * Static helper to get chord notes at a specific position.
488
+ * @param note - Root note with octave (e.g., "C4")
489
+ * @param chordName - Chord type from SHAPES (e.g., "M", "m7")
490
+ * @param inversion - Inversion number (0 = root position, 1 = first inversion, etc.)
491
+ * @param notesCount - Number of notes to return (0 = all chord tones)
492
+ * @returns Array of note strings
493
+ * @throws Error if note format is invalid or chordName is unknown
494
+ * @example
495
+ * Chord.notes("C4", "M") // ["C4", "E4", "G4"]
496
+ * Chord.notes("C4", "M", 1) // ["E4", "G4", "C5"] (first inversion)
497
+ */
498
+ static notes(note: string, chordName: ChordShapeName, inversion?: number, notesCount?: number): string[];
499
+ /**
500
+ * Creates a new Chord.
501
+ * @param root - Root note as string (e.g., "C") or KeySignature
502
+ * @param intervals - Chord shape name (e.g., "M", "m7") or array of intervals in semitones
503
+ * @example
504
+ * new Chord("C", "M") // C major from shape name
505
+ * new Chord("C", [4, 3]) // C major from intervals
506
+ */
507
+ constructor(root: string | KeySignature, intervals: ChordShapeName | readonly number[] | number[]);
508
+ /**
509
+ * Checks if this chord functions as a dominant (major or dominant 7th).
510
+ * @returns True if chord is major triad or dominant 7th
511
+ */
90
512
  isDominant(): boolean;
513
+ /**
514
+ * Gets possible resolution targets for this chord as a secondary dominant.
515
+ * A secondary dominant resolves down a fifth (up a fourth).
516
+ * @param noteCount - Number of notes in target chords (3 = triads, 4 = sevenths)
517
+ * @returns Array of possible target Chords (major and minor variants)
518
+ * @throws Error if this chord is not a dominant type
519
+ */
91
520
  getSecondaryDominantTargets(noteCount?: number): Chord[];
92
- chordShapeName(): string | undefined;
521
+ /**
522
+ * Gets the name of this chord's shape from SHAPES (e.g., "M", "m7", "dim").
523
+ * @returns Shape name string, or undefined if no matching shape found
524
+ */
525
+ chordShapeName(): ChordShapeName | undefined;
526
+ /**
527
+ * Checks if all given notes belong to this chord.
528
+ * @param notes - Array of note strings to check
529
+ * @returns True if all notes are chord tones
530
+ * @example
531
+ * new Chord("C", "M").containsNotes(["C4", "E4", "G4"]) // true
532
+ * new Chord("C", "M").containsNotes(["C4", "F4"]) // false
533
+ */
93
534
  containsNotes(notes: string[]): boolean;
535
+ /**
536
+ * Counts how many notes two chords have in common.
537
+ * @param otherChord - Chord to compare with
538
+ * @returns Number of shared notes
539
+ */
94
540
  countSharedNotes(otherChord: Chord): number;
541
+ /**
542
+ * Returns the chord name as a string (e.g., "C", "Am7", "Bdim").
543
+ * @returns Chord name with root and quality
544
+ */
95
545
  toString(): string;
96
546
  }
547
+ /** Valid chord shape names from Chord.SHAPES */
548
+ export type ChordShapeName = keyof typeof Chord.SHAPES;
549
+ /**
550
+ * Represents a musical staff with clef and note range information.
551
+ * Used for rendering notes on sheet music.
552
+ * @example
553
+ * const treble = Staff.forName("treble")
554
+ * treble.lowerNote // "E5" (bottom line)
555
+ * treble.upperNote // "F6" (top line)
556
+ */
97
557
  export declare class Staff {
98
558
  private static cache;
559
+ /**
560
+ * Gets a Staff instance by name.
561
+ * @param name - Staff name ("treble" or "bass")
562
+ * @returns Staff instance, or undefined if not found
563
+ */
99
564
  static forName(name: string): Staff | undefined;
565
+ /**
566
+ * Returns all available staff types.
567
+ * @returns Array of Staff instances
568
+ */
100
569
  static allStaves(): Staff[];
570
+ /** Staff name (e.g., "treble", "bass") */
101
571
  name: string;
572
+ /** Note on the bottom line of the staff */
102
573
  lowerNote: string;
574
+ /** Note on the top line of the staff */
103
575
  upperNote: string;
576
+ /** Note where the clef is positioned */
104
577
  clefNote: string;
578
+ /**
579
+ * Creates a new Staff.
580
+ * @param name - Staff identifier
581
+ * @param lowerNote - Note on bottom line (e.g., "E5" for treble)
582
+ * @param upperNote - Note on top line (e.g., "F6" for treble)
583
+ * @param clefNote - Note at clef position (e.g., "G5" for treble G-clef)
584
+ */
105
585
  constructor(name: string, lowerNote: string, upperNote: string, clefNote: string);
586
+ /**
587
+ * Gets the letter name of the clef (e.g., "G" for treble, "F" for bass).
588
+ * @returns Single letter clef name
589
+ */
106
590
  clefName(): string;
107
591
  }
592
+ /**
593
+ * Transposes a key signature by a given number of semitones using circle of fifths.
594
+ * Each semitone = 7 steps on the circle of fifths (mod 12).
595
+ * @param currentKs - Current key signature count (positive = sharps, negative = flats)
596
+ * @param semitones - Number of semitones to transpose (positive = up, negative = down)
597
+ * @returns New key signature count, normalized to -6..5 range
598
+ * @example
599
+ * transposeKeySignature(0, 1) // -5 (C major + 1 semitone = Db major)
600
+ * transposeKeySignature(1, 1) // -4 (G major + 1 semitone = Ab major)
601
+ * transposeKeySignature(0, 12) // 0 (octave transposition = no change)
602
+ */
603
+ export declare function transposeKeySignature(currentKs: number, semitones: number): number;
108
604
  //# sourceMappingURL=music.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"music.d.ts","sourceRoot":"","sources":["../src/music.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"music.d.ts","sourceRoot":"","sources":["../src/music.ts"],"names":[],"mappings":"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"}