Help us shape the future of Go! Take the 2026 Go Developer Survey

songs

package
v0.27.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 8, 2026 License: BSD-3-Clause Imports: 7 Imported by: 0

Documentation

Overview

Package songs provides built-in melodies for testing audio playback. All songs are defined using the beat-based notation system with tempo and time signature.

Index

Constants

View Source
const (
	// Octave 2
	C2 = 65.0
	D2 = 73.0
	E2 = 82.0
	F2 = 87.0
	G2 = 98.0
	A2 = 110.0
	B2 = 123.0

	// Octave 3
	C3  = 131.0
	D3  = 147.0
	Eb3 = 156.0 // Eb3 / D#3
	E3  = 165.0
	F3  = 175.0
	Fs3 = 185.0 // F#3
	G3  = 196.0
	Gs3 = 208.0 // G#3
	A3  = 220.0
	As3 = 233.0 // A#3
	Bb3 = 233.0 // Bb3 (enharmonic with A#3)
	B3  = 247.0

	// Octave 4
	C4  = 262.0
	Cs4 = 277.0 // C#4 / Db4
	D4  = 294.0
	Ds4 = 311.0 // D#4
	Eb4 = 311.0 // Eb4 (enharmonic with D#4)
	E4  = 330.0
	F4  = 349.0
	Fs4 = 370.0 // F#4
	G4  = 392.0
	Gs4 = 415.0 // G#4 / Ab4
	A4  = 440.0
	As4 = 466.0 // A#4
	Bb4 = 466.0 // Bb4 (enharmonic with A#4)
	B4  = 494.0

	// Octave 5
	C5  = 523.0
	Cs5 = 554.0 // C#5
	D5  = 587.0
	Ds5 = 622.0 // D#5
	Eb5 = 622.0 // Eb5 (enharmonic with D#5)
	E5  = 659.0
	F5  = 698.0
	Fs5 = 740.0 // F#5
	G5  = 784.0
	Gs5 = 831.0 // G#5
	A5  = 880.0
	As5 = 932.0 // A#5 / Bb5
	B5  = 988.0

	// Octave 6
	C6 = 1047.0

	Rest = 0.0
)

Note frequencies (Hz) - Extended range

View Source
const (
	Whole      = 4.0     // 全音符
	Half       = 2.0     // 二分音符
	Quarter    = 1.0     // 四分音符
	Eighth     = 0.5     // 八分音符
	Sixteenth  = 0.25    // 十六分音符
	DotWhole   = 6.0     // 附点全音符
	DotHalf    = 3.0     // 附点二分音符
	DotQuarter = 1.5     // 附点四分音符
	DotEighth  = 0.75    // 附点八分音符
	Triplet8   = 1.0 / 3 // 三连音八分音符
)

Note value constants (in terms of beats, quarter note = 1)

View Source
const Am = A3

Am is A minor root note (alias for readability)

View Source
const DefaultFormat = pcm.L16Mono16K

DefaultFormat is the default audio format for songs.

Variables

View Source
var (
	Time4_4 = TimeSignature{4, 4} // Common time (4/4)
	Time3_4 = TimeSignature{3, 4} // Waltz time (3/4)
	Time2_4 = TimeSignature{2, 4} // March time (2/4)
	Time6_8 = TimeSignature{6, 8} // Compound duple (6/8)
)

Common time signatures

All contains all built-in songs with tempo-based notation.

View Source
var SongBachInvention1 = Song{
	ID:    "bach_invention1",
	Name:  "巴赫二部创意曲 No.1",
	Tempo: Tempo{BPM: 100, Signature: Time4_4},
	Voices: func() []BeatVoice {

		soprano := BeatVoice{Notes: []BeatNote{

			N(C4, Sixteenth), N(D4, Sixteenth), N(E4, Sixteenth), N(F4, Sixteenth), N(D4, Sixteenth), N(E4, Sixteenth), N(C4, Eighth),
			N(Rest, Eighth), N(G4, Sixteenth), N(A4, Sixteenth), N(B4, Sixteenth), N(C5, Sixteenth), N(A4, Sixteenth), N(B4, Sixteenth), N(G4, Eighth),

			N(Rest, Eighth), N(C5, Sixteenth), N(D5, Sixteenth), N(E5, Sixteenth), N(F5, Sixteenth), N(D5, Sixteenth), N(E5, Sixteenth), N(C5, Eighth),
			N(A4, Sixteenth), N(G4, Sixteenth), N(F4, Sixteenth), N(E4, Sixteenth), N(F4, Sixteenth), N(A4, Sixteenth), N(G4, Quarter),

			N(G4, Sixteenth), N(A4, Sixteenth), N(B4, Sixteenth), N(C5, Sixteenth), N(A4, Sixteenth), N(B4, Sixteenth), N(G4, Eighth),
			N(Rest, Eighth), N(D5, Sixteenth), N(E5, Sixteenth), N(F5, Sixteenth), N(G5, Sixteenth), N(E5, Sixteenth), N(F5, Sixteenth), N(D5, Eighth),

			N(E5, Quarter), N(D5, Quarter), N(C5, Quarter), N(B4, Quarter),
			N(C5, Half),
		}}

		bass := BeatVoice{Notes: []BeatNote{

			N(Rest, DotQuarter),
			N(C3, Sixteenth), N(D3, Sixteenth), N(E3, Sixteenth), N(F3, Sixteenth), N(D3, Sixteenth), N(E3, Sixteenth), N(C3, Eighth),

			N(Rest, Eighth), N(G3, Sixteenth), N(A3, Sixteenth), N(B3, Sixteenth), N(C4, Sixteenth), N(A3, Sixteenth), N(B3, Sixteenth), N(G3, Eighth),

			N(Rest, Eighth), N(E3, Sixteenth), N(F3, Sixteenth), N(G3, Sixteenth), N(A3, Sixteenth), N(F3, Sixteenth), N(G3, Sixteenth), N(E3, Eighth),
			N(F3, Sixteenth), N(E3, Sixteenth), N(D3, Sixteenth), N(C3, Sixteenth), N(D3, Sixteenth), N(F3, Sixteenth), N(E3, Quarter),

			N(E3, Sixteenth), N(F3, Sixteenth), N(G3, Sixteenth), N(A3, Sixteenth), N(F3, Sixteenth), N(G3, Sixteenth), N(E3, Eighth),
			N(Rest, Eighth), N(B3, Sixteenth), N(C4, Sixteenth), N(D4, Sixteenth), N(E4, Sixteenth), N(C4, Sixteenth), N(D4, Sixteenth), N(B3, Eighth),

			N(C4, Quarter), N(G3, Quarter), N(E3, Quarter), N(G3, Quarter),
			N(C3, Half),
		}}

		return []BeatVoice{soprano, bass}
	},
}

SongBachInvention1 - 巴赫二部创意曲 No.1 (BWV 772)

View Source
var SongBachMinuet = Song{
	ID:    "bach_minuet",
	Name:  "巴赫小步舞曲",
	Tempo: Tempo{BPM: 110, Signature: Time3_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(D5, Quarter), N(G4, Quarter), N(A4, Quarter), N(B4, Quarter), N(C5, Quarter), N(D5, Quarter),
			N(G4, Half), N(G4, Quarter), N(E5, Quarter), N(C5, Quarter), N(D5, Quarter),
			N(E5, Quarter), N(Fs5, Quarter), N(G5, Quarter), N(G4, Half), N(G4, Quarter),
			N(C5, Quarter), N(D5, Quarter), N(C5, Quarter), N(B4, Quarter), N(A4, Quarter), N(B4, Quarter),

			N(A4, Half), N(D4, Quarter), N(D5, Quarter), N(G4, Quarter), N(A4, Quarter),
			N(B4, Quarter), N(C5, Quarter), N(D5, Quarter), N(G4, Half), N(G4, Quarter),
			N(E5, Quarter), N(C5, Quarter), N(D5, Quarter), N(E5, Quarter), N(Fs5, Quarter), N(G5, Quarter),
			N(G4, Half), N(G4, Quarter),

			N(B4, Quarter), N(G4, Quarter), N(A4, Quarter), N(B4, Quarter), N(G4, Quarter), N(Fs4, Quarter),
			N(G4, DotHalf),
		}}

		bass := BeatVoice{Notes: []BeatNote{

			N(G3, Half), N(Rest, Quarter), N(G3, Half), N(Rest, Quarter),
			N(B3, Half), N(Rest, Quarter), N(C4, Half), N(Rest, Quarter),
			N(D4, Half), N(Rest, Quarter), N(B3, Half), N(Rest, Quarter),
			N(C4, Half), N(Rest, Quarter), N(D4, Half), N(Rest, Quarter),

			N(D3, DotHalf), N(G3, Half), N(Rest, Quarter),
			N(G3, Half), N(Rest, Quarter), N(E3, Half), N(Rest, Quarter),
			N(C4, Half), N(Rest, Quarter), N(D4, Half), N(Rest, Quarter),
			N(B3, Half), N(Rest, Quarter),

			N(E3, Half), N(Rest, Quarter), N(D3, Half), N(Rest, Quarter),
			N(G3, DotHalf),
		}}

		return []BeatVoice{melody, bass}
	},
}

SongBachMinuet - 巴赫小步舞曲 (BWV Anh. 114)

View Source
var SongBurgmullerArabesque = Song{
	ID:    "burgmuller_arabesque",
	Name:  "阿拉伯风格曲",
	Tempo: Tempo{BPM: 130, Signature: Time2_4},
	Voices: func() []BeatVoice {

		melody := BeatVoice{Notes: []BeatNote{

			N(A4, Sixteenth), N(B4, Sixteenth), N(C5, Sixteenth), N(D5, Sixteenth),
			N(E5, Eighth), N(Rest, Eighth),
			N(E5, Sixteenth), N(D5, Sixteenth), N(C5, Sixteenth), N(B4, Sixteenth),
			N(A4, Eighth), N(Rest, Eighth),

			N(A4, Sixteenth), N(B4, Sixteenth), N(C5, Sixteenth), N(D5, Sixteenth),
			N(E5, Sixteenth), N(F5, Sixteenth), N(E5, Sixteenth), N(D5, Sixteenth),
			N(C5, Sixteenth), N(B4, Sixteenth), N(A4, Sixteenth), N(Gs4, Sixteenth),
			N(A4, Quarter),

			N(A4, Sixteenth), N(B4, Sixteenth), N(C5, Sixteenth), N(D5, Sixteenth),
			N(E5, Eighth), N(Rest, Eighth),
			N(E5, Sixteenth), N(F5, Sixteenth), N(E5, Sixteenth), N(D5, Sixteenth),
			N(C5, Eighth), N(Rest, Eighth),

			N(C5, Sixteenth), N(D5, Sixteenth), N(E5, Sixteenth), N(F5, Sixteenth),
			N(G5, Sixteenth), N(F5, Sixteenth), N(E5, Sixteenth), N(D5, Sixteenth),
			N(C5, Sixteenth), N(B4, Sixteenth), N(A4, Sixteenth), N(B4, Sixteenth),
			N(A4, Quarter),
		}}

		accomp := BeatVoice{Notes: []BeatNote{
			N(A3, Quarter), N(A3, Eighth), N(Rest, Eighth),
			N(A3, Quarter), N(A3, Eighth), N(Rest, Eighth),
			N(A3, Quarter), N(E3, Quarter),
			N(A3, Half),

			N(A3, Quarter), N(A3, Eighth), N(Rest, Eighth),
			N(C4, Quarter), N(C4, Eighth), N(Rest, Eighth),
			N(G3, Quarter), N(G3, Quarter),
			N(A3, Half),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongBurgmullerArabesque - 布格缪勒 阿拉伯风格曲 Op.100 No.2

View Source
var SongCanon = Song{
	ID:    "canon",
	Name:  "卡农",
	Tempo: Tempo{BPM: 60, Signature: Time4_4},
	Voices: func() []BeatVoice {

		melody := BeatVoice{Notes: []BeatNote{

			N(Fs5, Half), N(E5, Half), N(D5, Half), N(Cs5, Half),
			N(B4, Half), N(A4, Half), N(B4, Half), N(Cs5, Half),

			N(D5, Quarter), N(Fs5, Quarter), N(A5, Quarter), N(G5, Quarter),
			N(Fs5, Quarter), N(D5, Quarter), N(Fs5, Quarter), N(E5, Quarter),
			N(D5, Quarter), N(B4, Quarter), N(D5, Quarter), N(A4, Quarter),
			N(G4, Quarter), N(B4, Quarter), N(A4, Quarter), N(G4, Quarter),

			N(Fs4, Quarter), N(D4, Quarter), N(E4, Quarter), N(Fs4, Quarter),
			N(G4, Quarter), N(A4, Quarter), N(B4, Quarter), N(G4, Quarter),
			N(Fs4, Half), N(D5, Half), N(D5, Whole),
		}}

		bass := BeatVoice{Notes: []BeatNote{

			N(D3, Half), N(A3, Half), N(B3, Half), N(Fs3, Half),
			N(G3, Half), N(D3, Half), N(G3, Half), N(A3, Half),
			N(D3, Half), N(A3, Half), N(B3, Half), N(Fs3, Half),
			N(G3, Half), N(D3, Half), N(G3, Half), N(A3, Half),
			N(D3, Half), N(A3, Half), N(B3, Half), N(Fs3, Half),
			N(G3, Half), N(D3, Half), N(D3, Whole),
		}}

		return []BeatVoice{melody, bass}
	},
}

SongCanon - 卡农 (Pachelbel's Canon in D)

View Source
var SongCanon3Voice = Song{
	ID:    "canon_3voice",
	Name:  "卡农三声部",
	Tempo: Tempo{BPM: 60, Signature: Time4_4},
	Voices: func() []BeatVoice {

		voice1 := BeatVoice{Notes: []BeatNote{

			N(Fs5, Half), N(E5, Half), N(D5, Half), N(Cs5, Half),
			N(B4, Half), N(A4, Half), N(B4, Half), N(Cs5, Half),

			N(D5, Quarter), N(Fs5, Quarter), N(A5, Quarter), N(G5, Quarter), N(Fs5, Quarter), N(D5, Quarter), N(Fs5, Quarter), N(E5, Quarter),
			N(D5, Quarter), N(B4, Quarter), N(D5, Quarter), N(A4, Quarter), N(G4, Quarter), N(B4, Quarter), N(A4, Quarter), N(G4, Quarter),

			N(Fs4, Quarter), N(D4, Quarter), N(E4, Quarter), N(Fs4, Quarter), N(G4, Quarter), N(A4, Quarter), N(B4, Quarter), N(G4, Quarter),
			N(Fs4, Half), N(D5, Half), N(D5, Whole),
		}}

		voice2 := BeatVoice{Notes: []BeatNote{

			N(Rest, Whole), N(Rest, Whole),

			N(Fs5, Half), N(E5, Half), N(D5, Half), N(Cs5, Half),
			N(B4, Half), N(A4, Half), N(B4, Half), N(Cs5, Half),

			N(D5, Quarter), N(Fs5, Quarter), N(A5, Quarter), N(G5, Quarter), N(Fs5, Quarter), N(D5, Quarter), N(Fs5, Quarter), N(E5, Quarter),
			N(D5, Half), N(A4, Half), N(A4, Whole),
		}}

		voice3 := BeatVoice{Notes: []BeatNote{

			N(D3, Half), N(A3, Half), N(B3, Half), N(Fs3, Half),
			N(G3, Half), N(D3, Half), N(G3, Half), N(A3, Half),

			N(D3, Half), N(A3, Half), N(B3, Half), N(Fs3, Half),
			N(G3, Half), N(D3, Half), N(G3, Half), N(A3, Half),

			N(D3, Half), N(A3, Half), N(B3, Half), N(Fs3, Half),
			N(G3, Half), N(D3, Half), N(D3, Whole),
		}}

		return []BeatVoice{voice1, voice2, voice3}
	},
}

SongCanon3Voice - 卡农三声部

View Source
var SongCastleInTheSky = Song{
	ID:    "castle_in_sky",
	Name:  "天空之城",
	Tempo: Tempo{BPM: 80, Signature: Time4_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(A4, Quarter), N(B4, Eighth), N(C5, DotQuarter), N(B4, Quarter), N(C5, Quarter), N(E5, Half),
			N(Rest, Eighth), N(G4, Eighth), N(A4, Quarter), N(G4, Eighth), N(A4, Eighth), N(C5, Half),
			N(Rest, Eighth), N(G4, Quarter), N(E4, Quarter), N(E4, Eighth), N(D4, Eighth), N(E4, DotHalf),
			N(Rest, Quarter),

			N(A4, Quarter), N(B4, Eighth), N(C5, DotQuarter), N(B4, Quarter), N(C5, Quarter), N(E5, Half),
			N(Rest, Eighth), N(G4, Eighth), N(A4, Quarter), N(G4, Eighth), N(A4, Eighth), N(C5, Half),
			N(Rest, Eighth), N(G4, Quarter), N(E4, Quarter), N(D4, Eighth), N(C4, Eighth), N(D4, DotHalf),
			N(Rest, Quarter),

			N(E5, Quarter), N(E5, Eighth), N(E5, Quarter), N(B4, Eighth), N(C5, Half),
			N(C5, Quarter), N(C5, Eighth), N(C5, Eighth), N(B4, Eighth), N(A4, Half),
			N(Rest, Eighth), N(A4, Quarter), N(C5, Quarter), N(B4, Eighth), N(B4, Eighth), N(E4, Half),
			N(A4, DotHalf), N(Rest, Quarter),
		}}

		accomp := BeatVoice{Notes: []BeatNote{

			N(A3, Quarter), N(E4, Eighth), N(A4, Eighth), N(E4, Quarter), N(A3, Quarter), N(E4, Eighth), N(A4, Eighth), N(E4, Quarter),
			N(F3, Quarter), N(C4, Eighth), N(F4, Eighth), N(C4, Quarter), N(C3, Quarter), N(G3, Eighth), N(C4, Eighth), N(G3, Quarter),
			N(Am, Quarter), N(E4, Eighth), N(A4, Eighth), N(E4, Quarter), N(E3, Quarter), N(B3, Eighth), N(E4, Eighth), N(B3, Quarter),
			N(A3, Half), N(Rest, Half),

			N(A3, Quarter), N(E4, Eighth), N(A4, Eighth), N(E4, Quarter), N(A3, Quarter), N(E4, Eighth), N(A4, Eighth), N(E4, Quarter),
			N(F3, Quarter), N(C4, Eighth), N(F4, Eighth), N(C4, Quarter), N(C3, Quarter), N(G3, Eighth), N(C4, Eighth), N(G3, Quarter),
			N(G3, Quarter), N(D4, Eighth), N(G4, Eighth), N(D4, Quarter), N(G3, Quarter), N(D4, Eighth), N(G4, Eighth), N(D4, Quarter),
			N(Rest, Whole),

			N(A3, Half), N(E3, Half),
			N(F3, Half), N(C3, Half),
			N(A3, Half), N(E3, Half),
			N(A3, DotHalf), N(Rest, Quarter),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongCastleInTheSky - 天空之城 (Laputa: Castle in the Sky)

View Source
var SongCzerny299No1 = Song{
	ID:    "czerny_299_1",
	Name:  "车尔尼 299-1",
	Tempo: Tempo{BPM: 140, Signature: Time4_4},
	Voices: func() []BeatVoice {

		melody := BeatVoice{Notes: []BeatNote{

			N(C5, Sixteenth), N(D5, Sixteenth), N(E5, Sixteenth), N(F5, Sixteenth),
			N(G5, Sixteenth), N(F5, Sixteenth), N(E5, Sixteenth), N(D5, Sixteenth),
			N(C5, Sixteenth), N(D5, Sixteenth), N(E5, Sixteenth), N(F5, Sixteenth),
			N(G5, Sixteenth), N(A5, Sixteenth), N(B5, Sixteenth), N(C6, Sixteenth),

			N(C6, Sixteenth), N(B5, Sixteenth), N(A5, Sixteenth), N(G5, Sixteenth),
			N(F5, Sixteenth), N(E5, Sixteenth), N(D5, Sixteenth), N(C5, Sixteenth),
			N(B4, Sixteenth), N(C5, Sixteenth), N(D5, Sixteenth), N(E5, Sixteenth),
			N(F5, Sixteenth), N(E5, Sixteenth), N(D5, Sixteenth), N(C5, Sixteenth),

			N(C5, Sixteenth), N(E5, Sixteenth), N(G5, Sixteenth), N(E5, Sixteenth),
			N(C5, Sixteenth), N(E5, Sixteenth), N(G5, Sixteenth), N(E5, Sixteenth),
			N(C5, Sixteenth), N(E5, Sixteenth), N(G5, Sixteenth), N(C6, Sixteenth),
			N(G5, Sixteenth), N(E5, Sixteenth), N(C5, Sixteenth), N(G4, Sixteenth),

			N(D5, Sixteenth), N(F5, Sixteenth), N(A5, Sixteenth), N(F5, Sixteenth),
			N(D5, Sixteenth), N(F5, Sixteenth), N(A5, Sixteenth), N(F5, Sixteenth),
			N(G4, Sixteenth), N(B4, Sixteenth), N(D5, Sixteenth), N(G5, Sixteenth),
			N(D5, Sixteenth), N(B4, Sixteenth), N(G4, Sixteenth), N(D4, Sixteenth),

			N(C5, Eighth), N(E5, Eighth), N(G5, Quarter), N(C6, Half),
			N(G5, Quarter), N(E5, Quarter), N(C5, Half),
		}}

		accomp := BeatVoice{Notes: []BeatNote{
			N(C3, Eighth), N(G3, Eighth), N(E3, Eighth), N(G3, Eighth),
			N(C3, Eighth), N(G3, Eighth), N(E3, Eighth), N(G3, Eighth),
			N(C3, Eighth), N(G3, Eighth), N(E3, Eighth), N(G3, Eighth),
			N(C3, Eighth), N(G3, Eighth), N(E3, Eighth), N(G3, Eighth),
			N(C3, Eighth), N(G3, Eighth), N(E3, Eighth), N(G3, Eighth),
			N(C3, Eighth), N(G3, Eighth), N(E3, Eighth), N(G3, Eighth),
			N(D3, Eighth), N(A3, Eighth), N(F3, Eighth), N(A3, Eighth),
			N(G3, Eighth), N(D4, Eighth), N(B3, Eighth), N(D4, Eighth),
			N(C3, Quarter), N(E3, Quarter), N(G3, Quarter), N(C4, Quarter),
			N(G3, Quarter), N(E3, Quarter), N(C3, Half),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongCzerny299No1 - 车尔尼 Op.299 No.1 (快速练习曲)

View Source
var SongCzerny599No1 = Song{
	ID:    "czerny_599_1",
	Name:  "车尔尼 599-1",
	Tempo: Tempo{BPM: 100, Signature: Time4_4},
	Voices: func() []BeatVoice {

		melody := BeatVoice{Notes: []BeatNote{

			N(C4, Quarter), N(D4, Quarter), N(E4, Quarter), N(F4, Quarter),
			N(G4, Quarter), N(A4, Quarter), N(B4, Quarter), N(C5, Quarter),

			N(C5, Quarter), N(B4, Quarter), N(A4, Quarter), N(G4, Quarter),
			N(F4, Quarter), N(E4, Quarter), N(D4, Quarter), N(C4, Quarter),

			N(C4, Eighth), N(E4, Eighth), N(D4, Eighth), N(F4, Eighth), N(E4, Eighth), N(G4, Eighth), N(F4, Eighth), N(A4, Eighth),
			N(G4, Eighth), N(B4, Eighth), N(A4, Eighth), N(C5, Eighth), N(B4, Eighth), N(D5, Eighth), N(C5, Quarter),

			N(G4, Quarter), N(E4, Quarter), N(D4, Quarter), N(B3, Quarter),
			N(C4, Whole),
		}}

		accomp := BeatVoice{Notes: []BeatNote{

			N(C3, Whole), N(C3, Whole),
			N(C3, Whole), N(C3, Whole),

			N(C3, Half), N(G3, Half),
			N(C3, Half), N(G3, Half),

			N(G3, Half), N(G3, Half),
			N(C3, Whole),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongCzerny599No1 - 车尔尼 Op.599 No.1 (初学者练习曲)

View Source
var SongCzerny599No19 = Song{
	ID:    "czerny_599_19",
	Name:  "车尔尼 599-19",
	Tempo: Tempo{BPM: 120, Signature: Time4_4},
	Voices: func() []BeatVoice {

		melody := BeatVoice{Notes: []BeatNote{

			N(C4, Eighth), N(D4, Eighth), N(E4, Eighth), N(F4, Eighth), N(G4, Eighth), N(F4, Eighth), N(E4, Eighth), N(D4, Eighth),
			N(C4, Eighth), N(E4, Eighth), N(G4, Eighth), N(E4, Eighth), N(C5, Eighth), N(G4, Eighth), N(E4, Eighth), N(C4, Eighth),

			N(D4, Eighth), N(E4, Eighth), N(F4, Eighth), N(G4, Eighth), N(A4, Eighth), N(G4, Eighth), N(F4, Eighth), N(E4, Eighth),
			N(D4, Eighth), N(F4, Eighth), N(A4, Eighth), N(F4, Eighth), N(D5, Eighth), N(A4, Eighth), N(F4, Eighth), N(D4, Eighth),

			N(E4, Eighth), N(F4, Eighth), N(G4, Eighth), N(A4, Eighth), N(B4, Eighth), N(A4, Eighth), N(G4, Eighth), N(F4, Eighth),
			N(E4, Eighth), N(G4, Eighth), N(B4, Eighth), N(G4, Eighth), N(E5, Eighth), N(B4, Eighth), N(G4, Eighth), N(E4, Eighth),

			N(F4, Eighth), N(A4, Eighth), N(C5, Eighth), N(A4, Eighth), N(G4, Eighth), N(B4, Eighth), N(D5, Eighth), N(B4, Eighth),
			N(C5, Half), N(C4, Half),
		}}

		accomp := BeatVoice{Notes: []BeatNote{
			N(C3, Quarter), N(E3, Quarter), N(G3, Quarter), N(E3, Quarter),
			N(C3, Quarter), N(E3, Quarter), N(G3, Quarter), N(E3, Quarter),
			N(D3, Quarter), N(F3, Quarter), N(A3, Quarter), N(F3, Quarter),
			N(D3, Quarter), N(F3, Quarter), N(A3, Quarter), N(F3, Quarter),
			N(E3, Quarter), N(G3, Quarter), N(B3, Quarter), N(G3, Quarter),
			N(E3, Quarter), N(G3, Quarter), N(B3, Quarter), N(G3, Quarter),
			N(F3, Quarter), N(A3, Quarter), N(G3, Quarter), N(B3, Quarter),
			N(C3, Half), N(C3, Half),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongCzerny599No19 - 车尔尼 Op.599 No.19 (八分音符练习)

View Source
var SongCzerny599No38 = Song{
	ID:    "czerny_599_38",
	Name:  "车尔尼 599-38",
	Tempo: Tempo{BPM: 90, Signature: Time4_4},
	Voices: func() []BeatVoice {

		t := 1.0 / 3.0

		melody := BeatVoice{Notes: []BeatNote{

			N(C4, t), N(E4, t), N(G4, t), N(C5, t), N(G4, t), N(E4, t), N(C4, t), N(E4, t), N(G4, t), N(C5, t), N(G4, t), N(E4, t),
			N(D4, t), N(F4, t), N(A4, t), N(D5, t), N(A4, t), N(F4, t), N(D4, t), N(F4, t), N(A4, t), N(D5, t), N(A4, t), N(F4, t),

			N(E4, t), N(G4, t), N(B4, t), N(E5, t), N(B4, t), N(G4, t), N(E4, t), N(G4, t), N(B4, t), N(E5, t), N(B4, t), N(G4, t),
			N(F4, t), N(A4, t), N(C5, t), N(F5, t), N(C5, t), N(A4, t), N(G4, t), N(B4, t), N(D5, t), N(G5, t), N(D5, t), N(B4, t),

			N(C5, t), N(G4, t), N(E4, t), N(C4, t), N(E4, t), N(G4, t), N(C5, t), N(G4, t), N(E4, t), N(C4, t), N(E4, t), N(G4, t),
			N(B4, t), N(G4, t), N(D4, t), N(B3, t), N(D4, t), N(G4, t), N(B4, t), N(G4, t), N(D4, t), N(B3, t), N(D4, t), N(G4, t),

			N(C4, t), N(E4, t), N(G4, t), N(C5, t), N(E5, t), N(G5, t), N(G4, t), N(B4, t), N(D5, t), N(G5, t), N(D5, t), N(B4, t),
			N(C5, Whole),
		}}

		accomp := BeatVoice{Notes: []BeatNote{
			N(C3, Whole), N(D3, Whole),
			N(E3, Whole), N(F3, Half), N(G3, Half),
			N(C3, Whole), N(G3, Whole),
			N(C3, Half), N(G3, Half), N(C3, Whole),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongCzerny599No38 - 车尔尼 Op.599 No.38 (三连音练习)

View Source
var SongDollAndBear = Song{
	ID:    "doll_and_bear",
	Name:  "洋娃娃和小熊跳舞",
	Tempo: Tempo{BPM: 132, Signature: Time2_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(C4, Eighth), N(D4, Eighth), N(E4, Eighth), N(C4, Eighth), N(E4, Eighth), N(C4, Eighth), N(E4, Quarter),
			N(D4, Eighth), N(E4, Eighth), N(F4, Eighth), N(F4, Eighth), N(E4, Eighth), N(D4, Eighth), N(E4, Quarter),

			N(C4, Eighth), N(D4, Eighth), N(E4, Eighth), N(C4, Eighth), N(E4, Eighth), N(C4, Eighth), N(E4, Quarter),
			N(D4, Eighth), N(E4, Eighth), N(F4, Eighth), N(E4, Eighth), N(D4, Quarter), N(C4, Quarter),

			N(G4, Eighth), N(G4, Eighth), N(E4, Eighth), N(G4, Eighth), N(F4, Eighth), N(F4, Eighth), N(D4, Quarter),
			N(E4, Eighth), N(F4, Eighth), N(E4, Eighth), N(C4, Eighth), N(D4, Quarter), N(Rest, Quarter),

			N(G4, Eighth), N(G4, Eighth), N(E4, Eighth), N(G4, Eighth), N(F4, Eighth), N(E4, Eighth), N(D4, Quarter),
			N(C4, Eighth), N(D4, Eighth), N(E4, Eighth), N(D4, Eighth), N(C4, Half),
		}}

		accomp := BeatVoice{Notes: []BeatNote{

			N(C3, Quarter), N(G3, Quarter), N(C3, Quarter), N(G3, Quarter),
			N(G3, Quarter), N(D3, Quarter), N(C3, Quarter), N(G3, Quarter),
			N(C3, Quarter), N(G3, Quarter), N(C3, Quarter), N(G3, Quarter),
			N(G3, Quarter), N(D3, Quarter), N(C3, Half),

			N(C3, Quarter), N(G3, Quarter), N(D3, Quarter), N(G3, Quarter),
			N(C3, Quarter), N(G3, Quarter), N(G3, Half),
			N(C3, Quarter), N(G3, Quarter), N(G3, Quarter), N(D3, Quarter),
			N(C3, Quarter), N(G3, Quarter), N(C3, Half),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongDollAndBear - 洋娃娃和小熊跳舞 (Doll and Bear Dancing)

View Source
var SongDreamWedding = Song{
	ID:    "dream_wedding",
	Name:  "梦中的婚礼",
	Tempo: Tempo{BPM: 70, Signature: Time4_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(E5, Quarter), N(E5, Eighth), N(D5, Eighth), N(E5, Half),
			N(E5, Quarter), N(E5, Eighth), N(F5, Eighth), N(E5, Quarter), N(D5, Quarter),
			N(C5, Quarter), N(B4, Eighth), N(A4, Eighth), N(B4, Half),
			N(Rest, Whole),

			N(E5, Quarter), N(E5, Eighth), N(D5, Eighth), N(E5, Half),
			N(E5, Quarter), N(E5, Eighth), N(F5, Eighth), N(E5, Quarter), N(D5, Quarter),
			N(C5, Quarter), N(D5, Quarter), N(E5, Quarter), N(C5, Quarter),
			N(A4, Whole),
		}}

		accomp := BeatVoice{Notes: []BeatNote{

			N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth), N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth),
			N(G3, Eighth), N(D4, Eighth), N(G4, Eighth), N(D4, Eighth), N(G3, Eighth), N(D4, Eighth), N(G4, Eighth), N(D4, Eighth),
			N(F3, Eighth), N(C4, Eighth), N(F4, Eighth), N(C4, Eighth), N(F3, Eighth), N(C4, Eighth), N(F4, Eighth), N(C4, Eighth),
			N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth), N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth),

			N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth), N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth),
			N(G3, Eighth), N(D4, Eighth), N(G4, Eighth), N(D4, Eighth), N(G3, Eighth), N(D4, Eighth), N(G4, Eighth), N(D4, Eighth),
			N(F3, Eighth), N(C4, Eighth), N(F4, Eighth), N(C4, Eighth), N(G3, Eighth), N(D4, Eighth), N(G4, Eighth), N(D4, Eighth),
			N(A3, Whole),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongDreamWedding - 梦中的婚礼 (Mariage d'Amour)

View Source
var SongFurElise = Song{
	ID:    "fur_elise",
	Name:  "献给爱丽丝",
	Tempo: Tempo{BPM: 140, Signature: Time3_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(E5, Eighth), N(Ds5, Eighth), N(E5, Eighth), N(Ds5, Eighth), N(E5, Eighth), N(B4, Eighth), N(D5, Eighth), N(C5, Eighth),
			N(A4, Quarter), N(Rest, Eighth), N(C4, Eighth), N(E4, Eighth), N(A4, Eighth),
			N(B4, Quarter), N(Rest, Eighth), N(E4, Eighth), N(Gs4, Eighth), N(B4, Eighth),
			N(C5, Quarter), N(Rest, Eighth), N(E4, Eighth), N(E5, Eighth), N(Ds5, Eighth),

			N(E5, Eighth), N(Ds5, Eighth), N(E5, Eighth), N(B4, Eighth), N(D5, Eighth), N(C5, Eighth),
			N(A4, Quarter), N(Rest, Eighth), N(C4, Eighth), N(E4, Eighth), N(A4, Eighth),
			N(B4, Quarter), N(Rest, Eighth), N(E4, Eighth), N(C5, Eighth), N(B4, Eighth),
			N(A4, DotQuarter), N(Rest, DotQuarter),
		}}

		accomp := BeatVoice{Notes: []BeatNote{

			N(Rest, DotHalf),
			N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(Rest, DotQuarter),
			N(E3, Eighth), N(E4, Eighth), N(Gs4, Eighth), N(Rest, DotQuarter),
			N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(Rest, DotQuarter),

			N(Rest, DotHalf),
			N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(Rest, DotQuarter),
			N(E3, Eighth), N(E4, Eighth), N(Gs4, Eighth), N(Rest, DotQuarter),
			N(A3, DotQuarter), N(Rest, DotQuarter),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongFurElise - 献给爱丽丝 (Für Elise)

View Source
var SongHanonNo1 = Song{
	ID:    "hanon_1",
	Name:  "哈农练习 1",
	Tempo: Tempo{BPM: 100, Signature: Time4_4},
	Voices: func() []BeatVoice {

		melody := BeatVoice{Notes: []BeatNote{

			N(C4, Sixteenth), N(E4, Sixteenth), N(F4, Sixteenth), N(G4, Sixteenth),
			N(A4, Sixteenth), N(G4, Sixteenth), N(F4, Sixteenth), N(E4, Sixteenth),
			N(D4, Sixteenth), N(F4, Sixteenth), N(G4, Sixteenth), N(A4, Sixteenth),
			N(B4, Sixteenth), N(A4, Sixteenth), N(G4, Sixteenth), N(F4, Sixteenth),

			N(E4, Sixteenth), N(G4, Sixteenth), N(A4, Sixteenth), N(B4, Sixteenth),
			N(C5, Sixteenth), N(B4, Sixteenth), N(A4, Sixteenth), N(G4, Sixteenth),
			N(F4, Sixteenth), N(A4, Sixteenth), N(B4, Sixteenth), N(C5, Sixteenth),
			N(D5, Sixteenth), N(C5, Sixteenth), N(B4, Sixteenth), N(A4, Sixteenth),

			N(G4, Sixteenth), N(B4, Sixteenth), N(C5, Sixteenth), N(D5, Sixteenth),
			N(E5, Sixteenth), N(D5, Sixteenth), N(C5, Sixteenth), N(B4, Sixteenth),
			N(A4, Sixteenth), N(C5, Sixteenth), N(B4, Sixteenth), N(A4, Sixteenth),
			N(G4, Sixteenth), N(A4, Sixteenth), N(B4, Sixteenth), N(C5, Sixteenth),

			N(B4, Sixteenth), N(G4, Sixteenth), N(F4, Sixteenth), N(E4, Sixteenth),
			N(D4, Sixteenth), N(E4, Sixteenth), N(F4, Sixteenth), N(G4, Sixteenth),
			N(A4, Sixteenth), N(F4, Sixteenth), N(E4, Sixteenth), N(D4, Sixteenth),
			N(C4, Quarter), N(Rest, Quarter), N(C4, Half),
		}}

		accomp := BeatVoice{Notes: []BeatNote{
			N(C3, Sixteenth), N(E3, Sixteenth), N(F3, Sixteenth), N(G3, Sixteenth),
			N(A3, Sixteenth), N(G3, Sixteenth), N(F3, Sixteenth), N(E3, Sixteenth),
			N(D3, Sixteenth), N(F3, Sixteenth), N(G3, Sixteenth), N(A3, Sixteenth),
			N(B3, Sixteenth), N(A3, Sixteenth), N(G3, Sixteenth), N(F3, Sixteenth),

			N(E3, Sixteenth), N(G3, Sixteenth), N(A3, Sixteenth), N(B3, Sixteenth),
			N(C4, Sixteenth), N(B3, Sixteenth), N(A3, Sixteenth), N(G3, Sixteenth),
			N(F3, Sixteenth), N(A3, Sixteenth), N(B3, Sixteenth), N(C4, Sixteenth),
			N(D4, Sixteenth), N(C4, Sixteenth), N(B3, Sixteenth), N(A3, Sixteenth),

			N(G3, Sixteenth), N(B3, Sixteenth), N(C4, Sixteenth), N(D4, Sixteenth),
			N(E4, Sixteenth), N(D4, Sixteenth), N(C4, Sixteenth), N(B3, Sixteenth),
			N(A3, Sixteenth), N(C4, Sixteenth), N(B3, Sixteenth), N(A3, Sixteenth),
			N(G3, Sixteenth), N(A3, Sixteenth), N(B3, Sixteenth), N(C4, Sixteenth),

			N(B3, Sixteenth), N(G3, Sixteenth), N(F3, Sixteenth), N(E3, Sixteenth),
			N(D3, Sixteenth), N(E3, Sixteenth), N(F3, Sixteenth), N(G3, Sixteenth),
			N(A3, Sixteenth), N(F3, Sixteenth), N(E3, Sixteenth), N(D3, Sixteenth),
			N(C3, Quarter), N(Rest, Quarter), N(C3, Half),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongHanonNo1 - 哈农指法练习 No.1

View Source
var SongHappyBirthday = Song{
	ID:    "happy_birthday",
	Name:  "生日快乐",
	Tempo: Tempo{BPM: 120, Signature: Time3_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(C4, Eighth), N(C4, Eighth), N(D4, Quarter), N(C4, Quarter), N(F4, Quarter), N(E4, Half),

			N(C4, Eighth), N(C4, Eighth), N(D4, Quarter), N(C4, Quarter), N(G4, Quarter), N(F4, Half),

			N(C4, Eighth), N(C4, Eighth), N(C5, Quarter), N(A4, Quarter), N(F4, Quarter), N(E4, Quarter), N(D4, Half),

			N(As4, Eighth), N(As4, Eighth), N(A4, Quarter), N(F4, Quarter), N(G4, Quarter), N(F4, DotHalf),
		}}

		accomp := BeatVoice{Notes: []BeatNote{

			N(Rest, Quarter), N(F3, Quarter), N(A3, Quarter), N(C4, Quarter), N(C3, Quarter), N(G3, Quarter), N(C4, Quarter),

			N(Rest, Quarter), N(F3, Quarter), N(A3, Quarter), N(C4, Quarter), N(C3, Quarter), N(G3, Quarter), N(C4, Quarter),

			N(Rest, Quarter), N(F3, Quarter), N(A3, Quarter), N(C4, Quarter), N(E3, Quarter), N(G3, Quarter), N(C4, Quarter), N(D3, Quarter), N(F3, Quarter), N(A3, Quarter),

			N(Rest, Quarter), N(As3, Quarter), N(D4, Quarter), N(F4, Quarter), N(F3, Quarter), N(A3, Quarter), N(C4, Quarter), N(F3, DotHalf),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongHappyBirthday - 生日快乐 (Happy Birthday)

View Source
var SongRiverFlowsInYou = Song{
	ID:    "river_flows",
	Name:  "River Flows in You",
	Tempo: Tempo{BPM: 70, Signature: Time4_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(A4, Quarter), N(E5, Quarter), N(Fs5, Quarter), N(E5, Quarter),
			N(A4, Quarter), N(E5, Quarter), N(Fs5, Quarter), N(E5, Quarter),
			N(Gs4, Quarter), N(E5, Quarter), N(Fs5, Quarter), N(E5, Quarter),
			N(Gs4, Quarter), N(E5, Quarter), N(Fs5, Quarter), N(E5, Quarter),

			N(Fs5, DotQuarter), N(E5, Eighth), N(Cs5, Eighth), N(E5, DotQuarter), N(Fs5, Eighth), N(E5, Eighth),
			N(Cs5, DotQuarter), N(B4, Eighth), N(A4, Eighth), N(B4, DotQuarter), N(Cs5, Eighth), N(B4, Eighth),
			N(A4, Half), N(Gs4, Quarter), N(A4, Quarter), N(B4, Half),

			N(Cs5, DotQuarter), N(B4, Eighth), N(A4, Eighth), N(B4, DotQuarter), N(Cs5, Eighth), N(B4, Eighth),
			N(A4, DotQuarter), N(Gs4, Eighth), N(A4, Eighth), N(B4, DotQuarter), N(A4, Eighth), N(Gs4, Eighth),
			N(Fs4, Half), N(E4, Half), N(Fs4, Whole),
		}}

		accomp := BeatVoice{Notes: []BeatNote{

			N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth), N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth),
			N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth), N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth),
			N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth), N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth),
			N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth), N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth),

			N(Fs3, Eighth), N(Cs4, Eighth), N(Fs4, Eighth), N(Cs4, Eighth), N(Fs3, Eighth), N(Cs4, Eighth), N(Fs4, Eighth), N(Cs4, Eighth),
			N(Fs3, Eighth), N(Cs4, Eighth), N(Fs4, Eighth), N(Cs4, Eighth), N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth),
			N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth), N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth),

			N(Fs3, Eighth), N(Cs4, Eighth), N(Fs4, Eighth), N(Cs4, Eighth), N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth),
			N(A3, Eighth), N(E4, Eighth), N(A4, Eighth), N(E4, Eighth), N(E3, Eighth), N(B3, Eighth), N(E4, Eighth), N(B3, Eighth),
			N(A3, Whole), N(A3, Whole),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongRiverFlowsInYou - River Flows in You (Yiruma)

View Source
var SongScaleC = Song{
	ID:    "scale_c_major",
	Name:  "C大调音阶",
	Tempo: Tempo{BPM: 120, Signature: Time4_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(C4, Eighth), N(D4, Eighth), N(E4, Eighth), N(F4, Eighth),
			N(G4, Eighth), N(A4, Eighth), N(B4, Eighth), N(C5, Eighth),
			N(D5, Eighth), N(E5, Eighth), N(F5, Eighth), N(G5, Eighth),
			N(A5, Eighth), N(B5, Eighth), N(C6, Quarter),

			N(C6, Eighth), N(B5, Eighth), N(A5, Eighth), N(G5, Eighth),
			N(F5, Eighth), N(E5, Eighth), N(D5, Eighth), N(C5, Eighth),
			N(B4, Eighth), N(A4, Eighth), N(G4, Eighth), N(F4, Eighth),
			N(E4, Eighth), N(D4, Eighth), N(C4, Quarter),
		}}

		accomp := BeatVoice{Notes: []BeatNote{
			N(C3, Eighth), N(D3, Eighth), N(E3, Eighth), N(F3, Eighth),
			N(G3, Eighth), N(A3, Eighth), N(B3, Eighth), N(C4, Eighth),
			N(D4, Eighth), N(E4, Eighth), N(F4, Eighth), N(G4, Eighth),
			N(A4, Eighth), N(B4, Eighth), N(C5, Quarter),
			N(C5, Eighth), N(B4, Eighth), N(A4, Eighth), N(G4, Eighth),
			N(F4, Eighth), N(E4, Eighth), N(D4, Eighth), N(C4, Eighth),
			N(B3, Eighth), N(A3, Eighth), N(G3, Eighth), N(F3, Eighth),
			N(E3, Eighth), N(D3, Eighth), N(C3, Quarter),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongScaleC - C大调音阶练习

View Source
var SongScaleGMinor = Song{
	ID:    "scale_g_minor",
	Name:  "G小调音阶",
	Tempo: Tempo{BPM: 110, Signature: Time4_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(G4, Eighth), N(A4, Eighth), N(Bb4, Eighth), N(C5, Eighth),
			N(D5, Eighth), N(Eb5, Eighth), N(Fs5, Eighth), N(G5, Eighth),
			N(G5, Quarter), N(Rest, Quarter),

			N(G5, Eighth), N(Fs5, Eighth), N(Eb5, Eighth), N(D5, Eighth),
			N(C5, Eighth), N(Bb4, Eighth), N(A4, Eighth), N(G4, Eighth),
			N(G4, Half),
		}}

		accomp := BeatVoice{Notes: []BeatNote{
			N(G3, Eighth), N(A3, Eighth), N(Bb3, Eighth), N(C4, Eighth),
			N(D4, Eighth), N(Eb4, Eighth), N(Fs4, Eighth), N(G4, Eighth),
			N(G4, Quarter), N(Rest, Quarter),
			N(G4, Eighth), N(Fs4, Eighth), N(Eb4, Eighth), N(D4, Eighth),
			N(C4, Eighth), N(Bb3, Eighth), N(A3, Eighth), N(G3, Eighth),
			N(G3, Half),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongScaleGMinor - G小调音阶练习 (harmonic minor)

View Source
var SongSimpleWaltz = Song{
	ID:    "simple_waltz",
	Name:  "简单圆舞曲",
	Tempo: Tempo{BPM: 120, Signature: Time3_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(E5, DotQuarter), N(D5, Eighth), N(C5, Quarter),
			N(D5, DotQuarter), N(E5, Eighth), N(D5, Quarter),

			N(C5, DotQuarter), N(B4, Eighth), N(A4, Quarter),
			N(B4, Half), N(Rest, Quarter),

			N(E5, DotQuarter), N(D5, Eighth), N(C5, Quarter),
			N(D5, DotQuarter), N(E5, Eighth), N(D5, Quarter),

			N(C5, Half), N(B4, Quarter),
			N(C5, DotHalf),
		}}

		bass := BeatVoice{Notes: []BeatNote{

			N(C3, Quarter), N(E4, Quarter), N(G4, Quarter),
			N(G3, Quarter), N(D4, Quarter), N(G4, Quarter),

			N(A3, Quarter), N(E4, Quarter), N(A4, Quarter),
			N(E3, Quarter), N(Gs3, Quarter), N(B3, Quarter),

			N(C3, Quarter), N(E4, Quarter), N(G4, Quarter),
			N(G3, Quarter), N(D4, Quarter), N(G4, Quarter),

			N(F3, Quarter), N(A3, Quarter), N(C4, Quarter),
			N(C3, DotHalf),
		}}

		return []BeatVoice{melody, bass}
	},
}

SongSimpleWaltz - 简单圆舞曲

View Source
var SongTarantella = Song{
	ID:    "tarantella",
	Name:  "塔兰泰拉舞曲",
	Tempo: Tempo{BPM: 140, Signature: Time6_8},
	Voices: func() []BeatVoice {

		melody := BeatVoice{Notes: []BeatNote{

			N(A4, Eighth), N(C5, Eighth), N(E5, Eighth), N(A5, Eighth), N(E5, Eighth), N(C5, Eighth),
			N(A4, Eighth), N(C5, Eighth), N(E5, Eighth), N(A5, Eighth), N(E5, Eighth), N(C5, Eighth),
			N(B4, Eighth), N(D5, Eighth), N(F5, Eighth), N(B5, Eighth), N(F5, Eighth), N(D5, Eighth),
			N(E5, Quarter+Eighth), N(E5, Quarter+Eighth),

			N(E5, Eighth), N(F5, Eighth), N(E5, Eighth), N(D5, Eighth), N(C5, Eighth), N(B4, Eighth),
			N(A4, Eighth), N(B4, Eighth), N(C5, Eighth), N(D5, Eighth), N(E5, Eighth), N(F5, Eighth),
			N(E5, Eighth), N(D5, Eighth), N(C5, Eighth), N(B4, Eighth), N(A4, Eighth), N(Gs4, Eighth),
			N(A4, Quarter+Eighth), N(A4, Quarter+Eighth),
		}}

		accomp := BeatVoice{Notes: []BeatNote{
			N(A3, Eighth), N(E3, Eighth), N(A3, Eighth), N(E3, Eighth), N(A3, Eighth), N(E3, Eighth),
			N(A3, Eighth), N(E3, Eighth), N(A3, Eighth), N(E3, Eighth), N(A3, Eighth), N(E3, Eighth),
			N(E3, Eighth), N(B2, Eighth), N(E3, Eighth), N(B2, Eighth), N(E3, Eighth), N(B2, Eighth),
			N(A3, Quarter+Eighth), N(E3, Quarter+Eighth),

			N(A3, Eighth), N(E3, Eighth), N(A3, Eighth), N(E3, Eighth), N(A3, Eighth), N(E3, Eighth),
			N(A3, Eighth), N(E3, Eighth), N(A3, Eighth), N(E3, Eighth), N(A3, Eighth), N(E3, Eighth),
			N(E3, Eighth), N(B2, Eighth), N(E3, Eighth), N(B2, Eighth), N(E3, Eighth), N(B2, Eighth),
			N(A3, Quarter+Eighth), N(A2, Quarter+Eighth),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongTarantella - 塔兰泰拉舞曲 (6/8拍示例)

View Source
var SongTwinkleStar = Song{
	ID:    "twinkle_star",
	Name:  "小星星",
	Tempo: Tempo{BPM: 100, Signature: Time4_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(C4, Quarter), N(C4, Quarter), N(G4, Quarter), N(G4, Quarter),
			N(A4, Quarter), N(A4, Quarter), N(G4, Half),

			N(F4, Quarter), N(F4, Quarter), N(E4, Quarter), N(E4, Quarter),
			N(D4, Quarter), N(D4, Quarter), N(C4, Half),

			N(G4, Quarter), N(G4, Quarter), N(F4, Quarter), N(F4, Quarter),
			N(E4, Quarter), N(E4, Quarter), N(D4, Half),

			N(G4, Quarter), N(G4, Quarter), N(F4, Quarter), N(F4, Quarter),
			N(E4, Quarter), N(E4, Quarter), N(D4, Half),

			N(C4, Quarter), N(C4, Quarter), N(G4, Quarter), N(G4, Quarter),
			N(A4, Quarter), N(A4, Quarter), N(G4, Half),

			N(F4, Quarter), N(F4, Quarter), N(E4, Quarter), N(E4, Quarter),
			N(D4, Quarter), N(D4, Quarter), N(C4, Half),
		}}

		accomp := BeatVoice{Notes: []BeatNote{

			N(C3, Quarter), N(E3, Quarter), N(G3, Quarter), N(E3, Quarter),
			N(F3, Quarter), N(A3, Quarter), N(C3, Half),

			N(F3, Quarter), N(A3, Quarter), N(C3, Quarter), N(E3, Quarter),
			N(G3, Quarter), N(B3, Quarter), N(C3, Half),

			N(C3, Quarter), N(E3, Quarter), N(F3, Quarter), N(A3, Quarter),
			N(C3, Quarter), N(E3, Quarter), N(G3, Half),

			N(C3, Quarter), N(E3, Quarter), N(F3, Quarter), N(A3, Quarter),
			N(C3, Quarter), N(E3, Quarter), N(G3, Half),

			N(C3, Quarter), N(E3, Quarter), N(G3, Quarter), N(E3, Quarter),
			N(F3, Quarter), N(A3, Quarter), N(C3, Half),

			N(F3, Quarter), N(A3, Quarter), N(C3, Quarter), N(E3, Quarter),
			N(G3, Quarter), N(B3, Quarter), N(C3, Half),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongTwinkleStar - 小星星 (Twinkle Twinkle Little Star)

View Source
var SongTwoTigers = Song{
	ID:    "two_tigers",
	Name:  "两只老虎",
	Tempo: Tempo{BPM: 120, Signature: Time4_4},
	Voices: func() []BeatVoice {
		melody := BeatVoice{Notes: []BeatNote{

			N(C4, Quarter), N(D4, Quarter), N(E4, Quarter), N(C4, Quarter),
			N(C4, Quarter), N(D4, Quarter), N(E4, Quarter), N(C4, Quarter),

			N(E4, Quarter), N(F4, Quarter), N(G4, Half),
			N(E4, Quarter), N(F4, Quarter), N(G4, Half),

			N(G4, Eighth), N(A4, Eighth), N(G4, Eighth), N(F4, Eighth), N(E4, Quarter), N(C4, Quarter),
			N(G4, Eighth), N(A4, Eighth), N(G4, Eighth), N(F4, Eighth), N(E4, Quarter), N(C4, Quarter),

			N(C4, Quarter), N(G3, Quarter), N(C4, Half),
			N(C4, Quarter), N(G3, Quarter), N(C4, Half),
		}}

		accomp := BeatVoice{Notes: []BeatNote{

			N(C3, Half), N(E3, Half),
			N(A3, Half), N(E3, Half),

			N(C3, Half), N(G3, Half),
			N(C3, Half), N(G3, Half),

			N(C3, Half), N(G3, Half),
			N(C3, Half), N(G3, Half),

			N(C3, Quarter), N(G3, Quarter), N(C3, Half),
			N(C3, Quarter), N(G3, Quarter), N(C3, Half),
		}}

		return []BeatVoice{melody, accomp}
	},
}

SongTwoTigers - 两只老虎 (Two Tigers / Frère Jacques)

Functions

func DurationSamples

func DurationSamples(durMs int, sampleRate int) int

DurationSamples calculates the number of samples for a given duration in ms.

func DurationSamplesFormat

func DurationSamplesFormat(durMs int, format pcm.Format) int

DurationSamplesFormat calculates samples for a duration using pcm.Format.

func GenerateChord

func GenerateChord(freqs []float64, samples int, sampleRate int, volume float64) []int16

GenerateChord generates a chord with piano-like sound.

func GenerateRichNote

func GenerateRichNote(freq float64, samples int, sampleRate int, volume float64) []int16

GenerateRichNote generates a piano-like note with realistic harmonics and envelope.

func GenerateSineWave

func GenerateSineWave(freq float64, samples int, sampleRate int) []byte

GenerateSineWave generates a pure sine wave as 16-bit PCM data (little-endian).

func IDs

func IDs() []string

IDs returns all song IDs.

func Int16ToBytes

func Int16ToBytes(samples []int16) []byte

Int16ToBytes converts []int16 samples to raw PCM bytes (little-endian).

func Names

func Names() []string

Names returns all song names.

func TotalDuration

func TotalDuration(melody []Note) int

TotalDuration returns the total duration of a melody in milliseconds.

func VoiceToChunk

func VoiceToChunk(voice Voice, format pcm.Format, volume float64) pcm.Chunk

VoiceToChunk converts a Voice to a pcm.Chunk.

Types

type BeatNote

type BeatNote struct {
	Freq  float64 // Frequency in Hz
	Beats float64 // Duration in beats
}

BeatNote represents a note defined by beat value instead of milliseconds.

func N

func N(freq float64, beats float64) BeatNote

N is a shorthand constructor for BeatNote.

func (BeatNote) ToNote

func (bn BeatNote) ToNote(tempo Tempo) Note

ToNote converts a BeatNote to a Note using the given tempo.

type BeatVoice

type BeatVoice struct {
	Notes []BeatNote
}

BeatVoice represents a voice with beat-based notes.

func (BeatVoice) ToVoice

func (bv BeatVoice) ToVoice(tempo Tempo) Voice

ToVoice converts a BeatVoice to a Voice using the given tempo.

func (BeatVoice) TotalBeats

func (bv BeatVoice) TotalBeats() float64

TotalBeats calculates the total number of beats in a BeatVoice.

type Metronome

type Metronome struct {
	Tempo      Tempo
	TotalBeats int     // Total number of beats to generate
	HighFreq   float64 // Frequency for downbeat (first beat of bar)
	LowFreq    float64 // Frequency for other beats
	ClickDur   int     // Duration of each click in ms
}

Metronome generates a metronome click track.

func DefaultMetronome

func DefaultMetronome(tempo Tempo, totalBeats int) Metronome

DefaultMetronome creates a metronome with sensible defaults.

func (Metronome) Generate

func (m Metronome) Generate() Voice

Generate creates the metronome click track as a Voice.

type Note

type Note struct {
	Freq float64 // Frequency in Hz (use Rest for silence)
	Dur  int     // Duration in milliseconds
}

Note represents a single musical note with frequency and duration.

type RenderOptions

type RenderOptions struct {
	Format    pcm.Format // Audio format (default: L16Mono16K)
	Volume    float64    // Volume 0.0-1.0; 0 means mute
	Metronome bool       // Include metronome track
	RichSound bool       // true: rich harmonics, false: sine tone
}

RenderOptions configures song rendering.

func DefaultRenderOptions

func DefaultRenderOptions() RenderOptions

DefaultRenderOptions returns default rendering options.

type Song

type Song struct {
	ID     string             // Unique identifier
	Name   string             // Display name
	Tempo  Tempo              // Tempo configuration
	Voices func() []BeatVoice // Function that returns all voices (melody + accompaniment)
}

Song represents a complete song with tempo and multiple voices.

func ByID

func ByID(id string) *Song

ByID returns a song by its ID, or nil if not found.

func ByName

func ByName(name string) *Song

ByName returns a song by its name (exact match), or nil if not found.

func (Song) Duration

func (s Song) Duration() int

Duration returns the total duration of the song in milliseconds.

func (Song) Render

func (s Song) Render(opts RenderOptions) io.Reader

Render renders a song to mixed PCM audio using pcm.Mixer. It creates a track for each voice and mixes them together. Returns an io.Reader that reads the mixed audio data.

func (Song) RenderBytes

func (s Song) RenderBytes(opts RenderOptions) ([]byte, error)

RenderBytes renders a song to a byte slice.

func (Song) ToVoices

func (s Song) ToVoices(withMetronome bool) []Voice

ToVoices converts a Song to []Voice with optional metronome.

type Tempo

type Tempo struct {
	BPM       int           // Beats per minute
	Signature TimeSignature // Time signature
}

Tempo represents the tempo configuration for a song.

func (Tempo) BarDuration

func (t Tempo) BarDuration() int

BarDuration returns the duration of one full bar/measure in milliseconds.

func (Tempo) BeatDuration

func (t Tempo) BeatDuration(beats float64) int

BeatDuration converts beat count to milliseconds.

type TimeSignature

type TimeSignature struct {
	BeatsPerBar int // Numerator: how many beats per measure (e.g., 4 for 4/4)
	BeatUnit    int // Denominator: note value that gets one beat (e.g., 4 for quarter note)
}

TimeSignature represents the time signature of a song.

type Voice

type Voice struct {
	Notes []Note
}

Voice represents a single voice/part in a multi-voice composition.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL