Andersama / obs-asio

ASIO plugin for OBS-Studio
GNU General Public License v3.0
684 stars 43 forks source link

Save input selection on OBS restart, even when device has been disconnected. #91

Closed AronHetLam closed 3 years ago

AronHetLam commented 3 years ago

Hi

I have a A&H mixer connected to OBS through the plugin, and all works great. However, only until I start OBS with the mixer off, in that case it resets the selected inputs to Mute. In this case I have to manually go into the OBS source and reselect the inputs. For most of my team it wouldn't be a problem, but for some it has to "Just work", or else they don't know what to do, and need support... Because of this i would like to ask if it's possible to make the plugin save input selection, even when the device isn't connected, and it would be really nice if it auto connected once the device would turn on again.

I was just about to put the plugin into production, but can't because of this issue.

Andersama commented 3 years ago

Bit lost, I think I get what you're trying to say, the plugin reads the state of the asio drivers so if they're not responsive / not connected there's no channels listed. If I'm understanding this right you're probably running into a pattern where you're saving the plugin state with the channels "muted" even though you're really expecting the device to have its original channels listed.

Essentially, you open obs w/o the device connected or on -> plugin reads the device as missing, lists no channels, you close obs -> it saves state (now with channels muted). There's going to be an issue that the plugin isn't setup to be plug and play, I'll have to think about to fix this.

AronHetLam commented 3 years ago

Sorry if the description was a bit vague, but it looks like were on the same page.

It depends on the order of which you turn on the devices. So yes, when the mixer is off the drivers of cause wont read it, and the plugin resets the selected channels to Mute. I guess that's then saved as the state once OBS is shut down, and loaded again when reopened. Would it be possible to make it only save the new state when it's manually changed it the OBS source? I just looked at your commit, and somewaht remembered how properties work in OBS' API (I once made a python script using it). Looks like that might do the trick.

For the part where it should auto detect if the device is plugged in/turned on after OBS started i guess you'd need to have a callback running every few seconds to check if the device list has changed. I don't know how the ASIO libraries work, but maybe they have a deviceAdded event or something like that which would be perfect for the job?

Also, will you release this straight away, or do i need to build it myself for now?

AronHetLam commented 3 years ago

From a bit of digging into the Juice library and your code, i think it would be possible to add a listener that will trigger when ASIO devices are added/removed in the system. Take a look at addListener(Listener *listener) in Juice docs.

Andersama commented 3 years ago

I'm not setup to build the plugin and PKV's busy (so you'll have to build it yourself), fairly confident what I did would fix the issue of the settings changing to muted. I'll have to take a bit to figure out the addListener part.

If you're building it yourself you may want to build it with the other commits I also just added. I can't remember off the top of my head if audioDeviceAboutToStart is called every time any device setting is changed, if it is, it's safe for the silent buffer to be cached there.

Andersama commented 3 years ago

I think that part of the api existed when I originally wrote the Juce plugin, it might not catch whether devices connect / disconnect, it might be it only detects when they get installed / uninstalled because for windows the way asio picks up on the devices is scanning through the registry. It only knows whether something is connected by attempting to initialize the device, will probably need a function that loops over the devices and probes ones that aren't currently running.

Andersama commented 3 years ago

An easy quick dirty fix might be to have a button specifically to force the update function, that's where the device gets setup and prompted to run, provided the device you want is listed (should be unless it's been uninstalled).

AronHetLam commented 3 years ago

An even more dirty one would be to have the update function called every few seconds with an OBS timer when it's not connected (what I did in my Python script a few years ago, to make it auto connect to other software over IP. It would remove the callback once connected).

I don't have time atm. but maybe after my exam I would setup a build environment and see if i can get it going. 😊

AronHetLam commented 3 years ago

I tried to build it, but OBS won't recognize it as a plugin when I do so. I'm not an expert at CMake and compiling C++ like this, so there's probably something I'm missing. It can't find obs_module_load, which obviously is in the code...

OBS log writes: 20:02:46.264: Skipping module '../../obs-plugins/64bit/win-asio.dll', not an OBS plugin

Debug console in vs2019:

'obs64.exe' (Win32): Loaded 'C:\Users\aronh\Documents\Code\obs-studio\build\rundir\Release\obs-plugins\64bit\obs-asio.dll'. Module was built without symbols.
Required module function 'obs_module_load' in module '../../obs-plugins/64bit/obs-asio.dll' not found, loading of module failed
Failed to load module file '../../obs-plugins/64bit/obs-asio.dll': -3
Andersama commented 3 years ago

Reads like an error that the environment might be loading the wrong plugin? That error is usually what you'll see when obs is having problems with the abi, which if you're doing a proper build should be ok.

That and/or it could be a bitness issue make sure to build for x64 w/ x64 etc...

Andersama commented 3 years ago

When I did plugin development I didn't have it setup externally like here, it's normally quite a lot easier to build the plugin as though it were added in natively.

AronHetLam commented 3 years ago

I try to build it natively, but can't seem to get it working. First I cloned the obs-studio repo, and checked out the latest release (27.0.1). I get the x64 building and running with no problem. Then I add the obs-asio repo/folder to obs-studio/plugins, add the different juce paths in cmake, add add_subdirectory(obs-asio) in the CMakeLists.txt in the obs-studio/plugins dir. At this point the project copmpiles, but doesn't seem to properly build/include obs-asio at all. If I then in the CMakeLists.txt in the obs-asio folder uncomment either https://github.com/Andersama/obs-asio/blob/57cc9171696abdc995959b0c0f8afc97242f2490/CMakeLists.txt#L92-L93 I get this error when building in vs2019

Error   MSB3073 The command "setlocal
"C:\Program Files\CMake\bin\cmake.exe" -E copy C:/Users/aronh/Documents/Code/obs-studio/build64/plugins/obs-asio/Release/obs-asio.dll C:/Users/aronh/Documents/Code/obs-studio/build64/rundir/Release/obs-asio/bin/64bit/obs-asio.dll
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd
setlocal
"C:\Program Files\CMake\bin\cmake.exe" -E copy_directory C:/Users/aronh/Documents/Code/obs-studio/plugins/obs-asio/data C:/Users/aronh/Documents/Code/obs-studio/build64/rundir/Release/obs-asio/data
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd
setlocal
if 1==1 ( "C:/Program Files/CMake/bin/cmake.exe" -E make_directory C:/Users/aronh/Documents/Code/obs-studio/plugins/obs-asio/release/data/obs-plugins/obs-asio C:/Users/aronh/Documents/Code/obs-studio/plugins/obs-asio/release/obs-plugins/64bit )
if %errorlevel% neq 0 goto :cmEnd
if 1==1 ( "C:/Program Files/CMake/bin/cmake.exe" -E copy_directory C:/Users/aronh/Documents/Code/obs-studio/plugins/obs-asio/src/data C:/Users/aronh/Documents/Code/obs-studio/plugins/obs-asio/release/data/obs-plugins/obs-asio )
if %errorlevel% neq 0 goto :cmEnd
if 1==1 ( "C:/Program Files/CMake/bin/cmake.exe" -E copy C:/Users/aronh/Documents/Code/obs-studio/build64/plugins/obs-asio/Release/obs-asio.dll C:/Users/aronh/Documents/Code/obs-studio/plugins/obs-asio/release/obs-plugins/64bit )
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd
:VCEnd" exited with code 1.

To me it could seem like there's something wrong in the CMakeLists.txt file, but I'm happy to be proven wrong 😊

Andersama commented 3 years ago

Ah, I think maybe I might vaugely remember a cmake thing, the folder name I think has to match the project? Try renaming the folder to win-asio? I think that's what it was, can't remember.

AronHetLam commented 3 years ago

I finally got it to build, but haven't tested it with the A&H mixer yet. I made a pr as some function names were incorrect. I had to make some changes in the cmake file to get it working- later I'll see which exactly made it work, and i might make a pr for that too. 😊

AronHetLam commented 3 years ago

I got the version I compiled running on our streaming setup, and it correctly stores the selected channels on the A&H mixer. Tomorrow my team will see how it does in a livestream. 😉

A nice to have addition would be that the plugin could automatically detect if the asio source is connected while OBS is running, but for now a restart does the trick.

AronHetLam commented 3 years ago

It passed a stream 🙂