From 1728debe9465f3016d1cf025794b8ceee023ec2f Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Wed, 8 Jun 2022 21:32:52 -0700 Subject: [PATCH] [Visualizer] Bring back CoreGraphics visualizer For legacy systems that do not support Metal. The Metal SceneKit view does work on even 10.13.6, if a Metal GPU is present in the system. Signed-off-by: Christopher Snowhill --- Cog.xcodeproj/project.pbxproj | 24 ++- SpectrumViewLegacy.h | 20 +++ SpectrumViewLegacy.m | 296 ++++++++++++++++++++++++++++++++++ SpectrumWindowController.m | 26 ++- Utils/NSView+Visibility.h | 17 ++ Utils/NSView+Visibility.m | 26 +++ Visualization/SpectrumItem.h | 2 - Visualization/SpectrumItem.m | 7 +- Visualization/SpectrumView.m | 41 ++--- 9 files changed, 412 insertions(+), 47 deletions(-) create mode 100644 SpectrumViewLegacy.h create mode 100644 SpectrumViewLegacy.m create mode 100644 Utils/NSView+Visibility.h create mode 100644 Utils/NSView+Visibility.m diff --git a/Cog.xcodeproj/project.pbxproj b/Cog.xcodeproj/project.pbxproj index 9990fd7c2..77f9724cc 100644 --- a/Cog.xcodeproj/project.pbxproj +++ b/Cog.xcodeproj/project.pbxproj @@ -104,6 +104,8 @@ 832923AF279FAC400048201E /* Cog.q1.json in Resources */ = {isa = PBXBuildFile; fileRef = 832923AE279FAC400048201E /* Cog.q1.json */; }; 83293070277886250010C07E /* OpenMPTOld.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8329306D277885790010C07E /* OpenMPTOld.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 832C1253180BD1E2005507C1 /* Cog.help in Resources */ = {isa = PBXBuildFile; fileRef = 832C1252180BD1E2005507C1 /* Cog.help */; }; + 832CFC4F2851AA1A002AC26F /* NSView+Visibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 832CFC4E2851AA1A002AC26F /* NSView+Visibility.m */; }; + 832CFC562851AA8B002AC26F /* SpectrumViewLegacy.m in Sources */ = {isa = PBXBuildFile; fileRef = 832CFC552851AA8B002AC26F /* SpectrumViewLegacy.m */; }; 833D0C2527C4ABB80060E16A /* ScriptAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 833D0C2427C4ABB80060E16A /* ScriptAdditions.m */; }; 83489C6B2782F78700BDCEA2 /* libvgmPlayer.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83489C542782F2DF00BDCEA2 /* libvgmPlayer.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8349270C27B4EFFC0009AB2B /* duplicateItemsTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 8349270127B4EFFC0009AB2B /* duplicateItemsTemplate.pdf */; }; @@ -916,6 +918,10 @@ 832923AE279FAC400048201E /* Cog.q1.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Cog.q1.json; sourceTree = ""; }; 83293065277885790010C07E /* OpenMPTOld.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpenMPTOld.xcodeproj; path = Plugins/OpenMPT.old/OpenMPTOld.xcodeproj; sourceTree = ""; }; 832C1252180BD1E2005507C1 /* Cog.help */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Cog.help; sourceTree = ""; }; + 832CFC4E2851AA1A002AC26F /* NSView+Visibility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSView+Visibility.m"; sourceTree = ""; }; + 832CFC532851AA37002AC26F /* NSView+Visibility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSView+Visibility.h"; sourceTree = ""; }; + 832CFC542851AA8B002AC26F /* SpectrumViewLegacy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpectrumViewLegacy.h; sourceTree = SOURCE_ROOT; }; + 832CFC552851AA8B002AC26F /* SpectrumViewLegacy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpectrumViewLegacy.m; sourceTree = SOURCE_ROOT; }; 833D0C2027C4ABA00060E16A /* ScriptAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScriptAdditions.h; sourceTree = ""; }; 833D0C2427C4ABB80060E16A /* ScriptAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScriptAdditions.m; sourceTree = ""; }; 833F681E1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1230,20 +1236,22 @@ 172A12A80F59AF8A0078EF0C /* NSString+CogSort.m */, F6F9671A102C70C800D2C9B4 /* NSString+FinderCompare.h */, F6F96718102C709000D2C9B4 /* NSString+FinderCompare.m */, + 832CFC532851AA37002AC26F /* NSView+Visibility.h */, + 832CFC4E2851AA1A002AC26F /* NSView+Visibility.m */, + 83988F0C27BE0A5900A0E89A /* RedundantPlaylistDataStore.h */, + 83988F0D27BE0A5900A0E89A /* RedundantPlaylistDataStore.m */, + 8381A09027C5F72F00A1C530 /* SHA256Digest.h */, + 8381A09127C5F72F00A1C530 /* SHA256Digest.m */, 178456100F631E31007E8021 /* SideViewController.h */, 178456110F631E31007E8021 /* SideViewController.m */, + 8370D739277419D200245CE0 /* SQLiteStore.h */, + 8370D73C277419F700245CE0 /* SQLiteStore.m */, 17FAEBAA0F662985007C8707 /* ToolTipTextField.h */, 17FAEBAB0F662985007C8707 /* ToolTipTextField.m */, 177EC01A0B8BC2CF0000BC8C /* TrackingCell.h */, 177EC01B0B8BC2CF0000BC8C /* TrackingCell.m */, 177EC01C0B8BC2CF0000BC8C /* TrackingSlider.h */, 177EC01D0B8BC2CF0000BC8C /* TrackingSlider.m */, - 8370D739277419D200245CE0 /* SQLiteStore.h */, - 8370D73C277419F700245CE0 /* SQLiteStore.m */, - 83988F0C27BE0A5900A0E89A /* RedundantPlaylistDataStore.h */, - 83988F0D27BE0A5900A0E89A /* RedundantPlaylistDataStore.m */, - 8381A09027C5F72F00A1C530 /* SHA256Digest.h */, - 8381A09127C5F72F00A1C530 /* SHA256Digest.m */, ); path = Utils; sourceTree = ""; @@ -1814,6 +1822,8 @@ 8377C66427B8CF7A00E8BC0F /* VisualizationController.h */, 8377C66227B8CF6300E8BC0F /* SpectrumView.h */, 8377C66127B8CF6300E8BC0F /* SpectrumView.m */, + 832CFC542851AA8B002AC26F /* SpectrumViewLegacy.h */, + 832CFC552851AA8B002AC26F /* SpectrumViewLegacy.m */, 8377C6B727B900F000E8BC0F /* SpectrumItem.h */, 8377C6B827B900F000E8BC0F /* SpectrumItem.m */, 83229C9C283B0095004626A8 /* SpectrumWindowController.h */, @@ -2565,6 +2575,7 @@ 5604D4F60D60726E004F5C5D /* SpotlightPlaylistEntry.m in Sources */, 56462EAF0D6341F6000AB68C /* SpotlightTransformers.m in Sources */, 830C37A527B95EB300E02BB0 /* EqualizerWindowController.m in Sources */, + 832CFC562851AA8B002AC26F /* SpectrumViewLegacy.m in Sources */, 56462EB20D634206000AB68C /* SpotlightPlaylistController.m in Sources */, 07E18DF30D62B38400BB0E11 /* NSArray+ShuffleUtils.m in Sources */, 56C63D910D647DF300EAE25A /* NSComparisonPredicate+CogPredicate.m in Sources */, @@ -2614,6 +2625,7 @@ 835A8FD327957310005B3C39 /* json.c in Sources */, 17D1B25D0F633A4F00694C57 /* PreferencePluginController.m in Sources */, 171CB3DC0F63670D0047EF0A /* PreferencesWindow.m in Sources */, + 832CFC4F2851AA1A002AC26F /* NSView+Visibility.m in Sources */, 1778D3CA0F645BF00037E7A0 /* MissingAlbumArtTransformer.m in Sources */, 8399D4E21805A55000B503B1 /* XmlContainer.m in Sources */, 17FAEBAC0F662985007C8707 /* ToolTipTextField.m in Sources */, diff --git a/SpectrumViewLegacy.h b/SpectrumViewLegacy.h new file mode 100644 index 000000000..c23fc7f38 --- /dev/null +++ b/SpectrumViewLegacy.h @@ -0,0 +1,20 @@ +// +// SpectrumViewLegacy.h +// Cog +// +// Created by Christopher Snowhill on 2/12/22. +// + +#import + +#import "VisualizationController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SpectrumViewLegacy : NSView +@property(nonatomic) BOOL isListening; + +- (void)startPlayback; +@end + +NS_ASSUME_NONNULL_END diff --git a/SpectrumViewLegacy.m b/SpectrumViewLegacy.m new file mode 100644 index 000000000..df6c34db6 --- /dev/null +++ b/SpectrumViewLegacy.m @@ -0,0 +1,296 @@ +// +// SpectrumViewLegacy.m +// Cog +// +// Created by Christopher Snowhill on 2/12/22. +// + +#import "SpectrumViewLegacy.h" + +#import "NSView+Visibility.h" + +#import "analyzer.h" + +#define LOWER_BOUND -80 + +extern NSString *CogPlaybackDidBeginNotficiation; +extern NSString *CogPlaybackDidPauseNotficiation; +extern NSString *CogPlaybackDidResumeNotficiation; +extern NSString *CogPlaybackDidStopNotficiation; + +@interface SpectrumViewLegacy () { + VisualizationController *visController; + NSTimer *timer; + BOOL paused; + BOOL stopped; + BOOL isListening; + BOOL observersAdded; + + NSRect initFrame; + + NSColor *baseColor; + NSColor *peakColor; + NSColor *backgroundColor; + NSColor *borderColor; + ddb_analyzer_t _analyzer; + ddb_analyzer_draw_data_t _draw_data; +} +@end + +@implementation SpectrumViewLegacy + +@synthesize isListening; + +- (id)initWithFrame:(NSRect)frame { + self = [super initWithFrame:frame]; + if(self) { + initFrame = frame; + [self setup]; + } + return self; +} + +- (void)updateVisListening { + if(self.isListening && (![self visibleInWindow] || paused || stopped)) { + [self stopTimer]; + self.isListening = NO; + } else if(!self.isListening && ([self visibleInWindow] && !stopped && !paused)) { + [self startTimer]; + self.isListening = YES; + } +} + +- (void)setup { + visController = [NSClassFromString(@"VisualizationController") sharedController]; + timer = nil; + stopped = YES; + paused = NO; + isListening = NO; + + [self colorsDidChange:nil]; + + BOOL freqMode = [[NSUserDefaults standardUserDefaults] boolForKey:@"spectrumFreqMode"]; + + ddb_analyzer_init(&_analyzer); + _analyzer.db_lower_bound = LOWER_BOUND; + _analyzer.min_freq = 10; + _analyzer.max_freq = 22000; + _analyzer.peak_hold = 10; + _analyzer.view_width = 64; + _analyzer.fractional_bars = 1; + _analyzer.octave_bars_step = 2; + _analyzer.max_of_stereo_data = 1; + _analyzer.freq_is_log = 0; + _analyzer.mode = freqMode ? DDB_ANALYZER_MODE_FREQUENCIES : DDB_ANALYZER_MODE_OCTAVE_NOTE_BANDS; + + [self addObservers]; +} + +- (void)addObservers { + if(!observersAdded) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(colorsDidChange:) + name:NSSystemColorsDidChangeNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(playbackDidBegin:) + name:CogPlaybackDidBeginNotficiation + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(playbackDidPause:) + name:CogPlaybackDidPauseNotficiation + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(playbackDidResume:) + name:CogPlaybackDidResumeNotficiation + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(playbackDidStop:) + name:CogPlaybackDidStopNotficiation + object:nil]; + observersAdded = YES; + } +} + +- (void)dealloc { + ddb_analyzer_dealloc(&_analyzer); + ddb_analyzer_draw_data_dealloc(&_draw_data); + + [self removeObservers]; +} + +- (void)removeObservers { + if(observersAdded) { + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSSystemColorsDidChangeNotification + object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:CogPlaybackDidBeginNotficiation + object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:CogPlaybackDidPauseNotficiation + object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:CogPlaybackDidResumeNotficiation + object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:CogPlaybackDidStopNotficiation + object:nil]; + observersAdded = NO; + } +} + +- (void)repaint { + self.needsDisplay = YES; +} + +- (void)startTimer { + [self stopTimer]; + timer = [NSTimer timerWithTimeInterval:1.0 / 60.0 + target:self + selector:@selector(timerRun:) + userInfo:nil + repeats:YES]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; +} + +- (void)stopTimer { + [timer invalidate]; + timer = nil; +} + +- (void)timerRun:(NSTimer *)timer { + [self repaint]; +} + +- (void)colorsDidChange:(NSNotification *)notification { + backgroundColor = [NSColor textBackgroundColor]; + 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]; + } + + [self repaint]; +} + +- (void)startPlayback { + [self playbackDidBegin:nil]; +} + +- (void)playbackDidBegin:(NSNotification *)notification { + stopped = NO; + paused = NO; + [self updateVisListening]; +} + +- (void)playbackDidPause:(NSNotification *)notification { + stopped = NO; + paused = YES; + [self updateVisListening]; +} + +- (void)playbackDidResume:(NSNotification *)notification { + stopped = NO; + paused = NO; + [self updateVisListening]; +} + +- (void)playbackDidStop:(NSNotification *)notification { + stopped = YES; + paused = NO; + [self updateVisListening]; + [self repaint]; +} + +- (void)drawAnalyzerDescreteFrequencies { + CGContextRef context = NSGraphicsContext.currentContext.CGContext; + ddb_analyzer_draw_bar_t *bar = _draw_data.bars; + for(int i = 0; i < _draw_data.bar_count; i++, bar++) { + CGContextMoveToPoint(context, bar->xpos, 0); + CGContextAddLineToPoint(context, bar->xpos, bar->bar_height); + } + CGContextSetStrokeColorWithColor(context, baseColor.CGColor); + CGContextStrokePath(context); + + bar = _draw_data.bars; + for(int i = 0; i < _draw_data.bar_count; i++, bar++) { + CGContextMoveToPoint(context, bar->xpos - 0.5, bar->peak_ypos); + CGContextAddLineToPoint(context, bar->xpos + 0.5, bar->peak_ypos); + } + CGContextSetStrokeColorWithColor(context, peakColor.CGColor); + CGContextStrokePath(context); +} + +- (void)drawAnalyzerOctaveBands { + CGContextRef context = NSGraphicsContext.currentContext.CGContext; + ddb_analyzer_draw_bar_t *bar = _draw_data.bars; + for(int i = 0; i < _draw_data.bar_count; i++, bar++) { + CGContextAddRect(context, CGRectMake(bar->xpos, 0, _draw_data.bar_width, bar->bar_height)); + } + CGContextSetFillColorWithColor(context, baseColor.CGColor); + CGContextFillPath(context); + + bar = _draw_data.bars; + for(int i = 0; i < _draw_data.bar_count; i++, bar++) { + CGContextAddRect(context, CGRectMake(bar->xpos, bar->peak_ypos, _draw_data.bar_width, 1.0)); + } + CGContextSetFillColorWithColor(context, peakColor.CGColor); + CGContextFillPath(context); +} + +- (void)drawAnalyzer { + if(_analyzer.mode == DDB_ANALYZER_MODE_FREQUENCIES) { + [self drawAnalyzerDescreteFrequencies]; + } else { + [self drawAnalyzerOctaveBands]; + } +} + +- (void)drawRect:(NSRect)dirtyRect { + [super drawRect:dirtyRect]; + + [self updateVisListening]; + + [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(stopped) return; + + float visAudio[4096], visFFT[2048]; + + [self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0]]; + + ddb_analyzer_process(&_analyzer, [self->visController readSampleRate] / 2.0, 1, visFFT, 2048); + ddb_analyzer_tick(&_analyzer); + ddb_analyzer_get_draw_data(&_analyzer, self.bounds.size.width, self.bounds.size.height, &_draw_data); + + [self drawAnalyzer]; +} + +- (void)mouseDown:(NSEvent *)event { + BOOL freqMode = ![[NSUserDefaults standardUserDefaults] boolForKey:@"spectrumFreqMode"]; + [[NSUserDefaults standardUserDefaults] setBool:freqMode forKey:@"spectrumFreqMode"]; + + _analyzer.mode = freqMode ? DDB_ANALYZER_MODE_FREQUENCIES : DDB_ANALYZER_MODE_OCTAVE_NOTE_BANDS; + _analyzer.mode_did_change = 1; + + [self repaint]; +} + +@end diff --git a/SpectrumWindowController.m b/SpectrumWindowController.m index 5b3528a4e..2dcb6b720 100644 --- a/SpectrumWindowController.m +++ b/SpectrumWindowController.m @@ -8,9 +8,11 @@ #import "SpectrumWindowController.h" #import "SpectrumView.h" +#import "SpectrumViewLegacy.h" @interface SpectrumWindowController () @property SpectrumView *spectrumView; +@property SpectrumViewLegacy *spectrumViewLegacy; @end @implementation SpectrumWindowController @@ -26,21 +28,31 @@ } - (void)startRunning { - if(!self.spectrumView) { - self.spectrumView = [[SpectrumView alloc] initWithFrame:[[self window] frame]]; - [[self window] setContentView:self.spectrumView]; - if(!self.spectrumView) return; + if(!self.spectrumView && !self.spectrumViewLegacy) { + NSRect frame = [[self window] frame]; + self.spectrumView = [[SpectrumView alloc] initWithFrame:frame]; + if(self.spectrumView) { + [[self window] setContentView:self.spectrumView]; - [self.spectrumView enableCameraControl]; + [self.spectrumView enableCameraControl]; + } else { + self.spectrumViewLegacy = [[SpectrumViewLegacy alloc] initWithFrame:frame]; + [[self window] setContentView:self.spectrumViewLegacy]; + } } - if(playbackController.playbackStatus == CogStatusPlaying) - [self.spectrumView startPlayback]; + if(playbackController.playbackStatus == CogStatusPlaying) { + if(self.spectrumView) + [self.spectrumView startPlayback]; + else if(self.spectrumViewLegacy) + [self.spectrumViewLegacy startPlayback]; + } } - (void)stopRunning { [[self window] setContentView:nil]; self.spectrumView = nil; + self.spectrumViewLegacy = nil; } - (void)windowWillClose:(NSNotification *)notification { diff --git a/Utils/NSView+Visibility.h b/Utils/NSView+Visibility.h new file mode 100644 index 000000000..af5929363 --- /dev/null +++ b/Utils/NSView+Visibility.h @@ -0,0 +1,17 @@ +// +// NSView+Visibility.h +// Cog +// +// Created by Christopher Snowhill on 6/8/22. +// + +#ifndef NSView_Visibility_h +#define NSView_Visibility_h + +#import + +@interface NSView (Visibility) +- (BOOL)visibleInWindow; +@end + +#endif /* NSView_Visibility_h */ diff --git a/Utils/NSView+Visibility.m b/Utils/NSView+Visibility.m new file mode 100644 index 000000000..56a23d2e4 --- /dev/null +++ b/Utils/NSView+Visibility.m @@ -0,0 +1,26 @@ +// +// NSView+Visibility.m +// Cog +// +// Created by Christopher Snowhill on 6/8/22. +// + +#import "NSView+Visibility.h" + +@implementation NSView (Visibility) + +- (BOOL)visibleInWindow { + if(self.window == nil) { + return NO; + } + + // Might have zero opacity. + if(self.alphaValue == 0 || self.hiddenOrHasHiddenAncestor) { + return NO; + } + + // Might be clipped by an ancestor. + return !NSIsEmptyRect(self.visibleRect); +} + +@end diff --git a/Visualization/SpectrumItem.h b/Visualization/SpectrumItem.h index 91b5420b1..7fd4892f8 100644 --- a/Visualization/SpectrumItem.h +++ b/Visualization/SpectrumItem.h @@ -7,8 +7,6 @@ #import -#import "SpectrumView.h" - NS_ASSUME_NONNULL_BEGIN @interface SpectrumItem : NSToolbarItem diff --git a/Visualization/SpectrumItem.m b/Visualization/SpectrumItem.m index f2114abe5..d895bb490 100644 --- a/Visualization/SpectrumItem.m +++ b/Visualization/SpectrumItem.m @@ -7,10 +7,15 @@ #import "SpectrumItem.h" +#import "SpectrumView.h" +#import "SpectrumViewLegacy.h" + @implementation SpectrumItem - (void)awakeFromNib { - SpectrumView *view = [[SpectrumView alloc] initWithFrame:NSMakeRect(0, 0, 64, 26)]; + NSRect frame = NSMakeRect(0, 0, 64, 26); + NSView *view = [[SpectrumView alloc] initWithFrame:frame]; + if(!view) view = [[SpectrumViewLegacy alloc] initWithFrame:frame]; [self setView:view]; } diff --git a/Visualization/SpectrumView.m b/Visualization/SpectrumView.m index 932dba465..448882490 100644 --- a/Visualization/SpectrumView.m +++ b/Visualization/SpectrumView.m @@ -7,6 +7,8 @@ #import "SpectrumView.h" +#import "NSView+Visibility.h" + #import #import "analyzer.h" @@ -20,29 +22,6 @@ extern NSString *CogPlaybackDidPauseNotficiation; extern NSString *CogPlaybackDidResumeNotficiation; extern NSString *CogPlaybackDidStopNotficiation; -@interface NSView (Visibility) -- (BOOL)visibleInWindow; -@end - -@implementation NSView (Visibility) - -- (BOOL)visibleInWindow -{ - if(self.window == nil) { - return NO; - } - - // Might have zero opacity. - if(self.alphaValue == 0 || self.hiddenOrHasHiddenAncestor) { - return NO; - } - - // Might be clipped by an ancestor. - return !NSIsEmptyRect(self.visibleRect); -} - -@end - @interface SpectrumView () { VisualizationController *visController; NSTimer *timer; @@ -51,7 +30,7 @@ extern NSString *CogPlaybackDidStopNotficiation; BOOL isListening; BOOL bandsReset; BOOL cameraControlEnabled; - BOOL observersRegistered; + BOOL observersAdded; NSColor *backgroundColor; ddb_analyzer_t _analyzer; @@ -71,7 +50,7 @@ extern NSString *CogPlaybackDidStopNotficiation; - (id)initWithFrame:(NSRect)frame { id device = MTLCreateSystemDefaultDevice(); - if(!device) return nil; + if(1 || !device) return nil; NSDictionary *sceneOptions = @{ SCNPreferredRenderingAPIKey: @(SCNRenderingAPIMetal), @@ -197,11 +176,11 @@ extern NSString *CogPlaybackDidStopNotficiation; _analyzer.freq_is_log = 0; _analyzer.mode = freqMode ? DDB_ANALYZER_MODE_FREQUENCIES : DDB_ANALYZER_MODE_OCTAVE_NOTE_BANDS; - [self registerObservers]; + [self addObservers]; } -- (void)registerObservers { - if(!observersRegistered) { +- (void)addObservers { + if(!observersAdded) { [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.spectrumProjectionMode" options:0 context:kSpectrumViewContext]; [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.spectrumBarColor" options:0 context:kSpectrumViewContext]; [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.spectrumDotColor" options:0 context:kSpectrumViewContext]; @@ -225,7 +204,7 @@ extern NSString *CogPlaybackDidStopNotficiation; name:CogPlaybackDidStopNotficiation object:nil]; - observersRegistered = YES; + observersAdded = YES; } } @@ -237,7 +216,7 @@ extern NSString *CogPlaybackDidStopNotficiation; } - (void)removeObservers { - if(observersRegistered) { + if(observersAdded) { [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.spectrumProjectionMode"]; [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.spectrumBarColor"]; [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.spectrumDotColor"]; @@ -257,7 +236,7 @@ extern NSString *CogPlaybackDidStopNotficiation; name:CogPlaybackDidStopNotficiation object:nil]; - observersRegistered = NO; + observersAdded = NO; } }