go-sdl2-examples/examples/audio_network/audio_network.go

93 lines
1.7 KiB
Go

package main
// typedef unsigned char Uint8;
// void AudioCallback(void *userdata, Uint8 *stream, int len);
import "C"
import (
"io/ioutil"
"log"
"net/http"
"reflect"
"unsafe"
"github.com/veandco/go-sdl2/sdl"
)
const (
sampleHz = 48000
)
var (
audioData []byte
)
//export AudioCallback
func AudioCallback(userdata unsafe.Pointer, stream *C.Uint8, length C.int) {
n := int(length)
hdr := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(stream)), Len: n, Cap: n}
buf := *(*[]C.Uint8)(unsafe.Pointer(&hdr))
if len(audioData) == 0 {
for i := 0; i < n; i++ {
buf[i] = 0
}
} else {
for i := 0; i < n; i++ {
if i >= len(audioData) {
break
}
buf[i] = C.Uint8(audioData[i])
}
if n <= len(audioData) {
// Remove processed audio data
audioData = audioData[n:]
} else {
// Clear audio data
audioData = audioData[len(audioData):]
}
}
}
// Handle audio data that is sent through HTTP
// Must be stereo unsigned 8-bit audio data at 48000Hz to play correctly
func audioHandler(w http.ResponseWriter, r *http.Request) {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
audioData = append(audioData, data...)
w.WriteHeader(http.StatusOK)
}
func main() {
if err := sdl.Init(sdl.INIT_AUDIO); err != nil {
log.Println(err)
return
}
defer sdl.Quit()
spec := &sdl.AudioSpec{
Freq: sampleHz,
Format: sdl.AUDIO_U8,
Channels: 2,
Samples: sampleHz,
Callback: sdl.AudioCallback(C.AudioCallback),
}
if err := sdl.OpenAudio(spec, nil); err != nil {
log.Println(err)
return
}
defer sdl.CloseAudio()
sdl.PauseAudio(false)
http.HandleFunc("/audio", audioHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}