mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
audio: Add channel.nextInsertion
This commit is contained in:
parent
4b74411922
commit
8d250c6b25
@ -48,6 +48,12 @@ const score = `CCGGAAGR FFEEDDCR GGFFEEDR GGFFEEDR CCGGAAGR FFEEDDCR`
|
|||||||
var scoreIndex = 0
|
var scoreIndex = 0
|
||||||
|
|
||||||
func square(out []float32, volume float64, freq float64, sequence float64) {
|
func square(out []float32, volume float64, freq float64, sequence float64) {
|
||||||
|
if freq == 0 {
|
||||||
|
for i := 0; i < len(out); i++ {
|
||||||
|
out[i] = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
length := int(float64(ebiten.AudioSampleRate()) / freq)
|
length := int(float64(ebiten.AudioSampleRate()) / freq)
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
panic("invalid freq")
|
panic("invalid freq")
|
||||||
@ -69,8 +75,8 @@ func addNote() {
|
|||||||
scoreIndex++
|
scoreIndex++
|
||||||
scoreIndex %= len(score)
|
scoreIndex %= len(score)
|
||||||
}()
|
}()
|
||||||
l := make([]float32, size*30*2)
|
l := make([]float32, size*30)
|
||||||
r := make([]float32, size*30*2)
|
r := make([]float32, size*30)
|
||||||
note := score[scoreIndex]
|
note := score[scoreIndex]
|
||||||
for note == ' ' {
|
for note == ' ' {
|
||||||
scoreIndex++
|
scoreIndex++
|
||||||
@ -80,7 +86,7 @@ func addNote() {
|
|||||||
freq := 0.0
|
freq := 0.0
|
||||||
switch {
|
switch {
|
||||||
case note == 'R':
|
case note == 'R':
|
||||||
return
|
freq = 0
|
||||||
case note <= 'B':
|
case note <= 'B':
|
||||||
freq = notes[int(note)+len(notes)-int('C')]
|
freq = notes[int(note)+len(notes)-int('C')]
|
||||||
default:
|
default:
|
||||||
@ -89,7 +95,7 @@ func addNote() {
|
|||||||
vol := 1.0 / 32.0
|
vol := 1.0 / 32.0
|
||||||
square(l, vol, freq, 0.5)
|
square(l, vol, freq, 0.5)
|
||||||
square(r, vol, freq, 0.5)
|
square(r, vol, freq, 0.5)
|
||||||
ebiten.AppendToAudioBuffer(-1, l, r)
|
ebiten.AppendToAudioBuffer(0, l, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(screen *ebiten.Image) error {
|
func update(screen *ebiten.Image) error {
|
||||||
|
@ -35,3 +35,7 @@ func CurrentBytes() int {
|
|||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Update() {
|
||||||
|
// TODO: Implement
|
||||||
|
}
|
||||||
|
@ -30,6 +30,7 @@ const SampleRate = 44100
|
|||||||
type channel struct {
|
type channel struct {
|
||||||
l []float32
|
l []float32
|
||||||
r []float32
|
r []float32
|
||||||
|
nextInsertion int
|
||||||
}
|
}
|
||||||
|
|
||||||
var channels = make([]*channel, 16)
|
var channels = make([]*channel, 16)
|
||||||
@ -83,6 +84,7 @@ func Init() {
|
|||||||
usedLen := min(bufferSize, len(ch.l))
|
usedLen := min(bufferSize, len(ch.l))
|
||||||
ch.l = ch.l[usedLen:]
|
ch.l = ch.l[usedLen:]
|
||||||
ch.r = ch.r[usedLen:]
|
ch.r = ch.r[usedLen:]
|
||||||
|
ch.nextInsertion -= min(bufferSize, ch.nextInsertion)
|
||||||
}
|
}
|
||||||
for i := 0; i < bufferSize; i++ {
|
for i := 0; i < bufferSize; i++ {
|
||||||
// TODO: Use copyFromChannel?
|
// TODO: Use copyFromChannel?
|
||||||
@ -97,6 +99,15 @@ func Init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Update() {
|
||||||
|
for _, ch := range channels {
|
||||||
|
if len(ch.l) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ch.nextInsertion += SampleRate / 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Start() {
|
func Start() {
|
||||||
// TODO: For iOS, node should be connected with a buffer node.
|
// TODO: For iOS, node should be connected with a buffer node.
|
||||||
node.Call("connect", context.Get("destination"))
|
node.Call("connect", context.Get("destination"))
|
||||||
@ -105,19 +116,17 @@ func Start() {
|
|||||||
func channelAt(i int) *channel {
|
func channelAt(i int) *channel {
|
||||||
if i == -1 {
|
if i == -1 {
|
||||||
for _, ch := range channels {
|
for _, ch := range channels {
|
||||||
if 0 < len(ch.l) {
|
if len(ch.l) <= ch.nextInsertion {
|
||||||
continue
|
|
||||||
}
|
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ch := channels[i]
|
ch := channels[i]
|
||||||
// TODO: Can we append even though all data is not consumed? Need game timer?
|
if len(ch.l) <= ch.nextInsertion {
|
||||||
if 0 < len(ch.l) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return ch
|
return ch
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Append(i int, l []float32, r []float32) bool {
|
func Append(i int, l []float32, r []float32) bool {
|
||||||
@ -129,6 +138,9 @@ func Append(i int, l []float32, r []float32) bool {
|
|||||||
if ch == nil {
|
if ch == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
print(ch.nextInsertion)
|
||||||
|
ch.l = append(ch.l, make([]float32, ch.nextInsertion-len(ch.l))...)
|
||||||
|
ch.r = append(ch.r, make([]float32, ch.nextInsertion-len(ch.r))...)
|
||||||
ch.l = append(ch.l, l...)
|
ch.l = append(ch.l, l...)
|
||||||
ch.r = append(ch.r, r...)
|
ch.r = append(ch.r, r...)
|
||||||
return true
|
return true
|
||||||
|
3
run.go
3
run.go
@ -15,6 +15,7 @@
|
|||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/audio"
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
"github.com/hajimehoshi/ebiten/internal/ui"
|
"github.com/hajimehoshi/ebiten/internal/ui"
|
||||||
"time"
|
"time"
|
||||||
@ -69,6 +70,8 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
|
|||||||
if err := graphicsContext.postUpdate(); err != nil {
|
if err := graphicsContext.postUpdate(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// TODO: I'm not sure this is 'Update'. Is 'Tick' better?
|
||||||
|
audio.Update()
|
||||||
ui.SwapBuffers()
|
ui.SwapBuffers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user