[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 <kode54@gmail.com>
swiftingly
Christopher Snowhill 2022-06-10 22:38:46 -07:00
parent b821896560
commit b3b4d728f9
3 changed files with 121 additions and 17 deletions

View File

@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic) BOOL isListening; @property(nonatomic) BOOL isListening;
- (void)startPlayback; - (void)startPlayback;
- (void)enableFullView;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -13,6 +13,8 @@
#define LOWER_BOUND -80 #define LOWER_BOUND -80
static void *kSpectrumViewLegacyContext = &kSpectrumViewLegacyContext;
extern NSString *CogPlaybackDidBeginNotficiation; extern NSString *CogPlaybackDidBeginNotficiation;
extern NSString *CogPlaybackDidPauseNotficiation; extern NSString *CogPlaybackDidPauseNotficiation;
extern NSString *CogPlaybackDidResumeNotficiation; extern NSString *CogPlaybackDidResumeNotficiation;
@ -21,13 +23,16 @@ extern NSString *CogPlaybackDidStopNotficiation;
@interface SpectrumViewLegacy () { @interface SpectrumViewLegacy () {
VisualizationController *visController; VisualizationController *visController;
NSTimer *timer; NSTimer *timer;
float saLowerBound;
BOOL paused; BOOL paused;
BOOL stopped; BOOL stopped;
BOOL isListening; BOOL isListening;
BOOL observersAdded; BOOL observersAdded;
BOOL isFullView;
NSRect initFrame; NSRect initFrame;
NSDictionary *textAttrs;
NSColor *baseColor; NSColor *baseColor;
NSColor *peakColor; NSColor *peakColor;
NSColor *backgroundColor; NSColor *backgroundColor;
@ -67,6 +72,8 @@ extern NSString *CogPlaybackDidStopNotficiation;
paused = NO; paused = NO;
isListening = NO; isListening = NO;
saLowerBound = LOWER_BOUND;
[self colorsDidChange:nil]; [self colorsDidChange:nil];
BOOL freqMode = [[NSUserDefaults standardUserDefaults] boolForKey:@"spectrumFreqMode"]; BOOL freqMode = [[NSUserDefaults standardUserDefaults] boolForKey:@"spectrumFreqMode"];
@ -86,8 +93,32 @@ extern NSString *CogPlaybackDidStopNotficiation;
[self addObservers]; [self addObservers];
} }
- (void)enableFullView {
isFullView = YES;
_analyzer.freq_is_log = 1;
[self repaint];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey, id> *)change
context:(void *)context {
if(context == kSpectrumViewLegacyContext) {
if([keyPath isEqualToString:@"self.window.visible"]) {
[self updateVisListening];
} else {
[self colorsDidChange:nil];
}
}
}
- (void)addObservers { - (void)addObservers {
if(!observersAdded) { 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 [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(colorsDidChange:) selector:@selector(colorsDidChange:)
name:NSSystemColorsDidChangeNotification name:NSSystemColorsDidChangeNotification
@ -121,6 +152,11 @@ extern NSString *CogPlaybackDidStopNotficiation;
- (void)removeObservers { - (void)removeObservers {
if(observersAdded) { 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 [[NSNotificationCenter defaultCenter] removeObserver:self
name:NSSystemColorsDidChangeNotification name:NSSystemColorsDidChangeNotification
object:nil]; object:nil];
@ -168,14 +204,19 @@ extern NSString *CogPlaybackDidStopNotficiation;
backgroundColor = [backgroundColor colorWithAlphaComponent:0.0]; backgroundColor = [backgroundColor colorWithAlphaComponent:0.0];
borderColor = [NSColor systemGrayColor]; borderColor = [NSColor systemGrayColor];
if(@available(macOS 10.14, *)) { NSValueTransformer *colorToValueTransformer = [NSValueTransformer valueTransformerForName:@"ColorToValueTransformer"];
baseColor = [NSColor textColor];
peakColor = [NSColor controlAccentColor]; baseColor = [colorToValueTransformer transformedValue:[[NSUserDefaults standardUserDefaults] dataForKey:@"spectrumBarColor"]];
peakColor = [peakColor colorWithAlphaComponent:0.7]; peakColor = [colorToValueTransformer transformedValue:[[NSUserDefaults standardUserDefaults] dataForKey:@"spectrumDotColor"]];
} else {
peakColor = [NSColor textColor]; NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
baseColor = [peakColor colorWithAlphaComponent:0.6]; paragraphStyle.alignment = NSTextAlignmentLeft;
}
textAttrs = @{
NSFontAttributeName: [NSFont fontWithName:@"HelveticaNeue" size:10],
NSParagraphStyleAttributeName: paragraphStyle,
NSForegroundColorAttributeName: borderColor
};
[self repaint]; [self repaint];
} }
@ -209,6 +250,53 @@ extern NSString *CogPlaybackDidStopNotficiation;
[self repaint]; [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 { - (void)drawAnalyzerDescreteFrequencies {
CGContextRef context = NSGraphicsContext.currentContext.CGContext; CGContextRef context = NSGraphicsContext.currentContext.CGContext;
ddb_analyzer_draw_bar_t *bar = _draw_data.bars; ddb_analyzer_draw_bar_t *bar = _draw_data.bars;
@ -261,17 +349,23 @@ extern NSString *CogPlaybackDidStopNotficiation;
[backgroundColor setFill]; [backgroundColor setFill];
NSRectFill(dirtyRect); NSRectFill(dirtyRect);
CGContextRef context = NSGraphicsContext.currentContext.CGContext; if(!isFullView) {
CGContextMoveToPoint(context, 0.0, 0.0); CGContextRef context = NSGraphicsContext.currentContext.CGContext;
CGContextAddLineToPoint(context, initFrame.size.width, 0.0); CGContextMoveToPoint(context, 0.0, 0.0);
CGContextAddLineToPoint(context, initFrame.size.width, initFrame.size.height); CGContextAddLineToPoint(context, initFrame.size.width, 0.0);
CGContextAddLineToPoint(context, 0.0, initFrame.size.height); CGContextAddLineToPoint(context, initFrame.size.width, initFrame.size.height);
CGContextAddLineToPoint(context, 0.0, 0.0); CGContextAddLineToPoint(context, 0.0, initFrame.size.height);
CGContextSetStrokeColorWithColor(context, borderColor.CGColor); CGContextAddLineToPoint(context, 0.0, 0.0);
CGContextStrokePath(context); CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
CGContextStrokePath(context);
}
if(stopped) return; if(stopped) return;
if(isFullView) {
_analyzer.view_width = self.bounds.size.width;
}
float visAudio[4096], visFFT[2048]; float visAudio[4096], visFFT[2048];
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0]]; [self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0]];
@ -280,6 +374,11 @@ extern NSString *CogPlaybackDidStopNotficiation;
ddb_analyzer_tick(&_analyzer); ddb_analyzer_tick(&_analyzer);
ddb_analyzer_get_draw_data(&_analyzer, self.bounds.size.width, self.bounds.size.height, &_draw_data); ddb_analyzer_get_draw_data(&_analyzer, self.bounds.size.width, self.bounds.size.height, &_draw_data);
if(isFullView) {
[self drawSaGrid];
[self drawFrequencyLabels];
}
[self drawAnalyzer]; [self drawAnalyzer];
} }

View File

@ -37,7 +37,11 @@
[self.spectrumView enableCameraControl]; [self.spectrumView enableCameraControl];
} else { } else {
self.spectrumViewLegacy = [[SpectrumViewLegacy alloc] initWithFrame:frame]; self.spectrumViewLegacy = [[SpectrumViewLegacy alloc] initWithFrame:frame];
[[self window] setContentView:self.spectrumViewLegacy]; if(self.spectrumViewLegacy) {
[[self window] setContentView:self.spectrumViewLegacy];
[self.spectrumViewLegacy enableFullView];
}
} }
} }