mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
Play music at example/audio
This commit is contained in:
parent
355da1bcbc
commit
a220251716
6
audio.go
6
audio.go
@ -18,6 +18,10 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/internal/audio"
|
"github.com/hajimehoshi/ebiten/internal/audio"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AppendAudioBuffer(l []float32, r []float32) {
|
func AppendToAudioBuffer(l []float32, r []float32) {
|
||||||
audio.Append(l, r)
|
audio.Append(l, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AddToAudioBuffer(l []float32, r []float32) {
|
||||||
|
audio.Add(l, r)
|
||||||
|
}
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -30,30 +29,34 @@ const (
|
|||||||
var frames = 0
|
var frames = 0
|
||||||
|
|
||||||
const (
|
const (
|
||||||
hzA = 440.0
|
freqA = 440.0
|
||||||
hzAS = 466.2
|
freqAS = 466.2
|
||||||
hzB = 493.9
|
freqB = 493.9
|
||||||
hzC = 523.3
|
freqC = 523.3
|
||||||
hzCS = 554.4
|
freqCS = 554.4
|
||||||
hzD = 587.3
|
freqD = 587.3
|
||||||
hzDS = 622.3
|
freqDS = 622.3
|
||||||
hzE = 659.3
|
freqE = 659.3
|
||||||
hzF = 698.5
|
freqF = 698.5
|
||||||
hzFS = 740.0
|
freqFS = 740.0
|
||||||
hzG = 784.0
|
freqG = 784.0
|
||||||
hzGS = 830.6
|
freqGS = 830.6
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Need API to get sample rate?
|
// TODO: Need API to get sample rate?
|
||||||
const sampleRate = 44100
|
const sampleRate = 44100
|
||||||
|
|
||||||
func square(out []float32, hz float64, sequence float64) {
|
const score = `CCGGAAGR FFEEDDCR GGFFEEDR GGFFEEDR CCGGAAGR FFEEDDCR`
|
||||||
length := int(sampleRate / hz)
|
|
||||||
|
var scoreIndex = 0
|
||||||
|
|
||||||
|
func square(out []float32, volume float64, freq float64, sequence float64) {
|
||||||
|
length := int(sampleRate / freq)
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
panic("invalid hz")
|
panic("invalid freq")
|
||||||
}
|
}
|
||||||
for i := 0; i < len(out); i++ {
|
for i := 0; i < len(out); i++ {
|
||||||
a := float32(1.0)
|
a := float32(volume)
|
||||||
if i%length < int(float64(length)*sequence) {
|
if i%length < int(float64(length)*sequence) {
|
||||||
a = 0
|
a = 0
|
||||||
}
|
}
|
||||||
@ -61,22 +64,45 @@ func square(out []float32, hz float64, sequence float64) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addNote() {
|
||||||
|
const size = sampleRate / 60
|
||||||
|
notes := []float64{freqC, freqD, freqE, freqF, freqG, freqA * 2, freqB * 2}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
scoreIndex++
|
||||||
|
scoreIndex %= len(score)
|
||||||
|
}()
|
||||||
|
l := make([]float32, size*30)
|
||||||
|
r := make([]float32, size*30)
|
||||||
|
note := score[scoreIndex]
|
||||||
|
for note == ' ' {
|
||||||
|
scoreIndex++
|
||||||
|
scoreIndex %= len(score)
|
||||||
|
note = score[scoreIndex]
|
||||||
|
}
|
||||||
|
freq := 0.0
|
||||||
|
switch {
|
||||||
|
case note == 'R':
|
||||||
|
return
|
||||||
|
case note <= 'B':
|
||||||
|
freq = notes[int(note)+len(notes)-int('C')]
|
||||||
|
default:
|
||||||
|
freq = notes[note-'C']
|
||||||
|
}
|
||||||
|
vol := 1.0 / 32.0
|
||||||
|
square(l, vol, freq, 0.5)
|
||||||
|
square(r, vol, freq, 0.5)
|
||||||
|
ebiten.AddToAudioBuffer(l, r)
|
||||||
|
}
|
||||||
|
|
||||||
func update(screen *ebiten.Image) error {
|
func update(screen *ebiten.Image) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
frames++
|
frames++
|
||||||
}()
|
}()
|
||||||
|
|
||||||
const size = sampleRate / 60 // 3600 BPM
|
|
||||||
notes := []float64{hzA, hzB, hzC, hzD, hzE, hzF, hzG, hzA * 2}
|
|
||||||
if frames%30 == 0 {
|
if frames%30 == 0 {
|
||||||
l := make([]float32, size*30)
|
addNote()
|
||||||
r := make([]float32, size*30)
|
|
||||||
note := notes[rand.Intn(len(notes))]
|
|
||||||
square(l, note, 0.5)
|
|
||||||
square(r, note, 0.5)
|
|
||||||
ebiten.AppendAudioBuffer(l, r)
|
|
||||||
}
|
}
|
||||||
ebitenutil.DebugPrint(screen, fmt.Sprintf("%0.2f", ebiten.CurrentFPS()))
|
ebitenutil.DebugPrint(screen, fmt.Sprintf("FPS: %0.2f", ebiten.CurrentFPS()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,3 +76,19 @@ func Append(l []float32, r []float32) {
|
|||||||
bufferL = append(bufferL, l...)
|
bufferL = append(bufferL, l...)
|
||||||
bufferR = append(bufferR, r...)
|
bufferR = append(bufferR, r...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Add(l []float32, r []float32) {
|
||||||
|
// TODO: Adjust timing for frame?
|
||||||
|
if len(l) != len(r) {
|
||||||
|
panic("len(l) must equal to len(r)")
|
||||||
|
}
|
||||||
|
m := min(len(l), len(bufferL))
|
||||||
|
for i := 0; i < m; i++ {
|
||||||
|
bufferL[i] += l[i]
|
||||||
|
bufferR[i] += r[i]
|
||||||
|
}
|
||||||
|
if m < len(l) {
|
||||||
|
bufferL = append(bufferL, l[m:]...)
|
||||||
|
bufferR = append(bufferR, r[m:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user