/* Copyright 2012-2014 Kasper Skårhøj, SKAARHOJ K/S, kasper@skaarhoj.com This file is part of the Blackmagic Design ATEM Client library for Arduino The ATEM library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The ATEM library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the ATEM library. If not, see http://www.gnu.org/licenses/. IMPORTANT: If you want to use this library in your own projects and/or products, please play a fair game and heed the license rules! See our web page for a Q&A so you can keep a clear conscience: http://skaarhoj.com/about/licenses/ */ #include "ATEMstd.h" /** * Constructor (using arguments is deprecated! Use begin() instead) */ ATEMstd::ATEMstd(){} void ATEMstd::delay(const unsigned int delayTimeMillis) { // Responsible delay function which keeps the ATEM run loop up! DO NOT USE INSIDE THIS CLASS! Recursion could happen... runLoop(delayTimeMillis); } /******************************** * * ATEM Switcher state methods * Returns the most recent information we've * got about the switchers state * ********************************/ uint16_t ATEMstd::getProgramInput() { return getProgramInputVideoSource(0); } uint16_t ATEMstd::getPreviewInput() { return getPreviewInputVideoSource(0); } boolean ATEMstd::getProgramTally(uint8_t inputNumber) { return (getTallyByIndexTallyFlags(inputNumber-1) & 1) >0 ? true : false; } boolean ATEMstd::getPreviewTally(uint8_t inputNumber) { return (getTallyByIndexTallyFlags(inputNumber-1) & 2) >0 ? true : false; } boolean ATEMstd::getUpstreamKeyerStatus(uint8_t inputNumber) { return getKeyerOnAirEnabled(0,inputNumber-1); } boolean ATEMstd::getUpstreamKeyerOnNextTransitionStatus(uint8_t inputNumber) { // input 0 = background return (getTransitionNextTransition(0) & (0x01 << inputNumber)) ? true : false; } boolean ATEMstd::getDownstreamKeyerStatus(uint8_t inputNumber) { return getDownstreamKeyerOnAir(inputNumber-1); } uint16_t ATEMstd::getTransitionPosition() { return getTransitionPosition(0); } bool ATEMstd::getTransitionPreview() { return getTransitionPreviewEnabled(0); } uint8_t ATEMstd::getTransitionType() { return getTransitionStyle(0); } uint8_t ATEMstd::getTransitionMixTime() { return getTransitionMixRate(0); // Transition time for Mix Transitions } boolean ATEMstd::getFadeToBlackState() { return getFadeToBlackStateFullyBlack(0); // Active state of Fade-to-black } uint8_t ATEMstd::getFadeToBlackFrameCount() { return getFadeToBlackStateFramesRemaining(0); // Returns current frame in the FTB } uint8_t ATEMstd::getFadeToBlackTime() { return getFadeToBlackRate(0); // Transition time for Fade-to-black } bool ATEMstd::getDownstreamKeyTie(uint8_t keyer) { return getDownstreamKeyerTie(keyer-1); } uint16_t ATEMstd::getAuxState(uint8_t auxOutput) { return getAuxSourceInput(auxOutput-1); } uint8_t ATEMstd::getMediaPlayerType(uint8_t mediaPlayer) { return getMediaPlayerSourceType(mediaPlayer-1); } uint8_t ATEMstd::getMediaPlayerStill(uint8_t mediaPlayer) { return getMediaPlayerSourceStillIndex(mediaPlayer-1)+1; } uint8_t ATEMstd::getMediaPlayerClip(uint8_t mediaPlayer) { return getMediaPlayerSourceClipIndex(mediaPlayer-1)+1; } uint16_t ATEMstd::getAudioLevels(uint8_t channel) { if (channel>0) { return atemAudioMixerLevelsSourceRight; } else { return atemAudioMixerLevelsSourceLeft; } } uint8_t ATEMstd::getAudioChannelMode(uint16_t channelNumber) { return getAudioMixerInputMixOption(channelNumber); } /******************************** * * ATEM Switcher Change methods * Asks the switcher to changes something * ********************************/ void ATEMstd::changeProgramInput(uint16_t inputNumber) { setProgramInputVideoSource(0, inputNumber); } void ATEMstd::changePreviewInput(uint16_t inputNumber) { setPreviewInputVideoSource(0, inputNumber); } void ATEMstd::doCut() { performCutME(0); } void ATEMstd::doAuto() { performAutoME(0); } void ATEMstd::doAuto(uint8_t me) { performAutoME(me); } void ATEMstd::fadeToBlackActivate() { performFadeToBlackME(0); } void ATEMstd::changeTransitionPosition(word value) { setTransitionPosition(0,value); } void ATEMstd::changeTransitionPositionDone() { // When the last value of the transition is sent (1000), send this one too (we are done, change tally lights and preview bus!) setTransitionPosition(0,0); } void ATEMstd::changeTransitionPreview(bool state) { setTransitionPreviewEnabled(0, state); } void ATEMstd::changeTransitionType(uint8_t type) { setTransitionStyle(0, type); } void ATEMstd::changeTransitionMixTime(uint8_t frames) { setTransitionMixRate(0, frames); } void ATEMstd::changeFadeToBlackTime(uint8_t frames) { setFadeToBlackRate(0, frames); } void ATEMstd::changeUpstreamKeyOn(uint8_t keyer, bool state) { setKeyerOnAirEnabled(0, keyer-1, state); } void ATEMstd::changeUpstreamKeyNextTransition(uint8_t keyer, bool state) { // Supporting "Background" by "0" if (keyer>=0 && keyer<=4) { // Todo: Should match available keyers depending on model? uint8_t stateValue = getTransitionNextTransition(0); if (state) { stateValue = stateValue | (B1 << keyer); } else { stateValue = stateValue & (~(B1 << keyer)); } setTransitionNextTransition(0, stateValue); } } void ATEMstd::changeDownstreamKeyOn(uint8_t keyer, bool state) { setDownstreamKeyerOnAir(keyer-1, state); } void ATEMstd::changeDownstreamKeyTie(uint8_t keyer, bool state) { setDownstreamKeyerTie(keyer-1, state); } void ATEMstd::doAutoDownstreamKeyer(uint8_t keyer) { performDownstreamKeyerAutoKeyer(keyer-1); } void ATEMstd::changeAuxState(uint8_t auxOutput, uint16_t inputNumber) { setAuxSourceInput(auxOutput-1, inputNumber); } void ATEMstd::settingsMemorySave() { _prepareCommandPacket(PSTR("SRsv"),4); _finishCommandPacket(); } void ATEMstd::settingsMemoryClear() { _prepareCommandPacket(PSTR("SRcl"),4); _finishCommandPacket(); } void ATEMstd::changeColorValue(uint8_t colorGenerator, uint16_t hue, uint16_t saturation, uint16_t lightness) { commandBundleStart(); setColorGeneratorHue(colorGenerator-1, hue); setColorGeneratorSaturation(colorGenerator-1, saturation); setColorGeneratorLuma(colorGenerator-1, lightness); commandBundleEnd(); } void ATEMstd::mediaPlayerSelectSource(uint8_t mediaPlayer, boolean movieclip, uint8_t sourceIndex) { if (movieclip) { commandBundleStart(); setMediaPlayerSourceType(mediaPlayer-1, 2); setMediaPlayerSourceClipIndex(mediaPlayer-1,sourceIndex-1); commandBundleEnd(); } else { commandBundleStart(); setMediaPlayerSourceType(mediaPlayer-1, 1); setMediaPlayerSourceStillIndex(mediaPlayer-1,sourceIndex-1); commandBundleEnd(); } } void ATEMstd::mediaPlayerClipStart(uint8_t mediaPlayer) { setClipPlayerPlaying(mediaPlayer-1,true); } void ATEMstd::changeSwitcherVideoFormat(uint8_t format) { setVideoModeFormat(format); } void ATEMstd::changeDVESettingsTemp(unsigned long Xpos,unsigned long Ypos,unsigned long Xsize,unsigned long Ysize) { // TEMP commandBundleStart(); setKeyDVEPositionX(0, 0, Xpos); setKeyDVEPositionY(0, 0, Ypos); setKeyDVESizeX(0, 0, Xsize); setKeyDVESizeY(0, 0, Ysize); commandBundleEnd(); } void ATEMstd::changeDVEMaskTemp(unsigned long top,unsigned long bottom,unsigned long left,unsigned long right) { // TEMP // N/A } void ATEMstd::changeDVEBorder(bool enableBorder) { // TEMP setKeyDVEBorderEnabled(0, 0, enableBorder); } void ATEMstd::changeDVESettingsTemp_Rate(uint8_t rateFrames) { // TEMP setKeyDVERate(0,0,rateFrames); } void ATEMstd::changeDVESettingsTemp_RunKeyFrame(uint8_t runType) { // runType: 1=A, 2=B, 3=Full, 4=on of the others (with an extra paramter:) setRunFlyingKeyRuntoInfiniteindex(0,0, runType); } void ATEMstd::changeKeyerMask(uint16_t topMask, uint16_t bottomMask, uint16_t leftMask, uint16_t rightMask) { changeKeyerMask(0, topMask, bottomMask, leftMask, rightMask); } void ATEMstd::changeKeyerMask(uint8_t keyer, uint16_t topMask, uint16_t bottomMask, uint16_t leftMask, uint16_t rightMask) { commandBundleStart(); setKeyerTop(0, keyer, topMask); setKeyerBottom(0, keyer, bottomMask); setKeyerLeft(0, keyer, leftMask); setKeyerRight(0, keyer, rightMask); commandBundleEnd(); } void ATEMstd::changeDownstreamKeyMask(uint8_t keyer, uint16_t topMask, uint16_t bottomMask, uint16_t leftMask, uint16_t rightMask) { if (keyer>=1 && keyer<=2) { commandBundleStart(); setDownstreamKeyerTop(keyer, topMask); setDownstreamKeyerBottom(keyer, bottomMask); setDownstreamKeyerLeft(keyer, leftMask); setDownstreamKeyerRight(keyer, rightMask); commandBundleEnd(); } } void ATEMstd::changeUpstreamKeyFillSource(uint8_t keyer, uint16_t inputNumber) { if (keyer>=1 && keyer<=4) { // Todo: Should match available keyers depending on model? setKeyerFillSource(0, keyer, inputNumber); } } // TODO: ONLY clip works right now! there is a bug... void ATEMstd::changeUpstreamKeyBlending(uint8_t keyer, bool preMultipliedAlpha, uint16_t clip, uint16_t gain, bool invKey) { if (keyer>=1 && keyer<=4) { // Todo: Should match available keyers depending on model? commandBundleStart(); setKeyLumaPreMultiplied(0, keyer, preMultipliedAlpha); setKeyLumaClip(0, keyer, clip); setKeyLumaGain(0, keyer, gain); setKeyLumaInvertKey(0, keyer, invKey); commandBundleEnd(); } } // TODO: ONLY clip works right now! there is a bug... void ATEMstd::changeDownstreamKeyBlending(uint8_t keyer, bool preMultipliedAlpha, uint16_t clip, uint16_t gain, bool invKey) { if (keyer>=1 && keyer<=2) { // Todo: Should match available keyers depending on model? commandBundleStart(); setDownstreamKeyerPreMultiplied(keyer, preMultipliedAlpha); setDownstreamKeyerClip(keyer, clip); setDownstreamKeyerGain(keyer, gain); setDownstreamKeyerInvertKey(keyer, invKey); commandBundleEnd(); } } // Statuskode retur: DskB, data byte 2 derefter er fill source, data byte 3 er key source, data byte 1 er keyer 1-2 (0-1) // Key source command er : CDsC - og ellers ens med... void ATEMstd::changeDownstreamKeyFillSource(uint8_t keyer, uint16_t inputNumber) { if (keyer>=1 && keyer<=2) { // Todo: Should match available keyers depending on model? setDownstreamKeyerFillSource(keyer, inputNumber); } } void ATEMstd::changeDownstreamKeyKeySource(uint8_t keyer, uint16_t inputNumber) { if (keyer>=1 && keyer<=2) { // Todo: Should match available keyers depending on model? setDownstreamKeyerKeySource(keyer, inputNumber); } } void ATEMstd::changeAudioChannelMode(uint16_t channelNumber, uint8_t mode) { // Mode: 0=Off, 1=On, 2=AFV setAudioMixerInputMixOption(channelNumber, mode); } void ATEMstd::changeAudioChannelVolume(uint16_t channelNumber, uint16_t volume) { setAudioMixerInputVolume(channelNumber, volume); /* Based on data from the ATEM switcher, this is an approximation to the integer value vs. the dB value: dB +60 added Number from protocol Interpolated 6 66 65381 65381 3 63 46286 46301,04 0 60 32768 32789,13 -3 57 23198 23220,37 -6 54 16423 16444,03 -9 51 11627 11645,22 -20 40 3377 3285,93 -30 30 1036 1040,21 -40 20 328 329,3 -50 10 104 104,24 -60 0 33 33 for (int i=-60; i<=6; i=i+3) { Serial.print(i); Serial.print(" dB = "); Serial.print(33*pow(1.121898585, i+60)); Serial.println(); } */ } void ATEMstd::changeAudioMasterVolume(uint16_t volume) { setAudioMixerMasterVolume(volume); } void ATEMstd::sendAudioLevelNumbers(bool enable) { setAudioLevelsEnable(enable); } // IMCOMPATIBLE with the similar function in old ATEM library - here you enter the official number of the audio source instead! void ATEMstd::setAudioLevelReadoutChannel(uint16_t AMLv) { _ATEM_AMLv_channel = AMLv; // Should check that it's in range 0-12 } void ATEMstd::setWipeReverseDirection(bool reverse) { setTransitionWipeReverse(0,reverse); } // SPECIAL AUDIO: /** * Get Audio Mixer Levels; Master Left */ long ATEMstd::getAudioMixerLevelsMasterLeft() { return atemAudioMixerLevelsMasterLeft; } /** * Get Audio Mixer Levels; Master Right */ long ATEMstd::getAudioMixerLevelsMasterRight() { return atemAudioMixerLevelsMasterRight; } /** * Get Audio Mixer Levels; Monitor */ long ATEMstd::getAudioMixerLevelsMonitor() { return atemAudioMixerLevelsMonitor; } /** * Get Audio Mixer Levels; Source Left */ long ATEMstd::getAudioMixerLevelsSourceLeft() { return atemAudioMixerLevelsSourceLeft; } /** * Get Audio Mixer Levels; Source Right */ long ATEMstd::getAudioMixerLevelsSourceRight() { return atemAudioMixerLevelsSourceRight; } // ********************************* // ** // ** Implementations in ATEMstd.c: // ** // ********************************* // ********************************* // ** // ** Implementations in ATEMstd.c: // ** // ********************************* void ATEMstd::_parseGetCommands(const char *cmdStr) { uint8_t mE,keyer,colorGenerator,aUXChannel,mediaPlayer,macroIndex; uint16_t index,audioSource,sources; long temp; uint8_t readBytesForTlSr; if (!strcmp_P(cmdStr, PSTR("AMLv"))) { _readToPacketBuffer(36); } else if (!strcmp_P(cmdStr, PSTR("TlSr"))) { readBytesForTlSr = ((ATEM_packetBufferLength-2)/3)*3+2; _readToPacketBuffer(readBytesForTlSr); } else { _readToPacketBuffer(); // Default } if (!strcmp_P(cmdStr, PSTR("_pin"))) { if (_packetBuffer[5]=='T') { _ATEMmodel = 0; } else if (_packetBuffer[5]=='1') { _ATEMmodel = _packetBuffer[29]=='4' ? 4 : 1; } else if (_packetBuffer[5]=='2') { _ATEMmodel = _packetBuffer[29]=='4' ? 5 : 2; } else if (_packetBuffer[5]=='P') { _ATEMmodel = 3; } #if ATEM_debug if (_serialOutput>0) { Serial.print(F("Switcher type: ")); Serial.print(_ATEMmodel); switch(_ATEMmodel) { case 0: Serial.println(F(" - TeleVision Studio")); break; case 1: Serial.println(F(" - ATEM 1 M/E")); break; case 2: Serial.println(F(" - ATEM 2 M/E")); break; case 3: Serial.println(F(" - ATEM Production Studio 4K")); break; case 4: Serial.println(F(" - ATEM 1 M/E 4K")); break; case 5: Serial.println(F(" - ATEM 2 M/E 4K")); break; } } #endif } if(!strcmp_P(cmdStr, PSTR("AMLv"))) { sources = word(_packetBuffer[0],_packetBuffer[1]); if (sources<=24) { atemAudioMixerLevelsMasterLeft = (uint16_t)_packetBuffer[5]<<8 | _packetBuffer[6]; atemAudioMixerLevelsMasterRight = (uint16_t)_packetBuffer[9]<<8 | _packetBuffer[10]; atemAudioMixerLevelsMonitor = (uint16_t)_packetBuffer[21]<<8 | _packetBuffer[22]; _readToPacketBuffer(sources*2); for(uint8_t a=0;a>24) & 0xFF); _packetBuffer[12+_cBBO+4+4+9] = (int32_t)((sizeX>>16) & 0xFF); _packetBuffer[12+_cBBO+4+4+10] = (int32_t)((sizeX>>8) & 0xFF); _packetBuffer[12+_cBBO+4+4+11] = (int32_t)(sizeX & 0xFF); _finishCommandPacket(); } /** * Set Key DVE; Size Y * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * sizeY Example: 2000: 2.000 */ void ATEMstd::setKeyDVESizeY(uint8_t mE, uint8_t keyer, int32_t sizeY) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 2 _packetBuffer[12+_cBBO+4+4+3] |= 2; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+12] = (int32_t)((sizeY>>24) & 0xFF); _packetBuffer[12+_cBBO+4+4+13] = (int32_t)((sizeY>>16) & 0xFF); _packetBuffer[12+_cBBO+4+4+14] = (int32_t)((sizeY>>8) & 0xFF); _packetBuffer[12+_cBBO+4+4+15] = (int32_t)(sizeY & 0xFF); _finishCommandPacket(); } /** * Set Key DVE; Position X * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * positionX Example: 1000: 1.000 */ void ATEMstd::setKeyDVEPositionX(uint8_t mE, uint8_t keyer, int32_t positionX) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 4 _packetBuffer[12+_cBBO+4+4+3] |= 4; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+16] = (int32_t)((positionX>>24) & 0xFF); _packetBuffer[12+_cBBO+4+4+17] = (int32_t)((positionX>>16) & 0xFF); _packetBuffer[12+_cBBO+4+4+18] = (int32_t)((positionX>>8) & 0xFF); _packetBuffer[12+_cBBO+4+4+19] = (int32_t)(positionX & 0xFF); _finishCommandPacket(); } /** * Set Key DVE; Position Y * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * positionY Example: -1000: -1.000 */ void ATEMstd::setKeyDVEPositionY(uint8_t mE, uint8_t keyer, int32_t positionY) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 8 _packetBuffer[12+_cBBO+4+4+3] |= 8; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+20] = (int32_t)((positionY>>24) & 0xFF); _packetBuffer[12+_cBBO+4+4+21] = (int32_t)((positionY>>16) & 0xFF); _packetBuffer[12+_cBBO+4+4+22] = (int32_t)((positionY>>8) & 0xFF); _packetBuffer[12+_cBBO+4+4+23] = (int32_t)(positionY & 0xFF); _finishCommandPacket(); } /** * Set Key DVE; Rotation * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * rotation Example: 3670: 1 rotation+7 degress */ void ATEMstd::setKeyDVERotation(uint8_t mE, uint8_t keyer, int32_t rotation) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 16 _packetBuffer[12+_cBBO+4+4+3] |= 16; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+24] = (int32_t)((rotation>>24) & 0xFF); _packetBuffer[12+_cBBO+4+4+25] = (int32_t)((rotation>>16) & 0xFF); _packetBuffer[12+_cBBO+4+4+26] = (int32_t)((rotation>>8) & 0xFF); _packetBuffer[12+_cBBO+4+4+27] = (int32_t)(rotation & 0xFF); _finishCommandPacket(); } /** * Set Key DVE; Border Enabled * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderEnabled Bit 0: On/Off */ void ATEMstd::setKeyDVEBorderEnabled(uint8_t mE, uint8_t keyer, bool borderEnabled) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 32 _packetBuffer[12+_cBBO+4+4+3] |= 32; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+28] = borderEnabled; _finishCommandPacket(); } /** * Set Key DVE; Shadow * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * shadow Bit 0: On/Off */ void ATEMstd::setKeyDVEShadow(uint8_t mE, uint8_t keyer, bool shadow) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 64 _packetBuffer[12+_cBBO+4+4+3] |= 64; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+29] = shadow; _finishCommandPacket(); } /** * Set Key DVE; Border Bevel * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderBevel 0: No, 1: In/Out, 2: In, 3: Out */ void ATEMstd::setKeyDVEBorderBevel(uint8_t mE, uint8_t keyer, uint8_t borderBevel) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 128 _packetBuffer[12+_cBBO+4+4+3] |= 128; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+30] = borderBevel; _finishCommandPacket(); } /** * Set Key DVE; Border Outer Width * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderOuterWidth 0-1600: 0-16.00 */ void ATEMstd::setKeyDVEBorderOuterWidth(uint8_t mE, uint8_t keyer, uint16_t borderOuterWidth) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 256 _packetBuffer[12+_cBBO+4+4+2] |= 1; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+32] = highByte(borderOuterWidth); _packetBuffer[12+_cBBO+4+4+33] = lowByte(borderOuterWidth); _finishCommandPacket(); } /** * Set Key DVE; Border Inner Width * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderInnerWidth 0-1600: 0-16.00 */ void ATEMstd::setKeyDVEBorderInnerWidth(uint8_t mE, uint8_t keyer, uint16_t borderInnerWidth) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 512 _packetBuffer[12+_cBBO+4+4+2] |= 2; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+34] = highByte(borderInnerWidth); _packetBuffer[12+_cBBO+4+4+35] = lowByte(borderInnerWidth); _finishCommandPacket(); } /** * Set Key DVE; Border Outer Softness * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderOuterSoftness 0-100: 0-100% */ void ATEMstd::setKeyDVEBorderOuterSoftness(uint8_t mE, uint8_t keyer, uint8_t borderOuterSoftness) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 1024 _packetBuffer[12+_cBBO+4+4+2] |= 4; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+36] = borderOuterSoftness; _finishCommandPacket(); } /** * Set Key DVE; Border Inner Softness * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderInnerSoftness 0-100: 0-100% */ void ATEMstd::setKeyDVEBorderInnerSoftness(uint8_t mE, uint8_t keyer, uint8_t borderInnerSoftness) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 2048 _packetBuffer[12+_cBBO+4+4+2] |= 8; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+37] = borderInnerSoftness; _finishCommandPacket(); } /** * Set Key DVE; Border Bevel Softness * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderBevelSoftness 0-100: 0.0-1.0 */ void ATEMstd::setKeyDVEBorderBevelSoftness(uint8_t mE, uint8_t keyer, uint8_t borderBevelSoftness) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 4096 _packetBuffer[12+_cBBO+4+4+2] |= 16; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+38] = borderBevelSoftness; _finishCommandPacket(); } /** * Set Key DVE; Border Bevel Position * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderBevelPosition 0-100: 0.0-1.0 */ void ATEMstd::setKeyDVEBorderBevelPosition(uint8_t mE, uint8_t keyer, uint8_t borderBevelPosition) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 8192 _packetBuffer[12+_cBBO+4+4+2] |= 32; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+39] = borderBevelPosition; _finishCommandPacket(); } /** * Set Key DVE; Border Opacity * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderOpacity 0-100: 0-100% */ void ATEMstd::setKeyDVEBorderOpacity(uint8_t mE, uint8_t keyer, uint8_t borderOpacity) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 16384 _packetBuffer[12+_cBBO+4+4+2] |= 64; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+40] = borderOpacity; _finishCommandPacket(); } /** * Set Key DVE; Border Hue * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderHue 0-3599: 0-359.9 Degrees */ void ATEMstd::setKeyDVEBorderHue(uint8_t mE, uint8_t keyer, uint16_t borderHue) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 32768 _packetBuffer[12+_cBBO+4+4+2] |= 128; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+42] = highByte(borderHue); _packetBuffer[12+_cBBO+4+4+43] = lowByte(borderHue); _finishCommandPacket(); } /** * Set Key DVE; Border Saturation * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderSaturation 0-1000: 0-100% */ void ATEMstd::setKeyDVEBorderSaturation(uint8_t mE, uint8_t keyer, uint16_t borderSaturation) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 65536 _packetBuffer[12+_cBBO+4+4+1] |= 1; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+44] = highByte(borderSaturation); _packetBuffer[12+_cBBO+4+4+45] = lowByte(borderSaturation); _finishCommandPacket(); } /** * Set Key DVE; Border Luma * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * borderLuma 0-1000: 0-100% */ void ATEMstd::setKeyDVEBorderLuma(uint8_t mE, uint8_t keyer, uint16_t borderLuma) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 131072 _packetBuffer[12+_cBBO+4+4+1] |= 2; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+46] = highByte(borderLuma); _packetBuffer[12+_cBBO+4+4+47] = lowByte(borderLuma); _finishCommandPacket(); } /** * Set Key DVE; Light Source Direction * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * lightSourceDirection 0-3590: 0-359 Degrees */ void ATEMstd::setKeyDVELightSourceDirection(uint8_t mE, uint8_t keyer, uint16_t lightSourceDirection) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 262144 _packetBuffer[12+_cBBO+4+4+1] |= 4; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+48] = highByte(lightSourceDirection); _packetBuffer[12+_cBBO+4+4+49] = lowByte(lightSourceDirection); _finishCommandPacket(); } /** * Set Key DVE; Light Source Altitude * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * lightSourceAltitude 10-100: 10-100 */ void ATEMstd::setKeyDVELightSourceAltitude(uint8_t mE, uint8_t keyer, uint8_t lightSourceAltitude) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 524288 _packetBuffer[12+_cBBO+4+4+1] |= 8; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+50] = lightSourceAltitude; _finishCommandPacket(); } /** * Set Key DVE; Masked * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * masked Bit 0: On/Off */ void ATEMstd::setKeyDVEMasked(uint8_t mE, uint8_t keyer, bool masked) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 1048576 _packetBuffer[12+_cBBO+4+4+1] |= 16; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+51] = masked; _finishCommandPacket(); } /** * Set Key DVE; Top * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * top -9000-9000: -9.00-9.00 */ void ATEMstd::setKeyDVETop(uint8_t mE, uint8_t keyer, int16_t top) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 2097152 _packetBuffer[12+_cBBO+4+4+1] |= 32; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+52] = highByte(top); _packetBuffer[12+_cBBO+4+4+53] = lowByte(top); _finishCommandPacket(); } /** * Set Key DVE; Bottom * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * bottom -9000-9000: -9.00-9.00 */ void ATEMstd::setKeyDVEBottom(uint8_t mE, uint8_t keyer, int16_t bottom) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 4194304 _packetBuffer[12+_cBBO+4+4+1] |= 64; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+54] = highByte(bottom); _packetBuffer[12+_cBBO+4+4+55] = lowByte(bottom); _finishCommandPacket(); } /** * Set Key DVE; Left * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * left -16000-16000: -9.00-9.00 */ void ATEMstd::setKeyDVELeft(uint8_t mE, uint8_t keyer, int16_t left) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 8388608 _packetBuffer[12+_cBBO+4+4+1] |= 128; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+56] = highByte(left); _packetBuffer[12+_cBBO+4+4+57] = lowByte(left); _finishCommandPacket(); } /** * Set Key DVE; Right * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * right -16000-16000: -9.00-9.00 */ void ATEMstd::setKeyDVERight(uint8_t mE, uint8_t keyer, int16_t right) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 16777216 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+58] = highByte(right); _packetBuffer[12+_cBBO+4+4+59] = lowByte(right); _finishCommandPacket(); } /** * Set Key DVE; Rate * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * rate 1-250: Frames */ void ATEMstd::setKeyDVERate(uint8_t mE, uint8_t keyer, uint8_t rate) { _prepareCommandPacket(PSTR("CKDV"),64,(_packetBuffer[12+_cBBO+4+4+4]==mE) && (_packetBuffer[12+_cBBO+4+4+5]==keyer)); // Set Mask: 33554432 _packetBuffer[12+_cBBO+4+4+0] |= 2; _packetBuffer[12+_cBBO+4+4+4] = mE; _packetBuffer[12+_cBBO+4+4+5] = keyer; _packetBuffer[12+_cBBO+4+4+60] = rate; _finishCommandPacket(); } /** * Set Run Flying Key; Key Frame * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * keyFrame 1: A, 2: B, 3: Full, 4: Run-To-Infinite */ void ATEMstd::setRunFlyingKeyKeyFrame(uint8_t mE, uint8_t keyer, uint8_t keyFrame) { _prepareCommandPacket(PSTR("RFlK"),8,(_packetBuffer[12+_cBBO+4+4+1]==mE) && (_packetBuffer[12+_cBBO+4+4+2]==keyer)); _packetBuffer[12+_cBBO+4+4+1] = mE; _packetBuffer[12+_cBBO+4+4+2] = keyer; _packetBuffer[12+_cBBO+4+4+4] = keyFrame; _finishCommandPacket(); } /** * Set Run Flying Key; Run-to-Infinite-index * mE 0: ME1, 1: ME2 * keyer 0-3: Keyer 1-4 * runtoInfiniteindex */ void ATEMstd::setRunFlyingKeyRuntoInfiniteindex(uint8_t mE, uint8_t keyer, uint8_t runtoInfiniteindex) { _prepareCommandPacket(PSTR("RFlK"),8,(_packetBuffer[12+_cBBO+4+4+1]==mE) && (_packetBuffer[12+_cBBO+4+4+2]==keyer)); // Set Mask: 2 _packetBuffer[12+_cBBO+4+4+0] |= 2; _packetBuffer[12+_cBBO+4+4+1] = mE; _packetBuffer[12+_cBBO+4+4+2] = keyer; _packetBuffer[12+_cBBO+4+4+5] = runtoInfiniteindex; _finishCommandPacket(); } /** * Set Downstream Keyer; Fill Source * keyer 0-3: Keyer 1-4 * fillSource (See video source list) */ void ATEMstd::setDownstreamKeyerFillSource(uint8_t keyer, uint16_t fillSource) { _prepareCommandPacket(PSTR("CDsF"),4,(_packetBuffer[12+_cBBO+4+4+0]==keyer)); _packetBuffer[12+_cBBO+4+4+0] = keyer; _packetBuffer[12+_cBBO+4+4+2] = highByte(fillSource); _packetBuffer[12+_cBBO+4+4+3] = lowByte(fillSource); _finishCommandPacket(); } /** * Set Downstream Keyer; Key Source * keyer 0-3: Keyer 1-4 * keySource (See video source list) */ void ATEMstd::setDownstreamKeyerKeySource(uint8_t keyer, uint16_t keySource) { _prepareCommandPacket(PSTR("CDsC"),4,(_packetBuffer[12+_cBBO+4+4+0]==keyer)); _packetBuffer[12+_cBBO+4+4+0] = keyer; _packetBuffer[12+_cBBO+4+4+2] = highByte(keySource); _packetBuffer[12+_cBBO+4+4+3] = lowByte(keySource); _finishCommandPacket(); } /** * Get Downstream Keyer; Tie * keyer 0: DSK1, 1: DSK2 */ bool ATEMstd::getDownstreamKeyerTie(uint8_t keyer) { return atemDownstreamKeyerTie[keyer]; } /** * Get Downstream Keyer; Rate * keyer 0: DSK1, 1: DSK2 */ uint8_t ATEMstd::getDownstreamKeyerRate(uint8_t keyer) { return atemDownstreamKeyerRate[keyer]; } /** * Get Downstream Keyer; Pre Multiplied * keyer 0: DSK1, 1: DSK2 */ bool ATEMstd::getDownstreamKeyerPreMultiplied(uint8_t keyer) { return atemDownstreamKeyerPreMultiplied[keyer]; } /** * Get Downstream Keyer; Clip * keyer 0: DSK1, 1: DSK2 */ uint16_t ATEMstd::getDownstreamKeyerClip(uint8_t keyer) { return atemDownstreamKeyerClip[keyer]; } /** * Get Downstream Keyer; Gain * keyer 0: DSK1, 1: DSK2 */ uint16_t ATEMstd::getDownstreamKeyerGain(uint8_t keyer) { return atemDownstreamKeyerGain[keyer]; } /** * Get Downstream Keyer; Invert Key * keyer 0: DSK1, 1: DSK2 */ bool ATEMstd::getDownstreamKeyerInvertKey(uint8_t keyer) { return atemDownstreamKeyerInvertKey[keyer]; } /** * Get Downstream Keyer; Masked * keyer 0: DSK1, 1: DSK2 */ bool ATEMstd::getDownstreamKeyerMasked(uint8_t keyer) { return atemDownstreamKeyerMasked[keyer]; } /** * Get Downstream Keyer; Top * keyer 0: DSK1, 1: DSK2 */ int16_t ATEMstd::getDownstreamKeyerTop(uint8_t keyer) { return atemDownstreamKeyerTop[keyer]; } /** * Get Downstream Keyer; Bottom * keyer 0: DSK1, 1: DSK2 */ int16_t ATEMstd::getDownstreamKeyerBottom(uint8_t keyer) { return atemDownstreamKeyerBottom[keyer]; } /** * Get Downstream Keyer; Left * keyer 0: DSK1, 1: DSK2 */ int16_t ATEMstd::getDownstreamKeyerLeft(uint8_t keyer) { return atemDownstreamKeyerLeft[keyer]; } /** * Get Downstream Keyer; Right * keyer 0: DSK1, 1: DSK2 */ int16_t ATEMstd::getDownstreamKeyerRight(uint8_t keyer) { return atemDownstreamKeyerRight[keyer]; } /** * Set Downstream Keyer; Tie * keyer 0: DSK1, 1: DSK2 * tie Bit 0: On/Off */ void ATEMstd::setDownstreamKeyerTie(uint8_t keyer, bool tie) { _prepareCommandPacket(PSTR("CDsT"),4,(_packetBuffer[12+_cBBO+4+4+0]==keyer)); _packetBuffer[12+_cBBO+4+4+0] = keyer; _packetBuffer[12+_cBBO+4+4+1] = tie; _finishCommandPacket(); } /** * Set Downstream Keyer; Pre Multiplied * keyer 0-3: Keyer 1-4 * preMultiplied Bit 0: On/Off */ void ATEMstd::setDownstreamKeyerPreMultiplied(uint8_t keyer, bool preMultiplied) { _prepareCommandPacket(PSTR("CDsG"),12,(_packetBuffer[12+_cBBO+4+4+1]==keyer)); // Set Mask: 1 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+1] = keyer; _packetBuffer[12+_cBBO+4+4+2] = preMultiplied; _finishCommandPacket(); } /** * Set Downstream Keyer; Clip * keyer 0-3: Keyer 1-4 * clip 0-1000: 0-100% */ void ATEMstd::setDownstreamKeyerClip(uint8_t keyer, uint16_t clip) { _prepareCommandPacket(PSTR("CDsG"),12,(_packetBuffer[12+_cBBO+4+4+1]==keyer)); // Set Mask: 2 _packetBuffer[12+_cBBO+4+4+0] |= 2; _packetBuffer[12+_cBBO+4+4+1] = keyer; _packetBuffer[12+_cBBO+4+4+4] = highByte(clip); _packetBuffer[12+_cBBO+4+4+5] = lowByte(clip); _finishCommandPacket(); } /** * Set Downstream Keyer; Gain * keyer 0-3: Keyer 1-4 * gain 0-1000: 0-100% */ void ATEMstd::setDownstreamKeyerGain(uint8_t keyer, uint16_t gain) { _prepareCommandPacket(PSTR("CDsG"),12,(_packetBuffer[12+_cBBO+4+4+1]==keyer)); // Set Mask: 4 _packetBuffer[12+_cBBO+4+4+0] |= 4; _packetBuffer[12+_cBBO+4+4+1] = keyer; _packetBuffer[12+_cBBO+4+4+6] = highByte(gain); _packetBuffer[12+_cBBO+4+4+7] = lowByte(gain); _finishCommandPacket(); } /** * Set Downstream Keyer; Invert Key(??) * keyer 0-3: Keyer 1-4 * invertKey Bit 0: On/Off */ void ATEMstd::setDownstreamKeyerInvertKey(uint8_t keyer, bool invertKey) { _prepareCommandPacket(PSTR("CDsG"),12,(_packetBuffer[12+_cBBO+4+4+1]==keyer)); // Set Mask: 8 _packetBuffer[12+_cBBO+4+4+0] |= 8; _packetBuffer[12+_cBBO+4+4+1] = keyer; _packetBuffer[12+_cBBO+4+4+8] = invertKey; _finishCommandPacket(); } /** * Set Downstream Keyer; Masked * keyer 0-3: Keyer 1-4 * masked Bit 0: On/Off */ void ATEMstd::setDownstreamKeyerMasked(uint8_t keyer, bool masked) { _prepareCommandPacket(PSTR("CDsM"),12,(_packetBuffer[12+_cBBO+4+4+1]==keyer)); // Set Mask: 1 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+1] = keyer; _packetBuffer[12+_cBBO+4+4+2] = masked; _finishCommandPacket(); } /** * Set Downstream Keyer; Top * keyer 0-3: Keyer 1-4 * top -9000-9000: -9.00-9.00 */ void ATEMstd::setDownstreamKeyerTop(uint8_t keyer, int16_t top) { _prepareCommandPacket(PSTR("CDsM"),12,(_packetBuffer[12+_cBBO+4+4+1]==keyer)); // Set Mask: 2 _packetBuffer[12+_cBBO+4+4+0] |= 2; _packetBuffer[12+_cBBO+4+4+1] = keyer; _packetBuffer[12+_cBBO+4+4+4] = highByte(top); _packetBuffer[12+_cBBO+4+4+5] = lowByte(top); _finishCommandPacket(); } /** * Set Downstream Keyer; Bottom * keyer 0-3: Keyer 1-4 * bottom -9000-9000: -9.00-9.00 */ void ATEMstd::setDownstreamKeyerBottom(uint8_t keyer, int16_t bottom) { _prepareCommandPacket(PSTR("CDsM"),12,(_packetBuffer[12+_cBBO+4+4+1]==keyer)); // Set Mask: 4 _packetBuffer[12+_cBBO+4+4+0] |= 4; _packetBuffer[12+_cBBO+4+4+1] = keyer; _packetBuffer[12+_cBBO+4+4+6] = highByte(bottom); _packetBuffer[12+_cBBO+4+4+7] = lowByte(bottom); _finishCommandPacket(); } /** * Set Downstream Keyer; Left * keyer 0-3: Keyer 1-4 * left -16000-16000: -9.00-9.00 */ void ATEMstd::setDownstreamKeyerLeft(uint8_t keyer, int16_t left) { _prepareCommandPacket(PSTR("CDsM"),12,(_packetBuffer[12+_cBBO+4+4+1]==keyer)); // Set Mask: 8 _packetBuffer[12+_cBBO+4+4+0] |= 8; _packetBuffer[12+_cBBO+4+4+1] = keyer; _packetBuffer[12+_cBBO+4+4+8] = highByte(left); _packetBuffer[12+_cBBO+4+4+9] = lowByte(left); _finishCommandPacket(); } /** * Set Downstream Keyer; Right * keyer 0-3: Keyer 1-4 * right -16000-16000: -9.00-9.00 */ void ATEMstd::setDownstreamKeyerRight(uint8_t keyer, int16_t right) { _prepareCommandPacket(PSTR("CDsM"),12,(_packetBuffer[12+_cBBO+4+4+1]==keyer)); // Set Mask: 16 _packetBuffer[12+_cBBO+4+4+0] |= 16; _packetBuffer[12+_cBBO+4+4+1] = keyer; _packetBuffer[12+_cBBO+4+4+10] = highByte(right); _packetBuffer[12+_cBBO+4+4+11] = lowByte(right); _finishCommandPacket(); } /** * Set Downstream Keyer Auto; Keyer * keyer 0: DSK1, 1: DSK2 */ void ATEMstd::performDownstreamKeyerAutoKeyer(uint8_t keyer) { _prepareCommandPacket(PSTR("DDsA"),4); _packetBuffer[12+_cBBO+4+4+0] = keyer; _finishCommandPacket(); } /** * Get Downstream Keyer; On Air * keyer 0: DSK1, 1: DSK2 */ bool ATEMstd::getDownstreamKeyerOnAir(uint8_t keyer) { return atemDownstreamKeyerOnAir[keyer]; } /** * Get Downstream Keyer; In Transition * keyer 0: DSK1, 1: DSK2 */ bool ATEMstd::getDownstreamKeyerInTransition(uint8_t keyer) { return atemDownstreamKeyerInTransition[keyer]; } /** * Get Downstream Keyer; Is Auto Transitioning * keyer 0: DSK1, 1: DSK2 */ bool ATEMstd::getDownstreamKeyerIsAutoTransitioning(uint8_t keyer) { return atemDownstreamKeyerIsAutoTransitioning[keyer]; } /** * Get Downstream Keyer; Frames Remaining * keyer 0: DSK1, 1: DSK2 */ uint8_t ATEMstd::getDownstreamKeyerFramesRemaining(uint8_t keyer) { return atemDownstreamKeyerFramesRemaining[keyer]; } /** * Set Downstream Keyer; On Air * keyer 0: DSK1, 1: DSK2 * onAir Bit 0: On/Off */ void ATEMstd::setDownstreamKeyerOnAir(uint8_t keyer, bool onAir) { _prepareCommandPacket(PSTR("CDsL"),4,(_packetBuffer[12+_cBBO+4+4+0]==keyer)); _packetBuffer[12+_cBBO+4+4+0] = keyer; _packetBuffer[12+_cBBO+4+4+1] = onAir; _finishCommandPacket(); } /** * Get Fade-To-Black; Rate * mE 0: ME1, 1: ME2 */ uint8_t ATEMstd::getFadeToBlackRate(uint8_t mE) { return atemFadeToBlackRate[mE]; } /** * Set Fade-To-Black; Rate * mE 0: ME1, 1: ME2 * rate 1-250: Frames */ void ATEMstd::setFadeToBlackRate(uint8_t mE, uint8_t rate) { _prepareCommandPacket(PSTR("FtbC"),4,(_packetBuffer[12+_cBBO+4+4+1]==mE)); // Set Mask: 1 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+1] = mE; _packetBuffer[12+_cBBO+4+4+2] = rate; _finishCommandPacket(); } /** * Get Fade-To-Black State; Fully Black * mE 0: ME1, 1: ME2 */ bool ATEMstd::getFadeToBlackStateFullyBlack(uint8_t mE) { return atemFadeToBlackStateFullyBlack[mE]; } /** * Get Fade-To-Black State; In Transition * mE 0: ME1, 1: ME2 */ bool ATEMstd::getFadeToBlackStateInTransition(uint8_t mE) { return atemFadeToBlackStateInTransition[mE]; } /** * Get Fade-To-Black State; Frames Remaining * mE 0: ME1, 1: ME2 */ uint8_t ATEMstd::getFadeToBlackStateFramesRemaining(uint8_t mE) { return atemFadeToBlackStateFramesRemaining[mE]; } /** * Set Fade-To-Black; M/E * mE 0: ME1, 1: ME2 */ void ATEMstd::performFadeToBlackME(uint8_t mE) { _prepareCommandPacket(PSTR("FtbA"),4); _packetBuffer[12+_cBBO+4+4+0] = mE; _packetBuffer[12+_cBBO+4+4+1] = 0x02; _finishCommandPacket(); } /** * Set Color Generator; Hue * colorGenerator 0: Color Generator 1, 1: Color Generator 2 * hue 0-3599: 0-359.9 Degrees */ void ATEMstd::setColorGeneratorHue(uint8_t colorGenerator, uint16_t hue) { _prepareCommandPacket(PSTR("CClV"),8,(_packetBuffer[12+_cBBO+4+4+1]==colorGenerator)); // Set Mask: 1 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+1] = colorGenerator; _packetBuffer[12+_cBBO+4+4+2] = highByte(hue); _packetBuffer[12+_cBBO+4+4+3] = lowByte(hue); _finishCommandPacket(); } /** * Set Color Generator; Saturation * colorGenerator 0: Color Generator 1, 1: Color Generator 2 * saturation 0-1000: 0-100.0% */ void ATEMstd::setColorGeneratorSaturation(uint8_t colorGenerator, uint16_t saturation) { _prepareCommandPacket(PSTR("CClV"),8,(_packetBuffer[12+_cBBO+4+4+1]==colorGenerator)); // Set Mask: 2 _packetBuffer[12+_cBBO+4+4+0] |= 2; _packetBuffer[12+_cBBO+4+4+1] = colorGenerator; _packetBuffer[12+_cBBO+4+4+4] = highByte(saturation); _packetBuffer[12+_cBBO+4+4+5] = lowByte(saturation); _finishCommandPacket(); } /** * Set Color Generator; Luma * colorGenerator 0: Color Generator 1, 1: Color Generator 2 * luma 0-1000: 0-100.0% */ void ATEMstd::setColorGeneratorLuma(uint8_t colorGenerator, uint16_t luma) { _prepareCommandPacket(PSTR("CClV"),8,(_packetBuffer[12+_cBBO+4+4+1]==colorGenerator)); // Set Mask: 4 _packetBuffer[12+_cBBO+4+4+0] |= 4; _packetBuffer[12+_cBBO+4+4+1] = colorGenerator; _packetBuffer[12+_cBBO+4+4+6] = highByte(luma); _packetBuffer[12+_cBBO+4+4+7] = lowByte(luma); _finishCommandPacket(); } /** * Get Aux Source; Input * aUXChannel 0-5: Aux 1-6 */ uint16_t ATEMstd::getAuxSourceInput(uint8_t aUXChannel) { return atemAuxSourceInput[aUXChannel]; } /** * Set Aux Source; Input * aUXChannel 0-5: Aux 1-6 * input (See video source list) */ void ATEMstd::setAuxSourceInput(uint8_t aUXChannel, uint16_t input) { _prepareCommandPacket(PSTR("CAuS"),4,(_packetBuffer[12+_cBBO+4+4+1]==aUXChannel)); // Set Mask: 1 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+1] = aUXChannel; _packetBuffer[12+_cBBO+4+4+2] = highByte(input); _packetBuffer[12+_cBBO+4+4+3] = lowByte(input); _finishCommandPacket(); } /** * Set Clip Player; Playing * mediaPlayer 0: Media Player 1, 1: Media Player 2 * playing Bit 0: On/Off */ void ATEMstd::setClipPlayerPlaying(uint8_t mediaPlayer, bool playing) { _prepareCommandPacket(PSTR("SCPS"),8,(_packetBuffer[12+_cBBO+4+4+1]==mediaPlayer)); // Set Mask: 1 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+1] = mediaPlayer; _packetBuffer[12+_cBBO+4+4+2] = playing; _finishCommandPacket(); } /** * Set Clip Player; Loop * mediaPlayer 0: Media Player 1, 1: Media Player 2 * loop Bit 0: On/Off */ void ATEMstd::setClipPlayerLoop(uint8_t mediaPlayer, bool loop) { _prepareCommandPacket(PSTR("SCPS"),8,(_packetBuffer[12+_cBBO+4+4+1]==mediaPlayer)); // Set Mask: 2 _packetBuffer[12+_cBBO+4+4+0] |= 2; _packetBuffer[12+_cBBO+4+4+1] = mediaPlayer; _packetBuffer[12+_cBBO+4+4+3] = loop; _finishCommandPacket(); } /** * Set Clip Player; At Beginning * mediaPlayer 0: Media Player 1, 1: Media Player 2 * atBeginning Bit 0: On/Off */ void ATEMstd::setClipPlayerAtBeginning(uint8_t mediaPlayer, bool atBeginning) { _prepareCommandPacket(PSTR("SCPS"),8,(_packetBuffer[12+_cBBO+4+4+1]==mediaPlayer)); // Set Mask: 4 _packetBuffer[12+_cBBO+4+4+0] |= 4; _packetBuffer[12+_cBBO+4+4+1] = mediaPlayer; _packetBuffer[12+_cBBO+4+4+4] = atBeginning; _finishCommandPacket(); } /** * Set Clip Player; Clip Frame * mediaPlayer 0: Media Player 1, 1: Media Player 2 * clipFrame */ void ATEMstd::setClipPlayerClipFrame(uint8_t mediaPlayer, uint16_t clipFrame) { _prepareCommandPacket(PSTR("SCPS"),8,(_packetBuffer[12+_cBBO+4+4+1]==mediaPlayer)); // Set Mask: 8 _packetBuffer[12+_cBBO+4+4+0] |= 8; _packetBuffer[12+_cBBO+4+4+1] = mediaPlayer; _packetBuffer[12+_cBBO+4+4+6] = highByte(clipFrame); _packetBuffer[12+_cBBO+4+4+7] = lowByte(clipFrame); _finishCommandPacket(); } /** * Get Media Player Source; Type * mediaPlayer 0: Media Player 1, 1: Media Player 2 */ uint8_t ATEMstd::getMediaPlayerSourceType(uint8_t mediaPlayer) { return atemMediaPlayerSourceType[mediaPlayer]; } /** * Get Media Player Source; Still Index * mediaPlayer 0: Media Player 1, 1: Media Player 2 */ uint8_t ATEMstd::getMediaPlayerSourceStillIndex(uint8_t mediaPlayer) { return atemMediaPlayerSourceStillIndex[mediaPlayer]; } /** * Get Media Player Source; Clip Index * mediaPlayer 0: Media Player 1, 1: Media Player 2 */ uint8_t ATEMstd::getMediaPlayerSourceClipIndex(uint8_t mediaPlayer) { return atemMediaPlayerSourceClipIndex[mediaPlayer]; } /** * Set Media Player Source; Type * mediaPlayer 0: Media Player 1, 1: Media Player 2 * type 1: Still, 2: Clip */ void ATEMstd::setMediaPlayerSourceType(uint8_t mediaPlayer, uint8_t type) { _prepareCommandPacket(PSTR("MPSS"),8,(_packetBuffer[12+_cBBO+4+4+1]==mediaPlayer)); // Set Mask: 1 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+1] = mediaPlayer; _packetBuffer[12+_cBBO+4+4+2] = type; _finishCommandPacket(); } /** * Set Media Player Source; Still Index * mediaPlayer 0: Media Player 1, 1: Media Player 2 * stillIndex 0-x: Still 1-x */ void ATEMstd::setMediaPlayerSourceStillIndex(uint8_t mediaPlayer, uint8_t stillIndex) { _prepareCommandPacket(PSTR("MPSS"),8,(_packetBuffer[12+_cBBO+4+4+1]==mediaPlayer)); // Set Mask: 2 _packetBuffer[12+_cBBO+4+4+0] |= 2; _packetBuffer[12+_cBBO+4+4+1] = mediaPlayer; _packetBuffer[12+_cBBO+4+4+3] = stillIndex; _finishCommandPacket(); } /** * Set Media Player Source; Clip Index * mediaPlayer 0: Media Player 1, 1: Media Player 2 * clipIndex 0-x: Clip 1-x */ void ATEMstd::setMediaPlayerSourceClipIndex(uint8_t mediaPlayer, uint8_t clipIndex) { _prepareCommandPacket(PSTR("MPSS"),8,(_packetBuffer[12+_cBBO+4+4+1]==mediaPlayer)); // Set Mask: 4 _packetBuffer[12+_cBBO+4+4+0] |= 4; _packetBuffer[12+_cBBO+4+4+1] = mediaPlayer; _packetBuffer[12+_cBBO+4+4+4] = clipIndex; _finishCommandPacket(); } /** * Get Macro Run Status; State */ uint8_t ATEMstd::getMacroRunStatusState() { return atemMacroRunStatusState; } /** * Get Macro Run Status; Is Looping */ bool ATEMstd::getMacroRunStatusIsLooping() { return atemMacroRunStatusIsLooping; } /** * Get Macro Run Status; Index */ uint16_t ATEMstd::getMacroRunStatusIndex() { return atemMacroRunStatusIndex; } /** * Set Macro Action; Action * index 0-99: Macro Index Number. 0xFFFF: stop * action 0: Run Macro, 1: Stop (w/Index 0xFFFF), 2: Stop Recording (w/Index 0xFFFF), 3: Insert Wait for User (w/Index 0xFFFF), 4: Continue (w/Index 0xFFFF), 5: Delete Macro */ void ATEMstd::setMacroAction(uint16_t index, uint8_t action) { _prepareCommandPacket(PSTR("MAct"),4,(_packetBuffer[12+_cBBO+4+4+0]==highByte(index)) && (_packetBuffer[12+_cBBO+4+4+1]==lowByte(index))); _packetBuffer[12+_cBBO+4+4+0] = highByte(index); _packetBuffer[12+_cBBO+4+4+1] = lowByte(index); _packetBuffer[12+_cBBO+4+4+2] = action; _finishCommandPacket(); } /** * Get Macro Properties; Is Used * macroIndex 0-9: Macro Index Number */ bool ATEMstd::getMacroPropertiesIsUsed(uint8_t macroIndex) { return atemMacroPropertiesIsUsed[macroIndex]; } /** * Get Macro Properties; Name * macroIndex 0-9: Macro Index Number */ char * ATEMstd::getMacroPropertiesName(uint8_t macroIndex) { return atemMacroPropertiesName[macroIndex]; } /** * Set Macro Add Pause; Frames * frames Number of */ void ATEMstd::setMacroAddPauseFrames(uint16_t frames) { _prepareCommandPacket(PSTR("MSlp"),4); _packetBuffer[12+_cBBO+4+4+2] = highByte(frames); _packetBuffer[12+_cBBO+4+4+3] = lowByte(frames); _finishCommandPacket(); } /** * Get Macro Recording Status; Is Recording */ bool ATEMstd::getMacroRecordingStatusIsRecording() { return atemMacroRecordingStatusIsRecording; } /** * Get Macro Recording Status; Index */ uint16_t ATEMstd::getMacroRecordingStatusIndex() { return atemMacroRecordingStatusIndex; } /** * Get Audio Mixer Input; Mix Option * audioSource (See audio source list) */ uint8_t ATEMstd::getAudioMixerInputMixOption(uint16_t audioSource) { return atemAudioMixerInputMixOption[getAudioSrcIndex(audioSource)]; } /** * Get Audio Mixer Input; Volume * audioSource (See audio source list) */ uint16_t ATEMstd::getAudioMixerInputVolume(uint16_t audioSource) { return atemAudioMixerInputVolume[getAudioSrcIndex(audioSource)]; } /** * Get Audio Mixer Input; Balance * audioSource (See audio source list) */ int16_t ATEMstd::getAudioMixerInputBalance(uint16_t audioSource) { return atemAudioMixerInputBalance[getAudioSrcIndex(audioSource)]; } /** * Set Audio Mixer Input; Mix Option * audioSource (See audio source list) * mixOption 0: Off, 1: On, 2: AFV */ void ATEMstd::setAudioMixerInputMixOption(uint16_t audioSource, uint8_t mixOption) { _prepareCommandPacket(PSTR("CAMI"),12,(_packetBuffer[12+_cBBO+4+4+2]==highByte(audioSource)) && (_packetBuffer[12+_cBBO+4+4+3]==lowByte(audioSource))); // Set Mask: 1 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+2] = highByte(audioSource); _packetBuffer[12+_cBBO+4+4+3] = lowByte(audioSource); _packetBuffer[12+_cBBO+4+4+4] = mixOption; _finishCommandPacket(); } /** * Set Audio Mixer Input; Volume * audioSource (See audio source list) * volume 0-65381: (DB) */ void ATEMstd::setAudioMixerInputVolume(uint16_t audioSource, uint16_t volume) { _prepareCommandPacket(PSTR("CAMI"),12,(_packetBuffer[12+_cBBO+4+4+2]==highByte(audioSource)) && (_packetBuffer[12+_cBBO+4+4+3]==lowByte(audioSource))); // Set Mask: 2 _packetBuffer[12+_cBBO+4+4+0] |= 2; _packetBuffer[12+_cBBO+4+4+2] = highByte(audioSource); _packetBuffer[12+_cBBO+4+4+3] = lowByte(audioSource); _packetBuffer[12+_cBBO+4+4+6] = highByte(volume); _packetBuffer[12+_cBBO+4+4+7] = lowByte(volume); _finishCommandPacket(); } /** * Set Audio Mixer Input; Balance * audioSource (See audio source list) * balance -10000-10000: Left/Right Extremes */ void ATEMstd::setAudioMixerInputBalance(uint16_t audioSource, int16_t balance) { _prepareCommandPacket(PSTR("CAMI"),12,(_packetBuffer[12+_cBBO+4+4+2]==highByte(audioSource)) && (_packetBuffer[12+_cBBO+4+4+3]==lowByte(audioSource))); // Set Mask: 4 _packetBuffer[12+_cBBO+4+4+0] |= 4; _packetBuffer[12+_cBBO+4+4+2] = highByte(audioSource); _packetBuffer[12+_cBBO+4+4+3] = lowByte(audioSource); _packetBuffer[12+_cBBO+4+4+8] = highByte(balance); _packetBuffer[12+_cBBO+4+4+9] = lowByte(balance); _finishCommandPacket(); } /** * Set Audio Mixer Master; Volume * volume 0-65381: (DB) */ void ATEMstd::setAudioMixerMasterVolume(uint16_t volume) { _prepareCommandPacket(PSTR("CAMM"),8); // Set Mask: 1 _packetBuffer[12+_cBBO+4+4+0] |= 1; _packetBuffer[12+_cBBO+4+4+2] = highByte(volume); _packetBuffer[12+_cBBO+4+4+3] = lowByte(volume); _finishCommandPacket(); } /** * Set Audio Levels; Enable * enable Bit 0: On/Off */ void ATEMstd::setAudioLevelsEnable(bool enable) { _prepareCommandPacket(PSTR("SALN"),4); _packetBuffer[12+_cBBO+4+4+0] = enable; _finishCommandPacket(); } /** * Get Tally By Index; Sources */ uint16_t ATEMstd::getTallyByIndexSources() { return atemTallyByIndexSources; } /** * Get Tally By Index; Tally Flags * sources 0-20: Number of */ uint8_t ATEMstd::getTallyByIndexTallyFlags(uint16_t sources) { return atemTallyByIndexTallyFlags[sources]; }