Get view-menu to play the interface sound
This commit is contained in:
49
README.md
49
README.md
@@ -19,7 +19,7 @@ installed on your system:
|
|||||||
|
|
||||||
```
|
```
|
||||||
$ go version
|
$ go version
|
||||||
go version go1.13 linux/amd64
|
go version go1.14 linux/amd64
|
||||||
```
|
```
|
||||||
|
|
||||||
In addition, you'll also need the following packages installed, at least in
|
In addition, you'll also need the following packages installed, at least in
|
||||||
@@ -27,13 +27,11 @@ Debian:
|
|||||||
|
|
||||||
```
|
```
|
||||||
# apt install libx11-dev libxcursor-dev mesa-common-dev libxrandr-dev \
|
# apt install libx11-dev libxcursor-dev mesa-common-dev libxrandr-dev \
|
||||||
libxinerama-dev libgl1-mesa-dev libxi-dev mpv
|
libxinerama-dev libgl1-mesa-dev libxi-dev libasound2-dev mpv ffmpeg
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then run `make all` in the source tree to get the binaries that are
|
You can then run `make all` in the source tree to get the binaries that are
|
||||||
present at hte moment.
|
present at the moment.
|
||||||
|
|
||||||
They're not very interesting :D.
|
|
||||||
|
|
||||||
Place your WH40K: Chaos Gate installation in `./orig` to benefit from automatic
|
Place your WH40K: Chaos Gate installation in `./orig` to benefit from automatic
|
||||||
path defaults. Otherwise, point to it with `-game-path`
|
path defaults. Otherwise, point to it with `-game-path`
|
||||||
@@ -42,14 +40,13 @@ The `view-map` binary attempts to render a map, and is the current focus of
|
|||||||
effort. Once I can render a whole map, including pre-placed characters (cultist
|
effort. Once I can render a whole map, including pre-placed characters (cultist
|
||||||
scum), things can start to get more interesting.
|
scum), things can start to get more interesting.
|
||||||
|
|
||||||
Current status: map tiles are rendered at correct offsets. Static objects (four
|
Current status: almost pixel-perfect map rendering. Static objects (four per map
|
||||||
per map coordinate: floor, centre, left, and right) are rendered mostly fine,
|
coordinate: floor, centre, left, and right) are rendered fine, and each Z level
|
||||||
although objects at each Z level don't *quite* stack correctly on top of each
|
looks good. There are a few minor artifacts here and there.
|
||||||
other yet.
|
|
||||||
|
|
||||||
Characters and animations aren't touched at all yet. Rendering performance is
|
Characters and animations aren't touched at all yet. Rendering performance is
|
||||||
atrocious. No gameplay, no sound, no campaign logic. Interaction with the play
|
poor. No gameplay, no campaign logic. Interaction with the play area is minimal
|
||||||
area is minimal and limited to pan, zoom, and click for basic console output.
|
and limited to pan, zoom, and click for basic console output.
|
||||||
|
|
||||||
Still, I'm proud of myself.
|
Still, I'm proud of myself.
|
||||||
|
|
||||||
@@ -57,7 +54,7 @@ To run:
|
|||||||
|
|
||||||
```
|
```
|
||||||
$ make view-map
|
$ make view-map
|
||||||
$ ./view-map -map orig/Maps/Chapter01.MAP -txt orig/Maps/Chapter01.TXT
|
$ ./view-map -map Chapter01
|
||||||
```
|
```
|
||||||
|
|
||||||
Looks like this:
|
Looks like this:
|
||||||
@@ -72,12 +69,36 @@ Dependency management uses `go mod`, so ensure you have at least Go 1.11.
|
|||||||
There is the **start** of the menu / campaign flow in a `wh40k` binary:
|
There is the **start** of the menu / campaign flow in a `wh40k` binary:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
$ cp config.toml.example config.toml
|
||||||
$ make wh40k
|
$ make wh40k
|
||||||
$ ./wh40k
|
$ ./wh40k
|
||||||
```
|
```
|
||||||
|
|
||||||
This plays the introductory video so far, and nothing else. I'm hopeful I can
|
This plays the introductory videos so far, and nothing else.
|
||||||
render the main menu next.
|
|
||||||
|
Menus are in the process of being rendered; you can use the `view-menu` binary
|
||||||
|
to inspect them:
|
||||||
|
|
||||||
|
```
|
||||||
|
make view-menu
|
||||||
|
./view-menu -menu ./orig/Menu/Main.mnu
|
||||||
|
```
|
||||||
|
|
||||||
|
This menu *displays* OK, including
|
||||||
|
|
||||||
|
## Sound
|
||||||
|
|
||||||
|
Sound is in the very early stages. Chaos Gate uses ADPCM WAV files, which are a
|
||||||
|
pain to play in Go, so for now, a preprocessing step that converts them to .ogg
|
||||||
|
is used instead. To create ./orig/Wav/*.wav.ogg, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
# apt install ffmpeg
|
||||||
|
$ ./scripts/convert-wav ./orig/Wav
|
||||||
|
```
|
||||||
|
|
||||||
|
As with video playback, the ambition is to *eventually* remove this dependency
|
||||||
|
and operate on the unmodified files instead.
|
||||||
|
|
||||||
## Miscellany
|
## Miscellany
|
||||||
|
|
||||||
|
@@ -7,12 +7,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
|
||||||
|
|
||||||
"code.ur.gs/lupine/ordoor/internal/assetstore"
|
"code.ur.gs/lupine/ordoor/internal/assetstore"
|
||||||
"code.ur.gs/lupine/ordoor/internal/data"
|
"code.ur.gs/lupine/ordoor/internal/data"
|
||||||
"code.ur.gs/lupine/ordoor/internal/menus"
|
"code.ur.gs/lupine/ordoor/internal/menus"
|
||||||
"code.ur.gs/lupine/ordoor/internal/ui"
|
"code.ur.gs/lupine/ordoor/internal/ui"
|
||||||
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
"github.com/hajimehoshi/ebiten/audio"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -76,6 +76,20 @@ func main() {
|
|||||||
menuObjs = append(menuObjs, obj)
|
menuObjs = append(menuObjs, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Yay sound
|
||||||
|
if _, err := audio.NewContext(48000); err != nil {
|
||||||
|
log.Fatalf("Failed to audio: %v", err)
|
||||||
|
}
|
||||||
|
music, err := assets.Sound("music_interface") // FIXME: should be a reference to Sounds.dat
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to find interface music: %v", err)
|
||||||
|
}
|
||||||
|
player, err := music.InfinitePlayer()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to generate music player for interface: %v", err)
|
||||||
|
}
|
||||||
|
player.Play()
|
||||||
|
|
||||||
state := state{}
|
state := state{}
|
||||||
env := &env{
|
env := &env{
|
||||||
menu: menu,
|
menu: menu,
|
||||||
|
4
go.mod
4
go.mod
@@ -5,8 +5,8 @@ go 1.12
|
|||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5
|
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5
|
||||||
golang.org/x/exp v0.0.0-20200319221330-857350248e3d // indirect
|
golang.org/x/exp v0.0.0-20200320212757-167ffe94c325 // indirect
|
||||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
|
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
|
||||||
golang.org/x/mobile v0.0.0-20200222142934-3c8601c510d0 // indirect
|
golang.org/x/mobile v0.0.0-20200222142934-3c8601c510d0 // indirect
|
||||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d // indirect
|
golang.org/x/sys v0.0.0-20200321134203-328b4cd54aae // indirect
|
||||||
)
|
)
|
||||||
|
9
go.sum
9
go.sum
@@ -14,13 +14,18 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw
|
|||||||
github.com/hajimehoshi/bitmapfont v1.2.0/go.mod h1:h9QrPk6Ktb2neObTlAbma6Ini1xgMjbJ3w7ysmD7IOU=
|
github.com/hajimehoshi/bitmapfont v1.2.0/go.mod h1:h9QrPk6Ktb2neObTlAbma6Ini1xgMjbJ3w7ysmD7IOU=
|
||||||
github.com/hajimehoshi/ebiten v1.10.2 h1:PiJBY4Q4udip675T+Zqvb3NKMp1eyLWBelp660ZMrkQ=
|
github.com/hajimehoshi/ebiten v1.10.2 h1:PiJBY4Q4udip675T+Zqvb3NKMp1eyLWBelp660ZMrkQ=
|
||||||
github.com/hajimehoshi/ebiten v1.10.2/go.mod h1:i9dIEUf5/MuPtbK1/wHR0PB7ZtqhjOxxg+U1xfxapcY=
|
github.com/hajimehoshi/ebiten v1.10.2/go.mod h1:i9dIEUf5/MuPtbK1/wHR0PB7ZtqhjOxxg+U1xfxapcY=
|
||||||
|
github.com/hajimehoshi/ebiten v1.10.5 h1:hVb3GJP4IDqOETifRmPg4xmURRgbIJoB9gQk+Jqe8Uk=
|
||||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5 h1:hke9UdXY1YPfqjXG1bCSZnoVnfVBw9SzvmlrRn3dL3w=
|
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5 h1:hke9UdXY1YPfqjXG1bCSZnoVnfVBw9SzvmlrRn3dL3w=
|
||||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5/go.mod h1:0SLvfr8iI2NxzpNB/olBM+dLN9Ur5a9szG13wOgQ0nQ=
|
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5/go.mod h1:0SLvfr8iI2NxzpNB/olBM+dLN9Ur5a9szG13wOgQ0nQ=
|
||||||
|
github.com/hajimehoshi/go-mp3 v0.2.1 h1:DH4ns3cPv39n3cs8MPcAlWqPeAwLCK8iNgqvg0QBWI8=
|
||||||
github.com/hajimehoshi/go-mp3 v0.2.1/go.mod h1:Rr+2P46iH6PwTPVgSsEwBkon0CK5DxCAeX/Rp65DCTE=
|
github.com/hajimehoshi/go-mp3 v0.2.1/go.mod h1:Rr+2P46iH6PwTPVgSsEwBkon0CK5DxCAeX/Rp65DCTE=
|
||||||
github.com/hajimehoshi/oto v0.3.4/go.mod h1:PgjqsBJff0efqL2nlMJidJgVJywLn6M4y8PI4TfeWfA=
|
github.com/hajimehoshi/oto v0.3.4/go.mod h1:PgjqsBJff0efqL2nlMJidJgVJywLn6M4y8PI4TfeWfA=
|
||||||
|
github.com/hajimehoshi/oto v0.5.4 h1:Dn+WcYeF310xqStKm0tnvoruYUV5Sce8+sfUaIvWGkE=
|
||||||
github.com/hajimehoshi/oto v0.5.4/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
|
github.com/hajimehoshi/oto v0.5.4/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
|
||||||
github.com/jakecoffman/cp v0.1.0/go.mod h1:a3xPx9N8RyFAACD644t2dj/nK4SuLg1v+jL61m2yVo4=
|
github.com/jakecoffman/cp v0.1.0/go.mod h1:a3xPx9N8RyFAACD644t2dj/nK4SuLg1v+jL61m2yVo4=
|
||||||
|
github.com/jfreymuth/oggvorbis v1.0.0 h1:aOpiihGrFLXpsh2osOlEvTcg5/aluzGQeC7m3uYWOZ0=
|
||||||
github.com/jfreymuth/oggvorbis v1.0.0/go.mod h1:abe6F9QRjuU9l+2jek3gj46lu40N4qlYxh2grqkLEDM=
|
github.com/jfreymuth/oggvorbis v1.0.0/go.mod h1:abe6F9QRjuU9l+2jek3gj46lu40N4qlYxh2grqkLEDM=
|
||||||
|
github.com/jfreymuth/vorbis v1.0.0 h1:SmDf783s82lIjGZi8EGUUaS7YxPHgRj4ZXW/h7rUi7U=
|
||||||
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0=
|
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
@@ -38,6 +43,8 @@ golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85 h1:jqhIzSw5SQNkbu5hOGpgMHhkf
|
|||||||
golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||||
golang.org/x/exp v0.0.0-20200319221330-857350248e3d h1:1kJNg12kVM6Xid7xoFkhq/YJVU4NMTv5b3hJCfQnwjc=
|
golang.org/x/exp v0.0.0-20200319221330-857350248e3d h1:1kJNg12kVM6Xid7xoFkhq/YJVU4NMTv5b3hJCfQnwjc=
|
||||||
golang.org/x/exp v0.0.0-20200319221330-857350248e3d/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
golang.org/x/exp v0.0.0-20200319221330-857350248e3d/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||||
|
golang.org/x/exp v0.0.0-20200320212757-167ffe94c325 h1:iPGJw87eUJvke9YLYKX0jIwLHiIrY/kXcFSgOpjav28=
|
||||||
|
golang.org/x/exp v0.0.0-20200320212757-167ffe94c325/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
@@ -69,6 +76,8 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193
|
|||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d h1:62ap6LNOjDU6uGmKXHJbSfciMoV+FeI1sRXx/pLDL44=
|
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d h1:62ap6LNOjDU6uGmKXHJbSfciMoV+FeI1sRXx/pLDL44=
|
||||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200321134203-328b4cd54aae h1:3tcmuaB7wwSZtelmiv479UjUB+vviwABz7a133ZwOKQ=
|
||||||
|
golang.org/x/sys v0.0.0-20200321134203-328b4cd54aae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190909214602-067311248421/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190909214602-067311248421/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
@@ -32,9 +32,10 @@ type AssetStore struct {
|
|||||||
entries entryMap
|
entries entryMap
|
||||||
|
|
||||||
// These members are used to store things we've already loaded
|
// These members are used to store things we've already loaded
|
||||||
maps map[string]*Map
|
maps map[string]*Map
|
||||||
objs map[string]*Object
|
objs map[string]*Object
|
||||||
sets map[string]*Set
|
sets map[string]*Set
|
||||||
|
sounds map[string]*Sound
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new AssetStore
|
// New returns a new AssetStore
|
||||||
@@ -82,6 +83,7 @@ func (a *AssetStore) Refresh() error {
|
|||||||
a.maps = make(map[string]*Map)
|
a.maps = make(map[string]*Map)
|
||||||
a.objs = make(map[string]*Object)
|
a.objs = make(map[string]*Object)
|
||||||
a.sets = make(map[string]*Set)
|
a.sets = make(map[string]*Set)
|
||||||
|
a.sounds = make(map[string]*Sound)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
78
internal/assetstore/sound.go
Normal file
78
internal/assetstore/sound.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package assetstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/audio"
|
||||||
|
"github.com/hajimehoshi/ebiten/audio/vorbis"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Sound struct {
|
||||||
|
Name string
|
||||||
|
|
||||||
|
filename string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AssetStore) Sound(name string) (*Sound, error) {
|
||||||
|
name = canonical(name)
|
||||||
|
|
||||||
|
if sound, ok := a.sounds[name]; ok {
|
||||||
|
return sound, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Data/Sounds.dat + Sounds/wh40k.ds seem to operate together to allow
|
||||||
|
// attributes and a .wav file to be attached to event names, which could be
|
||||||
|
// what we use here instead. For now, we're just using the .wav files!
|
||||||
|
log.Printf("Loading sound %v", name)
|
||||||
|
|
||||||
|
// FIXME: a preprocessing script is used to create these files from the
|
||||||
|
// original ADPCM .wav files. Instead, use the original .wav files.
|
||||||
|
filename, err := a.lookup(name, "wav.ogg", "Wav")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sound := &Sound{
|
||||||
|
Name: name,
|
||||||
|
filename: filename,
|
||||||
|
}
|
||||||
|
|
||||||
|
a.sounds[name] = sound
|
||||||
|
return sound, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sound) Player() (*audio.Player, error) {
|
||||||
|
decoder, err := s.decoder()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return audio.NewPlayer(audio.CurrentContext(), decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sound) InfinitePlayer() (*audio.Player, error) {
|
||||||
|
decoder, err := s.decoder()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
infinite := audio.NewInfiniteLoop(decoder, decoder.Size())
|
||||||
|
|
||||||
|
return audio.NewPlayer(audio.CurrentContext(), infinite)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sound) decoder() (*vorbis.Stream, error) {
|
||||||
|
f, err := os.Open(s.filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder, err := vorbis.Decode(audio.CurrentContext(), f)
|
||||||
|
if err != nil {
|
||||||
|
_ = f.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return decoder, nil
|
||||||
|
}
|
6
scripts/convert-wav
Executable file
6
scripts/convert-wav
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
for file in $(ls $1/*.wav); do
|
||||||
|
ffmpeg -i $file -codec:a libvorbis $file.ogg
|
||||||
|
done
|
||||||
|
|
Reference in New Issue
Block a user