Package: voicemeeter-api
Python Wrapper for Voicemeeter APIThis package offers a Python interface for the Voicemeeter Remote C API.For an outline of past/future changes refer to:CHANGELOGTested againstBasic 1.0.8.8Banana 2.0.6.8Potato 3.0.2.8RequirementsVoicemeeterPython 3.10 or greaterInstallationpip install voicemeeter-apiUseSimplest use case, use a context manager to request a Remote class of a kind.Login and logout are handled for you in this scenario.__main__.pyimportvoicemeeterlibclassManyThings:def__init__(self,vm):self.vm=vmdefthings(self):self.vm.strip[0].label="podmic"self.vm.strip[0].mute=Trueprint(f"strip 0 ({self.vm.strip[0].label}) mute has been set to{self.vm.strip[0].mute}")defother_things(self):self.vm.bus[3].gain=-6.3self.vm.bus[4].eq.on=Trueinfo=(f"bus 3 gain has been set to{self.vm.bus[3].gain}",f"bus 4 eq has been set to{self.vm.bus[4].eq.on}",)print("\n".join(info))defmain():KIND_ID="banana"withvoicemeeterlib.api(KIND_ID)asvm:do=ManyThings(vm)do.things()do.other_things()# set many parameters at oncevm.apply({"strip-2":{"A1":True,"B1":True,"gain":-6.0},"bus-2":{"mute":True,"eq":{"on":True}},"button-0":{"state":True},"vban-in-0":{"on":True},"vban-out-1":{"name":"streamname"},})if__name__=="__main__":main()Otherwise you must remember to callvm.login(),vm.logout()at the start/end of your code.KIND_IDPass the kind of Voicemeeter as an argument. KIND_ID may be:basicbananapotatoAvailable commandsStripThe following properties are available.mono: booleansolo: booleanmute: booleangain: float, from -60.0 to 12.0audibility: float, from 0.0 to 10.0limit: int, from -40 to 12A1 - A5,B1 - B3: booleanlabel: stringmc: booleank: int, from 0 to 4bass: float, from -12.0 to 12.0mid: float, from -12.0 to 12.0treble: float, from -12.0 to 12.0reverb: float, from 0.0 to 10.0delay: float, from 0.0 to 10.0fx1: float, from 0.0 to 10.0fx2: float, from 0.0 to 10.0pan_x: float, from -0.5 to 0.5pan_y: float, from 0.0 to 1.0color_x: float, from -0.5 to 0.5color_y: float, from 0.0 to 1.0fx_x: float, from -0.5 to 0.5fx_y: float, from 0.0 to 1.0postreverb: booleanpostdelay: booleanpostfx1: booleanpostfx2: booleanexample:vm.strip[3].gain=3.7print(vm.strip[0].label)The following methods are available.appgain(name, value): string, float, from 0.0 to 1.0Set the gain in db by value for the app matching name.appmute(name, value): string, boolSet mute state as value for the app matching name.example:vm.strip[5].appmute("Spotify",True)vm.strip[5].appgain("Spotify",0.5)Strip.CompThe following properties are available.knob: float, from 0.0 to 10.0gainin: float, from -24.0 to 24.0ratio: float, from 1.0 to 8.0threshold: float, from -40.0 to -3.0attack: float, from 0.0 to 200.0release: float, from 0.0 to 5000.0knee: float, from 0.0 to 1.0gainout: float, from -24.0 to 24.0makeup: booleanexample:print(vm.strip[4].comp.knob)Strip Comp parameters are defined for PhysicalStrips.knobdefined for all versions, all other parameters potato only.Strip.GateThe following properties are available.knob: float, from 0.0 to 10.0threshold: float, from -60.0 to -10.0damping: float, from -60.0 to -10.0bpsidechain: int, from 100 to 4000attack: float, from 0.0 to 1000.0hold: float, from 0.0 to 5000.0release: float, from 0.0 to 5000.0example:vm.strip[2].gate.attack=300.8Strip Gate parameters are defined for PhysicalStrips.knobdefined for all versions, all other parameters potato only.Strip.DenoiserThe following properties are available.knob: float, from 0.0 to 10.0example:vm.strip[0].denoiser.knob=0.5Strip Denoiser parameters are defined for PhysicalStrips, potato version only.Strip.EQThe following properties are available.on: booleanab: booleanexample:vm.strip[0].eq.ab=TrueStrip EQ parameters are defined for PhysicalStrips, potato version only.Strip.Gainlayersgain: float, from -60.0 to 12.0example:vm.strip[3].gainlayer[3].gain=3.7Gainlayers are defined for potato version only.Strip.LevelsThe following properties are available.prefaderpostfaderpostmuteexample:print(vm.strip[3].levels.prefader)Level properties will return -200.0 if no audio detected.BusThe following properties are available.mono: booleanmute: booleansel: booleangain: float, from -60.0 to 12.0label: stringreturnreverb: float, from 0.0 to 10.0returndelay: float, from 0.0 to 10.0returnfx1: float, from 0.0 to 10.0returnfx2: float, from 0.0 to 10.0monitor: booleanexample:vm.bus[3].gain=3.7print(vm.bus[0].label)vm.bus[4].mono=TrueBus.EQThe following properties are available.on: booleanab: booleanexample:vm.bus[3].eq.on=TrueBus.ModesThe following properties are available.normal: booleanamix: booleanbmix: booleancomposite: booleantvmix: booleanupmix21: booleanupmix41: booleanupmix61: booleancenteronly: booleanlfeonly: booleanrearonly: booleanThe following methods are available.get(): Returns the current bus modeexample:vm.bus[4].mode.amix=Trueprint(vm.bus[2].mode.get())Bus.LevelsThe following properties are available.allexample:print(vm.bus[0].levels.all)levels.allwill return -200.0 if no audio detected.Strip | BusThe following methods are available.fadeto(amount, time): float, intfadeby(amount, time): float, intModify gain to or by the selected amount in db over a time interval in ms.example:vm.strip[0].fadeto(-10.3,1000)vm.bus[3].fadeby(-5.6,500)Strip.Device | Bus.DeviceThe following properties are availablename: strsr: intwdm: strks: strmme: strasio: strexample:print(vm.strip[0].device.name)vm.bus[0].device.asio="Audient USB Audio ASIO Driver"strip|bus device parameters are defined for physical channels only.name, sr are read only. wdm, ks, mme, asio are write only.MacrobuttonsThe following properties are available.state: booleanstateonly: booleantrigger: booleanexample:vm.button[37].state=Truevm.button[55].trigger=FalseRecorderThe following methods are availableplay()stop()pause()record()ff()rew()load(filepath): raw stringgoto(time_string): time string in formathh:mm:ssfiletype(filetype): string, ("wav", "aiff", "bwf", "mp3")The following properties are availableA1 - A5: booleanB1 - B3: booleansamplerate: int, (22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000)bitresolution: int, (8, 16, 24, 32)channel: int, from 1 to 8kbps: int, (32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320)gain: float, from -60.0 to 12.0example:vm.recorder.play()vm.recorder.stop()# Disable recorder out channel B2vm.recorder.B2=False# filepath as raw stringvm.recorder.load(r'C:\music\mytune.mp3')# set the goto time to 1m 30svm.recorder.goto("00:01:30")Recorder.ModeThe following properties are availablerecbus: booleanplayonload: booleanloop: booleanmultitrack: booleanexample:# Enable loop playvm.recorder.mode.loop=TrueRecorder.ArmStrip[i]|ArmBus[i]The following method is availableset(val): booleanexample:# Arm strip 3vm.recorder.armstrip[3].set(True)# Arm bus 0vm.recorder.armbus[0].set(True)VBANvm.vban.enable()vm.vban.disable()Turn VBAN on or offInstream | OutstreamThe following properties are available.on: booleanname: stringip: stringport: int, range from 1024 to 65535sr: int, (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)channel: int, from 1 to 8bit: int, 16 or 24quality: int, from 0 to 4route: int, from 0 to 8SR,channelandbitare defined as:readonly for instreams.read and write for outstreams.example:# turn VBAN onvm.vban.enable()# turn on vban instream 0vm.vban.instream[0].on=True# set bit property for outstream 3 to 24vm.vban.outstream[3].bit=24CommandCertain 'special' commands are defined by the API as performing actions rather than setting values.The following methods are available:show(): Bring Voiceemeter GUI to the frontshutdown(): Shuts down the GUIrestart(): Restart the audio enginereset(): Applies theresetconfig. (phys strip B1, virt strip A1, gains, comp, gate 0.0, mute, mono, solo, eq false)The following properties are available.showvbanchat: booleanlock: booleanexample:vm.command.restart()vm.command.showvbanchat=Trueshowvbanchatandlockare write only.Deviceinsouts: Returns the number of input/output devicesinput(i)output(i): Returns a dict of device properties for device[i]example:importvoicemeeterlibwithvoicemeeterlib.api(KIND_ID)asvm:foriinrange(vm.device.ins):print(vm.device.input(i))FXThe following properties are available:reverb: booleanreverb_ab: booleandelay: booleandelay_ab: booleanexample:vm.fx.reverb_ab=TruePatchThe following properties are available:postfadercomposite: booleanpostfxinsert: booleanexample:vm.patch.postfxinsert=Falseasio[i]get(): intset(patch_in): int, valid range determined by connected device.example:vm.patch.asio[3].set(4)i, from 0 to 10A2[i] - A5[i]get(): intset(patch_out): int, valid range determined by connected device.example:vm.patch.A3[5].set(3)i, from 0 to 8.composite[i]get(): intset(channel): int, from 0 up to number of channels depending on version.example:vm.patch.composite[7].set(4)i, from 0 to 8.insert[i]on: booleanexample:vm.patch.insert[18].on=Truei, from 0 up to number of channels depending on version.OptionThe following properties are available:sr: intasiosr: booleanmonitoronsel: booleanexample:vm.option.sr=48000The following methods are available:buffer(driver, buf): Set buffer size for particular audio driver.buf: int, from 128 to 2048driver:str, ("mme", "wdm", "ks", "asio")example:vm.option.buffer("wdm",512)delay[i]get(): intset(delay): int, from 0 to 500example:vm.option.delay[4].set(30)i, from 0 up to 4.MidiThe following properties are available:channel: int, returns the midi channelcurrent: int, returns the current (or most recently pressed) keyThe following methods are available:get(key): int, returns most recent velocity value for a keyexample:print(vm.midi.get(12))get() may return None if no value for requested key in midi cacheMultiple parametersapplySet many strip/bus/macrobutton/vban parameters at once, for example:vm.apply({"strip-2":{"A1":True,"B1":True,"gain":-6.0},"bus-2":{"mute":True,"eq":{"on":True}},"button-0":{"state":True},"vban-in-0":{"on":True},"vban-out-1":{"name":"streamname"},})Or for each class you may do:vm.strip[0].apply({"mute":True,"gain":3.2,"A1":True})vm.vban.outstream[0].apply({"on":True,"name":"streamname","bit":24})Config Filesvm.apply_config(configname)You may load config files in TOML format.
Three example configs have been included with the package. Remember to save
current settings before loading a user config. To load one you may do:importvoicemeeterlibwithvoicemeeterlib.api('banana')asvm:vm.apply_config('example')Your configs may be located in one of the following paths:<current working directory> / "configs" / kind_id<user home directory> / ".config" / "voicemeeter" / kind_id<user home directory> / "Documents" / "Voicemeeter" / "configs" / kind_idIf a config with the same name is located in multiple locations, only the first one found is loaded into memory, in the above order.config extendsYou may also load a config that extends another config with overrides or additional parameters.You just need to define a keyextendsin the config TOML, that names the config to be extended.Three example 'extender' configs are included with the repo. You may load them with:importvoicemeeterlibwithvoicemeeterlib.api('banana')asvm:vm.apply_config('extender')EventsBy default, NO events are listened for. Use events kwargs to enable specific event types.example:importvoicemeeterlib# Set event updates to occur every 50ms# Listen for level updates onlywithvoicemeeterlib.api('banana',ratelimit=0.05,ldirty=True)asvm:...vm.observerUse the Subject class to register an app as event observer.The following methods are available:add: registers an app as an event observerremove: deregisters an app as an event observerexample:# register an app to receive updatesclassApp():def__init__(self,vm):vm.observer.add(self)...vm.eventUse the event class to toggle updates as necessary.The following properties are available:pdirty: booleanmdirty: booleanmidi: booleanldirty: booleanexample:vm.event.ldirty=Truevm.event.pdirty=FalseOr add, remove a list of events.The following methods are available:add()remove()get()example:vm.event.remove(["pdirty","mdirty","midi"])# get a list of currently subscribedprint(vm.event.get())Remote classvoicemeeterlib.api(KIND_ID: str)You may pass the following optional keyword arguments:sync: boolean=False, force the getters to wait for dirty parameters to clear. For most cases leave this as False.ratelimit: float=0.033, how often to check for updates in ms.pdirty: boolean=False, parameter updatesmdirty: boolean=False, macrobutton updatesmidi: boolean=False, midi updatesldirty: boolean=False, level updatestimeout: float=2.0, maximum time to wait for a successful login in secondsAccess to lower level Getters and Setters are provided with these functions:vm.get(param, is_string=False): For getting the value of any parameter. Set string to True if getting a property value expected to return a string.vm.set(param, value): For setting the value of any parameter.example:vm.get('Strip[2].Mute')vm.set('Strip[4].Label','stripname')vm.set('Strip[0].Gain',-3.6)Access to lower level polling functions are provided with the following property objects:vm.pdirtyTrue iff a parameter has been updated.vm.mdirtyTrue iff a macrobutton has been updated.vm.ldirtyTrue iff a level has been updated.Errorserrors.VMError: Base custom exception class.errors.InstallError: Exception raised when installation errors occur.errors.CAPIError: Exception raised when the C-API returns error values.The following attributes are available:fn_name: C-API function name.code: error codeFor a full list of error codes check theVoicemeeterRemote header file.LoggingIt's possible to see the messages sent by the interface's setters and getters, may be useful for debugging.example:importvoicemeeterliblogging.basicConfig(level=logging.DEBUG)withvoicemeeterlib.api("banana")asvm:...Run testsTo run all tests:pytest -vOfficial DocumentationVoicemeeter Remote C API