mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 20:18:59 +01:00
audio: Change API to accept raw PCM data
This commit is contained in:
parent
23cef1b715
commit
de59c93219
@ -15,12 +15,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||
"github.com/hajimehoshi/ebiten/exp/audio"
|
||||
"log"
|
||||
"math"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -69,6 +72,19 @@ func square(out []int16, volume float64, freq float64, sequence float64) {
|
||||
}
|
||||
}
|
||||
|
||||
func toBytes(l, r []int16) []byte {
|
||||
if len(l) != len(r) {
|
||||
panic("len(l) must equal to len(r)")
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
for i := 0; i < len(l); i++ {
|
||||
if err := binary.Write(b, binary.LittleEndian, []int16{l[i], r[i]}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
func addNote() {
|
||||
size := audio.SampleRate() / 60
|
||||
notes := []float64{freqC, freqD, freqE, freqF, freqG, freqA * 2, freqB * 2}
|
||||
@ -97,7 +113,7 @@ func addNote() {
|
||||
vol := 1.0 / 16.0
|
||||
square(l, vol, freq, 0.25)
|
||||
square(r, vol, freq, 0.25)
|
||||
audio.Play(0, l, r)
|
||||
audio.Play(0, toBytes(l, r))
|
||||
}
|
||||
|
||||
func update(screen *ebiten.Image) error {
|
||||
|
@ -15,14 +15,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"log"
|
||||
"math"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||
"github.com/hajimehoshi/ebiten/example/common"
|
||||
"github.com/hajimehoshi/ebiten/exp/audio"
|
||||
"image/color"
|
||||
"log"
|
||||
"math"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -50,15 +53,26 @@ func init() {
|
||||
}
|
||||
|
||||
var (
|
||||
noteLCache = map[int][]int16{}
|
||||
noteRCache = map[int][]int16{}
|
||||
noteCache = map[int][]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 := 0; i < len(l); i++ {
|
||||
if err := binary.Write(b, binary.LittleEndian, []int16{l[i], r[i]}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
func addNote(freq float64, vol float64) {
|
||||
f := int(freq)
|
||||
if l, ok := noteLCache[f]; ok {
|
||||
r := noteRCache[f]
|
||||
audio.Play(-1, l, r)
|
||||
if n, ok := noteCache[f]; ok {
|
||||
audio.Play(-1, n)
|
||||
return
|
||||
}
|
||||
length := len(pcm) * baseFreq / f
|
||||
@ -73,9 +87,9 @@ func addNote(freq float64, vol float64) {
|
||||
jj += f
|
||||
j = jj / baseFreq
|
||||
}
|
||||
noteLCache[f] = l
|
||||
noteRCache[f] = r
|
||||
audio.Play(-1, l, r)
|
||||
n := toBytes(l, r)
|
||||
noteCache[f] = n
|
||||
audio.Play(-1, n)
|
||||
}
|
||||
|
||||
var keys = []ebiten.Key{
|
||||
|
@ -15,6 +15,9 @@
|
||||
package audio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/exp/audio/internal"
|
||||
)
|
||||
|
||||
@ -26,13 +29,32 @@ func SampleRate() int {
|
||||
// MaxChannel is a max number of channels.
|
||||
var MaxChannel = internal.MaxChannel
|
||||
|
||||
func toLR(data []byte) ([]int16, []int16) {
|
||||
buf := bytes.NewReader(data)
|
||||
b := make([]int16, len(data)/2)
|
||||
if err := binary.Read(buf, binary.LittleEndian, b); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
l := make([]int16, len(data)/4)
|
||||
r := make([]int16, len(data)/4)
|
||||
for i := 0; i < len(data)/4; i++ {
|
||||
l[i] = b[2*i]
|
||||
r[i] = b[2*i+1]
|
||||
}
|
||||
return l, r
|
||||
}
|
||||
|
||||
// Play appends the given data to the given channel.
|
||||
//
|
||||
// channel must be -1 or a channel index. If channel is -1, an empty channel is automatically selected.
|
||||
// If the channel is not empty, this function does nothing and returns false. This returns true otherwise.
|
||||
//
|
||||
// data's format must be linear PCM (44100Hz, stereo, 16bit little endian).
|
||||
//
|
||||
// This function is useful to play SE or a note of PCM synthesis immediately.
|
||||
func Play(channel int, l []int16, r []int16) bool {
|
||||
func Play(channel int, data []byte) bool {
|
||||
l, r := toLR(data)
|
||||
// TODO: Pass data directly.
|
||||
return internal.Play(channel, l, r)
|
||||
}
|
||||
|
||||
@ -41,8 +63,12 @@ func Play(channel int, l []int16, r []int16) bool {
|
||||
//
|
||||
// channel must be a channel index. You can't give -1 to channel.
|
||||
//
|
||||
// data's format must be linear PCM (44100Hz, stereo, 16bit little endian).
|
||||
//
|
||||
// This function is useful to play streaming data.
|
||||
func Queue(channel int, l []int16, r []int16) {
|
||||
func Queue(channel int, data []byte) {
|
||||
l, r := toLR(data)
|
||||
// TODO: Pass data directly.
|
||||
internal.Queue(channel, l, r)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user