voicemeeter-connector
Version:
A Connector to use the Voicemeeter API
3 lines (2 loc) • 16 kB
JavaScript
var e=require("koffi"),t=require("winreg");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n,a,o,i=/*#__PURE__*/r(e),l=/*#__PURE__*/r(t);!function(e){e.Mono="Mono",e.Mute="Mute",e.Solo="Solo",e.MC="MC",e.Gain="Gain",e.Pan_x="Pan_x",e.Pan_y="Pan_y",e.Color_x="Color_x",e.Color_y="Color_y",e.fx_x="fx_x",e.fx_y="fx_y",e.Audibility="Audibility",e.Comp="Comp",e.Gate="Gate",e.EqGain1="EqGain1",e.EqGain2="EqGain2",e.EqGain3="EqGain3",e.Label="Label",e.A1="A1",e.A2="A2",e.A3="A3",e.A4="A4",e.A5="A5",e.B1="B1",e.B2="B2",e.B3="B3",e.FadeTo="FadeTo"}(n||(n={})),function(e){e.Mono="Mono",e.Mute="Mute",e.EQ="EQ.on",e.Gain="Gain",e.NormalMode="mode.normal",e.AmixMode="mode.Amix",e.BmixMode="mode.Bmix",e.RepeatMode="mode.Repeat",e.CompositeMode="mode.Composite",e.FadeTo="FadeTo",e.Label="Label"}(a||(a={})),function(e){e[e.DEFAULT=0]="DEFAULT",e[e.STATEONLY=2]="STATEONLY",e[e.TRIGGER=3]="TRIGGER",e[e.COLOR=4]="COLOR"}(o||(o={}));var u,c,s,d={pointer:null,awaitUnregister:[],ended:!0};!function(e){e[e.INPUT=1]="INPUT",e[e.OUTPUT=2]="OUTPUT",e[e.MAIN=4]="MAIN"}(u||(u={})),(s=c||(c={}))[s.STARTING=1]="STARTING",s[s.ENDING=2]="ENDING",s[s.CHANGE=3]="CHANGE",s[s.BUFFER_IN=10]="BUFFER_IN",s[s.BUFFER_OUT=11]="BUFFER_OUT",s[s.BUFFER_MAIN=20]="BUFFER_MAIN";var f,_=i.default.struct("VBVMR_T_AUDIOINFO",{samplerate:"long",nbSamplePerFrame:"long"}),p=i.default.struct("VBVMR_T_AUDIOBUFFER",{audiobuffer_sr:"long",audiobuffer_nbs:"long",audiobuffer_nbi:"long",audiobuffer_nbo:"long",audiobuffer_r:i.default.array("float*",128),audiobuffer_w:i.default.array("float*",128)});function v(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function V(){return V=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)({}).hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},V.apply(null,arguments)}function b(e){var t=function(e){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:t+""}var g,m,h,B,M=/*#__PURE__*/function(){function e(){var e,t=this;this.isInitialised=!1,this.isConnected=!1,this.outputDevices=[],this.inputDevices=[],this.version="",this.type=void 0,this.eventPool=[],this.stringParameters=["Label","FadeTo","FadeBy","AppGain","AppMute","name","ip"],this.timerInterval=void 0,this.audioCallbackStates=((e={})[u.MAIN]=V({},d),e[u.INPUT]=V({},d),e[u.OUTPUT]=V({},d),e),this.awaitAudioCallbackEvents={start:[],stop:[]},this.connect=function(){if(!t.isInitialised)throw new Error("Await the initialisation before connect");if(t.isConnected)return{success:!0,message:"Already connected.",code:0};var e=m.VBVMR_Login();switch(e){case 0:return t.isConnected=!0,t.type=t.getVoicemeeterType(),t.version=t.getVoicemeeterVersion(),t.timerInterval=setInterval(t.checkPropertyChange,10),{success:!0,message:"Successfully connected to VoiceMeeter (VM Running).",code:0};case 1:return t.isConnected=!0,t.type=void 0,t.version="Unknown",t.timerInterval=setInterval(t.checkPropertyChange,10),{success:!0,message:"Connected to VoiceMeeter API (VM App Not Running).",code:1};case-1:throw t.isConnected=!1,new Error("VoiceMeeter connection failed: Unable to get client (Unexpected error -1).");case-2:throw t.isConnected=!1,new Error("VoiceMeeter connection failed: Unexpected login (Expected logout first -2).");default:throw t.isConnected=!1,new Error("VoiceMeeter connection failed with unknown error code: "+e+".")}},this.disconnect=function(){if(!t.isConnected)throw new Error("Not connected ");try{if(t.unregisterAllAudioCallbacks().catch(function(){}),0===m.VBVMR_Logout())return clearInterval(t.timerInterval),void(t.isConnected=!1);throw new Error("Disconnect failed")}catch(e){throw new Error("Disconnect failed")}},this.updateDeviceList=function(){if(!t.isConnected)throw new Error("Not connected ");t.outputDevices=[],t.inputDevices=[];for(var e=m.VBVMR_Output_GetDeviceNumber(),r=0;r<e;r++){var n=Buffer.alloc(256),a=Buffer.alloc(256),o=[0];m.VBVMR_Output_GetDeviceDescA(r,o,a,n),t.outputDevices.push({name:a.toString().replaceAll(/\u0000+$/g,""),hardwareId:n.toString().replaceAll(/\u0000+$/g,""),type:o[0]})}for(var i=m.VBVMR_Input_GetDeviceNumber(),l=0;l<i;l++){var u=Buffer.alloc(256),c=Buffer.alloc(256),s=[0];m.VBVMR_Input_GetDeviceDescA(l,s,c,u),t.inputDevices.push({name:c.toString().replaceAll(/\u0000+$/g,""),hardwareId:u.toString().replaceAll(/\u0000+$/g,""),type:s[0]})}},this.isParametersDirty=function(){return m.VBVMR_IsParametersDirty()},this.getBusParameter=function(e,r){return t.getParameter("Bus",e,r)},this.getStripParameter=function(e,r){return t.getParameter("Strip",e,r)},this.setStripParameter=function(e,r,n){return t.setParameter("Strip",e,r,n)},this.setBusParameter=function(e,r,n){return t.setParameter("Bus",e,r,n)},this.attachChangeEvent=function(e){t.eventPool.push(e)},this.getOption=function(e){if(!t.isConnected)throw new Error("Not correct connected ");if(t.stringParameters.some(function(t){return e.includes(t)})){var r=Buffer.alloc(512);return m.VBVMR_GetParameterStringA(e,r),[].concat(String.fromCharCode.apply(null,r)).filter(function(e){return"\0"!==e}).join("")}var n=[0];return m.VBVMR_GetParameterFloat(e,n),n[0]},this.setOption=function(e){var t=Buffer.alloc(e.length+1);return t.fill(0).write(e),m.VBVMR_SetParameters(t),new Promise(function(e){setTimeout(e,200)})},this.isMacroButtonDirty=function(){return m.VBVMR_MacroButton_IsDirty()},this.getMacroButtonStatus=function(e,t){void 0===t&&(t=o.DEFAULT);var r=[0];if(0===m.VBVMR_MacroButton_GetStatus(e,r,t))return r[0];throw new Error("Failed to get macro button "+e+" status")},this.setMacroButtonStatus=function(e,t,r){if(void 0===r&&(r=o.DEFAULT),0!==m.VBVMR_MacroButton_SetStatus(e,t,r))throw new Error("Failed to set macro button "+e+" status")},this.registerAudioCallback=function(e,r,n,a){var o;if(null!==t.audioCallbackStates[e].pointer)throw new Error('Audio callback for "'+e+'" is already registered.');t.audioCallbackStates[e].pointer=i.default.register(function(r,o,l,u){var s;try{switch(o){case c.STARTING:t.audioCallbackStates[e].ended=!1,s={lpUser:r,nnn:u,command:o,data:t.convertToAudioCallbackInfo(l)},t.resolveAudioCallbackEvent("start");break;case c.ENDING:t.audioCallbackStates[e].ended=!0,s={lpUser:r,nnn:u,command:o,data:t.convertToAudioCallbackInfo(l)},t.resolveAudioCallbackEvent("stop");break;case c.CHANGE:var d;s={lpUser:r,nnn:u,command:o,data:t.convertToAudioCallbackInfo(l)},(null==(d=null==a?void 0:a.restartOnChangedStream)||d)&&setTimeout(function(){t.startAudioCallback().catch(function(e){var r=t.convertToErrorObject(e);r.message="Failed to restart callback after changed stream: "+r.message,n(r,s)})},50);break;case c.BUFFER_IN:case c.BUFFER_OUT:case c.BUFFER_MAIN:s={lpUser:r,nnn:u,command:o,data:t.convertToAudioCallbackBuffer(l)};break;default:return 0}if(o===c.ENDING&&t.audioCallbackStates[e].awaitUnregister.length>0&&null!==t.audioCallbackStates[e].pointer)for(i.default.unregister(t.audioCallbackStates[e].pointer),t.audioCallbackStates[e].pointer=null;t.audioCallbackStates[e].awaitUnregister.length>0;){var f=t.audioCallbackStates[e].awaitUnregister.shift();void 0!==f&&f()}}catch(e){var _=t.convertToErrorObject(e);return n(_,s),0}return n(null,s),0},h);var l=Buffer.alloc(64);l.write(r);var u=m.VBVMR_AudioCallbackRegister(e,t.audioCallbackStates[e].pointer,null!=(o=null==a?void 0:a.lpUser)?o:null,l);switch(u){case 0:return;case-1:throw new Error("Failed to register audio callback");case-2:var s=l.toString().replace("/\0+$/g","");throw new Error("Audio callback already registered by: "+s);default:throw new Error("Unexpected result registering audio callback: "+u)}},this.startAudioCallback=function(){return new Promise(function(e,r){var n=m.VBVMR_AudioCallbackStart();if(0!==n){var a;switch(n){case-1:a="Failed to start audio callback";break;case-2:a="No audio callback registered";break;default:a="Unexpected result starting audio callback "+n}r(new Error(a))}else t.awaitAudioCallbackEvents.start.push(function(){return e()})})},this.stopAudioCallback=function(){return new Promise(function(e,r){var n=m.VBVMR_AudioCallbackStop();if(0!==n){var a;switch(n){case-1:a="Failed to stop audio callback";break;case-2:a="No audio callback registered";break;default:a="Unexpected result stopping audio callback: "+n}r(a)}else t.awaitAudioCallbackEvents.stop.push(function(){return e()})})},this.unregisterAudioCallback=function(e){return new Promise(function(r,n){if(null!==t.audioCallbackStates[e].pointer){var a=m.VBVMR_AudioCallbackUnregister(t.audioCallbackStates[e].pointer);switch(a){case 0:return void(t.audioCallbackStates[e].ended?(i.default.unregister(t.audioCallbackStates[e].pointer),t.audioCallbackStates[e].pointer=null,r()):t.audioCallbackStates[e].awaitUnregister.push(function(){return r()}));case-1:n(new Error("Failed to unregister audio callback"));break;case-2:t.audioCallbackStates[e].pointer=null,r();break;default:n(new Error("Unexpected result unregistering audio callback "+a))}}else n(new Error('No audio callback registered for "'+e+'"'))})},this.unregisterAllAudioCallbacks=function(){for(var e=[],r=0,n=Object.entries(t.audioCallbackStates);r<n.length;r++){var a=n[r];null!==a[1].pointer&&e.push(t.unregisterAudioCallback(a[0]))}return Promise.all(e)},this.convertToAudioCallbackInfo=function(e){var t=i.default.decode(e,_);return{sampleRate:t.samplerate,samplesPerFrame:t.nbSamplePerFrame}},this.convertToAudioCallbackBuffer=function(e){for(var t=i.default.decode(e,p),r={sampleRate:t.audiobuffer_sr,samplesPerFrame:t.audiobuffer_nbs,inputChannelCount:t.audiobuffer_nbi,outputChannelCount:t.audiobuffer_nbo,inputChannels:[],outputChannels:[]},n=0;n<t.audiobuffer_nbi;n++)r.inputChannels.push(new Float32Array(i.default.view(t.audiobuffer_r[n],4*t.audiobuffer_nbs)));for(var a=0;a<t.audiobuffer_nbo;a++)r.outputChannels.push(new Float32Array(i.default.view(t.audiobuffer_w[a],4*t.audiobuffer_nbs)));return r},this.convertToErrorObject=function(e){return e instanceof Error?e:"string"==typeof e?new Error(e):new Error("Unknown error: "+String(e))},this.checkPropertyChange=function(){var e=!1;if(1===t.isParametersDirty()&&(e=!0),1===t.isMacroButtonDirty()&&(e=!0),e)for(var r,n=function(e){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,t){if(e){if("string"==typeof e)return v(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?v(e,t):void 0}}(e))){t&&(e=t);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(t.eventPool);!(r=n()).done;)(0,r.value)()},this.getVoicemeeterType=function(){var e=[0];if(0!==m.VBVMR_GetVoicemeeterType(e))throw new Error("running failed");switch(e[0]){case 1:return"voicemeeter";case 2:return"voicemeeterBanana";case 3:return"voicemeeterPotato";default:throw new Error("Voicemeeter seems not to be installed")}},this.getVoicemeeterVersion=function(){var e=[0];if(0!==m.VBVMR_GetVoicemeeterVersion(e))throw new Error("running failed");return((4278190080&e[0])>>24)+"."+((16711680&e[0])>>16)+"."+((65280&e[0])>>8)+"."+(255&e[0])},this.getParameter=function(e,r,n){return t.getOption(e+"["+r+"]."+n)},this.setParameter=function(e,r,n,a){if(!t.isConnected)throw new Error("Not connected ");return t.setOption(e+"["+r+"]."+n+"="+a+";")},this.getLevel=function(e,t){var r=[0];return m.VBVMR_GetLevel(e,t,r),r[0]}}var t,r;return e.prototype.resolveAudioCallbackEvent=function(e){for(;this.awaitAudioCallbackEvents[e].length>0;){var t=this.awaitAudioCallbackEvents[e].shift();void 0!==t&&t()}},t=e,(r=[{key:"$outputDevices",get:function(){return this.outputDevices}},{key:"$inputDevices",get:function(){return this.inputDevices}},{key:"$version",get:function(){return this.version}},{key:"$type",get:function(){return this.type}}])&&function(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,b(n.key),n)}}(t.prototype,r),Object.defineProperty(t,"prototype",{writable:!1}),t}();g=M,M.init=function(){try{return Promise.resolve(function(){try{var e=new l.default({hive:l.default.HKLM,key:String.raw(f||(t=["SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionUninstallVB:Voicemeeter {17359A74-1236-5467}"],r=["\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VB:Voicemeeter {17359A74-1236-5467}"],r||(r=t.slice(0)),t.raw=r,f=t))});return Promise.resolve(new Promise(function(t){e.values(function(e,r){if(e)throw new Error(e);var n=r.find(function(e){return"UninstallString"===e.name}).value,a=n.lastIndexOf("\\");t(n.slice(0,a))})}))}catch(t){return Promise.reject(t)}var t,r}()).then(function(e){return new Promise(function(t){B||(B=new g);var r=i.default.load(e+"/VoicemeeterRemote64.dll");m={VBVMR_Login:r.func("long __stdcall VBVMR_Login(void)"),VBVMR_Logout:r.func("long __stdcall VBVMR_Logout(void)"),VBVMR_RunVoicemeeter:r.func("long __stdcall VBVMR_RunVoicemeeter(long mode)"),VBVMR_IsParametersDirty:r.func("long __stdcall VBVMR_IsParametersDirty(void)"),VBVMR_GetLevel:r.func("long __stdcall VBVMR_GetLevel(long type, long channel, _Out_ float* value)"),VBVMR_GetParameterFloat:r.func("long __stdcall VBVMR_GetParameterFloat(const char* param, _Out_ float* value)"),VBVMR_GetParameterStringA:r.func("long __stdcall VBVMR_GetParameterStringA(const char* param, _Out_ char* value)"),VBVMR_SetParameters:r.func("long __stdcall VBVMR_SetParameters(const char* param)"),VBVMR_Output_GetDeviceNumber:r.func("long __stdcall VBVMR_Output_GetDeviceNumber(void)"),VBVMR_Output_GetDeviceDescA:r.func("long __stdcall VBVMR_Output_GetDeviceDescA(long index, _Out_ long* type, _Out_ char* name, _Out_ char* hardwareId)"),VBVMR_Input_GetDeviceNumber:r.func("long __stdcall VBVMR_Input_GetDeviceNumber(void)"),VBVMR_Input_GetDeviceDescA:r.func("long __stdcall VBVMR_Input_GetDeviceDescA(long index, long* type, char* name, char* hardwareId)"),VBVMR_GetVoicemeeterType:r.func("long __stdcall VBVMR_GetVoicemeeterType(_Out_ long* type)"),VBVMR_GetVoicemeeterVersion:r.func("long __stdcall VBVMR_GetVoicemeeterVersion(_Out_ long* version)"),VBVMR_MacroButton_IsDirty:r.func("long __stdcall VBVMR_MacroButton_IsDirty(void)"),VBVMR_MacroButton_GetStatus:r.func("long __stdcall VBVMR_MacroButton_GetStatus(long nuLogicalButton, _Out_ float* pValue, long bitmode)"),VBVMR_MacroButton_SetStatus:r.func("long __stdcall VBVMR_MacroButton_SetStatus(long nuLogicalButton, float fValue, long bitmode)"),VBVMR_AudioCallbackRegister:r.func("long __stdcall VBVMR_AudioCallbackRegister(long mode, void* audioCallback, void* lpUser, char* szClientName)"),VBVMR_AudioCallbackStart:r.func("long __stdcall VBVMR_AudioCallbackStart(void)"),VBVMR_AudioCallbackStop:r.func("long __stdcall VBVMR_AudioCallbackStop(void)"),VBVMR_AudioCallbackUnregister:r.func("long __stdcall VBVMR_AudioCallbackUnregister(void* audioCallback)")},h=i.default.pointer(i.default.proto("long __stdcall AudioCallback(void* lpUser, long nCommand, void* lpData, long nnn)")),B.isInitialised=!0,t(B)})})}catch(e){return Promise.reject(e)}},M.inputChannelCountMap={voicemeeter:12,voicemeeterBanana:22,voicemeeterPotato:34},M.outputChannelCountMap={voicemeeter:16,voicemeeterBanana:40,voicemeeterPotato:64};var C=a,A=n,w=o,R=u;exports.AudioCallbackCommands=c,exports.AudioCallbackModes=R,exports.BusProperties=C,exports.InterfaceTypes={strip:0,bus:1},exports.MacroButtonModes=w,exports.StripProperties=A,exports.Voicemeeter=M,exports.types={__proto__:null};
//# sourceMappingURL=index.js.map