SteffeyDev / atemOSC

Control ATEM video switchers over the network with OSC messages
http://www.atemosc.com
202 stars 32 forks source link

DSK and USK support for conditional tying #30

Closed SteffeyDev closed 7 years ago

SteffeyDev commented 7 years ago

At my organization, we are trying to set up a queuing system, where we can pre-stage video controller changes and run them using OSC messages. The problem is that we want to be able to go from any scene to any other scene, so for each transition may or may not need to tie a given USK or DSK.

For example, consider the following scenes: Scene 1: DSK 1 On-air Scene 2: DSK 1 Off-air Scene 3: DSK1 On-air

If I am transitioning from scene 1 to scene 2, I want to enable the DSK toggle before doing an auto transition (/atem/dsk/set-tie/1 1). However, if I transition from scene 1 to scene 3, I don't want to tie DSK 1 (/atem/dsk/set-tie/1 0). For obvious reasons, I don't want to define what should happen from every scene to every other scene, and just want to say for each scene whether a DSK/USK should be on or off air.

Is this scenario currently handled by some combination of OSC messages I could send, or would a new OSC message (e.g. /atem/dsk/conditional-tie/1) be needed?

In the latter case, I think that the Atem Blackmagic SDK can give feedback for whether a given DSK is currently live or not, and ideally I would like to be able to poll the switcher and only tie if needed. Alternatively, (though less ideal) the atemOSC could store whether a DSK/USK is enabled (by looking at what OSC messages have been processed and how they affect the switcher), and then act on that for a conditional tie effect.

I am fairly fluent in Obj-C development and the OSC protocol, so if this is a feature that could be used more widely, I would love to work with this project to create a PR. If not, I would still appreciate input about the best way to approach this, but can fork and implement it for our organization only.

sneat commented 7 years ago

@SteffeyDev adding functionality to be able to query the status would be worthwhile. Use something like /atem/dsk/get-tie/1 and then send the value back over OSC. This block should give you some pointers (https://github.com/danielbuechele/atemOSC/blob/master/atemOSC/SwitcherPanelAppDelegate.mm#L407-L423), but do something like:

bool isTied;
key->GetTie(&isTied):

Similarly with the USK (https://github.com/danielbuechele/atemOSC/blob/master/atemOSC/SwitcherPanelAppDelegate.mm#L402).

An example of how to send an OSC message back from atemOSC to the originator is at https://github.com/danielbuechele/atemOSC/blob/master/atemOSC/SwitcherPanelAppDelegate.mm#L690-L692

If you wanted to be really fancy, you could also register callback to the keyers to have it automatically send OSC messages whenever anything changes the Tie states (you wouldn't have to poll then, you'd just get told what the new value was).

You'd make use of IBMDSwitcherKey::AddCallback for the USKs and IBMDSwitcherDownstreamKey::AddCallback for the DSKs.

SteffeyDev commented 7 years ago

@sneat That's a good idea, I may look into doing that just because of its potential usefulness. Unfortunately, it doesn't help directly with what I am trying to do, because I am using OSCulator, which can send and receive OSC but not do things like send a signal, wait for a response, and then make a decision based on that response (at least not easily).

In addition, I'm not actually interested if it is currently tied, but more interested if it is currently on air, so maybe something like /atem/dsk/get-on-air/1?

What do you think about the idea of having an /atem/dsk/conditional-tie/1 (or similar) that would make atemOSC query the switcher and tie the DSK only if not tied (or untie the DSK only if not untied)?

This way, if I want to fade into Cam3 with DSK1 overlay, I could send (in sequence) /atem/preview/3 1, /atem/dsk/conditional-tie/1 1, /atem/transition/auto.

As for naming, /atem/dsk/conditional-tie is only one thought, another could be /atem/dsk/tie-if-needed or /atem/dsk/set-next

sneat commented 7 years ago

I quite like the name /atem/dsk/set-next.

Essentially you'd do a block similar to https://github.com/danielbuechele/atemOSC/blob/master/atemOSC/SwitcherPanelAppDelegate.mm#L456-L470 but get the current OnAir status, compare it to the requested status, and tie if they are different. Something like:

bool isOnAir;
key->GetOnAir(&isOnAir):
if (value != isOnAir && !isTransitioning) {
    key->SetTie(true);
}
SteffeyDev commented 7 years ago

Ok, I'll try it out and send a PR if it works. Thanks for the help!

SteffeyDev commented 7 years ago

@sneat How would you recommend implementing a similar function for USK?

sneat commented 7 years ago

The USK is slightly harder because there always has to be at least one SetNextTransitionSelection set. Generally this will be the bmdSwitcherTransitionSelectionBackground one, but it can be multiple. The Atem won't do anything at all if you try to tell it to turn off the only TransitionSelection.

Get whether the a particular USK is onAir like this: https://github.com/danielbuechele/atemOSC/blob/master/atemOSC/SwitcherPanelAppDelegate.mm#L402

You will then also need to get the current values of whether the USKs are "tied" or not by calling switcherTransitionParameters ->GetNextTransitionSelection similar to https://github.com/danielbuechele/atemOSC/blob/master/atemOSC/SwitcherPanelAppDelegate.mm#L379

That will return a bit set (BMDSwitcherTransitionSelection) which you can then compare (and set) with what you actually want.

e.g. if you calculate that you need to have bmdSwitcherTransitionSelectionBackground and bmdSwitcherTransitionSelectionKey1 you would call switcherTransitionParameters->SetNextTransitionSelection(bmdSwitcherTransitionSelectionBackground | bmdSwitcherTransitionSelectionKey1)

Apologies if any of the above is wrong, it's all from memory, but should get you on the right track at least.

SteffeyDev commented 7 years ago

Looks great, I've implemented but can't test yet because I don't have access to a switch for a while. If it works I will submit a PR.