tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/tone/notes.go (about) 1 package tone 2 3 // Note represents a MIDI note number. For example, Note(69) is A4 or 440Hz. 4 type Note uint8 5 6 // Define all the notes in a format similar to the Tone library in the Arduino 7 // IDE. 8 const ( 9 A0 Note = iota + 21 // 27.5Hz 10 AS0 11 B0 12 C1 13 CS1 14 D1 15 DS1 16 E1 17 F1 18 FS1 19 G1 20 GS1 21 A1 // 55Hz 22 AS1 23 B1 24 C2 25 CS2 26 D2 27 DS2 28 E2 29 F2 30 FS2 31 G2 32 GS2 33 A2 // 110Hz 34 AS2 35 B2 36 C3 37 CS3 38 D3 39 DS3 40 E3 41 F3 42 FS3 43 G3 44 GS3 45 A3 // 220Hz 46 AS3 47 B3 48 C4 49 CS4 50 D4 51 DS4 52 E4 53 F4 54 FS4 55 G4 56 GS4 57 A4 // 440Hz 58 AS4 59 B4 60 C5 61 CS5 62 D5 63 DS5 64 E5 65 F5 66 FS5 67 G5 68 GS5 69 A5 // 880Hz 70 AS5 71 B5 72 C6 73 CS6 74 D6 75 DS6 76 E6 77 F6 78 FS6 79 G6 80 GS6 81 A6 // 1760Hz 82 AS6 83 B6 84 C7 85 CS7 86 D7 87 DS7 88 E7 89 F7 90 FS7 91 G7 92 GS7 93 A7 // 3520Hz 94 AS7 95 B7 96 C8 97 CS8 98 D8 99 DS8 100 E8 101 F8 102 FS8 103 G8 104 GS8 105 A8 // 7040Hz 106 AS8 107 B8 108 ) 109 110 // Period returns the period in nanoseconds of a single wave. 111 func (n Note) Period() uint64 { 112 if n == 0 { 113 // Assume that a zero note means no sound. 114 return 0 115 } 116 117 octave := (n - 9) / 12 118 note := (n - 9) - octave*12 119 120 // Start with a base period (in nanoseconds) of 6.875Hz (quarter the 121 // frequency of A0) and shift it right with the octave to get the base 122 // period of this note. 123 // 145454545 = 1e9 / 6.875 124 basePeriod := uint32(145454545) >> octave 125 126 // Make the pitch higher based on the note within the octave. 127 period := uint64(basePeriod) * uint64(tones[note]) / 32768 128 129 return period 130 } 131 132 // Constants to calculate the pitch within an octave. Python oneliner: 133 // [round(1e9/(440*(2**(n/12))) / (1e9/440) * 0x8000) for n in range(12)] 134 var tones = [12]uint16{ 135 32768, 136 30929, 137 29193, 138 27554, 139 26008, 140 24548, 141 23170, 142 21870, 143 20643, 144 19484, 145 18390, 146 17358, 147 }