Browse Source

Added pixel skip and FPS logging

Thomas Buck 7 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
 
19
 
20
 @end
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
 #import "Serial.h"
10
 #import "Serial.h"
11
 #import "Screenshot.h"
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
 // With a baudrate of 115200 and 156 LEDs and 14-bytes Magic-Word,
56
 // With a baudrate of 115200 and 156 LEDs and 14-bytes Magic-Word,
15
 // theoretically you could transmit:
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
 // Inserting (1.0 / 30.0) here would try to reach these 30FPS,
59
 // Inserting (1.0 / 30.0) here would try to reach these 30FPS,
18
 // but will probably cause high CPU-Usage.
60
 // but will probably cause high CPU-Usage.
19
 // (Run-Time of the algorithm is ignored here, so real speed will be
61
 // (Run-Time of the algorithm is ignored here, so real speed will be
20
 // slightly lower.)
62
 // slightly lower.)
21
 #define DISPLAY_DELAY (1.0 / 30.0)
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
 // Magic identifying string used to differntiate start of packets.
69
 // Magic identifying string used to differntiate start of packets.
24
 // Has to be the same here and in the Arduino Sketch.
70
 // Has to be the same here and in the Arduino Sketch.
25
 #define MAGIC_WORD @"xythobuzRGBled"
71
 #define MAGIC_WORD @"xythobuzRGBled"
29
 #define PREF_BRIGHTNESS @"Brightness"
75
 #define PREF_BRIGHTNESS @"Brightness"
30
 #define PREF_TURNED_ON @"IsEnabled"
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
 @interface AppDelegate ()
83
 @interface AppDelegate ()
33
 
84
 
34
 @property (weak) IBOutlet NSMenu *statusMenu;
85
 @property (weak) IBOutlet NSMenu *statusMenu;
272
     [application orderFrontStandardAboutPanel:self];
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
 // ------------ 'Ambilight' Visualizations ------------
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
 UInt8 ledColorData[LED_COUNT * 3];
344
 UInt8 ledColorData[LED_COUNT * 3];
340
 
345
 
341
 - (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 {
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
     }
366
     }
362
     
367
     
363
     unsigned long red = 0, green = 0, blue = 0, count = 0;
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
         for (NSInteger j = ya; j < yb; j++) {
370
         for (NSInteger j = ya; j < yb; j++) {
366
             count++;
371
             count++;
367
             unsigned long index = i + (j * width);
372
             unsigned long index = i + (j * width);
396
                 blockHeight = strands[i].size;
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
                 // First move appropriately in the direction of the strand
405
                 // First move appropriately in the direction of the strand
401
                 unsigned long endX = x, endY = y;
406
                 unsigned long endX = x, endY = y;
402
                 if (strands[i].direction == DIR_LEFT) {
407
                 if (strands[i].direction == DIR_LEFT) {
428
                 // Calculate average color for this led
433
                 // Calculate average color for this led
429
                 UInt32 color = [self calculateAverage:data Width:width Height:height SPP:spp Alpha:alpha StartX:x StartY:y EndX:endX EndY:endY];
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
                 ledColorData[led * 3] = (color & 0xFF0000) >> 16;
436
                 ledColorData[led * 3] = (color & 0xFF0000) >> 16;
433
                 ledColorData[(led * 3) + 1] = (color & 0x00FF00) >> 8;
437
                 ledColorData[(led * 3) + 1] = (color & 0x00FF00) >> 8;
434
                 ledColorData[(led * 3) + 2] = color & 0x0000FF;
438
                 ledColorData[(led * 3) + 2] = color & 0x0000FF;
445
 }
449
 }
446
 
450
 
447
 - (void)visualizeDisplay:(NSTimer *)time {
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
     //NSLog(@"Running Ambilight-Algorithm (%lu)...", (unsigned long)[lastDisplayIDs count]);
460
     //NSLog(@"Running Ambilight-Algorithm (%lu)...", (unsigned long)[lastDisplayIDs count]);
449
     
461
     
450
     // Create a Screenshot for all connected displays
462
     // Create a Screenshot for all connected displays
478
     
490
     
479
     [self sendLEDFrame];
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
 @end
507
 @end

+ 1
- 1
DisplayBacklight/Info.plist View File

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

Loading…
Cancel
Save