From b3b4d728f97ae0248eb3a722168b3204fd43cd15 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Fri, 10 Jun 2022 22:38:46 -0700 Subject: [PATCH] [Legacy Visualizer] Customizable colors, labels The legacy 2D visualizer now supports customizable bar and peak dot colors, and renders a grid and labels in the windowed mode. Signed-off-by: Christopher Snowhill --- SpectrumViewLegacy.h | 1 + SpectrumViewLegacy.m | 131 ++++++++++++++++++++++++++++++++----- SpectrumWindowController.m | 6 +- 3 files changed, 121 insertions(+), 17 deletions(-) diff --git a/SpectrumViewLegacy.h b/SpectrumViewLegacy.h index c23fc7f38..90feb8a0f 100644 --- a/SpectrumViewLegacy.h +++ b/SpectrumViewLegacy.h @@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic) BOOL isListening; - (void)startPlayback; +- (void)enableFullView; @end NS_ASSUME_NONNULL_END diff --git a/SpectrumViewLegacy.m b/SpectrumViewLegacy.m index df6c34db6..7efc9d3b6 100644 --- a/SpectrumViewLegacy.m +++ b/SpectrumViewLegacy.m @@ -13,6 +13,8 @@ #define LOWER_BOUND -80 +static void *kSpectrumViewLegacyContext = &kSpectrumViewLegacyContext; + extern NSString *CogPlaybackDidBeginNotficiation; extern NSString *CogPlaybackDidPauseNotficiation; extern NSString *CogPlaybackDidResumeNotficiation; @@ -21,13 +23,16 @@ extern NSString *CogPlaybackDidStopNotficiation; @interface SpectrumViewLegacy () { VisualizationController *visController; NSTimer *timer; + float saLowerBound; BOOL paused; BOOL stopped; BOOL isListening; BOOL observersAdded; + BOOL isFullView; NSRect initFrame; + NSDictionary *textAttrs; NSColor *baseColor; NSColor *peakColor; NSColor *backgroundColor; @@ -67,6 +72,8 @@ extern NSString *CogPlaybackDidStopNotficiation; paused = NO; isListening = NO; + saLowerBound = LOWER_BOUND; + [self colorsDidChange:nil]; BOOL freqMode = [[NSUserDefaults standardUserDefaults] boolForKey:@"spectrumFreqMode"]; @@ -86,8 +93,32 @@ extern NSString *CogPlaybackDidStopNotficiation; [self addObservers]; } +- (void)enableFullView { + isFullView = YES; + _analyzer.freq_is_log = 1; + [self repaint]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context { + if(context == kSpectrumViewLegacyContext) { + if([keyPath isEqualToString:@"self.window.visible"]) { + [self updateVisListening]; + } else { + [self colorsDidChange:nil]; + } + } +} + - (void)addObservers { if(!observersAdded) { + [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.spectrumBarColor" options:0 context:kSpectrumViewLegacyContext]; + [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.spectrumDotColor" options:0 context:kSpectrumViewLegacyContext]; + + [self addObserver:self forKeyPath:@"self.window.visible" options:0 context:kSpectrumViewLegacyContext]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(colorsDidChange:) name:NSSystemColorsDidChangeNotification @@ -121,6 +152,11 @@ extern NSString *CogPlaybackDidStopNotficiation; - (void)removeObservers { if(observersAdded) { + [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.spectrumBarColor" context:kSpectrumViewLegacyContext]; + [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.spectrumDotColor" context:kSpectrumViewLegacyContext]; + + [self removeObserver:self forKeyPath:@"self.window.visible" context:kSpectrumViewLegacyContext]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSSystemColorsDidChangeNotification object:nil]; @@ -168,14 +204,19 @@ extern NSString *CogPlaybackDidStopNotficiation; backgroundColor = [backgroundColor colorWithAlphaComponent:0.0]; borderColor = [NSColor systemGrayColor]; - if(@available(macOS 10.14, *)) { - baseColor = [NSColor textColor]; - peakColor = [NSColor controlAccentColor]; - peakColor = [peakColor colorWithAlphaComponent:0.7]; - } else { - peakColor = [NSColor textColor]; - baseColor = [peakColor colorWithAlphaComponent:0.6]; - } + NSValueTransformer *colorToValueTransformer = [NSValueTransformer valueTransformerForName:@"ColorToValueTransformer"]; + + baseColor = [colorToValueTransformer transformedValue:[[NSUserDefaults standardUserDefaults] dataForKey:@"spectrumBarColor"]]; + peakColor = [colorToValueTransformer transformedValue:[[NSUserDefaults standardUserDefaults] dataForKey:@"spectrumDotColor"]]; + + NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; + paragraphStyle.alignment = NSTextAlignmentLeft; + + textAttrs = @{ + NSFontAttributeName: [NSFont fontWithName:@"HelveticaNeue" size:10], + NSParagraphStyleAttributeName: paragraphStyle, + NSForegroundColorAttributeName: borderColor + }; [self repaint]; } @@ -209,6 +250,53 @@ extern NSString *CogPlaybackDidStopNotficiation; [self repaint]; } +- (void)drawSaGrid { + CGContextRef context = NSGraphicsContext.currentContext.CGContext; + + // horz lines, db scale + CGContextSetStrokeColorWithColor(context, borderColor.CGColor); + CGFloat lower = -floor(saLowerBound); + for(int db = 10; db < lower; db += 10) { + CGFloat y = (CGFloat)(db / lower) * NSHeight(self.bounds); + if(y >= NSHeight(self.bounds)) { + break; + } + + CGPoint points[] = { + CGPointMake(0, y), + CGPointMake(NSWidth(self.bounds) - 1, y) + }; + CGContextAddLines(context, points, 2); + } + CGFloat dash[2] = { 1, 2 }; + CGContextSetLineDash(context, 0, dash, 2); + CGContextStrokePath(context); + CGContextSetLineDash(context, 0, NULL, 0); + + // db text + for(int db = 10; db < lower; db += 10) { + CGFloat y = (CGFloat)(db / lower) * NSHeight(self.bounds); + if(y >= NSHeight(self.bounds)) { + break; + } + + NSString *string = [NSString stringWithFormat:@"%d dB", -db]; + [string drawAtPoint:NSMakePoint(0, NSHeight(self.bounds) - y - 12) withAttributes:textAttrs]; + } +} + +- (void)drawFrequencyLabels { + // octaves text + for(int i = 0; i < _draw_data.label_freq_count; i++) { + if(_draw_data.label_freq_positions < 0) { + continue; + } + NSString *string = [NSString stringWithUTF8String:_draw_data.label_freq_texts[i]]; + CGFloat x = _draw_data.label_freq_positions[i]; + [string drawAtPoint:NSMakePoint(x, NSHeight(self.bounds) - 12) withAttributes:textAttrs]; + } +} + - (void)drawAnalyzerDescreteFrequencies { CGContextRef context = NSGraphicsContext.currentContext.CGContext; ddb_analyzer_draw_bar_t *bar = _draw_data.bars; @@ -261,17 +349,23 @@ extern NSString *CogPlaybackDidStopNotficiation; [backgroundColor setFill]; NSRectFill(dirtyRect); - CGContextRef context = NSGraphicsContext.currentContext.CGContext; - CGContextMoveToPoint(context, 0.0, 0.0); - CGContextAddLineToPoint(context, initFrame.size.width, 0.0); - CGContextAddLineToPoint(context, initFrame.size.width, initFrame.size.height); - CGContextAddLineToPoint(context, 0.0, initFrame.size.height); - CGContextAddLineToPoint(context, 0.0, 0.0); - CGContextSetStrokeColorWithColor(context, borderColor.CGColor); - CGContextStrokePath(context); + if(!isFullView) { + CGContextRef context = NSGraphicsContext.currentContext.CGContext; + CGContextMoveToPoint(context, 0.0, 0.0); + CGContextAddLineToPoint(context, initFrame.size.width, 0.0); + CGContextAddLineToPoint(context, initFrame.size.width, initFrame.size.height); + CGContextAddLineToPoint(context, 0.0, initFrame.size.height); + CGContextAddLineToPoint(context, 0.0, 0.0); + CGContextSetStrokeColorWithColor(context, borderColor.CGColor); + CGContextStrokePath(context); + } if(stopped) return; + if(isFullView) { + _analyzer.view_width = self.bounds.size.width; + } + float visAudio[4096], visFFT[2048]; [self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0]]; @@ -280,6 +374,11 @@ extern NSString *CogPlaybackDidStopNotficiation; ddb_analyzer_tick(&_analyzer); ddb_analyzer_get_draw_data(&_analyzer, self.bounds.size.width, self.bounds.size.height, &_draw_data); + if(isFullView) { + [self drawSaGrid]; + [self drawFrequencyLabels]; + } + [self drawAnalyzer]; } diff --git a/SpectrumWindowController.m b/SpectrumWindowController.m index 2dcb6b720..9b05f8a92 100644 --- a/SpectrumWindowController.m +++ b/SpectrumWindowController.m @@ -37,7 +37,11 @@ [self.spectrumView enableCameraControl]; } else { self.spectrumViewLegacy = [[SpectrumViewLegacy alloc] initWithFrame:frame]; - [[self window] setContentView:self.spectrumViewLegacy]; + if(self.spectrumViewLegacy) { + [[self window] setContentView:self.spectrumViewLegacy]; + + [self.spectrumViewLegacy enableFullView]; + } } }