Play music at example/audio

This commit is contained in:
Hajime Hoshi 2015-01-11 19:52:11 +09:00
parent 355da1bcbc
commit a220251716
3 changed files with 74 additions and 28 deletions

View File

@ -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)
}

View File

@ -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
} }

View File

@ -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:]...)
}
}