tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/tone/tone.go (about) 1 package tone 2 3 import ( 4 "machine" 5 ) 6 7 // PWM is the interface necessary for controlling a speaker. 8 type PWM interface { 9 Configure(config machine.PWMConfig) error 10 Channel(pin machine.Pin) (channel uint8, err error) 11 Top() uint32 12 Set(channel uint8, value uint32) 13 SetPeriod(period uint64) error 14 } 15 16 // Speaker is a configured audio output channel based on a PWM. 17 type Speaker struct { 18 pwm PWM 19 ch uint8 20 } 21 22 // New returns a new Speaker instance readily configured for the given PWM and 23 // pin combination. The lowest frequency possible is 27.5Hz, or A0. The audio 24 // output uses a PWM so the audio will form a square wave, a sound that 25 // generally sounds rather harsh. 26 func New(pwm PWM, pin machine.Pin) (Speaker, error) { 27 err := pwm.Configure(machine.PWMConfig{ 28 Period: uint64(1e9) / 55 / 2, 29 }) 30 if err != nil { 31 return Speaker{}, err 32 } 33 ch, err := pwm.Channel(pin) 34 if err != nil { 35 return Speaker{}, err 36 } 37 return Speaker{pwm, ch}, nil 38 } 39 40 // Stop disables the speaker, setting the output to low continuously. 41 func (s Speaker) Stop() { 42 s.pwm.Set(s.ch, 0) 43 } 44 45 // SetPeriod sets the period for the signal in nanoseconds. Use the following 46 // formula to convert frequency to period: 47 // 48 // period = 1e9 / frequency 49 // 50 // You can also use s.SetNote() instead for MIDI note numbers. 51 func (s Speaker) SetPeriod(period uint64) { 52 // Disable output. 53 s.Stop() 54 55 if period == 0 { 56 // Assume a period of 0 is intended as "no output". 57 return 58 } 59 60 // Reconfigure period. 61 s.pwm.SetPeriod(period) 62 63 // Make this a square wave by setting the channel position to half the 64 // period. 65 s.pwm.Set(s.ch, s.pwm.Top()/2) 66 } 67 68 // SetNote starts playing the given note. For example, s.SetNote(C4) will 69 // produce a 440Hz square wave tone. 70 func (s Speaker) SetNote(note Note) { 71 period := note.Period() 72 s.SetPeriod(period) 73 }