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

Committer:
tobyspark
Date:
Sat Mar 10 19:26:44 2012 +0000
Revision:
0:87aab40d5806
Child:
1:f9fca21102e0
v15 - PCB a la toby; OLED a la toby

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tobyspark 0:87aab40d5806 1 // *SPARK D-FUSER
tobyspark 0:87aab40d5806 2 // A project by *spark audio-visual
tobyspark 0:87aab40d5806 3 //
tobyspark 0:87aab40d5806 4 // 'DJ' controller styke RS232 Control for TV-One products
tobyspark 0:87aab40d5806 5 // Good for 1T-C2-750, others will need some extra work
tobyspark 0:87aab40d5806 6 //
tobyspark 0:87aab40d5806 7 // Copyright *spark audio-visual 2009-2011
tobyspark 0:87aab40d5806 8 //
tobyspark 0:87aab40d5806 9 // v10 - Port to mBed, keying redux - Apr'11
tobyspark 0:87aab40d5806 10 // v11 - Sign callbacks, code clean-up - Apr'11
tobyspark 0:87aab40d5806 11 // v12 - TVOne header split into two: defines and mbed class. v002 header updates pulled down. Removed sign callbacks, rewrite of debug and signing. - Apr'11
tobyspark 0:87aab40d5806 12 // v13 - Menu system for Resolution + Keying implemented, it writing to debug, it sending TVOne commands - Apr'11
tobyspark 0:87aab40d5806 13 // v14 - Fixes for new PCB - Oct'11
tobyspark 0:87aab40d5806 14 // v15 - TBZ PCB, OLED - Mar'12
tobyspark 0:87aab40d5806 15 // v16 - TODO: EDID upload from USB mass storage
tobyspark 0:87aab40d5806 16 // v17 - TODO: EDID creation from resolution
tobyspark 0:87aab40d5806 17
tobyspark 0:87aab40d5806 18 // !! AIN on own thread doing some kind of low pass / median filter? ie. take average of two most similar values from last three
tobyspark 0:87aab40d5806 19
tobyspark 0:87aab40d5806 20 #include "mbed.h"
tobyspark 0:87aab40d5806 21
tobyspark 0:87aab40d5806 22 #include "spk_tvone_mbed.h"
tobyspark 0:87aab40d5806 23 #include "spk_utils.h"
tobyspark 0:87aab40d5806 24 #include "spk_mRotaryEncoder.h"
tobyspark 0:87aab40d5806 25 #include "spk_oled_ssd1305.h"
tobyspark 0:87aab40d5806 26
tobyspark 0:87aab40d5806 27 #include <sstream>
tobyspark 0:87aab40d5806 28
tobyspark 0:87aab40d5806 29 #define kMenuLine1 4
tobyspark 0:87aab40d5806 30 #define kMenuLine2 5
tobyspark 0:87aab40d5806 31 #define kStatusLine 7
tobyspark 0:87aab40d5806 32
tobyspark 0:87aab40d5806 33 //// DEBUG
tobyspark 0:87aab40d5806 34
tobyspark 0:87aab40d5806 35 // Comment out one or the other...
tobyspark 0:87aab40d5806 36 Serial *debug = new Serial(USBTX, USBRX); // For debugging via USB serial
tobyspark 0:87aab40d5806 37 // Serial *debug = NULL; // For release (no debugging)
tobyspark 0:87aab40d5806 38
tobyspark 0:87aab40d5806 39 //// mBED PIN ASSIGNMENTS
tobyspark 0:87aab40d5806 40
tobyspark 0:87aab40d5806 41 // Inputs
tobyspark 0:87aab40d5806 42 AnalogIn xFadeAIN(p19);
tobyspark 0:87aab40d5806 43 AnalogIn fadeUpAIN(p20);
tobyspark 0:87aab40d5806 44 DigitalIn tapLeftDIN(p24);
tobyspark 0:87aab40d5806 45 DigitalIn tapRightDIN(p21);
tobyspark 0:87aab40d5806 46
tobyspark 0:87aab40d5806 47 SPKRotaryEncoder menuEnc(p17, p16, p15);
tobyspark 0:87aab40d5806 48
tobyspark 0:87aab40d5806 49 // Outputs
tobyspark 0:87aab40d5806 50 PwmOut fadeAPO(LED1);
tobyspark 0:87aab40d5806 51 PwmOut fadeBPO(LED2);
tobyspark 0:87aab40d5806 52
tobyspark 0:87aab40d5806 53 // SPKTVOne(PinName txPin, PinName rxPin, PinName signWritePin, PinName signErrorPin, Serial *debugSerial)
tobyspark 0:87aab40d5806 54 SPKTVOne tvOne(p28, p27, LED3, LED4, debug);
tobyspark 0:87aab40d5806 55 //SPKTVOne tvOne(p28, p27, LED3, LED4);
tobyspark 0:87aab40d5806 56
tobyspark 0:87aab40d5806 57 // SPKDisplay(PinName mosi, PinName clk, PinName cs, PinName dc, PinName res, Serial *debugSerial = NULL);
tobyspark 0:87aab40d5806 58 SPKDisplay screen(p5, p7, p8, p10, p9, debug);
tobyspark 0:87aab40d5806 59
tobyspark 0:87aab40d5806 60
tobyspark 0:87aab40d5806 61
tobyspark 0:87aab40d5806 62 // Menu
tobyspark 0:87aab40d5806 63
tobyspark 0:87aab40d5806 64 SPKMenu *selectedMenu;
tobyspark 0:87aab40d5806 65 SPKMenu *lastSelectedMenu;
tobyspark 0:87aab40d5806 66 SPKMenuOfMenus mainMenu;
tobyspark 0:87aab40d5806 67 SPKMenuPayload resolutionMenu;
tobyspark 0:87aab40d5806 68 SPKMenuPayload mixModeMenu;
tobyspark 0:87aab40d5806 69
tobyspark 0:87aab40d5806 70 // Fade logic constants + variables
tobyspark 0:87aab40d5806 71 const float xFadeTolerance = 0.05;
tobyspark 0:87aab40d5806 72 const float fadeUpTolerance = 0.05;
tobyspark 0:87aab40d5806 73 float xFade = 0;
tobyspark 0:87aab40d5806 74 float fadeUp = 1;
tobyspark 0:87aab40d5806 75
tobyspark 0:87aab40d5806 76 // A&B Fade as resolved percent
tobyspark 0:87aab40d5806 77 int fadeAPercent = 0;
tobyspark 0:87aab40d5806 78 int fadeBPercent = 0;
tobyspark 0:87aab40d5806 79
tobyspark 0:87aab40d5806 80 // Tap button states
tobyspark 0:87aab40d5806 81 bool tapLeftPrevious = false;
tobyspark 0:87aab40d5806 82 bool tapRightPrevious = false;
tobyspark 0:87aab40d5806 83
tobyspark 0:87aab40d5806 84 // Key mode parameters
tobyspark 0:87aab40d5806 85 int keyerParamsSet = -1; // last keyParams index uploaded to unit
tobyspark 0:87aab40d5806 86 // {lumakey, chroma on blue [, to be extended as needed] }
tobyspark 0:87aab40d5806 87 // {minY, maxY, minU, maxU, minV, maxV }
tobyspark 0:87aab40d5806 88 int keyerParams[2][6] =
tobyspark 0:87aab40d5806 89 {
tobyspark 0:87aab40d5806 90 {0, 18, 128, 129, 128, 129}, // lumakey
tobyspark 0:87aab40d5806 91 {41, 42, 240, 241, 109, 110} // chroma on blue
tobyspark 0:87aab40d5806 92 // ...
tobyspark 0:87aab40d5806 93 };
tobyspark 0:87aab40d5806 94
tobyspark 0:87aab40d5806 95
tobyspark 0:87aab40d5806 96
tobyspark 0:87aab40d5806 97 inline float fadeCalc (const float AIN, const float tolerance) {
tobyspark 0:87aab40d5806 98 float pos ;
tobyspark 0:87aab40d5806 99 if (AIN < tolerance) pos = 0;
tobyspark 0:87aab40d5806 100 else if (AIN > 1.0 - tolerance) pos = 1;
tobyspark 0:87aab40d5806 101 else pos = (AIN - tolerance) / (1 - 2*tolerance);
tobyspark 0:87aab40d5806 102 if (debug && false) debug->printf("fadeCalc in: %f out: %f \r\n", AIN, pos);
tobyspark 0:87aab40d5806 103 return pos;
tobyspark 0:87aab40d5806 104 }
tobyspark 0:87aab40d5806 105
tobyspark 0:87aab40d5806 106 bool setKeyParamsTo(int index) {
tobyspark 0:87aab40d5806 107 // Only spend the time uploading six parameters if we need to
tobyspark 0:87aab40d5806 108 // Might want to bounds check here
tobyspark 0:87aab40d5806 109
tobyspark 0:87aab40d5806 110 bool ok = false;
tobyspark 0:87aab40d5806 111
tobyspark 0:87aab40d5806 112 if (index != keyerParamsSet)
tobyspark 0:87aab40d5806 113 {
tobyspark 0:87aab40d5806 114 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinY, keyerParams[index][0]);
tobyspark 0:87aab40d5806 115 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxY, keyerParams[index][1]);
tobyspark 0:87aab40d5806 116 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinU, keyerParams[index][2]);
tobyspark 0:87aab40d5806 117 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxU, keyerParams[index][3]);
tobyspark 0:87aab40d5806 118 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMinV, keyerParams[index][4]);
tobyspark 0:87aab40d5806 119 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerMaxV, keyerParams[index][5]);
tobyspark 0:87aab40d5806 120
tobyspark 0:87aab40d5806 121 keyerParamsSet = index;
tobyspark 0:87aab40d5806 122 }
tobyspark 0:87aab40d5806 123
tobyspark 0:87aab40d5806 124 return ok;
tobyspark 0:87aab40d5806 125 }
tobyspark 0:87aab40d5806 126
tobyspark 0:87aab40d5806 127 int main()
tobyspark 0:87aab40d5806 128 {
tobyspark 0:87aab40d5806 129
tobyspark 0:87aab40d5806 130 if (debug)
tobyspark 0:87aab40d5806 131 {
tobyspark 0:87aab40d5806 132 debug->printf("\r\n\r\n");
tobyspark 0:87aab40d5806 133 debug->printf("*spark d-fuser -----------\r\n");
tobyspark 0:87aab40d5806 134 debug->printf(" debug channel\r\n");
tobyspark 0:87aab40d5806 135 }
tobyspark 0:87aab40d5806 136
tobyspark 0:87aab40d5806 137 // Splash screen
tobyspark 0:87aab40d5806 138 screen.imageToBuffer();
tobyspark 0:87aab40d5806 139 screen.textToBuffer("SPK:D-Fuser",0);
tobyspark 0:87aab40d5806 140 screen.textToBuffer("SW beta.15",1);
tobyspark 0:87aab40d5806 141 screen.sendBuffer();
tobyspark 0:87aab40d5806 142
tobyspark 0:87aab40d5806 143
tobyspark 0:87aab40d5806 144 // Set menu structure
tobyspark 0:87aab40d5806 145 mixModeMenu.title = "Mix Mode";
tobyspark 0:87aab40d5806 146 enum { blend, additive, lumaKey, chromaKey1, chromaKey2, chromaKey3 }; // additive will require custom TVOne firmware.
tobyspark 0:87aab40d5806 147 mixModeMenu.addMenuItem("Blend", blend, 0);
tobyspark 0:87aab40d5806 148 mixModeMenu.addMenuItem("LumaKey", lumaKey, 0);
tobyspark 0:87aab40d5806 149 mixModeMenu.addMenuItem("ChromaKey - Blue", chromaKey1, 0);
tobyspark 0:87aab40d5806 150
tobyspark 0:87aab40d5806 151 resolutionMenu.title = "Resolution";
tobyspark 0:87aab40d5806 152 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionVGA, kTV1ResolutionVGA, 5);
tobyspark 0:87aab40d5806 153 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionSVGA, kTV1ResolutionSVGA, 5);
tobyspark 0:87aab40d5806 154 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionXGAp60, kTV1ResolutionXGAp60, 5);
tobyspark 0:87aab40d5806 155 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionWSXGAPLUSp60, kTV1ResolutionWSXGAPLUSp60, 5);
tobyspark 0:87aab40d5806 156 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionWUXGAp60, kTV1ResolutionWUXGAp60, 5);
tobyspark 0:87aab40d5806 157 resolutionMenu.addMenuItem(kTV1ResolutionDescription720p60, kTV1Resolution720p60, 5);
tobyspark 0:87aab40d5806 158 resolutionMenu.addMenuItem(kTV1ResolutionDescription1080p60, kTV1Resolution1080p60, 5);
tobyspark 0:87aab40d5806 159 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionDualHeadSVGAp60, kTV1ResolutionDualHeadSVGAp60, 0);
tobyspark 0:87aab40d5806 160 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionDualHeadXGAp60, kTV1ResolutionDualHeadXGAp60, 0);
tobyspark 0:87aab40d5806 161 resolutionMenu.addMenuItem(kTV1ResolutionDescriptionTripleHeadVGAp60, kTV1ResolutionTripleHeadVGAp60, 0);
tobyspark 0:87aab40d5806 162
tobyspark 0:87aab40d5806 163 mainMenu.title = "Main Menu";
tobyspark 0:87aab40d5806 164 mainMenu.addMenuItem(&mixModeMenu);
tobyspark 0:87aab40d5806 165 mainMenu.addMenuItem(&resolutionMenu);
tobyspark 0:87aab40d5806 166
tobyspark 0:87aab40d5806 167 selectedMenu = &mainMenu;
tobyspark 0:87aab40d5806 168 lastSelectedMenu = &mainMenu;
tobyspark 0:87aab40d5806 169
tobyspark 0:87aab40d5806 170 // Misc I/O stuff
tobyspark 0:87aab40d5806 171
tobyspark 0:87aab40d5806 172 fadeAPO.period(0.001);
tobyspark 0:87aab40d5806 173 fadeBPO.period(0.001);
tobyspark 0:87aab40d5806 174
tobyspark 0:87aab40d5806 175 // TVOne setup
tobyspark 0:87aab40d5806 176
tobyspark 0:87aab40d5806 177 bool ok = false;
tobyspark 0:87aab40d5806 178
tobyspark 0:87aab40d5806 179 // horrid, horrid HDCP
tobyspark 0:87aab40d5806 180 ok = tvOne.setHDCPOff();
tobyspark 0:87aab40d5806 181
tobyspark 0:87aab40d5806 182 std::string sendOK = ok ? "Sent: HDCP Off" : "Send Error: HDCP Off";
tobyspark 0:87aab40d5806 183
tobyspark 0:87aab40d5806 184 // display menu and framing lines
tobyspark 0:87aab40d5806 185 screen.horizLineToBuffer(kMenuLine1*pixInPage - 1);
tobyspark 0:87aab40d5806 186 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 187 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 188 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 189 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 190 screen.horizLineToBuffer(kMenuLine2*pixInPage + pixInPage);
tobyspark 0:87aab40d5806 191 screen.horizLineToBuffer(kStatusLine*pixInPage - 1);
tobyspark 0:87aab40d5806 192 screen.clearBufferRow(kStatusLine);
tobyspark 0:87aab40d5806 193 screen.textToBuffer(sendOK, 7);
tobyspark 0:87aab40d5806 194 screen.sendBuffer();
tobyspark 0:87aab40d5806 195
tobyspark 0:87aab40d5806 196
tobyspark 0:87aab40d5806 197 //// CONTROLS TEST
tobyspark 0:87aab40d5806 198
tobyspark 0:87aab40d5806 199 while (0) {
tobyspark 0:87aab40d5806 200 if (debug) debug->printf("xFade: %f, fadeOut: %f, tapLeft %i, tapRight: %i encPos: %i encChange:%i encHasPressed:%i \r\n" , xFadeAIN.read(), fadeUpAIN.read(), tapLeftDIN.read(), tapRightDIN.read(), menuEnc.getPos(), menuEnc.getChange(), menuEnc.hasPressed());
tobyspark 0:87aab40d5806 201 }
tobyspark 0:87aab40d5806 202
tobyspark 0:87aab40d5806 203 //// MIXER RUN
tobyspark 0:87aab40d5806 204
tobyspark 0:87aab40d5806 205 while (1) {
tobyspark 0:87aab40d5806 206
tobyspark 0:87aab40d5806 207 //// MENU
tobyspark 0:87aab40d5806 208
tobyspark 0:87aab40d5806 209 int menuChange = menuEnc.getChange();
tobyspark 0:87aab40d5806 210
tobyspark 0:87aab40d5806 211 // Update GUI
tobyspark 0:87aab40d5806 212 if (menuChange != 0)
tobyspark 0:87aab40d5806 213 {
tobyspark 0:87aab40d5806 214 if (debug) debug->printf("Menu changed by %i\r\n", menuChange);
tobyspark 0:87aab40d5806 215
tobyspark 0:87aab40d5806 216 *selectedMenu = selectedMenu->selectedIndex() + menuChange;
tobyspark 0:87aab40d5806 217
tobyspark 0:87aab40d5806 218 // update OLED line 2 here
tobyspark 0:87aab40d5806 219 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 220 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 221 screen.sendBuffer();
tobyspark 0:87aab40d5806 222
tobyspark 0:87aab40d5806 223 if (debug) debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 0:87aab40d5806 224
tobyspark 0:87aab40d5806 225 }
tobyspark 0:87aab40d5806 226
tobyspark 0:87aab40d5806 227 // Action menu item
tobyspark 0:87aab40d5806 228 if (menuEnc.hasPressed())
tobyspark 0:87aab40d5806 229 {
tobyspark 0:87aab40d5806 230 if (debug) debug->printf("Action Menu Item!\r\n");
tobyspark 0:87aab40d5806 231
tobyspark 0:87aab40d5806 232 // Are we changing menus?
tobyspark 0:87aab40d5806 233 if (selectedMenu->type() == menuOfMenus)
tobyspark 0:87aab40d5806 234 {
tobyspark 0:87aab40d5806 235 // point selected menu to the new menu
tobyspark 0:87aab40d5806 236 // FIXME. Make this function abstract virtual of base class or get dynamic_cast working. BTW: C++ sucks / Obj-c rocks / Right now.
tobyspark 0:87aab40d5806 237 if (selectedMenu == &mainMenu) selectedMenu = mainMenu.selectedMenu();
tobyspark 0:87aab40d5806 238 else if (debug) debug->printf("FIXME: You've missed a SPKMenuOfMenus");
tobyspark 0:87aab40d5806 239
tobyspark 0:87aab40d5806 240 // reset the selection within that menu to the first position
tobyspark 0:87aab40d5806 241 (*selectedMenu) = 0;
tobyspark 0:87aab40d5806 242
tobyspark 0:87aab40d5806 243 // update OLED lines 1&2
tobyspark 0:87aab40d5806 244 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 245 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 246 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 247 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 248 screen.sendBuffer();
tobyspark 0:87aab40d5806 249
tobyspark 0:87aab40d5806 250 if (debug)
tobyspark 0:87aab40d5806 251 {
tobyspark 0:87aab40d5806 252 debug->printf("\r\n");
tobyspark 0:87aab40d5806 253 debug->printf("%s \r\n", selectedMenu->title.c_str());
tobyspark 0:87aab40d5806 254 debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 0:87aab40d5806 255 }
tobyspark 0:87aab40d5806 256 }
tobyspark 0:87aab40d5806 257 // Are we cancelling?
tobyspark 0:87aab40d5806 258 else if (selectedMenu->type() == payload && selectedMenu->selectedIndex() == 0)
tobyspark 0:87aab40d5806 259 {
tobyspark 0:87aab40d5806 260 selectedMenu = lastSelectedMenu;
tobyspark 0:87aab40d5806 261
tobyspark 0:87aab40d5806 262 // update OLED lines 1&2
tobyspark 0:87aab40d5806 263 screen.clearBufferRow(kMenuLine1);
tobyspark 0:87aab40d5806 264 screen.clearBufferRow(kMenuLine2);
tobyspark 0:87aab40d5806 265 screen.textToBuffer(selectedMenu->title, kMenuLine1);
tobyspark 0:87aab40d5806 266 screen.textToBuffer(selectedMenu->selectedString(), kMenuLine2);
tobyspark 0:87aab40d5806 267 screen.sendBuffer();
tobyspark 0:87aab40d5806 268
tobyspark 0:87aab40d5806 269 if (debug)
tobyspark 0:87aab40d5806 270 {
tobyspark 0:87aab40d5806 271 debug->printf("\r\n");
tobyspark 0:87aab40d5806 272 debug->printf("%s \r\n", selectedMenu->title.c_str());
tobyspark 0:87aab40d5806 273 debug->printf("%s \r\n", selectedMenu->selectedString().c_str());
tobyspark 0:87aab40d5806 274 }
tobyspark 0:87aab40d5806 275 }
tobyspark 0:87aab40d5806 276 // With that out of the way, we should be actioning a specific menu's payload?
tobyspark 0:87aab40d5806 277 else if (selectedMenu == &mixModeMenu)
tobyspark 0:87aab40d5806 278 {
tobyspark 0:87aab40d5806 279 bool ok = false;
tobyspark 0:87aab40d5806 280 std::string sentOK;
tobyspark 0:87aab40d5806 281 std::stringstream sentMSG;
tobyspark 0:87aab40d5806 282
tobyspark 0:87aab40d5806 283 // Set keying parameters
tobyspark 0:87aab40d5806 284 switch (mixModeMenu.selectedPayload1()) {
tobyspark 0:87aab40d5806 285 case lumaKey:
tobyspark 0:87aab40d5806 286 ok = setKeyParamsTo(0);
tobyspark 0:87aab40d5806 287 sentMSG << "Keyer Params 0, ";
tobyspark 0:87aab40d5806 288 break;
tobyspark 0:87aab40d5806 289 case chromaKey1:
tobyspark 0:87aab40d5806 290 ok = setKeyParamsTo(1);
tobyspark 0:87aab40d5806 291 sentMSG << "Keyer Params 1, ";
tobyspark 0:87aab40d5806 292 break;
tobyspark 0:87aab40d5806 293 }
tobyspark 0:87aab40d5806 294
tobyspark 0:87aab40d5806 295 // Set keying on or off
tobyspark 0:87aab40d5806 296 switch (mixModeMenu.selectedPayload1()) {
tobyspark 0:87aab40d5806 297 case blend:
tobyspark 0:87aab40d5806 298 case additive:
tobyspark 0:87aab40d5806 299 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, false);
tobyspark 0:87aab40d5806 300 sentMSG << "Keyer Off";
tobyspark 0:87aab40d5806 301 break;
tobyspark 0:87aab40d5806 302 case lumaKey:
tobyspark 0:87aab40d5806 303 case chromaKey1:
tobyspark 0:87aab40d5806 304 case chromaKey2:
tobyspark 0:87aab40d5806 305 case chromaKey3:
tobyspark 0:87aab40d5806 306 ok = ok && tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustKeyerEnable, true);
tobyspark 0:87aab40d5806 307 sentMSG << "Keyer On";
tobyspark 0:87aab40d5806 308 break;
tobyspark 0:87aab40d5806 309 }
tobyspark 0:87aab40d5806 310
tobyspark 0:87aab40d5806 311 if (ok) sentOK = "Sent:";
tobyspark 0:87aab40d5806 312 else sentOK = "Send Error:";
tobyspark 0:87aab40d5806 313
tobyspark 0:87aab40d5806 314 screen.clearBufferRow(kStatusLine);
tobyspark 0:87aab40d5806 315 screen.textToBuffer(sentOK + sentMSG.str(), kStatusLine);
tobyspark 0:87aab40d5806 316 screen.sendBuffer();
tobyspark 0:87aab40d5806 317
tobyspark 0:87aab40d5806 318 if (debug) { debug->printf("Changing mix mode"); }
tobyspark 0:87aab40d5806 319 }
tobyspark 0:87aab40d5806 320 else if (selectedMenu == &resolutionMenu)
tobyspark 0:87aab40d5806 321 {
tobyspark 0:87aab40d5806 322 bool ok = false;
tobyspark 0:87aab40d5806 323
tobyspark 0:87aab40d5806 324 ok = tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustOutputsOutputResolution, resolutionMenu.selectedPayload1());
tobyspark 0:87aab40d5806 325 ok = ok && tvOne.command(kTV1SourceRGB1, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, resolutionMenu.selectedPayload2());
tobyspark 0:87aab40d5806 326 ok = ok && tvOne.command(kTV1SourceRGB2, kTV1WindowIDA, kTV1FunctionAdjustSourceEDID, resolutionMenu.selectedPayload2());
tobyspark 0:87aab40d5806 327
tobyspark 0:87aab40d5806 328 std::string sentOK;
tobyspark 0:87aab40d5806 329 if (ok) sentOK = "Sent: ";
tobyspark 0:87aab40d5806 330 else sentOK = "Send Error: ";
tobyspark 0:87aab40d5806 331
tobyspark 0:87aab40d5806 332 std::stringstream sentMSG;
tobyspark 0:87aab40d5806 333 sentMSG << "Res " << resolutionMenu.selectedPayload1() << ", EDID " << resolutionMenu.selectedPayload2();
tobyspark 0:87aab40d5806 334
tobyspark 0:87aab40d5806 335 screen.clearBufferRow(kStatusLine);
tobyspark 0:87aab40d5806 336 screen.textToBuffer(sentOK + sentMSG.str(), kStatusLine);
tobyspark 0:87aab40d5806 337 screen.sendBuffer();
tobyspark 0:87aab40d5806 338
tobyspark 0:87aab40d5806 339 if (debug) { debug->printf("Changing resolution"); }
tobyspark 0:87aab40d5806 340 }
tobyspark 0:87aab40d5806 341 else
tobyspark 0:87aab40d5806 342 {
tobyspark 0:87aab40d5806 343 if (debug) { debug->printf("Warning: No action identified"); }
tobyspark 0:87aab40d5806 344 }
tobyspark 0:87aab40d5806 345
tobyspark 0:87aab40d5806 346 }
tobyspark 0:87aab40d5806 347
tobyspark 0:87aab40d5806 348
tobyspark 0:87aab40d5806 349
tobyspark 0:87aab40d5806 350 //// MIX
tobyspark 0:87aab40d5806 351
tobyspark 0:87aab40d5806 352 bool updateFade = false;
tobyspark 0:87aab40d5806 353
tobyspark 0:87aab40d5806 354 // Get new states of tap buttons, remembering at end of loop() assign these current values to the previous variables
tobyspark 0:87aab40d5806 355 const bool tapLeft = (tapLeftDIN) ? false : true;
tobyspark 0:87aab40d5806 356 const bool tapRight = (tapRightDIN) ? false : true;
tobyspark 0:87aab40d5806 357
tobyspark 0:87aab40d5806 358 // We're going to cache the analog in reads, as have seen wierdness otherwise
tobyspark 0:87aab40d5806 359 const float xFadeAINCached = xFadeAIN.read();
tobyspark 0:87aab40d5806 360 const float fadeUpAINCached = fadeUpAIN.read();
tobyspark 0:87aab40d5806 361
tobyspark 0:87aab40d5806 362 // When a tap is depressed, we can ignore any move of the crossfader but not fade to black
tobyspark 0:87aab40d5806 363 if (tapLeft || tapRight)
tobyspark 0:87aab40d5806 364 {
tobyspark 0:87aab40d5806 365 // If both are pressed, which was not pressed in the last loop?
tobyspark 0:87aab40d5806 366 if (tapLeft && tapRight)
tobyspark 0:87aab40d5806 367 {
tobyspark 0:87aab40d5806 368 if (!tapLeftPrevious) xFade = 0;
tobyspark 0:87aab40d5806 369 if (!tapRightPrevious) xFade = 1;
tobyspark 0:87aab40d5806 370 }
tobyspark 0:87aab40d5806 371 // If just one is pressed, is this it going high or the other going low?
tobyspark 0:87aab40d5806 372 else if (tapLeft && (!tapLeftPrevious || tapRightPrevious)) xFade = 0;
tobyspark 0:87aab40d5806 373 else if (tapRight && (!tapRightPrevious || tapLeftPrevious)) xFade = 1;
tobyspark 0:87aab40d5806 374 }
tobyspark 0:87aab40d5806 375 else xFade = fadeCalc(xFadeAINCached, xFadeTolerance);
tobyspark 0:87aab40d5806 376
tobyspark 0:87aab40d5806 377 fadeUp = 1.0 - fadeCalc(fadeUpAINCached, fadeUpTolerance);
tobyspark 0:87aab40d5806 378
tobyspark 0:87aab40d5806 379 // WISH: Really, we should have B at 100% and A fading in over that, with fade to black implemented as a fade in black layer on top of that correct mix.
tobyspark 0:87aab40d5806 380 // There is no way to implement that though, and the alphas get messy, so this is the only way (afaik).
tobyspark 0:87aab40d5806 381
tobyspark 0:87aab40d5806 382 // Calculate new A&B fade percents
tobyspark 0:87aab40d5806 383 int newFadeAPercent = 0;
tobyspark 0:87aab40d5806 384 int newFadeBPercent = 0;
tobyspark 0:87aab40d5806 385
tobyspark 0:87aab40d5806 386 switch (mixModeMenu.selectedPayload1()) {
tobyspark 0:87aab40d5806 387 case blend:
tobyspark 0:87aab40d5806 388 case additive:
tobyspark 0:87aab40d5806 389 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 0:87aab40d5806 390 newFadeBPercent = xFade * fadeUp * 100.0;
tobyspark 0:87aab40d5806 391 break;
tobyspark 0:87aab40d5806 392 case lumaKey:
tobyspark 0:87aab40d5806 393 case chromaKey1:
tobyspark 0:87aab40d5806 394 case chromaKey2:
tobyspark 0:87aab40d5806 395 case chromaKey3:
tobyspark 0:87aab40d5806 396 newFadeAPercent = (1.0-xFade) * fadeUp * 100.0;
tobyspark 0:87aab40d5806 397 newFadeBPercent = fadeUp * 100.0;
tobyspark 0:87aab40d5806 398 break;
tobyspark 0:87aab40d5806 399 }
tobyspark 0:87aab40d5806 400
tobyspark 0:87aab40d5806 401 // Send to TVOne if percents have changed
tobyspark 0:87aab40d5806 402 if (newFadeAPercent != fadeAPercent) {
tobyspark 0:87aab40d5806 403 fadeAPercent = newFadeAPercent;
tobyspark 0:87aab40d5806 404 updateFade = true;
tobyspark 0:87aab40d5806 405
tobyspark 0:87aab40d5806 406 fadeAPO = fadeAPercent / 100.0;
tobyspark 0:87aab40d5806 407 tvOne.command(0, kTV1WindowIDA, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeAPercent);
tobyspark 0:87aab40d5806 408 }
tobyspark 0:87aab40d5806 409
tobyspark 0:87aab40d5806 410 if (newFadeBPercent != fadeBPercent) {
tobyspark 0:87aab40d5806 411 fadeBPercent = newFadeBPercent;
tobyspark 0:87aab40d5806 412 updateFade = true;
tobyspark 0:87aab40d5806 413
tobyspark 0:87aab40d5806 414 fadeBPO = fadeBPercent / 100.0;
tobyspark 0:87aab40d5806 415 tvOne.command(0, kTV1WindowIDB, kTV1FunctionAdjustWindowsMaxFadeLevel, fadeBPercent);
tobyspark 0:87aab40d5806 416 }
tobyspark 0:87aab40d5806 417
tobyspark 0:87aab40d5806 418 if (updateFade && debug) {
tobyspark 0:87aab40d5806 419 debug->printf("\r\n");
tobyspark 0:87aab40d5806 420 //debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAIN.read(), fadeUpAIN.read());
tobyspark 0:87aab40d5806 421 debug->printf("xFade = %3f fadeUp = %3f \r\n", xFadeAINCached, fadeUpAINCached);
tobyspark 0:87aab40d5806 422 debug->printf("xFade = %3f fadeUp = %3f fadeA% = %i fadeB% = %i \r\n", xFade, fadeUp, fadeAPercent, fadeBPercent);
tobyspark 0:87aab40d5806 423 }
tobyspark 0:87aab40d5806 424
tobyspark 0:87aab40d5806 425 // END OF LOOP - Reset
tobyspark 0:87aab40d5806 426 tapLeftPrevious = tapLeft;
tobyspark 0:87aab40d5806 427 tapRightPrevious = tapRight;
tobyspark 0:87aab40d5806 428 }
tobyspark 0:87aab40d5806 429 }