The piano plays sound
This commit is contained in:
parent
5c7e243566
commit
c5ee7c8cdb
69
elements/fun/music/music.go
Normal file
69
elements/fun/music/music.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package music
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
var semitone = math.Pow(2, 1.0 / 12.0)
|
||||||
|
|
||||||
|
// Tuning is an interface representing a tuning.
|
||||||
|
type Tuning interface {
|
||||||
|
// Tune returns the frequency of a given note in Hz.
|
||||||
|
Tune (Note) float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// EqualTemparment implements twelve-tone equal temparment.
|
||||||
|
type EqualTemparment struct { A4 float64 }
|
||||||
|
|
||||||
|
// Tune returns the EqualTemparment frequency of a given note in Hz.
|
||||||
|
func (tuning EqualTemparment) Tune (note Note) float64 {
|
||||||
|
return tuning.A4 * math.Pow(semitone, float64(note - NoteA4))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Octave represents a MIDI octave.
|
||||||
|
type Octave int
|
||||||
|
|
||||||
|
// Note returns the note at the specified scale degree in the chromatic scale.
|
||||||
|
func (octave Octave) Note (degree int) Note {
|
||||||
|
return Note(int(octave + 1) * 12 + degree)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note represents a MIDI note.
|
||||||
|
type Note int
|
||||||
|
|
||||||
|
const (
|
||||||
|
NoteC0 Note = iota
|
||||||
|
NoteDb0
|
||||||
|
NoteD0
|
||||||
|
NoteEb0
|
||||||
|
NoteE0
|
||||||
|
NoteF0
|
||||||
|
NoteGb0
|
||||||
|
NoteG0
|
||||||
|
NoteAb0
|
||||||
|
NoteA0
|
||||||
|
NoteBb0
|
||||||
|
NoteB0
|
||||||
|
|
||||||
|
NoteA4 Note = 69
|
||||||
|
)
|
||||||
|
|
||||||
|
// Octave returns the octave of the note
|
||||||
|
func (note Note) Octave () int {
|
||||||
|
return int(note / 12 - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Degree returns the scale degree of the note in the chromatic scale.
|
||||||
|
func (note Note) Degree () int {
|
||||||
|
mod := note % 12
|
||||||
|
if mod < 0 { mod += 12 }
|
||||||
|
return int(mod)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSharp returns whether or not the note is a sharp.
|
||||||
|
func (note Note) IsSharp () bool {
|
||||||
|
degree := note.Degree()
|
||||||
|
return degree == 1 ||
|
||||||
|
degree == 3 ||
|
||||||
|
degree == 6 ||
|
||||||
|
degree == 8 ||
|
||||||
|
degree == 10
|
||||||
|
}
|
||||||
@ -6,51 +6,19 @@ import "git.tebibyte.media/sashakoshka/tomo/theme"
|
|||||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||||
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
||||||
|
import "git.tebibyte.media/sashakoshka/tomo/elements/fun/music"
|
||||||
// Octave represents a MIDI octave.
|
|
||||||
type Octave int
|
|
||||||
|
|
||||||
// Note returns the note at the specified scale degree in the chromatic scale.
|
|
||||||
func (octave Octave) Note (degree int) Note {
|
|
||||||
return Note(int(octave + 1) * 12 + degree)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note represents a MIDI note.
|
|
||||||
type Note int
|
|
||||||
|
|
||||||
// Octave returns the octave of the note
|
|
||||||
func (note Note) Octave () int {
|
|
||||||
return int(note / 12 - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Degree returns the scale degree of the note in the chromatic scale.
|
|
||||||
func (note Note) Degree () int {
|
|
||||||
mod := note % 12
|
|
||||||
if mod < 0 { mod += 12 }
|
|
||||||
return int(mod)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSharp returns whether or not the note is a sharp.
|
|
||||||
func (note Note) IsSharp () bool {
|
|
||||||
degree := note.Degree()
|
|
||||||
return degree == 1 ||
|
|
||||||
degree == 3 ||
|
|
||||||
degree == 6 ||
|
|
||||||
degree == 8 ||
|
|
||||||
degree == 10
|
|
||||||
}
|
|
||||||
|
|
||||||
const pianoKeyWidth = 18
|
const pianoKeyWidth = 18
|
||||||
|
|
||||||
type pianoKey struct {
|
type pianoKey struct {
|
||||||
image.Rectangle
|
image.Rectangle
|
||||||
Note
|
music.Note
|
||||||
}
|
}
|
||||||
|
|
||||||
type Piano struct {
|
type Piano struct {
|
||||||
*core.Core
|
*core.Core
|
||||||
core core.CoreControl
|
core core.CoreControl
|
||||||
low, high Octave
|
low, high music.Octave
|
||||||
|
|
||||||
config config.Wrapped
|
config config.Wrapped
|
||||||
theme theme.Wrapped
|
theme theme.Wrapped
|
||||||