example/piano: Speed up

This commit is contained in:
Hajime Hoshi 2015-02-16 10:33:27 +09:00
parent 8c2301e542
commit 9ec7b13f27
4 changed files with 59 additions and 54 deletions

View File

@ -103,6 +103,36 @@ func updateInput() {
}
}
var pianoImage *ebiten.Image
func init() {
var err error
pianoImage, err = ebiten.NewImage(screenWidth, screenHeight, ebiten.FilterNearest)
if err != nil {
panic(err)
}
whiteKeys := []string{"A", "S", "D", "F", "G", "H", "J", "K", "L"}
width := 24
y := 48
for i, k := range whiteKeys {
x := i*width + 36
height := 112
pianoImage.DrawFilledRect(x, y, width-1, height, color.White)
common.ArcadeFont.DrawText(pianoImage, k, x+8, y+height-16, 1, color.Black)
}
blackKeys := []string{"Q", "W", "", "R", "T", "", "U", "I", "O"}
for i, k := range blackKeys {
if k == "" {
continue
}
x := i*width + 24
height := 64
pianoImage.DrawFilledRect(x, y, width-1, height, color.Black)
common.ArcadeFont.DrawText(pianoImage, k, x+8, y+height-16, 1, color.White)
}
}
func update(screen *ebiten.Image) error {
updateInput()
for i, key := range keys {
@ -113,27 +143,7 @@ func update(screen *ebiten.Image) error {
}
screen.Fill(color.RGBA{0x80, 0x80, 0xc0, 0xff})
whiteKeys := []string{"A", "S", "D", "F", "G", "H", "J", "K", "L"}
width := 24
y := 48
for i, k := range whiteKeys {
x := i*width + 36
height := 112
screen.DrawFilledRect(x, y, width-1, height, color.White)
common.ArcadeFont.DrawText(screen, k, x+8, y+height-16, 1, color.Black)
}
blackKeys := []string{"Q", "W", "", "R", "T", "", "U", "I", "O"}
for i, k := range blackKeys {
if k == "" {
continue
}
x := i*width + 24
height := 64
screen.DrawFilledRect(x, y, width-1, height, color.Black)
common.ArcadeFont.DrawText(screen, k, x+8, y+height-16, 1, color.White)
}
screen.DrawImage(pianoImage, nil)
ebitenutil.DebugPrint(screen, fmt.Sprintf("FPS: %0.2f", ebiten.CurrentFPS()))
return nil

View File

@ -18,8 +18,6 @@ var audioEnabled = false
const SampleRate = 44100
var currentPosition = 0
type channel struct {
l []int16
r []int16
@ -143,10 +141,8 @@ func loadChannelBuffer(channel int, bufferSize int) (l, r []int16) {
ch := channels[channel]
length := min(len(ch.l), bufferSize)
inputL := make([]int16, length)
inputR := make([]int16, length)
copy(inputL, ch.l[:length])
copy(inputR, ch.r[:length])
inputL := ch.l[:length]
inputR := ch.r[:length]
ch.l = ch.l[length:]
ch.r = ch.r[length:]
ch.nextInsertionPosition -= min(bufferSize, ch.nextInsertionPosition)

View File

@ -33,28 +33,21 @@ var (
const bufferSize = 1024
func audioProcess(channel int) func(e js.Object) {
return func(e js.Object) {
// Can't use 'go' here. Probably it may cause race conditions.
defer func() {
currentPosition += bufferSize
}()
type audioProcessor struct {
channel int
}
b := e.Get("outputBuffer")
l := b.Call("getChannelData", 0)
r := b.Call("getChannelData", 1)
inputL, inputR := loadChannelBuffer(channel, bufferSize)
const max = 1 << 15
for i := 0; i < bufferSize; i++ {
// TODO: Use copyToChannel?
if len(inputL) <= i {
l.SetIndex(i, 0)
r.SetIndex(i, 0)
continue
}
l.SetIndex(i, float64(inputL[i])/max)
r.SetIndex(i, float64(inputR[i])/max)
}
func (a *audioProcessor) Process(e js.Object) {
// Can't use 'go' here. Probably it may cause race conditions.
b := e.Get("outputBuffer")
l := b.Call("getChannelData", 0)
r := b.Call("getChannelData", 1)
inputL, inputR := loadChannelBuffer(a.channel, bufferSize)
const max = 1 << 15
for i := 0; i < len(inputL); i++ {
// TODO: Use copyToChannel?
l.SetIndex(i, float64(inputL[i])/max)
r.SetIndex(i, float64(inputR[i])/max)
}
}
@ -69,7 +62,8 @@ func initialize() {
// https://developer.mozilla.org/ja/docs/Web/API/ScriptProcessorNode
for i := 0; i < MaxChannel; i++ {
node := context.Call("createScriptProcessor", bufferSize, 0, 2)
node.Call("addEventListener", "audioprocess", audioProcess(i))
processor := &audioProcessor{i}
node.Call("addEventListener", "audioprocess", processor.Process)
nodes = append(nodes, node)
dummy := context.Call("createBufferSource")

View File

@ -53,10 +53,11 @@ func orthoProjectionMatrix(left, right, bottom, top int) *[4][4]float64 {
}
type Framebuffer struct {
native opengl.Framebuffer
width int
height int
flipY bool
native opengl.Framebuffer
width int
height int
flipY bool
proMatrix *[4][4]float64
}
func NewZeroFramebuffer(c *opengl.Context, width, height int) (*Framebuffer, error) {
@ -100,6 +101,9 @@ func (f *Framebuffer) setAsViewport(c *opengl.Context) error {
}
func (f *Framebuffer) projectionMatrix() *[4][4]float64 {
if f.proMatrix != nil {
return f.proMatrix
}
width := NextPowerOf2Int(f.width)
height := NextPowerOf2Int(f.height)
m := orthoProjectionMatrix(0, width, 0, height)
@ -107,7 +111,8 @@ func (f *Framebuffer) projectionMatrix() *[4][4]float64 {
m[1][1] *= -1
m[1][3] += float64(f.height) / float64(NextPowerOf2Int(f.height)) * 2
}
return m
f.proMatrix = m
return f.proMatrix
}
func (f *Framebuffer) Fill(c *opengl.Context, clr color.Color) error {