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  }