mirror of
https://github.com/onyx-and-iris/voicemeeter.git
synced 2024-11-25 14:20:50 +00:00
initial commit
interface code + a few tests
This commit is contained in:
parent
2dacfab629
commit
9d16f4c534
16
README.md
16
README.md
@ -1,2 +1,14 @@
|
||||
# voicemeeter-api-go
|
||||
A Go wrapper for the Voiceemeter API
|
||||
# A Go Wrapper for Voicemeeter API
|
||||
|
||||
A WIP...
|
||||
|
||||
## Tested against
|
||||
|
||||
- Basic 1.0.8.2
|
||||
- Banana 2.0.6.2
|
||||
- Potato 3.0.2.2
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Voicemeeter](https://voicemeeter.com/)
|
||||
- Go 1.18 or greater
|
||||
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/onyx-and-iris/voicemeeter-api-go
|
||||
|
||||
go 1.18
|
||||
|
||||
require golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664
|
2
go.sum
Normal file
2
go.sum
Normal file
@ -0,0 +1,2 @@
|
||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664 h1:wEZYwx+kK+KlZ0hpvP2Ls1Xr4+RWnlzGFwPP0aiDjIU=
|
||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
51
tests/higher_test.go
Normal file
51
tests/higher_test.go
Normal file
@ -0,0 +1,51 @@
|
||||
package voicemeeter_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/onyx-and-iris/voicemeeter-api-go/voicemeeter"
|
||||
)
|
||||
|
||||
var (
|
||||
vmRem = voicemeeter.NewRemote("banana")
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
vmRem.Login()
|
||||
code := m.Run()
|
||||
vmRem.Logout()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func TestStrip0Mute(t *testing.T) {
|
||||
//t.Skip("skipping test")
|
||||
vmRem.Strip[0].SetMute(true)
|
||||
if vmRem.Strip[0].GetMute() != true {
|
||||
t.Error("TestStrip0Mute did not match true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrip2Limit(t *testing.T) {
|
||||
//t.Skip("skipping test")
|
||||
vmRem.Strip[2].SetLimit(-8)
|
||||
if vmRem.Strip[2].GetLimit() != -8 {
|
||||
t.Error("TestStrip3Limit did not match -8")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrip4Label(t *testing.T) {
|
||||
//t.Skip("skipping test")
|
||||
vmRem.Strip[4].SetLabel("test0")
|
||||
if vmRem.Strip[4].GetLabel() != "test0" {
|
||||
t.Error("TestStrip4Label did not match test0")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrip5Gain(t *testing.T) {
|
||||
//t.Skip("skipping test")
|
||||
vmRem.Strip[4].SetGain(-20.8)
|
||||
if vmRem.Strip[4].GetGain() != -20.8 {
|
||||
t.Error("TestStrip5Gain did not match -20.8")
|
||||
}
|
||||
}
|
264
voicemeeter/base.go
Normal file
264
voicemeeter/base.go
Normal file
@ -0,0 +1,264 @@
|
||||
package voicemeeter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
mod = syscall.NewLazyDLL(getDllPath())
|
||||
|
||||
vmLogin = mod.NewProc("VBVMR_Login")
|
||||
vmLogout = mod.NewProc("VBVMR_Logout")
|
||||
vmRunvm = mod.NewProc("VBVMR_RunVoicemeeter")
|
||||
vmGetvmType = mod.NewProc("VBVMR_GetVoicemeeterType")
|
||||
vmGetvmVersion = mod.NewProc("VBVMR_GetVoicemeeterVersion")
|
||||
vmPdirty = mod.NewProc("VBVMR_IsParametersDirty")
|
||||
getParamFloat = mod.NewProc("VBVMR_GetParameterFloat")
|
||||
getParamString = mod.NewProc("VBVMR_GetParameterStringA")
|
||||
|
||||
//getLevelFloat = mod.NewProc("VBVMR_GetLevel")
|
||||
|
||||
setParamFloat = mod.NewProc("VBVMR_SetParameterFloat")
|
||||
setParameters = mod.NewProc("VBVMR_SetParameters")
|
||||
setParamString = mod.NewProc("VBVMR_SetParameterStringA")
|
||||
|
||||
//getDevNumOut = mod.NewProc("VBVMR_Output_GetDeviceNumber")
|
||||
//getDevDescOut = mod.NewProc("VBVMR_Output_GetDeviceDescA")
|
||||
//getDevNumIn = mod.NewProc("VBVMR_Input_GetDeviceNumber")
|
||||
//getDevDescIn = mod.NewProc("VBVMR_Input_GetDeviceDescA")
|
||||
|
||||
vmMdirty = mod.NewProc("VBVMR_MacroButton_IsDirty")
|
||||
getMacroButtonStatus = mod.NewProc("VBVMR_MacroButton_GetStatus")
|
||||
setMacroButtonStatus = mod.NewProc("VBVMR_MacroButton_SetStatus")
|
||||
)
|
||||
|
||||
// login logs into the API,
|
||||
// then attempts to launch Voicemeeter if it's not running.
|
||||
func login(kind_id string) {
|
||||
res, _, _ := vmLogin.Call()
|
||||
if res == 1 {
|
||||
runVoicemeeter(kind_id)
|
||||
time.Sleep(time.Second)
|
||||
} else if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_Login returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("Logged into API")
|
||||
sync()
|
||||
}
|
||||
|
||||
// logout logs out of the API,
|
||||
// delayed for 100ms to allow final operation to complete.
|
||||
func logout() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
res, _, _ := vmLogout.Call()
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_Logout returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("Logged out of API")
|
||||
}
|
||||
|
||||
// runVoicemeeter attempts to launch a Voicemeeter GUI of a kind.
|
||||
func runVoicemeeter(kind_id string) {
|
||||
vals := map[string]uint64{
|
||||
"basic": 1,
|
||||
"banana": 2,
|
||||
"potato": 3,
|
||||
}
|
||||
res, _, _ := vmRunvm.Call(uintptr(vals[kind_id]))
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_RunVoicemeeter returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// getVersion returns the version of Voicemeeter as a string
|
||||
func getVersion() string {
|
||||
var ver uint64
|
||||
res, _, _ := vmGetvmVersion.Call(uintptr(unsafe.Pointer(&ver)))
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_GetVoicemeeterVersion returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
v1 := (ver & 0xFF000000) >> 24
|
||||
v2 := (ver & 0x00FF0000) >> 16
|
||||
v3 := (ver & 0x0000FF00) >> 8
|
||||
v4 := ver & 0x000000FF
|
||||
return fmt.Sprintf("%d.%d.%d.%d", v1, v2, v3, v4)
|
||||
}
|
||||
|
||||
// pdirty returns true iff a parameter value has changed
|
||||
func pdirty() bool {
|
||||
res, _, _ := vmPdirty.Call()
|
||||
return int(res) == 1
|
||||
}
|
||||
|
||||
// mdirty returns true iff a macrobutton value has changed
|
||||
func mdirty() bool {
|
||||
res, _, _ := vmMdirty.Call()
|
||||
return int(res) == 1
|
||||
}
|
||||
|
||||
func sync() {
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
for pdirty() || mdirty() {
|
||||
}
|
||||
}
|
||||
|
||||
// getVMType returns the type of Voicemeeter, as a string
|
||||
func getVMType() string {
|
||||
var type_ uint64
|
||||
res, _, _ := vmGetvmType.Call(
|
||||
uintptr(unsafe.Pointer(&type_)),
|
||||
)
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_GetVoicemeeterType returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
vals := map[uint64]string{
|
||||
1: "basic",
|
||||
2: "banana",
|
||||
3: "potato",
|
||||
}
|
||||
return vals[type_]
|
||||
}
|
||||
|
||||
// getParameterFloat gets the value of a float parameter
|
||||
func getParameterFloat(name string) float64 {
|
||||
var value float32
|
||||
b := append([]byte(name), 0)
|
||||
res, _, _ := getParamFloat.Call(
|
||||
uintptr(unsafe.Pointer(&b[0])),
|
||||
uintptr(unsafe.Pointer(&value)),
|
||||
)
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_GetParameterFloat returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return math.Round(float64(value)*10) / 10
|
||||
}
|
||||
|
||||
// getParameterFloat sets the value of a float parameter
|
||||
func setParameterFloat(name string, value float32) {
|
||||
b1 := append([]byte(name), 0)
|
||||
b2 := math.Float32bits(value)
|
||||
res, _, _ := setParamFloat.Call(
|
||||
uintptr(unsafe.Pointer(&b1[0])),
|
||||
uintptr(b2),
|
||||
)
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_SetParameterFloat returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
sync()
|
||||
}
|
||||
|
||||
// getParameterString gets the value of a string parameter
|
||||
func getParameterString(name string) string {
|
||||
b1 := append([]byte(name), 0)
|
||||
var b2 [512]byte
|
||||
res, _, _ := getParamString.Call(
|
||||
uintptr(unsafe.Pointer(&b1[0])),
|
||||
uintptr(unsafe.Pointer(&b2[0])),
|
||||
)
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_GetParameterStringA returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
str := bytes.Trim(b2[:], "\x00")
|
||||
return string(str)
|
||||
}
|
||||
|
||||
// getParameterString sets the value of a string parameter
|
||||
func setParameterString(name, value string) {
|
||||
b1 := append([]byte(name), 0)
|
||||
b2 := append([]byte(value), 0)
|
||||
res, _, _ := setParamString.Call(
|
||||
uintptr(unsafe.Pointer(&b1[0])),
|
||||
uintptr(unsafe.Pointer(&b2[0])),
|
||||
)
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_SetParameterStringA returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
sync()
|
||||
}
|
||||
|
||||
// setParametersMulti sets multiple parameters with a script
|
||||
func setParametersMulti(script string) {
|
||||
b1 := append([]byte(script), 0)
|
||||
res, _, _ := setParameters.Call(
|
||||
uintptr(unsafe.Pointer(&b1[0])),
|
||||
)
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_SetParameters returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// getMacroStatus gets a macrobutton value
|
||||
func getMacroStatus(id, mode int) float32 {
|
||||
var state float32
|
||||
res, _, _ := getMacroButtonStatus.Call(
|
||||
uintptr(id),
|
||||
uintptr(unsafe.Pointer(&state)),
|
||||
uintptr(mode),
|
||||
)
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_MacroButton_GetStatus returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
// setMacroStatus sets a macrobutton value
|
||||
func setMacroStatus(id, state, mode int) {
|
||||
res, _, _ := setMacroButtonStatus.Call(
|
||||
uintptr(id),
|
||||
uintptr(state),
|
||||
uintptr(mode),
|
||||
)
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_MacroButton_SetStatus returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
sync()
|
||||
}
|
||||
|
||||
/*
|
||||
// getLevel returns a single level value of type type_ for channel[i]
|
||||
func getLevel(type_, i int) float32 {
|
||||
var val float32
|
||||
res, _, _ := getLevelFloat.Call(
|
||||
uintptr(type_),
|
||||
uintptr(i),
|
||||
uintptr(unsafe.Pointer(&val)),
|
||||
)
|
||||
if res != 0 {
|
||||
err := fmt.Errorf("VBVMR_GetLevel returned %d", res)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return val
|
||||
}
|
||||
*/
|
44
voicemeeter/bus.go
Normal file
44
voicemeeter/bus.go
Normal file
@ -0,0 +1,44 @@
|
||||
package voicemeeter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// custom bus type, struct forwarding channel
|
||||
type bus struct {
|
||||
channel
|
||||
}
|
||||
|
||||
// newBus returns a strip type
|
||||
// it also initializes embedded channel type
|
||||
func newBus(i int, k *kind) bus {
|
||||
return bus{channel{"bus", i, *k}}
|
||||
}
|
||||
|
||||
// String implements the stringer interface
|
||||
func (b *bus) String() string {
|
||||
if b.index < b.kind.physOut {
|
||||
return fmt.Sprintf("PhysicalBus%d\n", b.index)
|
||||
}
|
||||
return fmt.Sprintf("VirtualBus%d\n", b.index)
|
||||
}
|
||||
|
||||
// GetMute returns the value of the Mute parameter
|
||||
func (b *bus) GetMute() bool {
|
||||
return b.getter_bool("Mute")
|
||||
}
|
||||
|
||||
// SetMute sets the value of the Mute parameter
|
||||
func (b *bus) SetMute(val bool) {
|
||||
b.setter_bool("Mute", val)
|
||||
}
|
||||
|
||||
// GetEq returns the value of the Eq.On parameter
|
||||
func (b *bus) GetEq() bool {
|
||||
return b.getter_bool("Eq.On")
|
||||
}
|
||||
|
||||
// SetEq sets the value of the Eq.On parameter
|
||||
func (b *bus) SetEq(val bool) {
|
||||
b.setter_bool("Eq.On", val)
|
||||
}
|
64
voicemeeter/button.go
Normal file
64
voicemeeter/button.go
Normal file
@ -0,0 +1,64 @@
|
||||
package voicemeeter
|
||||
|
||||
import "fmt"
|
||||
|
||||
// custom strip type, struct forwarding channel
|
||||
type button struct {
|
||||
index int
|
||||
}
|
||||
|
||||
// getter returns the value of a macrobutton parameter
|
||||
func (m *button) getter(mode int) bool {
|
||||
return getMacroStatus(m.index, mode) == 1
|
||||
}
|
||||
|
||||
// setter sets the value of a macrobutton parameter
|
||||
func (m *button) setter(v bool, mode int) {
|
||||
var value int
|
||||
if v {
|
||||
value = 1
|
||||
} else {
|
||||
value = 0
|
||||
}
|
||||
setMacroStatus(m.index, value, mode)
|
||||
}
|
||||
|
||||
// newButton returns a button type
|
||||
func newButton(i int) button {
|
||||
return button{i}
|
||||
}
|
||||
|
||||
// String implements the stringer interface
|
||||
func (m *button) String() string {
|
||||
return fmt.Sprintf("MacroButton%d\n", m.index)
|
||||
}
|
||||
|
||||
// GetState returns the value of the State parameter
|
||||
func (m *button) GetState() bool {
|
||||
return m.getter(1)
|
||||
}
|
||||
|
||||
// SetState sets the value of the State parameter
|
||||
func (m *button) SetState(val bool) {
|
||||
m.setter(val, 1)
|
||||
}
|
||||
|
||||
// GetStateOnly returns the value of the StateOnly parameter
|
||||
func (m *button) GetStateOnly() bool {
|
||||
return m.getter(2)
|
||||
}
|
||||
|
||||
// SetStateOnly sets the value of the StateOnly parameter
|
||||
func (m *button) SetStateOnly(val bool) {
|
||||
m.setter(val, 2)
|
||||
}
|
||||
|
||||
// GetTrigger returns the value of the Trigger parameter
|
||||
func (m *button) GetTrigger() bool {
|
||||
return m.getter(2)
|
||||
}
|
||||
|
||||
// SetTrigger returns the value of the Trigger parameter
|
||||
func (m *button) SetTrigger(val bool) {
|
||||
m.setter(val, 2)
|
||||
}
|
56
voicemeeter/cdll.go
Normal file
56
voicemeeter/cdll.go
Normal file
@ -0,0 +1,56 @@
|
||||
package voicemeeter
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
// dllPath returns the Voicemeeter installation path as a string
|
||||
func dllPath() (string, error) {
|
||||
if runtime.GOOS != "windows" {
|
||||
return "", errors.New("only Windows OS supported")
|
||||
}
|
||||
|
||||
var regkey string
|
||||
if strings.Contains(runtime.GOARCH, "64") {
|
||||
regkey = `SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall`
|
||||
} else {
|
||||
regkey = `SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall`
|
||||
}
|
||||
var vmkey = `\VB:Voicemeeter {17359A74-1236-5467}`
|
||||
|
||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, regkey+vmkey, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
return "", errors.New("unable to access registry")
|
||||
}
|
||||
defer k.Close()
|
||||
|
||||
path, _, err := k.GetStringValue(`UninstallString`)
|
||||
if err != nil {
|
||||
return "", errors.New("unable to read Voicemeeter path from registry")
|
||||
}
|
||||
|
||||
var dllName string
|
||||
if strings.Contains(runtime.GOARCH, "64") {
|
||||
dllName = `VoicemeeterRemote64.dll`
|
||||
} else {
|
||||
dllName = `VoicemeeterRemote.dll`
|
||||
}
|
||||
return fmt.Sprintf("%v\\%s", filepath.Dir(path), dllName), nil
|
||||
}
|
||||
|
||||
// getDllPath is a helper function for error handling
|
||||
func getDllPath() string {
|
||||
path, err := dllPath()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return path
|
||||
}
|
65
voicemeeter/channel.go
Normal file
65
voicemeeter/channel.go
Normal file
@ -0,0 +1,65 @@
|
||||
package voicemeeter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type channel struct {
|
||||
identifier string
|
||||
index int
|
||||
kind kind
|
||||
}
|
||||
|
||||
// getter_bool returns the value of a boolean parameter
|
||||
func (c *channel) getter_bool(p string) bool {
|
||||
param := fmt.Sprintf("%s[%d].%s", c.identifier, c.index, p)
|
||||
return getParameterFloat(param) == 1
|
||||
}
|
||||
|
||||
// setter_bool sets the value of a boolean parameter
|
||||
func (c *channel) setter_bool(p string, v bool) {
|
||||
param := fmt.Sprintf("%s[%d].%s", c.identifier, c.index, p)
|
||||
var value float32
|
||||
if v {
|
||||
value = 1
|
||||
} else {
|
||||
value = 0
|
||||
}
|
||||
setParameterFloat(param, float32(value))
|
||||
}
|
||||
|
||||
// getter_int returns the value of an int parameter p
|
||||
func (c *channel) getter_int(p string) int {
|
||||
param := fmt.Sprintf("%s[%d].%s", c.identifier, c.index, p)
|
||||
return int(getParameterFloat(param))
|
||||
}
|
||||
|
||||
// setter_int sets the value v of an int parameter p
|
||||
func (c *channel) setter_int(p string, v int) {
|
||||
param := fmt.Sprintf("%s[%d].%s", c.identifier, c.index, p)
|
||||
setParameterFloat(param, float32(v))
|
||||
}
|
||||
|
||||
// getter_float returns the value of an int parameter p
|
||||
func (c *channel) getter_float(p string) float64 {
|
||||
param := fmt.Sprintf("%s[%d].%s", c.identifier, c.index, p)
|
||||
return getParameterFloat(param)
|
||||
}
|
||||
|
||||
// setter_float sets the value v of an int parameter p
|
||||
func (c *channel) setter_float(p string, v float32) {
|
||||
param := fmt.Sprintf("%s[%d].%s", c.identifier, c.index, p)
|
||||
setParameterFloat(param, float32(v))
|
||||
}
|
||||
|
||||
// getter_string returns the value of a string parameter p
|
||||
func (c *channel) getter_string(p string) string {
|
||||
param := fmt.Sprintf("%s[%d].%s", c.identifier, c.index, p)
|
||||
return getParameterString(param)
|
||||
}
|
||||
|
||||
// setter_string sets the value v of a string parameter p
|
||||
func (c *channel) setter_string(p, v string) {
|
||||
param := fmt.Sprintf("%s[%d].%s", c.identifier, c.index, p)
|
||||
setParameterString(param, v)
|
||||
}
|
44
voicemeeter/kinds.go
Normal file
44
voicemeeter/kinds.go
Normal file
@ -0,0 +1,44 @@
|
||||
package voicemeeter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A kind represents a Voicemeeter kinds layout
|
||||
type kind struct {
|
||||
name string
|
||||
physIn int
|
||||
virtIn int
|
||||
physOut int
|
||||
virtOut int
|
||||
}
|
||||
|
||||
func (k *kind) numStrip() int {
|
||||
n := k.physIn + k.virtIn
|
||||
return n
|
||||
}
|
||||
|
||||
func (k *kind) numBus() int {
|
||||
n := k.physOut + k.virtOut
|
||||
return n
|
||||
}
|
||||
|
||||
func (k *kind) String() string {
|
||||
return fmt.Sprintf("%s%s", strings.ToUpper(k.name[:1]), k.name[1:])
|
||||
}
|
||||
|
||||
// newBasicKind returns a basic kind struct address
|
||||
func newBasicKind() *kind {
|
||||
return &kind{"basic", 2, 1, 1, 1}
|
||||
}
|
||||
|
||||
// newBananaKind returns a banana kind struct address
|
||||
func newBananaKind() *kind {
|
||||
return &kind{"banana", 3, 2, 3, 2}
|
||||
}
|
||||
|
||||
// newPotatoKind returns a potato kind struct address
|
||||
func newPotatoKind() *kind {
|
||||
return &kind{"potato", 5, 3, 5, 3}
|
||||
}
|
77
voicemeeter/remote.go
Normal file
77
voicemeeter/remote.go
Normal file
@ -0,0 +1,77 @@
|
||||
package voicemeeter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// A remote type represents the API for a kind,
|
||||
// comprised of slices representing each member
|
||||
type remote struct {
|
||||
kind *kind
|
||||
Strip []strip
|
||||
Bus []bus
|
||||
Button []button
|
||||
}
|
||||
|
||||
// String implements the stringer interface
|
||||
func (r *remote) String() string {
|
||||
return fmt.Sprintf("Voicemeeter %s", r.kind)
|
||||
}
|
||||
|
||||
func (r *remote) Login() {
|
||||
login(r.kind.name)
|
||||
}
|
||||
|
||||
func (r *remote) Logout() {
|
||||
logout()
|
||||
}
|
||||
|
||||
func (r *remote) Type() string {
|
||||
return getVMType()
|
||||
}
|
||||
|
||||
func (r *remote) Version() string {
|
||||
return getVersion()
|
||||
}
|
||||
|
||||
func (r *remote) SendText(script string) {
|
||||
setParametersMulti(script)
|
||||
}
|
||||
|
||||
// NewRemote returns a remote type of a kind,
|
||||
// this exported method is the interface entry point.
|
||||
func NewRemote(kind_id string) remote {
|
||||
kindMap := map[string]*kind{
|
||||
"basic": newBasicKind(),
|
||||
"banana": newBananaKind(),
|
||||
"potato": newPotatoKind(),
|
||||
}
|
||||
|
||||
_kind, ok := kindMap[kind_id]
|
||||
if !ok {
|
||||
err := fmt.Errorf("unknown Voicemeeter kind '%s'", kind_id)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
_strip := make([]strip, _kind.numStrip())
|
||||
for i := 0; i < _kind.physIn+_kind.virtIn; i++ {
|
||||
_strip[i] = newStrip(i, _kind)
|
||||
}
|
||||
_bus := make([]bus, _kind.numBus())
|
||||
for i := 0; i < _kind.physOut+_kind.virtOut; i++ {
|
||||
_bus[i] = newBus(i, _kind)
|
||||
}
|
||||
_button := make([]button, 80)
|
||||
for i := 0; i < 80; i++ {
|
||||
_button[i] = newButton(i)
|
||||
}
|
||||
|
||||
return remote{
|
||||
kind: _kind,
|
||||
Strip: _strip,
|
||||
Bus: _bus,
|
||||
Button: _button,
|
||||
}
|
||||
}
|
73
voicemeeter/strip.go
Normal file
73
voicemeeter/strip.go
Normal file
@ -0,0 +1,73 @@
|
||||
package voicemeeter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// custom strip type, struct forwarding channel
|
||||
type strip struct {
|
||||
channel
|
||||
}
|
||||
|
||||
// constructor method for strip
|
||||
func newStrip(i int, k *kind) strip {
|
||||
return strip{channel{"strip", i, *k}}
|
||||
}
|
||||
|
||||
// implement stringer interface in fmt
|
||||
func (s *strip) String() string {
|
||||
if s.index < s.kind.physIn {
|
||||
return fmt.Sprintf("PhysicalStrip%d\n", s.index)
|
||||
}
|
||||
return fmt.Sprintf("VirtualStrip%d\n", s.index)
|
||||
}
|
||||
|
||||
// GetMute returns the value of the Mute parameter
|
||||
func (s *strip) GetMute() bool {
|
||||
return s.getter_bool("Mute")
|
||||
}
|
||||
|
||||
// SetMute sets the value of the Mute parameter
|
||||
func (s *strip) SetMute(val bool) {
|
||||
s.setter_bool("Mute", val)
|
||||
}
|
||||
|
||||
// GetLimit returns the value of the Limit parameter
|
||||
func (s *strip) GetLimit() int {
|
||||
return s.getter_int("Limit")
|
||||
}
|
||||
|
||||
// SetLimit sets the value of the Limit parameter
|
||||
func (s *strip) SetLimit(val int) {
|
||||
s.setter_int("Limit", val)
|
||||
}
|
||||
|
||||
// GetMc returns the value of the MC parameter
|
||||
func (s *strip) GetMc() bool {
|
||||
return s.getter_bool("MC")
|
||||
}
|
||||
|
||||
// SetMc sets the value of the MC parameter
|
||||
func (s *strip) SetMc(val bool) {
|
||||
s.setter_bool("MC", val)
|
||||
}
|
||||
|
||||
// GetMc returns the value of the MC parameter
|
||||
func (s *strip) GetLabel() string {
|
||||
return s.getter_string("Label")
|
||||
}
|
||||
|
||||
// SetMc sets the value of the MC parameter
|
||||
func (s *strip) SetLabel(val string) {
|
||||
s.setter_string("Label", val)
|
||||
}
|
||||
|
||||
// GetGain returns the value of the Gain parameter
|
||||
func (s *strip) GetGain() float64 {
|
||||
return s.getter_float("Gain")
|
||||
}
|
||||
|
||||
// SetGain sets the value of the Gain parameter
|
||||
func (s *strip) SetGain(val float32) {
|
||||
s.setter_float("Gain", val)
|
||||
}
|
Loading…
Reference in New Issue
Block a user