diff --git a/voicemeeter/base.go b/voicemeeter/base.go index a15d260..1e2a7ea 100644 --- a/voicemeeter/base.go +++ b/voicemeeter/base.go @@ -23,7 +23,7 @@ var ( vmGetParamFloat = mod.NewProc("VBVMR_GetParameterFloat") vmGetParamString = mod.NewProc("VBVMR_GetParameterStringA") - //vmGetLevelFloat = mod.NewProc("VBVMR_GetLevel") + vmGetLevelFloat = mod.NewProc("VBVMR_GetLevel") vmSetParamFloat = mod.NewProc("VBVMR_SetParameterFloat") vmSetParameters = mod.NewProc("VBVMR_SetParameters") @@ -290,11 +290,10 @@ func get_device_description(i int, dir string) (string, uint64, string) { return string(name), t_, string(hwid) } -/* // getLevel returns a single level value of type type_ for channel[i] func getLevel(type_, i int) float32 { var val float32 - res, _, _ := getLevelFloat.Call( + res, _, _ := vmGetLevelFloat.Call( uintptr(type_), uintptr(i), uintptr(unsafe.Pointer(&val)), @@ -306,4 +305,3 @@ func getLevel(type_, i int) float32 { } return val } -*/ diff --git a/voicemeeter/bus.go b/voicemeeter/bus.go index 7313c25..db6b10b 100644 --- a/voicemeeter/bus.go +++ b/voicemeeter/bus.go @@ -17,12 +17,14 @@ type t_bus interface { GetGain() float64 SetGain(val float32) Mode() t_busMode + Levels() *levels } // bus represents a bus channel type bus struct { iRemote mode busMode + levels } // GetMute returns the value of the Mute parameter @@ -80,15 +82,20 @@ func (b *bus) Mode() t_busMode { return &b.mode } +// Levels returns the gainlayer field +func (b *bus) Levels() *levels { + return &b.levels +} + type physicalBus struct { bus } -func newPhysicalBus(i int) t_bus { - pb := physicalBus{bus{ - iRemote{fmt.Sprintf("bus[%d]", i), i}, - newBusMode(i), - }} +func newPhysicalBus(i int, k *kind) t_bus { + b := newBusMode(i) + l := newBusLevels(i, k) + pb := physicalBus{bus{iRemote{fmt.Sprintf("bus[%d]", i), i}, b, l}} + return t_bus(&pb) } @@ -101,11 +108,10 @@ type virtualBus struct { bus } -func newVirtualBus(i int) t_bus { - vb := virtualBus{bus{ - iRemote{fmt.Sprintf("bus[%d]", i), i}, - newBusMode(i), - }} +func newVirtualBus(i int, k *kind) t_bus { + b := newBusMode(i) + l := newBusLevels(i, k) + vb := virtualBus{bus{iRemote{fmt.Sprintf("bus[%d]", i), i}, b, l}} return t_bus(&vb) } @@ -244,3 +250,17 @@ func (bm *busMode) SetRearOnly(val bool) { func (bm *busMode) GetRearOnly() bool { return bm.getter_bool("RearOnly") } + +func newBusLevels(i int, k *kind) levels { + var init int + init = i * 8 + return levels{iRemote{fmt.Sprintf("bus[%d]", i), i}, k, init, 8} +} + +func (l *levels) All() []float32 { + var levels []float32 + for i := l.init; i < l.init+l.offset; i++ { + levels = append(levels, l.convertLevel(getLevel(3, i))) + } + return levels +} diff --git a/voicemeeter/bus_test.go b/voicemeeter/bus_test.go index cf34d07..6d44688 100644 --- a/voicemeeter/bus_test.go +++ b/voicemeeter/bus_test.go @@ -8,7 +8,7 @@ import ( func TestGetPhysBus(t *testing.T) { //t.Skip("skipping test") - __bus := newPhysicalBus(0) + __bus := newPhysicalBus(0, newPotatoKind()) t.Run("Should return a physical bus type", func(t *testing.T) { assert.NotNil(t, __bus) }) @@ -19,7 +19,7 @@ func TestGetPhysBus(t *testing.T) { func TestGetVirtBus(t *testing.T) { //t.Skip("skipping test") - __bus := newVirtualBus(4) + __bus := newVirtualBus(4, newPotatoKind()) t.Run("Should return a basic kind", func(t *testing.T) { assert.NotNil(t, __bus) }) diff --git a/voicemeeter/iremote.go b/voicemeeter/iremote.go index ff69873..96e4aec 100644 --- a/voicemeeter/iremote.go +++ b/voicemeeter/iremote.go @@ -2,6 +2,7 @@ package voicemeeter import ( "fmt" + "math" ) // iRemote provides a set of common forwarding methods @@ -67,3 +68,18 @@ func (ir *iRemote) setter_string(p, v string) { param := fmt.Sprintf("%s.%s", ir.identifier(), p) 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 +} diff --git a/voicemeeter/remote.go b/voicemeeter/remote.go index ea8bc05..58881e1 100644 --- a/voicemeeter/remote.go +++ b/voicemeeter/remote.go @@ -111,9 +111,9 @@ func (b *genericBuilder) makeStrip() remoteBuilder { _strip := make([]t_strip, b.k.numStrip()) for i := 0; i < b.k.numStrip(); i++ { if i < b.k.physIn { - _strip[i] = newPhysicalStrip(i) + _strip[i] = newPhysicalStrip(i, b.k) } else { - _strip[i] = newVirtualStrip(i) + _strip[i] = newVirtualStrip(i, b.k) } } b.r.Strip = _strip @@ -127,9 +127,9 @@ func (b *genericBuilder) makeBus() remoteBuilder { _bus := make([]t_bus, b.k.numBus()) for i := 0; i < b.k.numBus(); i++ { if i < b.k.physOut { - _bus[i] = newPhysicalBus(i) + _bus[i] = newPhysicalBus(i, b.k) } else { - _bus[i] = newVirtualBus(i) + _bus[i] = newVirtualBus(i, b.k) } } b.r.Bus = _bus diff --git a/voicemeeter/strip.go b/voicemeeter/strip.go index 0eda6d7..d03af2f 100644 --- a/voicemeeter/strip.go +++ b/voicemeeter/strip.go @@ -27,6 +27,7 @@ type t_strip interface { GetAudibility() bool SetAudibility(val bool) GainLayer() []gainLayer + Levels() *levels t_outputs } @@ -35,6 +36,7 @@ type strip struct { iRemote outputs gainLayer []gainLayer + levels } // GetMute returns the value of the Mute parameter @@ -97,22 +99,28 @@ func (s *strip) SetGain(val float32) { s.setter_float("Gain", val) } -// Mode returns address of a busMode struct +// GainLayer returns the gainlayer field func (s *strip) GainLayer() []gainLayer { return s.gainLayer } +// Levels returns the gainlayer field +func (s *strip) Levels() *levels { + return &s.levels +} + type physicalStrip struct { strip } -func newPhysicalStrip(i int) t_strip { +func newPhysicalStrip(i int, k *kind) t_strip { o := newOutputs("strip", i) gl := make([]gainLayer, 8) for j := 0; j < 8; j++ { gl[j] = newGainLayer(i, j) } - ps := physicalStrip{strip{iRemote{fmt.Sprintf("strip[%d]", i), i}, o, gl}} + l := newStripLevels(i, k) + ps := physicalStrip{strip{iRemote{fmt.Sprintf("strip[%d]", i), i}, o, gl, l}} return t_strip(&ps) } @@ -165,13 +173,14 @@ type virtualStrip struct { strip } -func newVirtualStrip(i int) t_strip { +func newVirtualStrip(i int, k *kind) t_strip { o := newOutputs("strip", i) gl := make([]gainLayer, 8) for j := 0; j < 8; j++ { gl[j] = newGainLayer(i, j) } - vs := virtualStrip{strip{iRemote{fmt.Sprintf("strip[%d]", i), i}, o, gl}} + l := newStripLevels(i, k) + vs := virtualStrip{strip{iRemote{fmt.Sprintf("strip[%d]", i), i}, o, gl, l}} return t_strip(&vs) } @@ -236,3 +245,40 @@ func (gl *gainLayer) Get() float64 { func (gl *gainLayer) Set(val float32) { gl.setter_float(fmt.Sprintf("gainlayer[%d]", gl.index), val) } + +func newStripLevels(i int, k *kind) levels { + var init int + var os int + if i < k.physIn { + init = i * 2 + os = 2 + } else { + init = (k.physIn * 2) + ((i - k.physIn) * 8) + os = 8 + } + return levels{iRemote{fmt.Sprintf("strip[%d]", i), i}, k, init, os} +} + +func (l *levels) PreFader() []float32 { + var levels []float32 + for i := l.init; i < l.init+l.offset; i++ { + levels = append(levels, l.convertLevel(getLevel(0, i))) + } + return levels +} + +func (l *levels) PostFader() []float32 { + var levels []float32 + for i := l.init; i < l.init+l.offset; i++ { + levels = append(levels, l.convertLevel(getLevel(1, i))) + } + return levels +} + +func (l *levels) PostMute() []float32 { + var levels []float32 + for i := l.init; i < l.init+l.offset; i++ { + levels = append(levels, l.convertLevel(getLevel(2, i))) + } + return levels +} diff --git a/voicemeeter/strip_test.go b/voicemeeter/strip_test.go index a2a3b2c..5443492 100644 --- a/voicemeeter/strip_test.go +++ b/voicemeeter/strip_test.go @@ -8,7 +8,7 @@ import ( func TestGetPhysStrip(t *testing.T) { //t.Skip("skipping test") - __strip := newPhysicalStrip(0) + __strip := newPhysicalStrip(0, newPotatoKind()) t.Run("Should return a physical strip type", func(t *testing.T) { assert.NotNil(t, __strip) }) @@ -19,7 +19,7 @@ func TestGetPhysStrip(t *testing.T) { func TestGetVirtStrip(t *testing.T) { //t.Skip("skipping test") - __strip := newVirtualStrip(4) + __strip := newVirtualStrip(4, newPotatoKind()) t.Run("Should return a basic kind", func(t *testing.T) { assert.NotNil(t, __strip) })