mirror of
https://github.com/onyx-and-iris/voicemeeter.git
synced 2024-11-23 05:10:54 +00:00
package module moved into root of repository.
example in readme updated. level pooler implemented, runs in its own goroutine. Remote type now exported observers example updated.
This commit is contained in:
parent
f16bed893f
commit
70d69f5599
@ -41,7 +41,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/onyx-and-iris/voicemeeter-api-go/voicemeeter"
|
"github.com/onyx-and-iris/voicemeeter-api-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -112,6 +112,21 @@ func mdirty() bool {
|
|||||||
return int(res) == 1
|
return int(res) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ldirty(k *kind) bool {
|
||||||
|
_levelCache.stripLevelsBuff = make([]float32, (2*k.physIn)+(8*k.virtIn))
|
||||||
|
_levelCache.busLevelsBuff = make([]float32, 8*k.numBus())
|
||||||
|
|
||||||
|
for i := 0; i < (2*k.physIn)+(8*k.virtIn); i++ {
|
||||||
|
_levelCache.stripLevelsBuff[i] = float32(getLevel(_levelCache.stripMode, i))
|
||||||
|
_levelCache.stripComp[i] = _levelCache.stripLevelsBuff[i] == _levelCache.stripLevels[i]
|
||||||
|
}
|
||||||
|
for i := 0; i < 8*k.numBus(); i++ {
|
||||||
|
_levelCache.busLevelsBuff[i] = float32(getLevel(3, i))
|
||||||
|
_levelCache.busComp[i] = _levelCache.busLevelsBuff[i] == _levelCache.busLevels[i]
|
||||||
|
}
|
||||||
|
return !(allTrue(_levelCache.stripComp, (2*k.physIn)+(8*k.virtIn)) && allTrue(_levelCache.busComp, 8*k.numBus()))
|
||||||
|
}
|
||||||
|
|
||||||
// getVMType returns the type of Voicemeeter, as a string
|
// getVMType returns the type of Voicemeeter, as a string
|
||||||
func getVMType() string {
|
func getVMType() string {
|
||||||
var type_ uint64
|
var type_ uint64
|
@ -253,13 +253,13 @@ func (bm *busMode) GetRearOnly() bool {
|
|||||||
|
|
||||||
func newBusLevels(i int, k *kind) levels {
|
func newBusLevels(i int, k *kind) levels {
|
||||||
init := i * 8
|
init := i * 8
|
||||||
return levels{iRemote{fmt.Sprintf("bus[%d]", i), i}, k, init, 8}
|
return levels{iRemote{fmt.Sprintf("bus[%d]", i), i}, k, init, 8, "bus"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *levels) All() []float32 {
|
func (l *levels) All() []float32 {
|
||||||
var levels []float32
|
var levels []float32
|
||||||
for i := l.init; i < l.init+l.offset; i++ {
|
for i := l.init; i < l.init+l.offset; i++ {
|
||||||
levels = append(levels, l.convertLevel(getLevel(3, i)))
|
levels = append(levels, l.convertLevel(_levelCache.busLevels[i]))
|
||||||
}
|
}
|
||||||
return levels
|
return levels
|
||||||
}
|
}
|
@ -2,37 +2,45 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onyx-and-iris/voicemeeter-api-go/voicemeeter"
|
"github.com/onyx-and-iris/voicemeeter-api-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
type observer struct {
|
type observer struct {
|
||||||
i int
|
vm *voicemeeter.Remote
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o observer) OnUpdate(subject string) {
|
func (o observer) OnUpdate(subject string) {
|
||||||
fmt.Println(o.i, subject)
|
if strings.Compare(subject, "pdirty") == 0 {
|
||||||
|
fmt.Println("pdirty!")
|
||||||
|
}
|
||||||
|
if strings.Compare(subject, "mdirty") == 0 {
|
||||||
|
fmt.Println("mdirty!")
|
||||||
|
}
|
||||||
|
if strings.Compare(subject, "ldirty") == 0 {
|
||||||
|
fmt.Printf("%v %v %v %v %v %v %v %v\n",
|
||||||
|
o.vm.Bus[0].Levels().IsDirty(),
|
||||||
|
o.vm.Bus[1].Levels().IsDirty(),
|
||||||
|
o.vm.Bus[2].Levels().IsDirty(),
|
||||||
|
o.vm.Bus[3].Levels().IsDirty(),
|
||||||
|
o.vm.Bus[4].Levels().IsDirty(),
|
||||||
|
o.vm.Bus[5].Levels().IsDirty(),
|
||||||
|
o.vm.Bus[6].Levels().IsDirty(),
|
||||||
|
o.vm.Bus[7].Levels().IsDirty(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
vmRem := voicemeeter.GetRemote("banana")
|
vmRem := voicemeeter.GetRemote("potato")
|
||||||
vmRem.Login()
|
vmRem.Login()
|
||||||
|
|
||||||
o := observer{1}
|
o := observer{vmRem}
|
||||||
o2 := observer{2}
|
|
||||||
o3 := observer{3}
|
|
||||||
o4 := observer{4}
|
|
||||||
vmRem.Register(o)
|
vmRem.Register(o)
|
||||||
vmRem.Register(o2)
|
time.Sleep(30 * time.Second)
|
||||||
vmRem.Register(o3)
|
vmRem.Deregister(o)
|
||||||
vmRem.Register(o4)
|
|
||||||
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
|
|
||||||
vmRem.Deregister(o2)
|
|
||||||
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
|
|
||||||
vmRem.Logout()
|
vmRem.Logout()
|
||||||
}
|
}
|
||||||
|
4
go.mod
4
go.mod
@ -3,8 +3,8 @@ module github.com/onyx-and-iris/voicemeeter-api-go
|
|||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/stretchr/testify v1.7.5
|
github.com/stretchr/testify v1.8.0
|
||||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664
|
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
8
go.sum
8
go.sum
@ -6,10 +6,10 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q=
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664 h1:wEZYwx+kK+KlZ0hpvP2Ls1Xr4+RWnlzGFwPP0aiDjIU=
|
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I=
|
||||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
@ -2,7 +2,6 @@ package voicemeeter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// iRemote provides a set of common forwarding methods
|
// iRemote provides a set of common forwarding methods
|
||||||
@ -68,18 +67,3 @@ func (ir *iRemote) setter_string(p, v string) {
|
|||||||
param := fmt.Sprintf("%s.%s", ir.identifier(), p)
|
param := fmt.Sprintf("%s.%s", ir.identifier(), p)
|
||||||
setParameterString(param, v)
|
setParameterString(param, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
type levels struct {
|
|
||||||
iRemote
|
|
||||||
k *kind
|
|
||||||
init int
|
|
||||||
offset int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *levels) convertLevel(i float32) float32 {
|
|
||||||
if i > 0 {
|
|
||||||
val := 20 * math.Log10(float64(i))
|
|
||||||
return float32(val)
|
|
||||||
}
|
|
||||||
return -200.0
|
|
||||||
}
|
|
45
levels.go
Normal file
45
levels.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package voicemeeter
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
// levels
|
||||||
|
type levels struct {
|
||||||
|
iRemote
|
||||||
|
k *kind
|
||||||
|
init int
|
||||||
|
offset int
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *levels) convertLevel(i float32) float32 {
|
||||||
|
if i > 0 {
|
||||||
|
val := 20 * math.Log10(float64(i))
|
||||||
|
return float32(roundFloat(float64(val), 1))
|
||||||
|
}
|
||||||
|
return -200.0
|
||||||
|
}
|
||||||
|
|
||||||
|
var _levelCache *levelCache
|
||||||
|
|
||||||
|
// levelCache defines level slices used by the pooler to track updates
|
||||||
|
type levelCache struct {
|
||||||
|
stripMode int
|
||||||
|
stripLevels []float32
|
||||||
|
busLevels []float32
|
||||||
|
stripLevelsBuff []float32
|
||||||
|
busLevelsBuff []float32
|
||||||
|
stripComp []bool
|
||||||
|
busComp []bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// newLevelCache returns a levelCache struct address
|
||||||
|
func newLevelCache(k *kind) *levelCache {
|
||||||
|
stripLevels := make([]float32, (2*k.physIn)+(8*k.virtIn))
|
||||||
|
busLevels := make([]float32, 8*k.numBus())
|
||||||
|
stripComp := make([]bool, (2*k.physIn)+(8*k.virtIn))
|
||||||
|
busComp := make([]bool, 8*k.numBus())
|
||||||
|
if _levelCache == nil {
|
||||||
|
_levelCache = &levelCache{stripMode: 0, stripLevels: stripLevels, busLevels: busLevels, stripComp: stripComp, busComp: busComp}
|
||||||
|
}
|
||||||
|
return _levelCache
|
||||||
|
}
|
@ -43,15 +43,18 @@ func (p *publisher) notify(subject string) {
|
|||||||
// pooler continuously polls the dirty paramters
|
// pooler continuously polls the dirty paramters
|
||||||
// it is expected to be run in a goroutine
|
// it is expected to be run in a goroutine
|
||||||
type pooler struct {
|
type pooler struct {
|
||||||
|
k *kind
|
||||||
run bool
|
run bool
|
||||||
publisher
|
publisher
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPooler() *pooler {
|
func newPooler(k *kind) *pooler {
|
||||||
p := &pooler{
|
p := &pooler{
|
||||||
|
k: k,
|
||||||
run: true,
|
run: true,
|
||||||
}
|
}
|
||||||
go p.runner()
|
go p.runner()
|
||||||
|
go p.levels()
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,3 +69,16 @@ func (p *pooler) runner() {
|
|||||||
time.Sleep(33 * time.Millisecond)
|
time.Sleep(33 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *pooler) levels() {
|
||||||
|
_levelCache = newLevelCache(p.k)
|
||||||
|
|
||||||
|
for p.run {
|
||||||
|
if ldirty(p.k) {
|
||||||
|
update(_levelCache.stripLevels, _levelCache.stripLevelsBuff, (2*p.k.physIn)+(8*p.k.virtIn))
|
||||||
|
update(_levelCache.busLevels, _levelCache.busLevelsBuff, 8*p.k.numBus())
|
||||||
|
p.notify("ldirty")
|
||||||
|
}
|
||||||
|
time.Sleep(33 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A remote type represents the API for a kind,
|
// A Remote type represents the API for a kind
|
||||||
// comprised of slices representing each member
|
type Remote struct {
|
||||||
type remote struct {
|
|
||||||
kind *kind
|
kind *kind
|
||||||
Strip []t_strip
|
Strip []t_strip
|
||||||
Bus []t_bus
|
Bus []t_bus
|
||||||
@ -21,53 +20,53 @@ type remote struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String implements the fmt.stringer interface
|
// String implements the fmt.stringer interface
|
||||||
func (r *remote) String() string {
|
func (r *Remote) String() string {
|
||||||
return fmt.Sprintf("Voicemeeter %s", r.kind)
|
return fmt.Sprintf("Voicemeeter %s", r.kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login logs into the API
|
// Login logs into the API
|
||||||
// then it intializes the pooler
|
// then it intializes the pooler
|
||||||
func (r *remote) Login() {
|
func (r *Remote) Login() {
|
||||||
r.pooler = newPooler()
|
|
||||||
login(r.kind.name)
|
login(r.kind.name)
|
||||||
|
r.pooler = newPooler(r.kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logout logs out of the API
|
// Logout logs out of the API
|
||||||
// it also terminates the pooler
|
// it also terminates the pooler
|
||||||
func (r *remote) Logout() {
|
func (r *Remote) Logout() {
|
||||||
r.pooler.run = false
|
r.pooler.run = false
|
||||||
logout()
|
logout()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *remote) Type() string {
|
func (r *Remote) Type() string {
|
||||||
return getVMType()
|
return getVMType()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *remote) Version() string {
|
func (r *Remote) Version() string {
|
||||||
return getVersion()
|
return getVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pdirty returns true iff a parameter value has changed
|
// Pdirty returns true iff a parameter value has changed
|
||||||
func (r *remote) Pdirty() bool {
|
func (r *Remote) Pdirty() bool {
|
||||||
return pdirty()
|
return pdirty()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mdirty returns true iff a macrobutton value has changed
|
// Mdirty returns true iff a macrobutton value has changed
|
||||||
func (r *remote) Mdirty() bool {
|
func (r *Remote) Mdirty() bool {
|
||||||
return mdirty()
|
return mdirty()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *remote) SendText(script string) {
|
func (r *Remote) SendText(script string) {
|
||||||
setParametersMulti(script)
|
setParametersMulti(script)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register forwards the register method to Pooler
|
// Register forwards the register method to Pooler
|
||||||
func (r *remote) Register(o observer) {
|
func (r *Remote) Register(o observer) {
|
||||||
r.pooler.Register(o)
|
r.pooler.Register(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register forwards the deregister method to Pooler
|
// Register forwards the deregister method to Pooler
|
||||||
func (r *remote) Deregister(o observer) {
|
func (r *Remote) Deregister(o observer) {
|
||||||
r.pooler.Deregister(o)
|
r.pooler.Deregister(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +80,7 @@ type remoteBuilder interface {
|
|||||||
makeDevice() remoteBuilder
|
makeDevice() remoteBuilder
|
||||||
makeRecorder() remoteBuilder
|
makeRecorder() remoteBuilder
|
||||||
Build() remoteBuilder
|
Build() remoteBuilder
|
||||||
Get() *remote
|
Get() *Remote
|
||||||
}
|
}
|
||||||
|
|
||||||
// directory is responsible for directing the genericBuilder
|
// directory is responsible for directing the genericBuilder
|
||||||
@ -100,13 +99,13 @@ func (d *director) Construct() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get forwards the Get method to the builder
|
// Get forwards the Get method to the builder
|
||||||
func (d *director) Get() *remote {
|
func (d *director) Get() *Remote {
|
||||||
return d.builder.Get()
|
return d.builder.Get()
|
||||||
}
|
}
|
||||||
|
|
||||||
type genericBuilder struct {
|
type genericBuilder struct {
|
||||||
k *kind
|
k *kind
|
||||||
r remote
|
r Remote
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *genericBuilder) setKind() remoteBuilder {
|
func (b *genericBuilder) setKind() remoteBuilder {
|
||||||
@ -157,28 +156,28 @@ func (b *genericBuilder) makeButton() remoteBuilder {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeCommand makes a Command type and assigns it to remote.Command
|
// makeCommand makes a command type and assigns it to remote.Command
|
||||||
func (b *genericBuilder) makeCommand() remoteBuilder {
|
func (b *genericBuilder) makeCommand() remoteBuilder {
|
||||||
fmt.Println("building command")
|
fmt.Println("building command")
|
||||||
b.r.Command = newCommand()
|
b.r.Command = newCommand()
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeVban makes a Vban type and assigns it to remote.Vban
|
// makeVban makes a vban type and assigns it to remote.Vban
|
||||||
func (b *genericBuilder) makeVban() remoteBuilder {
|
func (b *genericBuilder) makeVban() remoteBuilder {
|
||||||
fmt.Println("building vban")
|
fmt.Println("building vban")
|
||||||
b.r.Vban = newVban(b.k)
|
b.r.Vban = newVban(b.k)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeVban makes a Vban type and assigns it to remote.Vban
|
// makeDevice makes a device type and assigns it to remote.Device
|
||||||
func (b *genericBuilder) makeDevice() remoteBuilder {
|
func (b *genericBuilder) makeDevice() remoteBuilder {
|
||||||
fmt.Println("building device")
|
fmt.Println("building device")
|
||||||
b.r.Device = newDevice()
|
b.r.Device = newDevice()
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeRecorder makes a recorder type and assigns it to remote.Vban
|
// makeRecorder makes a recorder type and assigns it to remote.Recorder
|
||||||
func (b *genericBuilder) makeRecorder() remoteBuilder {
|
func (b *genericBuilder) makeRecorder() remoteBuilder {
|
||||||
fmt.Println("building recorder")
|
fmt.Println("building recorder")
|
||||||
b.r.Recorder = newRecorder()
|
b.r.Recorder = newRecorder()
|
||||||
@ -186,7 +185,7 @@ func (b *genericBuilder) makeRecorder() remoteBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a fully constructed remote type for a kind
|
// Get returns a fully constructed remote type for a kind
|
||||||
func (b *genericBuilder) Get() *remote {
|
func (b *genericBuilder) Get() *Remote {
|
||||||
return &b.r
|
return &b.r
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,9 +216,9 @@ func (potb *potatoBuilder) Build() remoteBuilder {
|
|||||||
return potb.setKind().makeStrip().makeBus().makeButton().makeCommand().makeVban().makeDevice().makeRecorder()
|
return potb.setKind().makeStrip().makeBus().makeButton().makeCommand().makeVban().makeDevice().makeRecorder()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRemote returns a remote type for a kind
|
// GetRemote returns a Remote type for a kind
|
||||||
// this is the interface entry point
|
// this is the interface entry point
|
||||||
func GetRemote(kindId string) *remote {
|
func GetRemote(kindId string) *Remote {
|
||||||
_kind, ok := kindMap[kindId]
|
_kind, ok := kindMap[kindId]
|
||||||
if !ok {
|
if !ok {
|
||||||
err := fmt.Errorf("unknown Voicemeeter kind '%s'", kindId)
|
err := fmt.Errorf("unknown Voicemeeter kind '%s'", kindId)
|
||||||
@ -230,11 +229,11 @@ func GetRemote(kindId string) *remote {
|
|||||||
director := director{}
|
director := director{}
|
||||||
switch _kind.name {
|
switch _kind.name {
|
||||||
case "basic":
|
case "basic":
|
||||||
director.SetBuilder(&basicBuilder{genericBuilder{_kind, remote{}}})
|
director.SetBuilder(&basicBuilder{genericBuilder{_kind, Remote{}}})
|
||||||
case "banana":
|
case "banana":
|
||||||
director.SetBuilder(&bananaBuilder{genericBuilder{_kind, remote{}}})
|
director.SetBuilder(&bananaBuilder{genericBuilder{_kind, Remote{}}})
|
||||||
case "potato":
|
case "potato":
|
||||||
director.SetBuilder(&potatoBuilder{genericBuilder{_kind, remote{}}})
|
director.SetBuilder(&potatoBuilder{genericBuilder{_kind, Remote{}}})
|
||||||
}
|
}
|
||||||
director.Construct()
|
director.Construct()
|
||||||
return director.Get()
|
return director.Get()
|
@ -256,29 +256,42 @@ func newStripLevels(i int, k *kind) levels {
|
|||||||
init = (k.physIn * 2) + ((i - k.physIn) * 8)
|
init = (k.physIn * 2) + ((i - k.physIn) * 8)
|
||||||
os = 8
|
os = 8
|
||||||
}
|
}
|
||||||
return levels{iRemote{fmt.Sprintf("strip[%d]", i), i}, k, init, os}
|
return levels{iRemote{fmt.Sprintf("strip[%d]", i), i}, k, init, os, "strip"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *levels) PreFader() []float32 {
|
func (l *levels) PreFader() []float32 {
|
||||||
|
_levelCache.stripMode = 0
|
||||||
var levels []float32
|
var levels []float32
|
||||||
for i := l.init; i < l.init+l.offset; i++ {
|
for i := l.init; i < l.init+l.offset; i++ {
|
||||||
levels = append(levels, l.convertLevel(getLevel(0, i)))
|
levels = append(levels, l.convertLevel(_levelCache.stripLevels[i]))
|
||||||
}
|
}
|
||||||
return levels
|
return levels
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *levels) PostFader() []float32 {
|
func (l *levels) PostFader() []float32 {
|
||||||
|
_levelCache.stripMode = 1
|
||||||
var levels []float32
|
var levels []float32
|
||||||
for i := l.init; i < l.init+l.offset; i++ {
|
for i := l.init; i < l.init+l.offset; i++ {
|
||||||
levels = append(levels, l.convertLevel(getLevel(1, i)))
|
levels = append(levels, l.convertLevel(_levelCache.stripLevels[i]))
|
||||||
}
|
}
|
||||||
return levels
|
return levels
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *levels) PostMute() []float32 {
|
func (l *levels) PostMute() []float32 {
|
||||||
|
_levelCache.stripMode = 2
|
||||||
var levels []float32
|
var levels []float32
|
||||||
for i := l.init; i < l.init+l.offset; i++ {
|
for i := l.init; i < l.init+l.offset; i++ {
|
||||||
levels = append(levels, l.convertLevel(getLevel(2, i)))
|
levels = append(levels, l.convertLevel(_levelCache.stripLevels[i]))
|
||||||
}
|
}
|
||||||
return levels
|
return levels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *levels) IsDirty() bool {
|
||||||
|
var vals []bool
|
||||||
|
if l.id == "strip" {
|
||||||
|
vals = _levelCache.stripComp[l.init : l.init+l.offset]
|
||||||
|
} else if l.id == "bus" {
|
||||||
|
vals = _levelCache.busComp[l.init : l.init+l.offset]
|
||||||
|
}
|
||||||
|
return !allTrue(vals, l.offset)
|
||||||
|
}
|
@ -5,7 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onyx-and-iris/voicemeeter-api-go/voicemeeter"
|
"github.com/onyx-and-iris/voicemeeter-api-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
24
util.go
Normal file
24
util.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package voicemeeter
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
// allTrue accepts a boolean slice and evaluates if all elements are True
|
||||||
|
func allTrue(s []bool, sz int) bool {
|
||||||
|
for i := 0; i < sz; i++ {
|
||||||
|
if !s[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(s1 []float32, s2 []float32, sz int) {
|
||||||
|
for i := 0; i < sz; i++ {
|
||||||
|
s1[i] = s2[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func roundFloat(val float64, precision uint) float64 {
|
||||||
|
ratio := math.Pow(10, float64(precision))
|
||||||
|
return math.Round(val*ratio) / ratio
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user