The codebase to run the *spark d-fuser controller www.sparkav.co.uk/dvimixer
Dependencies: SPK-TVOne DMX DmxArtNet NetServicesMin OSC PinDetect mRotaryEncoder iniparser mbed spk_oled_ssd1305 filter
Diff: main.cpp
- Revision:
- 69:cd1c85de3e38
- Parent:
- 68:c26478f42ca4
- Child:
- 71:d6d0ff33cf5b
--- a/main.cpp Sat Jul 27 18:27:11 2013 +0000 +++ b/main.cpp Sat Jul 27 20:41:57 2013 +0000 @@ -45,6 +45,7 @@ * v26 - Tweaks: Network in works with hands-on controls, EDID Change message, Fit/Fill * v27 - Rework Keying UX, having current key saved in processor and loading in presets. * v28 - Network tweaks. Reads OSC and ArtNet network info from .ini + * v29 - Keying: Can change between Left over Right and Right over Left * vxx - TODO: Writes back to .ini on USB mass storage: keyer updates, comms, hdcp, edid internal/passthrough, ...? * vxx - TODO: EDID creation from resolution */ @@ -63,7 +64,7 @@ #include "DMX.h" #include "filter.h" -#define kSPKDFSoftwareVersion "28" +#define kSPKDFSoftwareVersion "29" // MBED PINS @@ -150,8 +151,9 @@ SPKMenu mixModeMenu; SPKMenu mixModeAdditiveMenu; SPKMenu mixModeUpdateKeyMenu; -enum { mixBlend, mixAdditive, mixKey }; -int mixKeyStartIndex = 1; // need this hard coded as mixBlend and mixAdditive are now combined into the same menu item +enum { mixBlend, mixAdditive, mixKeyLeft, mixKeyRight }; +int mixKeyPresetStartIndex = 100; // need this hard coded as mixBlend and mixAdditive are now combined into the same menu item +int mixKeyWindow = kTV1WindowIDA; // The window we've last used to key int mixMode = mixBlend; // Start with safe mix mode, and test to get out of it. Safe mode will work with inputs missing and without hold frames. int mixModeOld = mixMode; float fadeCurve = 0.0f; // 0 = "X", ie. as per blend, 1 = "/\", ie. as per additive <-- pictograms! @@ -474,52 +476,66 @@ return ok; } -void actionMixMode() +void actionMixMode(bool reset = false) { if (debug) debug->printf("Changing mix mode \r\n"); bool ok = true; string sentOK; - char sentMSGBuffer[kStringBufferLength]; + char* sentMSGBuffer = "Blend"; - // Set Keyer - if (mixMode != mixKey) - { - // Set Keyer Off. Quicker to set and fail than to test for on and then turn off - tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, false); - - if (mixMode == mixBlend) + if (mixMode == mixAdditive) + { + sentMSGBuffer = "Additive"; + + // First set B to what you'd expect for additive; it may be left at 100 if optimised blend mixing was previous mixmode. + ok = tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent); + // Then turn on Additive Mixing + if (tvOne.getProcessorType().version == 423) { - // Turn off Additive Mixing on output - if (tvOne.getProcessorType().version == 423) - { - ok = tvOne.command(0, kTV1WindowIDA, 0x298, 0); - } - snprintf(sentMSGBuffer, kStringBufferLength, "Blend"); + ok = ok && tvOne.command(0, kTV1WindowIDA, 0x298, 1); } - if (mixMode == mixAdditive) - { - // First set B to what you'd expect for additive; it may be left at 100 if optimised blend mixing was previous mixmode. - ok = tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent); - // Then turn on Additive Mixing - if (tvOne.getProcessorType().version == 423) - { - ok = ok && tvOne.command(0, kTV1WindowIDA, 0x298, 1); - } - snprintf(sentMSGBuffer, kStringBufferLength, "Additive"); - } } - else + if (mixModeOld == mixAdditive || reset) { // Turn off Additive Mixing on output if (tvOne.getProcessorType().version == 423) { ok = tvOne.command(0, kTV1WindowIDA, 0x298, 0); } + } + + if (mixMode == mixKeyLeft) + { + sentMSGBuffer = "Key L over R"; + // Turn on Keyer ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, true); + } + if (mixModeOld == mixKeyLeft || reset) + { + // Turn off Keyer + tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, false); + } + + if (mixMode == mixKeyRight) + { + sentMSGBuffer = "Key R over L"; - snprintf(sentMSGBuffer, kStringBufferLength, "Key L over R"); + // Turn on Keyer + ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustKeyerEnable, true); + + + // Set window B above window A + ok = ok && tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsLayerPriority, 0); + } + if (mixModeOld == mixKeyRight || reset) + { + // Turn off Keyer + tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustKeyerEnable, false); + + // Restore window positions + ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsLayerPriority, 0); } mixModeOld = mixMode; @@ -538,11 +554,13 @@ // Mix Mode bool mixModeNeedsAction = false; - bool additiveOn = false, keyerOn = false; + bool additiveOn = false, keyLeftOn = false, keyRightOn = false; + int windowAPriority = -1; - if (mixMode == mixBlend) { additiveOn = false; keyerOn = false;} - if (mixMode == mixAdditive) { additiveOn = true; keyerOn = false;} - if (mixMode >= mixKey) { additiveOn = false; keyerOn = true; } + if (mixMode == mixBlend) { additiveOn = false; keyLeftOn = false; keyRightOn = false; windowAPriority = 0;} + if (mixMode == mixAdditive) { additiveOn = true; keyLeftOn = false; keyRightOn = false; windowAPriority = 0;} + if (mixMode == mixKeyLeft) { additiveOn = false; keyLeftOn = true; keyRightOn = false; windowAPriority = 0;} + if (mixMode == mixKeyRight) { additiveOn = false; keyLeftOn = false; keyRightOn = true; windowAPriority = 1;} if (tvOne.getProcessorType().version == 423) { @@ -553,12 +571,20 @@ payload = -1; ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, payload); - if (payload != keyerOn) mixModeNeedsAction = true; + if (payload != keyLeftOn) mixModeNeedsAction = true; + + payload = -1; + ok = ok && tvOne.readCommand(0, kTV1WindowIDB, kTV1FunctionAdjustKeyerEnable, payload); + if (payload != keyRightOn) mixModeNeedsAction = true; + + payload = -1; + ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsLayerPriority, payload); + if (payload != windowAPriority) mixModeNeedsAction = true; if (ok && mixModeNeedsAction) { if (debug) debug->printf("Check TVOne Mix Status requiring mixMode action. mixMode: %i \r\n", mixMode); - actionMixMode(); + actionMixMode(true); } // Check Fade @@ -716,14 +742,15 @@ mixModeMenu.addMenuItem(SPKMenuItem("Blend", mixBlend)); } - mixModeMenu.addMenuItem(SPKMenuItem("Key: L over R", mixKey)); + mixModeMenu.addMenuItem(SPKMenuItem("Key: L over R", mixKeyLeft)); + mixModeMenu.addMenuItem(SPKMenuItem("Key: R over L", mixKeyRight)); mixModeMenu.addMenuItem(SPKMenuItem("Key: Tweak key values", &mixModeUpdateKeyMenu)); // Load in presets from settings. Index 0 is the "live" key read from TVOne, so we ignore here. if (settings.keyerSetCount() > 1) for (int i=1; i < settings.keyerSetCount(); i++) { - mixModeMenu.addMenuItem(SPKMenuItem("Key Preset: " + settings.keyerParamName(i), mixKey + i)); + mixModeMenu.addMenuItem(SPKMenuItem("Key Preset: " + settings.keyerParamName(i), mixKeyPresetStartIndex + i)); } mixModeMenu.addMenuItem(SPKMenuItem("Back to Main Menu", &mainMenu)); @@ -1005,26 +1032,29 @@ void mixModeUpdateKeyMenuHandler(int menuChange, bool action) { static int actionCount = 0; + static int state = 0; + + if (mixMode == mixKeyLeft) mixKeyWindow = kTV1WindowIDA; + if (mixMode == mixKeyRight) mixKeyWindow = kTV1WindowIDB; if (action) actionCount++; if (actionCount == 0) { settings.editingKeyerSetIndex = 0; - printf("about to load\r\n"); + bool ok; int minY, maxY, minU, maxU, minV, maxV; - ok = tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinY, minY); - ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxY, maxY); - ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinU, minU); - ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxU, maxU); - ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinV, minV); - ok = ok && tvOne.readCommand(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxV, maxV); + ok = tvOne.readCommand(0, mixKeyWindow, kTV1FunctionAdjustKeyerMinY, minY); + ok = ok && tvOne.readCommand(0, mixKeyWindow, kTV1FunctionAdjustKeyerMaxY, maxY); + ok = ok && tvOne.readCommand(0, mixKeyWindow, kTV1FunctionAdjustKeyerMinU, minU); + ok = ok && tvOne.readCommand(0, mixKeyWindow, kTV1FunctionAdjustKeyerMaxU, maxU); + ok = ok && tvOne.readCommand(0, mixKeyWindow, kTV1FunctionAdjustKeyerMinV, minV); + ok = ok && tvOne.readCommand(0, mixKeyWindow, kTV1FunctionAdjustKeyerMaxV, maxV); if (ok) { - printf("%u %u %u %u", minY, maxY, minU, maxU); settings.setEditingKeyerSetValue(SPKSettings::minY, minY); settings.setEditingKeyerSetValue(SPKSettings::maxY, maxY); settings.setEditingKeyerSetValue(SPKSettings::minU, minU); @@ -1042,6 +1072,44 @@ } if (actionCount == 1) { + state += menuChange; + + screen.clearBufferRow(kMenuLine1); + screen.clearBufferRow(kMenuLine2); + screen.textToBuffer("Tweak or start over?", kMenuLine1); + + char paramLine[kStringBufferLength]; + + if (state % 2) snprintf(paramLine, kStringBufferLength, "[%3i/%3i][%3i/%3i][%3i/%3i]", 0, + 255, + 0, + 255, + 0, + 255); + else snprintf(paramLine, kStringBufferLength, "[%3i/%3i][%3i/%3i][%3i/%3i]", settings.editingKeyerSetValue(SPKSettings::minY), + settings.editingKeyerSetValue(SPKSettings::maxY), + settings.editingKeyerSetValue(SPKSettings::minU), + settings.editingKeyerSetValue(SPKSettings::maxU), + settings.editingKeyerSetValue(SPKSettings::minV), + settings.editingKeyerSetValue(SPKSettings::maxV)); + screen.textToBuffer(paramLine, kMenuLine2); + } + if (actionCount == 2) + { + if (state % 2) + { + settings.setEditingKeyerSetValue(SPKSettings::minY,0); + settings.setEditingKeyerSetValue(SPKSettings::maxY,255); + settings.setEditingKeyerSetValue(SPKSettings::minU,0); + settings.setEditingKeyerSetValue(SPKSettings::maxU,255); + settings.setEditingKeyerSetValue(SPKSettings::minV,0); + settings.setEditingKeyerSetValue(SPKSettings::maxV,255); + } + + actionCount = 3; + } + if (actionCount == 3) + { int value = settings.editingKeyerSetValue(SPKSettings::maxY); value += menuChange; if (value < 0) value = 0; @@ -1056,9 +1124,9 @@ snprintf(paramLine, kStringBufferLength, "[ /%3i][ / ][ / ]", value); screen.textToBuffer(paramLine, kMenuLine2); - tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxY, value); + tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMaxY, value); } - else if (actionCount == 2) + else if (actionCount == 4) { int value = settings.editingKeyerSetValue(SPKSettings::minY); value += menuChange; @@ -1075,9 +1143,9 @@ settings.editingKeyerSetValue(SPKSettings::maxY)); screen.textToBuffer(paramLine, kMenuLine2); - tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinY, value); + tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMinY, value); } - else if (actionCount == 3) + else if (actionCount == 5) { int value = settings.editingKeyerSetValue(SPKSettings::maxU); value += menuChange; @@ -1095,9 +1163,9 @@ value); screen.textToBuffer(paramLine, kMenuLine2); - tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxU, value); + tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMaxU, value); } - else if (actionCount == 4) + else if (actionCount == 6) { int value = settings.editingKeyerSetValue(SPKSettings::minU); value += menuChange; @@ -1116,9 +1184,9 @@ settings.editingKeyerSetValue(SPKSettings::maxU)); screen.textToBuffer(paramLine, kMenuLine2); - tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinU, value); + tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMinU, value); } - else if (actionCount == 5) + else if (actionCount == 7) { int value = settings.editingKeyerSetValue(SPKSettings::maxV); value += menuChange; @@ -1138,9 +1206,9 @@ value); screen.textToBuffer(paramLine, kMenuLine2); - tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxV, value); + tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMaxV, value); } - else if (actionCount == 6) + else if (actionCount == 8) { int value = settings.editingKeyerSetValue(SPKSettings::minV); value += menuChange; @@ -1161,12 +1229,12 @@ settings.editingKeyerSetValue(SPKSettings::maxV)); screen.textToBuffer(paramLine, kMenuLine2); - tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinV, value); + tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMinV, value); } - else if (actionCount == 7) + else if (actionCount == 9) { // Save settings - tvOne.command(0, kTV1WindowIDA, kTV1FunctionPowerOnPresetStore, 1); + tvOne.command(0, mixKeyWindow, kTV1FunctionPowerOnPresetStore, 1); // Get back to menu actionCount = 0; @@ -1461,39 +1529,29 @@ { int mixModeMenuPayload = mixModeMenu.selectedItem().payload.command[0]; - if (mixModeMenuPayload == mixAdditive) + if (mixModeMenuPayload < mixKeyPresetStartIndex) { - // This will have been handled by the mixModeAdditiveMenuHandler - } - else if (mixModeMenuPayload == mixBlend) - { - mixMode = mixBlend; + mixMode = mixModeMenuPayload; - if (mixMode == mixModeOld) tvOneStatusMessage.addMessage("Blend already active", kTVOneStatusMessageHoldTime); + if (mixMode == mixModeOld) tvOneStatusMessage.addMessage("Already active", kTVOneStatusMessageHoldTime); } - else if (mixModeMenuPayload >= mixKey) - { - mixMode = mixKey; + else + { + int keySetIndex = mixModeMenuPayload - mixKeyPresetStartIndex; - int keySetIndex = mixModeMenuPayload - mixKey; - - if (keySetIndex > 0) + if (keySetIndex > 0) // Key set 0 is now the "live" set, we read from processor rather than write to it. { bool ok; - ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinY, settings.keyerParamSet(keySetIndex)[SPKSettings::minY]); - ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxY, settings.keyerParamSet(keySetIndex)[SPKSettings::maxY]); - ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinU, settings.keyerParamSet(keySetIndex)[SPKSettings::minU]); - ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxU, settings.keyerParamSet(keySetIndex)[SPKSettings::maxU]); - ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinV, settings.keyerParamSet(keySetIndex)[SPKSettings::minV]); - ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxV, settings.keyerParamSet(keySetIndex)[SPKSettings::maxV]); + ok = tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMinY, settings.keyerParamSet(keySetIndex)[SPKSettings::minY]); + ok = ok && tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMaxY, settings.keyerParamSet(keySetIndex)[SPKSettings::maxY]); + ok = ok && tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMinU, settings.keyerParamSet(keySetIndex)[SPKSettings::minU]); + ok = ok && tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMaxU, settings.keyerParamSet(keySetIndex)[SPKSettings::maxU]); + ok = ok && tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMinV, settings.keyerParamSet(keySetIndex)[SPKSettings::minV]); + ok = ok && tvOne.command(0, mixKeyWindow, kTV1FunctionAdjustKeyerMaxV, settings.keyerParamSet(keySetIndex)[SPKSettings::maxV]); tvOne.command(0, kTV1WindowIDA, kTV1FunctionPowerOnPresetStore, 1); - tvOneStatusMessage.addMessage(ok ? "Activated: " + settings.keyerParamName(keySetIndex) + " values" : "Send error: keyer values", kTVOneStatusMessageHoldTime); - } - else - { - if (mixMode == mixModeOld) tvOneStatusMessage.addMessage("Keying already active", kTVOneStatusMessageHoldTime); + tvOneStatusMessage.addMessage(ok ? "Loaded: " + settings.keyerParamName(keySetIndex) + " values" : "Send error: keyer values", kTVOneStatusMessageHoldTime, kTVOneStatusMessageHoldTime); } } } @@ -1813,11 +1871,16 @@ newFadeAPercent = newFadeA * fadeUp * 100.0; newFadeBPercent = newFadeB * fadeUp * 100.0; } - else if (mixMode >= mixKeyStartIndex) + else if (mixMode == mixKeyLeft) { newFadeAPercent = (1.0-xFade) * fadeUp * 100.0; newFadeBPercent = fadeUp * 100.0; - } + } + else if (mixMode == mixKeyRight) + { + newFadeAPercent = fadeUp * 100.0; + newFadeBPercent = xFade * fadeUp * 100.0; + } //// TASK: Send to TVOne if percents have changed