Skip to content

Commit 0558e8f

Browse files
committed
login() is now tested for up to {Remote}.timeout seconds
if timeout exceeded return an error runVoicemeeter() now promotes types to x64bit on 64-bit OS unless overridden. Option functions WithTimeout() and WithBits() added.
1 parent 07018d1 commit 0558e8f

File tree

2 files changed

+78
-25
lines changed

2 files changed

+78
-25
lines changed

base.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package voicemeeter
22

33
import (
44
"bytes"
5+
"errors"
56
"fmt"
67
"math"
8+
"runtime"
79
"strings"
810
"syscall"
911
"time"
@@ -45,16 +47,29 @@ var (
4547
// login logs into the API,
4648
// attempts to launch Voicemeeter if it's not running,
4749
// initializes dirty parameters.
48-
func login(kindId string) error {
50+
func login(kindId string, timeout, bits int) error {
4951
res, _, _ := vmLogin.Call()
5052
if res == 1 {
51-
runVoicemeeter(kindId)
52-
time.Sleep(time.Second)
53+
runVoicemeeter(kindId, bits)
5354
} else if res != 0 {
5455
err := fmt.Errorf("VBVMR_Login returned %d", res)
5556
return err
5657
}
57-
log.Info("Logged into Voicemeeter ", kindId)
58+
59+
var ver_s string
60+
start := time.Now()
61+
var err error
62+
for time.Since(start).Seconds() < float64(timeout) {
63+
time.Sleep(time.Duration(100) * time.Millisecond)
64+
if ver_s, err = getVersion(); err == nil {
65+
log.Infof("Logged into Voicemeeter %s v%s", kindMap[kindId], ver_s)
66+
log.Debugf("Log in time: %.2f", time.Since(start).Seconds())
67+
break
68+
}
69+
}
70+
if err != nil {
71+
return errors.New("timeout logging into the API")
72+
}
5873
clear()
5974
return nil
6075
}
@@ -68,18 +83,22 @@ func logout(kindId string) error {
6883
err := fmt.Errorf("VBVMR_Logout returned %d", int32(res))
6984
return err
7085
}
71-
log.Info("Logged out of Voicemeeter ", kindId)
86+
log.Infof("Logged out of Voicemeeter %s", kindMap[kindId])
7287
return nil
7388
}
7489

7590
// runVoicemeeter attempts to launch a Voicemeeter GUI of a kind.
76-
func runVoicemeeter(kindId string) error {
91+
func runVoicemeeter(kindId string, bits int) error {
7792
vals := map[string]uint64{
7893
"basic": 1,
7994
"banana": 2,
8095
"potato": 3,
8196
}
82-
res, _, _ := vmRunvm.Call(uintptr(vals[kindId]))
97+
val := vals[kindId]
98+
if strings.Contains(runtime.GOARCH, "64") && bits == 64 {
99+
val += 3
100+
}
101+
res, _, _ := vmRunvm.Call(uintptr(val))
83102
if int32(res) != 0 {
84103
err := fmt.Errorf("VBVMR_RunVoicemeeter returned %d", int32(res))
85104
return err
@@ -93,6 +112,7 @@ func getVersion() (string, error) {
93112
res, _, _ := vmGetvmVersion.Call(uintptr(unsafe.Pointer(&ver)))
94113
if int32(res) != 0 {
95114
err := fmt.Errorf("VBVMR_GetVoicemeeterVersion returned %d", int32(res))
115+
log.Error(err.Error())
96116
return "", err
97117
}
98118
v1 := (ver & 0xFF000000) >> 24

remote.go

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ type Remote struct {
2020
Recorder *recorder
2121
Midi *midi_t
2222

23-
pooler *pooler
23+
pooler *pooler
24+
timeout int
25+
bits int
2426
}
2527

2628
// String implements the fmt.stringer interface
@@ -31,7 +33,7 @@ func (r *Remote) String() string {
3133
// Login logs into the API
3234
// then it intializes the pooler
3335
func (r *Remote) Login() error {
34-
err := login(r.Kind.Name)
36+
err := login(r.Kind.Name, r.timeout, r.bits)
3537
if err != nil {
3638
return err
3739
}
@@ -57,12 +59,10 @@ func (r *Remote) InitPooler() {
5759

5860
// Run launches the Voicemeeter GUI for a kind.
5961
func (r *Remote) Run(kindId string) error {
60-
err := runVoicemeeter(kindId)
62+
err := runVoicemeeter(kindId, r.bits)
6163
if err != nil {
6264
return err
6365
}
64-
time.Sleep(time.Second)
65-
clear()
6666
return nil
6767
}
6868

@@ -173,6 +173,7 @@ type remoteBuilder interface {
173173
makeDevice() remoteBuilder
174174
makeRecorder() remoteBuilder
175175
makeMidi() remoteBuilder
176+
setDefaults() remoteBuilder
176177
Build() remoteBuilder
177178
Get() *Remote
178179
}
@@ -212,7 +213,7 @@ func (b *genericBuilder) setKind() remoteBuilder {
212213
// makeStrip makes a strip slice and assigns it to remote.Strip
213214
// []iStrip comprises of both physical and virtual strip types
214215
func (b *genericBuilder) makeStrip() remoteBuilder {
215-
log.Info("building strip")
216+
log.Debug("building strip")
216217
strip := make([]iStrip, b.k.NumStrip())
217218
for i := 0; i < b.k.NumStrip(); i++ {
218219
if i < b.k.PhysIn {
@@ -228,7 +229,7 @@ func (b *genericBuilder) makeStrip() remoteBuilder {
228229
// makeBus makes a bus slice and assigns it to remote.Bus
229230
// []t_bus comprises of both physical and virtual bus types
230231
func (b *genericBuilder) makeBus() remoteBuilder {
231-
log.Info("building bus")
232+
log.Debug("building bus")
232233
bus := make([]iBus, b.k.NumBus())
233234
for i := 0; i < b.k.NumBus(); i++ {
234235
if i < b.k.PhysOut {
@@ -243,7 +244,7 @@ func (b *genericBuilder) makeBus() remoteBuilder {
243244

244245
// makeButton makes a button slice and assigns it to remote.Button
245246
func (b *genericBuilder) makeButton() remoteBuilder {
246-
log.Info("building button")
247+
log.Debug("building button")
247248
button := make([]button, 80)
248249
for i := 0; i < 80; i++ {
249250
button[i] = newButton(i)
@@ -254,39 +255,46 @@ func (b *genericBuilder) makeButton() remoteBuilder {
254255

255256
// makeCommand makes a command type and assigns it to remote.Command
256257
func (b *genericBuilder) makeCommand() remoteBuilder {
257-
log.Info("building command")
258+
log.Debug("building command")
258259
b.r.Command = newCommand()
259260
return b
260261
}
261262

262263
// makeVban makes a vban type and assigns it to remote.Vban
263264
func (b *genericBuilder) makeVban() remoteBuilder {
264-
log.Info("building vban")
265+
log.Debug("building vban")
265266
b.r.Vban = newVban(b.k)
266267
return b
267268
}
268269

269270
// makeDevice makes a device type and assigns it to remote.Device
270271
func (b *genericBuilder) makeDevice() remoteBuilder {
271-
log.Info("building device")
272+
log.Debug("building device")
272273
b.r.Device = newDevice()
273274
return b
274275
}
275276

276277
// makeRecorder makes a recorder type and assigns it to remote.Recorder
277278
func (b *genericBuilder) makeRecorder() remoteBuilder {
278-
log.Info("building recorder")
279+
log.Debug("building recorder")
279280
b.r.Recorder = newRecorder()
280281
return b
281282
}
282283

283284
// makeMidi makes a midi type and assigns it to remote.Midi
284285
func (b *genericBuilder) makeMidi() remoteBuilder {
285-
log.Info("building midi")
286+
log.Debug("building midi")
286287
b.r.Midi = newMidi()
287288
return b
288289
}
289290

291+
// setDefaults sets defaults for optional members
292+
func (b *genericBuilder) setDefaults() remoteBuilder {
293+
b.r.bits = 64
294+
b.r.timeout = 2
295+
return b
296+
}
297+
290298
// Get returns a fully constructed remote type for a kind
291299
func (b *genericBuilder) Get() *Remote {
292300
return &b.r
@@ -306,7 +314,8 @@ func (basb *genericBuilder) Build() remoteBuilder {
306314
makeCommand().
307315
makeVban().
308316
makeDevice().
309-
makeMidi()
317+
makeMidi().
318+
setDefaults()
310319
}
311320

312321
// bananaBuilder represents a builder specific to banana type
@@ -324,7 +333,8 @@ func (banb *bananaBuilder) Build() remoteBuilder {
324333
makeVban().
325334
makeDevice().
326335
makeRecorder().
327-
makeMidi()
336+
makeMidi().
337+
setDefaults()
328338
}
329339

330340
// potatoBuilder represents a builder specific to potato type
@@ -342,22 +352,39 @@ func (potb *potatoBuilder) Build() remoteBuilder {
342352
makeVban().
343353
makeDevice().
344354
makeRecorder().
345-
makeMidi()
355+
makeMidi().
356+
setDefaults()
346357
}
347358

348359
var (
349360
vmsync bool
350361
vmdelay int
351362
)
352363

364+
type Option func(*Remote)
365+
366+
func WithTimeout(timeout int) Option {
367+
return func(r *Remote) {
368+
r.timeout = timeout
369+
}
370+
}
371+
372+
func WithBits(bits int) Option {
373+
return func(r *Remote) {
374+
if bits == 32 || bits == 64 {
375+
r.bits = bits
376+
}
377+
}
378+
}
379+
353380
func init() {
354381
log.SetOutput(os.Stdout)
355382
log.SetLevel(log.WarnLevel)
356383
}
357384

358385
// NewRemote returns a Remote type for a kind
359386
// this is the interface entry point
360-
func NewRemote(kindId string, delay int) (*Remote, error) {
387+
func NewRemote(kindId string, delay int, opts ...Option) (*Remote, error) {
361388
kind, ok := kindMap[kindId]
362389
if !ok {
363390
err := fmt.Errorf("unknown Voicemeeter kind '%s'", kindId)
@@ -380,5 +407,11 @@ func NewRemote(kindId string, delay int) (*Remote, error) {
380407
director.SetBuilder(&potatoBuilder{genericBuilder{kind, Remote{}}})
381408
}
382409
director.Construct()
383-
return director.Get(), nil
410+
r := director.Get()
411+
412+
for _, opt := range opts {
413+
opt(r)
414+
}
415+
416+
return r, nil
384417
}

0 commit comments

Comments
 (0)