1 /**
2 * Copyright © Underground Rekordz 2019
3 * License: MIT (https://github.com/UndergroundRekordz/Musicpulator/blob/master/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 */
6 module musicpulator.notes;
7 
8 import musicpulator.musicalnote;
9 
10 /// Collection of notes and base ids.
11 static immutable(ptrdiff_t[MusicalNote]) noteBaseIds;
12 
13 /// Static constructor for the module.
14 static this()
15 {
16   noteBaseIds =
17   [
18     MusicalNote.c : 0,
19     MusicalNote.cSharp : 1,
20     MusicalNote.dFlat : 1,
21     MusicalNote.d : 2,
22     MusicalNote.dSharp : 3,
23     MusicalNote.eFlat : 3,
24     MusicalNote.e : 4,
25     MusicalNote.f : 5,
26     MusicalNote.fSharp : 6,
27     MusicalNote.gFlat : 6,
28     MusicalNote.g : 7,
29     MusicalNote.gSharp : 8,
30     MusicalNote.aFlat : 8,
31     MusicalNote.a : 9,
32     MusicalNote.aSharp : 10,
33     MusicalNote.bFlat : 10,
34     MusicalNote.b : 11,
35     MusicalNote.cFlat : 11
36   ];
37 }
38 
39 /// An invalid note id.
40 private static const NoteId invalidNoteId = NoteId(-1);
41 
42 /// A note id.
43 struct NoteId
44 {
45   /// The id of the note.
46   package(musicpulator) ptrdiff_t id;
47   /**
48   * Creates a new note id.
49   * Params:
50   *   id = The id of the note.
51   */
52   private this(ptrdiff_t id)
53   {
54     this.id = id;
55   }
56 }
57 
58 /**
59 * Gets the id of a note.
60 * Params:
61 *   note = The note to get the id of.
62 *   octave = The octave the id should be relative to.
63 * Returns:
64 *   Returns the id for a note relative to the specific octave.
65 */
66 NoteId getNoteId(MusicalNote note, ptrdiff_t octave)
67 {
68   import std..string : toLower;
69 
70   if (!note || !note.length)
71   {
72     return invalidNoteId;
73   }
74 
75   auto noteIndex = noteBaseIds.get(note, -1);
76 
77   if (noteIndex == -1)
78   {
79     return invalidNoteId;
80   }
81 
82   return NoteId((octave * 100) + noteIndex);
83 }