From e1336c2eba392f20e425174568920363f2fb6c07 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 25 Jan 2015 19:17:53 +0900 Subject: [PATCH] audio: Change API: accept []int16 instead of []float32 --- example/audio/main.go | 9 +++++---- exp/audio/audio.go | 4 ++-- internal/audio/audio.go | 22 +++++++++++----------- internal/audio/audio_js.go | 5 +++-- internal/audio/audio_openal.go | 7 ++----- 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/example/audio/main.go b/example/audio/main.go index 62da4a78f..b3a82fcee 100644 --- a/example/audio/main.go +++ b/example/audio/main.go @@ -20,6 +20,7 @@ import ( "github.com/hajimehoshi/ebiten/ebitenutil" "github.com/hajimehoshi/ebiten/exp/audio" "log" + "math" ) const ( @@ -48,7 +49,7 @@ const score = `CCGGAAGR FFEEDDCR GGFFEEDR GGFFEEDR CCGGAAGR FFEEDDCR` var scoreIndex = 0 -func square(out []float32, volume float64, freq float64, sequence float64) { +func square(out []int16, volume float64, freq float64, sequence float64) { if freq == 0 { for i := 0; i < len(out); i++ { out[i] = 0 @@ -60,7 +61,7 @@ func square(out []float32, volume float64, freq float64, sequence float64) { panic("invalid freq") } for i := 0; i < len(out); i++ { - a := float32(volume) + a := int16(volume * math.MaxInt16) if i%length < int(float64(length)*sequence) { a = -a } @@ -76,8 +77,8 @@ func addNote() { scoreIndex++ scoreIndex %= len(score) }() - l := make([]float32, size*30) - r := make([]float32, size*30) + l := make([]int16, size*30) + r := make([]int16, size*30) note := score[scoreIndex] for note == ' ' { scoreIndex++ diff --git a/exp/audio/audio.go b/exp/audio/audio.go index f0465bcd3..d623ffdd6 100644 --- a/exp/audio/audio.go +++ b/exp/audio/audio.go @@ -32,7 +32,7 @@ var MaxChannel = audio.MaxChannel // If the channel is not empty, this function does nothing and returns false. This returns true otherwise. // // This function is useful to play SE or a note of PCM synthesis immediately. -func Play(channel int, l []float32, r []float32) bool { +func Play(channel int, l []int16, r []int16) bool { return audio.Play(channel, l, r) } @@ -42,7 +42,7 @@ func Play(channel int, l []float32, r []float32) bool { // channel must be a channel index. You can't give -1 to channel. // // This function is useful to play streaming data. -func Queue(channel int, l []float32, r []float32) { +func Queue(channel int, l []int16, r []int16) { audio.Queue(channel, l, r) } diff --git a/internal/audio/audio.go b/internal/audio/audio.go index d30a5be62..5cbd16b4b 100644 --- a/internal/audio/audio.go +++ b/internal/audio/audio.go @@ -27,8 +27,8 @@ var nextInsertionPosition = 0 var currentPosition = 0 type channel struct { - l []float32 - r []float32 + l []int16 + r []int16 } var MaxChannel = 32 @@ -39,8 +39,8 @@ var channelsLock sync.Mutex func init() { for i, _ := range channels { channels[i] = &channel{ - l: []float32{}, - r: []float32{}, + l: []int16{}, + r: []int16{}, } } } @@ -73,7 +73,7 @@ func channelAt(i int) *channel { return nil } -func Play(channel int, l []float32, r []float32) bool { +func Play(channel int, l []int16, r []int16) bool { channelsLock.Lock() defer channelsLock.Unlock() @@ -88,14 +88,14 @@ func Play(channel int, l []float32, r []float32) bool { if ch == nil { return false } - ch.l = append(ch.l, make([]float32, nextInsertionPosition-len(ch.l))...) - ch.r = append(ch.r, make([]float32, nextInsertionPosition-len(ch.r))...) + ch.l = append(ch.l, make([]int16, nextInsertionPosition-len(ch.l))...) + ch.r = append(ch.r, make([]int16, nextInsertionPosition-len(ch.r))...) ch.l = append(ch.l, l...) ch.r = append(ch.r, r...) return true } -func Queue(channel int, l []float32, r []float32) { +func Queue(channel int, l []int16, r []int16) { channelsLock.Lock() defer channelsLock.Unlock() @@ -138,7 +138,7 @@ func isChannelsEmpty() bool { return true } -func loadChannelBuffers() (l, r []float32) { +func loadChannelBuffers() (l, r []int16) { channelsLock.Lock() defer channelsLock.Unlock() @@ -146,8 +146,8 @@ func loadChannelBuffers() (l, r []float32) { return nil, nil } - inputL := make([]float32, bufferSize) - inputR := make([]float32, bufferSize) + inputL := make([]int16, bufferSize) + inputR := make([]int16, bufferSize) for _, ch := range channels { if len(ch.l) == 0 { continue diff --git a/internal/audio/audio_js.go b/internal/audio/audio_js.go index 1af796300..0dd9d7aaf 100644 --- a/internal/audio/audio_js.go +++ b/internal/audio/audio_js.go @@ -38,6 +38,7 @@ func initialize() { r := e.Get("outputBuffer").Call("getChannelData", 1) inputL, inputR := loadChannelBuffers() nextInsertionPosition -= min(bufferSize, nextInsertionPosition) + const max = 1 << 16 for i := 0; i < bufferSize; i++ { // TODO: Use copyFromChannel? if len(inputL) <= i { @@ -45,8 +46,8 @@ func initialize() { r.SetIndex(i, 0) continue } - l.SetIndex(i, inputL[i]) - r.SetIndex(i, inputR[i]) + l.SetIndex(i, float64(inputL[i])/max) + r.SetIndex(i, float64(inputR[i])/max) } }) audioEnabled = true diff --git a/internal/audio/audio_openal.go b/internal/audio/audio_openal.go index c2911a7b4..a673f41c2 100644 --- a/internal/audio/audio_openal.go +++ b/internal/audio/audio_openal.go @@ -22,20 +22,17 @@ import ( "fmt" "github.com/timshannon/go-openal/openal" "log" - "math" "runtime" "time" ) -func toBytes(l, r []float32) []byte { +func toBytes(l, r []int16) []byte { if len(l) != len(r) { panic("len(l) must equal to len(r)") } b := &bytes.Buffer{} for i, _ := range l { - l := int16(l[i] * math.MaxInt16) - r := int16(r[i] * math.MaxInt16) - if err := binary.Write(b, binary.LittleEndian, []int16{l, r}); err != nil { + if err := binary.Write(b, binary.LittleEndian, []int16{l[i], r[i]}); err != nil { panic(err) } }