Browse Source

Added pixel skip and FPS logging

Thomas Buck 8 years ago
parent
commit
f8e5916e7c
No account linked to committer's email address
3 changed files with 107 additions and 80 deletions
  1. 18
    0
      DisplayBacklight/AppDelegate.h
  2. 88
    79
      DisplayBacklight/AppDelegate.m
  3. 1
    1
      DisplayBacklight/Info.plist

+ 18
- 0
DisplayBacklight/AppDelegate.h View File

@@ -19,3 +19,21 @@
19 19
 
20 20
 @end
21 21
 
22
+// ToDo: add support for display names or IDs here, so we can distinguish
23
+// between multiple displays with the same resolution
24
+struct DisplayAssignment {
25
+    int width, height;
26
+};
27
+
28
+struct LEDStrand {
29
+    int idMin, count;
30
+    int display;
31
+    int startX, startY;
32
+    int direction;
33
+    int size;
34
+};
35
+
36
+#define DIR_LEFT 0
37
+#define DIR_RIGHT 1
38
+#define DIR_UP 2
39
+#define DIR_DOWN 3

+ 88
- 79
DisplayBacklight/AppDelegate.m View File

@@ -10,16 +10,62 @@
10 10
 #import "Serial.h"
11 11
 #import "Screenshot.h"
12 12
 
13
-// This defined the update-speed of the Ambilight, in seconds.
13
+// ----------------------- Config starts here -----------------------
14
+
15
+// The idea behind this algorithm is very simple. It assumes that each LED strand
16
+// follows one edge of one of your displays. So one of the two coordinates should
17
+// always be zero or the width / height of your display.
18
+
19
+// Define the amount of LEDs in your strip here
20
+#define LED_COUNT 156
21
+
22
+// This defines how large the averaging-boxes should be in the dimension perpendicular
23
+// to the strand. So eg. for a bottom strand, how high the box should be in px.
24
+#define COLOR_AVERAGE_OTHER_DIMENSION_SIZE 100
25
+
26
+// Identify your displays here. Currently they're only distinguished by their resolution.
27
+// The ID will be the index in the list, so the first entry is display 0 and so on.
28
+struct DisplayAssignment displays[] = {
29
+    { 1920, 1080 },
30
+    {  900, 1600 }
31
+};
32
+
33
+// This defines the orientation and placement of your strands and is the most important part.
34
+// It begins with the LED IDs this strand includes, starting with ID 0 up to LED_COUNT - 1.
35
+// The second item is the length of this strip, as in the count of LEDs in it.
36
+// The third item is the display ID, defined by the previous struct.
37
+// The fourth and fifth items are the starting X and Y coordinates of the strand.
38
+// As described above, one should always be zero or the display width / height.
39
+// The sixth element is the direction the strand goes (no diagonals supported yet).
40
+// The last element is the size of the averaging-box for each LED, moving with the strand.
41
+// So, if your strand contains 33 LEDs and spans 1920 pixels, this should be (1920 / 33).
42
+// By default you can always use (length in pixel / LED count) for the last item, except
43
+// if your strand does not span the whole length of this screen edge.
44
+struct LEDStrand strands[] = {
45
+    {   0, 33, 0, 1920, 1080,  DIR_LEFT, 1920 / 33 },
46
+    {  33, 19, 0,    0, 1080,    DIR_UP, 1080 / 19 },
47
+    {  52, 33, 0,    0,    0, DIR_RIGHT, 1920 / 33 },
48
+    {  85,  5, 1,    0,  250,    DIR_UP,  250 / 5 },
49
+    {  90, 17, 1,    0,    0, DIR_RIGHT,  900 / 17 },
50
+    { 107, 28, 1,  900,    0,  DIR_DOWN, 1600 / 28 },
51
+    { 135, 17, 1,  900, 1600,  DIR_LEFT,  900 / 17 },
52
+    { 152,  4, 1,    0, 1600,    DIR_UP,  180 / 4 }
53
+};
54
+
55
+// This defines the update-speed of the Ambilight, in seconds.
14 56
 // With a baudrate of 115200 and 156 LEDs and 14-bytes Magic-Word,
15 57
 // theoretically you could transmit:
16
-//     115200 / (14 + (156 * 3) * 8) =~ 30 Frames per Second
58
+//     115200 / (14 + (156 * 3)) * 8 =~ 30 Frames per Second
17 59
 // Inserting (1.0 / 30.0) here would try to reach these 30FPS,
18 60
 // but will probably cause high CPU-Usage.
19 61
 // (Run-Time of the algorithm is ignored here, so real speed will be
20 62
 // slightly lower.)
21 63
 #define DISPLAY_DELAY (1.0 / 30.0)
22 64
 
65
+// How many pixels to skip when calculating the average color.
66
+// Slightly increases performance and doesn't really alter the result.
67
+#define AVERAGE_PIXEL_SKIP 2
68
+
23 69
 // Magic identifying string used to differntiate start of packets.
24 70
 // Has to be the same here and in the Arduino Sketch.
25 71
 #define MAGIC_WORD @"xythobuzRGBled"
@@ -29,6 +75,11 @@
29 75
 #define PREF_BRIGHTNESS @"Brightness"
30 76
 #define PREF_TURNED_ON @"IsEnabled"
31 77
 
78
+// If this is defined it will print the FPS every DEBUG_PRINT_FPS seconds
79
+//#define DEBUG_PRINT_FPS 10
80
+
81
+// ------------------------ Config ends here ------------------------
82
+
32 83
 @interface AppDelegate ()
33 84
 
34 85
 @property (weak) IBOutlet NSMenu *statusMenu;
@@ -272,70 +323,24 @@
272 323
     [application orderFrontStandardAboutPanel:self];
273 324
 }
274 325
 
326
+- (void)sendLEDFrame {
327
+    if ([serial isOpen]) {
328
+        [serial sendString:MAGIC_WORD];
329
+        [serial sendData:(char *)ledColorData withLength:(sizeof(ledColorData) / sizeof(ledColorData[0]))];
330
+    }
331
+}
332
+
333
+- (void)sendNullFrame {
334
+    for (int i = 0; i < (sizeof(ledColorData) / sizeof(ledColorData[0])); i++) {
335
+        ledColorData[i] = 0;
336
+    }
337
+    [self sendLEDFrame];
338
+}
339
+
275 340
 // ----------------------------------------------------
276 341
 // ------------ 'Ambilight' Visualizations ------------
277 342
 // ----------------------------------------------------
278 343
 
279
-// ToDo: add support for display names or IDs here, so we can distinguish
280
-// between multiple displays with the same resolution
281
-struct DisplayAssignment {
282
-    int width, height;
283
-};
284
-
285
-struct LEDStrand {
286
-    int idMin, idMax;
287
-    int display;
288
-    int startX, startY;
289
-    int direction;
290
-    int size;
291
-};
292
-
293
-#define DIR_LEFT 0
294
-#define DIR_RIGHT 1
295
-#define DIR_UP 2
296
-#define DIR_DOWN 3
297
-
298
-// ----------------------- Config starts here -----------------------
299
-
300
-// The idea behind this algorithm is very simple. It assumes that each LED strand
301
-// follows one edge of one of your displays. So one of the two coordinates should
302
-// always be zero or the width / height of your display.
303
-
304
-// Define the amount of LEDs in your strip here
305
-#define LED_COUNT 156
306
-
307
-// This defined how large the averaging-boxes should be in the dimension perpendicular
308
-// to the strand. So eg. for a bottom strand, how high the box should be in px.
309
-#define COLOR_AVERAGE_OTHER_DIMENSION_SIZE 150
310
-
311
-// Identify your displays here. Currently they're only distinguished by their resolution.
312
-// The ID will be the index in the list, so the first entry is display 0 and so on.
313
-struct DisplayAssignment displays[] = {
314
-    { 1920, 1080 },
315
-    {  900, 1600 }
316
-};
317
-
318
-// This defined the orientation and placement of your strands and is the most important part.
319
-// It begins with the LED IDs this strand includes, starting with ID 0 up to LED_COUNT - 1.
320
-// The third item is the display ID, defined by the previous struct.
321
-// The fourth and fifth items are the starting X and Y coordinates of the strand.
322
-// As described above, one should always be zero or the display width / height.
323
-// The sixth element is the direction the strand goes (no diagonals supported yet).
324
-// The last element is the size of the averaging-box for each LED, moving with the strand.
325
-// So, if your strand contains 33 LEDs and spans 1920 pixels, this should be (1920 / 33).
326
-struct LEDStrand strands[] = {
327
-    {   0,  32, 0, 1920, 1080,  DIR_LEFT, 1920 / 33 },
328
-    {  33,  51, 0,    0, 1080,    DIR_UP, 1080 / 19 },
329
-    {  52,  84, 0,    0,    0, DIR_RIGHT, 1920 / 33 },
330
-    {  85,  89, 1,    0,  250,    DIR_UP,  250 / 5 },
331
-    {  90, 106, 1,    0,    0, DIR_RIGHT,  900 / 17 },
332
-    { 107, 134, 1,  900,    0,  DIR_DOWN, 1600 / 28 },
333
-    { 135, 151, 1,  900, 1600,  DIR_LEFT,  900 / 17 },
334
-    { 152, 155, 1,    0, 1600,    DIR_UP,  180 / 4 }
335
-};
336
-
337
-// ------------------------ Config ends here ------------------------
338
-
339 344
 UInt8 ledColorData[LED_COUNT * 3];
340 345
 
341 346
 - (UInt32)calculateAverage:(unsigned char *)data Width:(NSInteger)width Height:(NSInteger)height SPP:(NSInteger)spp Alpha:(BOOL)alpha StartX:(NSInteger)startX StartY:(NSInteger)startY EndX:(NSInteger)endX EndY:(NSInteger)endY {
@@ -361,7 +366,7 @@ UInt8 ledColorData[LED_COUNT * 3];
361 366
     }
362 367
     
363 368
     unsigned long red = 0, green = 0, blue = 0, count = 0;
364
-    for (NSInteger i = xa; i < xb; i++) {
369
+    for (NSInteger i = xa; i < xb; i += AVERAGE_PIXEL_SKIP) {
365 370
         for (NSInteger j = ya; j < yb; j++) {
366 371
             count++;
367 372
             unsigned long index = i + (j * width);
@@ -396,7 +401,7 @@ UInt8 ledColorData[LED_COUNT * 3];
396 401
                 blockHeight = strands[i].size;
397 402
             }
398 403
             
399
-            for (int led = strands[i].idMin; led <= strands[i].idMax; led++) {
404
+            for (int led = strands[i].idMin; led < (strands[i].idMin + strands[i].count); led++) {
400 405
                 // First move appropriately in the direction of the strand
401 406
                 unsigned long endX = x, endY = y;
402 407
                 if (strands[i].direction == DIR_LEFT) {
@@ -428,7 +433,6 @@ UInt8 ledColorData[LED_COUNT * 3];
428 433
                 // Calculate average color for this led
429 434
                 UInt32 color = [self calculateAverage:data Width:width Height:height SPP:spp Alpha:alpha StartX:x StartY:y EndX:endX EndY:endY];
430 435
                 
431
-                
432 436
                 ledColorData[led * 3] = (color & 0xFF0000) >> 16;
433 437
                 ledColorData[(led * 3) + 1] = (color & 0x00FF00) >> 8;
434 438
                 ledColorData[(led * 3) + 2] = color & 0x0000FF;
@@ -445,6 +449,14 @@ UInt8 ledColorData[LED_COUNT * 3];
445 449
 }
446 450
 
447 451
 - (void)visualizeDisplay:(NSTimer *)time {
452
+#ifdef DEBUG_PRINT_FPS
453
+    static NSInteger frameCount = 0;
454
+    static NSDate *lastPrintTime = nil;
455
+    if (lastPrintTime == nil) {
456
+        lastPrintTime = [NSDate date];
457
+    }
458
+#endif
459
+    
448 460
     //NSLog(@"Running Ambilight-Algorithm (%lu)...", (unsigned long)[lastDisplayIDs count]);
449 461
     
450 462
     // Create a Screenshot for all connected displays
@@ -478,21 +490,18 @@ UInt8 ledColorData[LED_COUNT * 3];
478 490
     
479 491
     [self sendLEDFrame];
480 492
     
481
-    timer = [NSTimer scheduledTimerWithTimeInterval:DISPLAY_DELAY target:self selector:@selector(visualizeDisplay:) userInfo:nil repeats:NO];
482
-}
483
-
484
-- (void)sendLEDFrame {
485
-    if ([serial isOpen]) {
486
-        [serial sendString:MAGIC_WORD];
487
-        [serial sendData:(char *)ledColorData withLength:(sizeof(ledColorData) / sizeof(ledColorData[0]))];
488
-    }
489
-}
490
-
491
-- (void)sendNullFrame {
492
-    for (int i = 0; i < (sizeof(ledColorData) / sizeof(ledColorData[0])); i++) {
493
-        ledColorData[i] = 0;
493
+#ifdef DEBUG_PRINT_FPS
494
+    frameCount++;
495
+    NSDate *now = [NSDate date];
496
+    NSTimeInterval interval = [now timeIntervalSinceDate:lastPrintTime];
497
+    if (interval >= DEBUG_PRINT_FPS) {
498
+        NSLog(@"FPS: %.2f", frameCount / interval);
499
+        frameCount = 0;
500
+        lastPrintTime = now;
494 501
     }
495
-    [self sendLEDFrame];
502
+#endif
503
+    
504
+    timer = [NSTimer scheduledTimerWithTimeInterval:DISPLAY_DELAY target:self selector:@selector(visualizeDisplay:) userInfo:nil repeats:NO];
496 505
 }
497 506
 
498 507
 @end

+ 1
- 1
DisplayBacklight/Info.plist View File

@@ -21,7 +21,7 @@
21 21
 	<key>CFBundleSignature</key>
22 22
 	<string>????</string>
23 23
 	<key>CFBundleVersion</key>
24
-	<string>65</string>
24
+	<string>81</string>
25 25
 	<key>LSApplicationCategoryType</key>
26 26
 	<string>public.app-category.utilities</string>
27 27
 	<key>LSMinimumSystemVersion</key>

Loading…
Cancel
Save