diff --git a/main.go b/main.go index ee14c24f..11637643 100644 --- a/main.go +++ b/main.go @@ -19,11 +19,10 @@ import ( "github.com/gorilla/websocket" pionRTC "github.com/pion/webrtc" - // "gopkg.in/hraban/opus.v2" - "github.com/xlab/opus-go/opus" - "github.com/gordonklaus/portaudio" + "gopkg.in/hraban/opus.v2" ) + const ( width = 256 height = 240 @@ -33,6 +32,7 @@ const ( debugIndex = "./static/index_ws.html" ) + var indexFN = gameboyIndex // Time allowed to write a message to the peer. @@ -308,140 +308,73 @@ func fanoutScreen(imageChannel chan *image.RGBA, roomID string) { if isRoomRunning == false { log.Println("Closed room from screen routine", roomID) rooms[roomID].closedChannel <- true + return } } } -var cc chan float32 = make(chan float32, 100000) - -func Callback(out []float32) { - var output float32 - for i := range out { - if i % 2 == 0 { - select { - case sample := <-cc: - output = sample - default: - output = 0 - } - out[i] = output - - } - } -} - // fanoutAudio fanout outputs to all webrtc in the same room func fanoutAudio(audioChannel chan float32, roomID string) { - var output float32 - pcm := make([]float32, 240) + log.Println("Enter fan audio") - portaudio.Initialize() - defer portaudio.Terminate() + enc, err := opus.NewEncoder(ui.SampleRate, ui.Channels, opus.AppAudio) - host, err := portaudio.DefaultHostApi() - if err != nil { - log.Println(err) - return - } - parameters := portaudio.HighLatencyParameters(nil, host.DefaultOutputDevice) - stream, err := portaudio.OpenStream(parameters, Callback) - if err != nil { - log.Println(err) - return - } - log.Println(parameters.SampleRate, parameters.Output.Channels) - stream.Start() - - - - // dec, err := opus.NewDecoder(48000, 2) - - - // enc, err := opus.NewEncoder(48000, 2, opus.AppAudio) - // // ix, _ := enc.DTX() //false - // // ix1, _ := enc.Bitrate() //120000 - // // ix2, _ := enc.Complexity() //9 - // // ix3, _ := enc.MaxBandwidth() //1105 - // // ix4, _ := enc.PacketLossPerc() //0 - - // enc.SetMaxBandwidth(opus.Fullband) - // enc.SetBitrateToAuto() - // enc.SetComplexity(10) - - var err2 int32 - dec := opus.DecoderCreate(48000, 2, &err2) - enc := opus.EncoderCreate(48000, 2, opus.ApplicationAudio, &err2) - - + maxBufferSize := ui.TimeFrame * ui.SampleRate / 1000 + pcm := make([]float32, maxBufferSize) // 640 * 1000 / 16000 == 40 ms + idx := 0 if err != nil { log.Println("[!] Cannot create audio encoder") return } - c := time.Tick(time.Microsecond * 2500) + for { + pcm[idx] = <- audioChannel + idx ++ - for range c { - // for { - for i := 0; i < len(pcm); i++ { - if i % 2 == 0 { - select { - case sample := <- audioChannel: - output = sample - default: - output = 0 - - } - pcm[i] = output - } - } + if idx >= len(pcm) { + data := make([]byte, 640) - data := make([]byte, 1000) - // n, err := enc.EncodeFloat32(pcm, data) - - n := opus.EncodeFloat(enc, pcm, 120, data, 1000) - - if err != nil { - log.Println("[!] Failed to decode") - continue - } - data = data[:n] - - pcm2 := make([]float32, 1000) - // n2, err := dec.DecodeFloat32(data, pcm2) - n2 := opus.DecodeFloat(dec, string(data), n, pcm2, 1000, 0) - pcm2 = pcm2[:n2] - for i := 0; i < int(n2); i++ { - cc <- pcm2[i] - } - log.Println(n, n2) - - - isRoomRunning := false - for _, webRTC := range rooms[roomID].rtcSessions { - // Client stopped - if webRTC.IsClosed() { + n, err := enc.EncodeFloat32(pcm, data) + // n := opus.EncodeFloat(enc, pcm, 120, data, 1000) + + if err != nil { + log.Println("[!] Failed to decode") continue } + data = data[:n] + - // encode frame - // fanout imageChannel - if webRTC.IsConnected() { - // NOTE: can block here - webRTC.AudioChannel <- data + isRoomRunning := false + for _, webRTC := range rooms[roomID].rtcSessions { + // Client stopped + if webRTC.IsClosed() { + continue + } + + // encode frame + // fanout imageChannel + if webRTC.IsConnected() { + // NOTE: can block here + webRTC.AudioChannel <- data + } + isRoomRunning = true } - isRoomRunning = true - } - - if isRoomRunning == false { - log.Println("Closed room from audio routine", roomID) - rooms[roomID].closedChannel <- true + + if isRoomRunning == false { + log.Println("Closed room from audio routine", roomID) + rooms[roomID].closedChannel <- true + return + } + idx = 0 } } } + + // faninInput fan-in of the same room to inputChannel func faninInput(inputChannel chan int, webRTC *webrtc.WebRTC, playerIndex int) { for { diff --git a/static/index_ws.html b/static/index_ws.html index ebd54ff5..b697f077 100644 --- a/static/index_ws.html +++ b/static/index_ws.html @@ -10,7 +10,9 @@ textarea { -

+ + +

Your current room:
You can join a remote game by roomID.
Room ID: @@ -51,6 +53,10 @@ Play as player(1,2): +