From 7a0c1d230e2d72739f2bf835372475dfb9722ea2 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Mon, 17 Jan 2022 22:41:26 -0800 Subject: [PATCH] Volume control: Make preamp optional, defaulting to a limit of 100% volume --- Application/PlaybackController.m | 41 ++++++++++++++----- Audio/AudioPlayer.m | 12 ++++-- Audio/Helper.h | 6 +-- Audio/Helper.m | 8 ++-- .../Preferences/Base.lproj/Preferences.xib | 39 +++++++++++------- Window/VolumeSlider.h | 1 + Window/VolumeSlider.m | 28 ++++++++++++- 7 files changed, 97 insertions(+), 38 deletions(-) diff --git a/Application/PlaybackController.m b/Application/PlaybackController.m index 5b1a17167..a90b05f11 100644 --- a/Application/PlaybackController.m +++ b/Application/PlaybackController.m @@ -63,6 +63,7 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation"; [NSNumber numberWithBool:NO], @"GraphicEQenable", [NSNumber numberWithInt:-1], @"GraphicEQpreset", [NSNumber numberWithBool:NO], @"GraphicEQtrackgenre", + [NSNumber numberWithBool:YES], @"volumeLimit", nil]; [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsDictionary]; @@ -72,9 +73,12 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation"; - (void)awakeFromNib { - double volume = [[NSUserDefaults standardUserDefaults] doubleForKey:@"volume"]; + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; - [volumeSlider setDoubleValue:logarithmicToLinear(volume)]; + double volume = [[NSUserDefaults standardUserDefaults] doubleForKey:@"volume"]; + + [volumeSlider setDoubleValue:logarithmicToLinear(volume, MAX_VOLUME)]; [audioPlayer setVolume:volume]; [self setSeekable:NO]; @@ -350,9 +354,12 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe) */ - (IBAction)changeVolume:(id)sender { - DLog(@"VOLUME: %lf, %lf", [sender doubleValue], linearToLogarithmic([sender doubleValue])); + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; - [audioPlayer setVolume:linearToLogarithmic([sender doubleValue])]; + DLog(@"VOLUME: %lf, %lf", [sender doubleValue], linearToLogarithmic([sender doubleValue], MAX_VOLUME)); + + [audioPlayer setVolume:linearToLogarithmic([sender doubleValue], MAX_VOLUME)]; [[NSUserDefaults standardUserDefaults] setDouble:[audioPlayer volume] forKey:@"volume"]; } @@ -374,9 +381,12 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe) } else // volume is at 0 or below, we are ready to release the timer and move on { - [audioPlayer pause]; + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; + + [audioPlayer pause]; [audioPlayer setVolume:originalVolume]; - [volumeSlider setDoubleValue: logarithmicToLinear(originalVolume)]; + [volumeSlider setDoubleValue: logarithmicToLinear(originalVolume, MAX_VOLUME)]; [audioTimer invalidate]; fading = NO; @@ -401,8 +411,11 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe) } else // volume is at or near original level, we are ready to release the timer and move on { + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; + [audioPlayer setVolume:originalVolume]; - [volumeSlider setDoubleValue: logarithmicToLinear(originalVolume)]; + [volumeSlider setDoubleValue: logarithmicToLinear(originalVolume, MAX_VOLUME)]; [audioTimer invalidate]; fading = NO; @@ -539,8 +552,11 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe) - (IBAction)volumeDown:(id)sender { - double newVolume = [audioPlayer volumeDown:DEFAULT_VOLUME_DOWN]; - [volumeSlider setDoubleValue:logarithmicToLinear(newVolume)]; + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; + + double newVolume = [audioPlayer volumeDown:DEFAULT_VOLUME_DOWN]; + [volumeSlider setDoubleValue:logarithmicToLinear(newVolume, MAX_VOLUME)]; [[NSUserDefaults standardUserDefaults] setDouble:[audioPlayer volume] forKey:@"volume"]; @@ -548,9 +564,12 @@ NSDictionary * makeRGInfo(PlaylistEntry *pe) - (IBAction)volumeUp:(id)sender { - double newVolume; + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; + + double newVolume; newVolume = [audioPlayer volumeUp:DEFAULT_VOLUME_UP]; - [volumeSlider setDoubleValue:logarithmicToLinear(newVolume)]; + [volumeSlider setDoubleValue:logarithmicToLinear(newVolume, MAX_VOLUME)]; [[NSUserDefaults standardUserDefaults] setDouble:[audioPlayer volume] forKey:@"volume"]; } diff --git a/Audio/AudioPlayer.m b/Audio/AudioPlayer.m index 9d8a23967..2d647e37f 100644 --- a/Audio/AudioPlayer.m +++ b/Audio/AudioPlayer.m @@ -566,7 +566,10 @@ - (double)volumeUp:(double)amount { - double newVolume = linearToLogarithmic(logarithmicToLinear(volume + amount)); + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; + + double newVolume = linearToLogarithmic(logarithmicToLinear(volume + amount, MAX_VOLUME), MAX_VOLUME); if (newVolume > MAX_VOLUME) newVolume = MAX_VOLUME; @@ -579,11 +582,14 @@ - (double)volumeDown:(double)amount { - double newVolume; + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; + + double newVolume; if (amount > volume) newVolume = 0.0; else - newVolume = linearToLogarithmic(logarithmicToLinear(volume - amount)); + newVolume = linearToLogarithmic(logarithmicToLinear(volume - amount, MAX_VOLUME), MAX_VOLUME); [self setVolume:newVolume]; return newVolume; diff --git a/Audio/Helper.h b/Audio/Helper.h index 5517e65ee..c28b7170f 100644 --- a/Audio/Helper.h +++ b/Audio/Helper.h @@ -7,7 +7,5 @@ * */ -#define MAX_VOLUME 800.0 - -double logarithmicToLinear(double logarithmic); -double linearToLogarithmic(double linear); +double logarithmicToLinear(double logarithmic, double MAX_VOLUME); +double linearToLogarithmic(double linear, double MAX_VOLUME); diff --git a/Audio/Helper.m b/Audio/Helper.m index 4c885ce0b..48998e6e6 100644 --- a/Audio/Helper.m +++ b/Audio/Helper.m @@ -15,13 +15,13 @@ //Here's why: http://www.dr-lex.34sp.com/info-stuff/volumecontrols.html //We are using the approximation of X^4. //Input/Output values are in percents. -double logarithmicToLinear(double logarithmic) +double logarithmicToLinear(double logarithmic, double MAX_VOLUME) { - return pow((logarithmic/MAX_VOLUME), 0.25) * 100.0; + return pow((logarithmic/MAX_VOLUME), 0.25) * 100.0; } -double linearToLogarithmic(double linear) +double linearToLogarithmic(double linear, double MAX_VOLUME) { - return (linear/100.0) * (linear/100.0) * (linear/100.0) * (linear/100.0) * MAX_VOLUME; + return (linear/100.0) * (linear/100.0) * (linear/100.0) * (linear/100.0) * MAX_VOLUME; } //End helper volume function thingies. ONWARDS TO GLORY! diff --git a/Preferences/Preferences/Base.lproj/Preferences.xib b/Preferences/Preferences/Base.lproj/Preferences.xib index df7bb438e..52566f149 100644 --- a/Preferences/Preferences/Base.lproj/Preferences.xib +++ b/Preferences/Preferences/Base.lproj/Preferences.xib @@ -245,18 +245,9 @@ - + - - - - - - - - - @@ -267,7 +258,7 @@ - + @@ -288,7 +279,7 @@ - + @@ -297,7 +288,7 @@ - + @@ -338,8 +329,28 @@ + + + + + + + + + + - + diff --git a/Window/VolumeSlider.h b/Window/VolumeSlider.h index e62a9585f..e3e56866d 100644 --- a/Window/VolumeSlider.h +++ b/Window/VolumeSlider.h @@ -11,6 +11,7 @@ @interface VolumeSlider : NSSlider { NSPopover *popover; NSText *textView; + double MAX_VOLUME; } - (void)showToolTip; diff --git a/Window/VolumeSlider.m b/Window/VolumeSlider.m index 62bc8f292..c23386cd5 100644 --- a/Window/VolumeSlider.m +++ b/Window/VolumeSlider.m @@ -28,6 +28,9 @@ } - (void) awakeFromNib { + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; + wasInsideSnapRange = NO; textView = [[NSText alloc] init]; [textView setFrame:NSMakeRect(0, 0, 50, 20)]; @@ -44,12 +47,19 @@ popover.behavior = NSPopoverBehaviorTransient; popover.animates = NO; [popover setContentSize:textView.bounds.size]; + + [[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.volumeLimit" options:0 context:nil]; +} + +- (void)dealloc +{ + [[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.volumeLimit"]; } - (void)updateToolTip { double value = [self doubleValue]; - double volume = linearToLogarithmic(value); + double volume = linearToLogarithmic(value, MAX_VOLUME); NSString *text = [NSString stringWithFormat:@"%0.lf%%", volume]; @@ -114,10 +124,24 @@ } } +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if ([keyPath isEqualToString:@"values.volumeLimit"]) { + BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"]; + const double new_MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0; + + if (MAX_VOLUME != new_MAX_VOLUME) { + double currentLevel = linearToLogarithmic([self doubleValue], MAX_VOLUME); + [self setDoubleValue:logarithmicToLinear(currentLevel, new_MAX_VOLUME)]; + } + MAX_VOLUME = new_MAX_VOLUME; + } +} + - (BOOL)sendAction:(SEL)theAction to:(id)theTarget { // Snap to 100% if value is close - double snapTarget = logarithmicToLinear(100.0); + double snapTarget = logarithmicToLinear(100.0, MAX_VOLUME); double snapProgress = ([self doubleValue] - snapTarget) / (self.maxValue - self.minValue); if (fabs(snapProgress) < 0.005)