examples/pcm/main.go
func playNote(scoreIndex int) rune {
	note := score[scoreIndex]

	// If the note is 'rest', play nothing.
	if note == 'R' {
		return rune(note)
	}

	freqs := []float64{freqC, freqD, freqE, freqF, freqG, freqA * 2, freqB * 2}
	freq := 0.0
	switch {
	case 'A' <= note && note <= 'B':
		freq = freqs[int(note)+len(freqs)-int('C')]
	case 'C' <= note && note <= 'G':
		freq = freqs[note-'C']
	default:
		panic("note out of range")
	}

	const vol = 1.0 / 16.0
	size := (ebiten.MaxTPS()/2 - 2) * sampleRate / ebiten.MaxTPS()
	l := make([]int16, size)
	r := make([]int16, size)
	square(l, vol, freq, 0.25)
	square(r, vol, freq, 0.25)

	p, _ := audio.NewPlayerFromBytes(audioContext, toBytes(l, r))
	p.Play()

	return rune(note)
}
func playNote(scoreIndex int) rune {
	note := score[scoreIndex]

	// If the note is 'rest', play nothing.
	if note == 'R' {
		return rune(note)
	}

	freqs := []float64{freqC, freqD, freqE, freqF, freqG, freqA * 2, freqB * 2}
	freq := 0.0
	switch {
	case 'A' <= note && note <= 'B':
		freq = freqs[int(note)+len(freqs)-int('C')]
	case 'C' <= note && note <= 'G':
		freq = freqs[note-'C']
	default:
		panic("note out of range")
	}

	const vol = 1.0 / 16.0
	size := (ebiten.MaxTPS()/2 - 2) * sampleRate / ebiten.MaxTPS()
	l := make([]int16, size)
	r := make([]int16, size)
	square(l, vol, freq, 0.25)
	square(r, vol, freq, 0.25)

	p, _ := audio.NewPlayerFromBytes(audioContext, toBytes(l, r))
	p.Play()

	return rune(note)
}
// playNote plays the note at scoreIndex of the score.