Skip to content

Commit

Permalink
use portaudio instead of oto
Browse files Browse the repository at this point in the history
  • Loading branch information
ichirin2501 committed Jan 13, 2024
1 parent a73abae commit 49da8e9
Show file tree
Hide file tree
Showing 5 changed files with 704 additions and 87 deletions.
2 changes: 1 addition & 1 deletion Dockerfile.test
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM golang:1.20-buster

RUN apt-get update && \
apt-get install -y --no-install-recommends --no-install-suggests \
gcc libgl1-mesa-dev xorg-dev libasound2-dev
gcc libgl1-mesa-dev xorg-dev portaudio19-dev

WORKDIR /work
COPY . .
Expand Down
75 changes: 55 additions & 20 deletions cmd/rgnes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"github.com/hajimehoshi/oto"
"github.com/gordonklaus/portaudio"
"github.com/ichirin2501/rgnes/nes"
)

Expand Down Expand Up @@ -56,29 +56,60 @@ func (r *renderer) Refresh() {
r.currImg.Refresh()
}

type player struct {
p *oto.Player
buf []byte
// ref: https://github.com/fogleman/nes/blob/3880f3400500b1ff2e89af4e12e90be46c73ae07/ui/audio.go#L5
type Player struct {
stream *portaudio.Stream
sampleRate float64
outputChannels int
channel chan float32
}

func newPlayer() (*player, error) {
c, err := oto.NewContext(44100, 1, 1, 1)
func newPlayer() *Player {
a := Player{}
a.channel = make(chan float32, 44100)
return &a
}

func (a *Player) Start() error {
host, err := portaudio.DefaultHostApi()
if err != nil {
return err
}
parameters := portaudio.HighLatencyParameters(nil, host.DefaultOutputDevice)
stream, err := portaudio.OpenStream(parameters, a.Callback)
if err != nil {
return nil, err
return err
}
if err := stream.Start(); err != nil {
return err
}
p := c.NewPlayer()
return &player{
p: p,
buf: make([]byte, 1),
}, nil
a.stream = stream
a.sampleRate = parameters.SampleRate
a.outputChannels = parameters.Output.Channels
return nil
}

func (a *Player) Stop() error {
return a.stream.Close()
}

func (p *player) Sample(v float32) {
p.buf[0] = byte(v * 0xFF)
if _, err := p.p.Write(p.buf); err != nil {
fmt.Println("why: ", err)
func (a *Player) Callback(out []float32) {
var output float32
for i := range out {
if i%a.outputChannels == 0 {
select {
case sample := <-a.channel:
output = sample
default:
output = 0
}
}
out[i] = output
}
}
func (a *Player) Sample(v float32) {
a.channel <- v
}

func realMain() error {
var (
Expand All @@ -94,8 +125,9 @@ func realMain() error {

canvasImg1 := canvas.NewImageFromImage(img1)
canvasImg2 := canvas.NewImageFromImage(img2)
canvasImg1.SetMinSize(fyne.NewSize(256, 240))
canvasImg2.SetMinSize(fyne.NewSize(256, 240))
canvasImg1.SetMinSize(fyne.NewSize(256*2, 240*2))
canvasImg2.SetMinSize(fyne.NewSize(256*2, 240*2))

canvasImg1.ScaleMode = canvas.ImageScalePixels
canvasImg2.ScaleMode = canvas.ImageScalePixels

Expand All @@ -115,10 +147,13 @@ func realMain() error {
return err
}

player, err := newPlayer()
if err != nil {
portaudio.Initialize()
defer portaudio.Terminate()
player := newPlayer()
if err := player.Start(); err != nil {
return err
}
defer player.Stop()

n := nes.New(mapper, renderer, player)
n.PowerUp()
Expand Down
48 changes: 29 additions & 19 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,38 @@ module github.com/ichirin2501/rgnes
go 1.20

require (
fyne.io/fyne/v2 v2.1.4
github.com/hajimehoshi/oto v1.0.1
github.com/stretchr/testify v1.6.1
fyne.io/fyne/v2 v2.4.3
github.com/gordonklaus/portaudio v0.0.0-20230709114228-aafa478834f5
github.com/stretchr/testify v1.8.4
)

require (
fyne.io/systray v1.10.1-0.20231115130155-104f5ef7839e // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be // indirect
github.com/godbus/dbus/v5 v5.0.4 // indirect
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff // indirect
github.com/fredbi/uri v1.0.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect
github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 // indirect
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b // indirect
github.com/go-text/render v0.0.0-20230619120952-35bccb6164b8 // indirect
github.com/go-text/typesetting v0.0.0-20230905121921-abdbcca6e0eb // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 // indirect
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 // indirect
github.com/yuin/goldmark v1.3.8 // indirect
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8 // indirect
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6 // indirect
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f // indirect
golang.org/x/text v0.3.3 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
github.com/tevino/abool v1.2.0 // indirect
github.com/yuin/goldmark v1.5.5 // indirect
golang.org/x/image v0.12.0 // indirect
golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect
)
Loading

0 comments on commit 49da8e9

Please sign in to comment.