Crash Fix: Only selectively register observer

This affects User Defaults, but only has any effect on ChunkLists which
are being used for conversion, and only if they're processing DSD source
material. Thus, the observer should only be added on the one stream that
is converting DSD, and should definitely be removed when the object is
deallocated.

This fixes a serious crash bug that mostly appears to only affect Intel
Macs, and has no major side effects on Apple Silicon that I can tell.
It's a good thing I still own an Intel Mac or two to test on, even if
they are both trapped on older releases of macOS.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-03-13 19:20:12 -07:00
parent fdd0244067
commit 9aaf6d1c2d
2 changed files with 22 additions and 3 deletions

View file

@ -39,6 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
int dsd2pcmLatency; int dsd2pcmLatency;
#endif #endif
BOOL observersRegistered;
BOOL halveDSDVolume; BOOL halveDSDVolume;
void *hdcd_decoder; void *hdcd_decoder;

View file

@ -399,19 +399,36 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
dsd2pcmLatency = 0; dsd2pcmLatency = 0;
#endif #endif
halveDSDVolume = NO; observersRegistered = NO;
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.halveDSDVolume" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kChunkListContext];
} }
return self; return self;
} }
- (void)addObservers {
if(!observersRegistered) {
halveDSDVolume = NO;
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.halveDSDVolume" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kChunkListContext];
observersRegistered = YES;
}
}
- (void)removeObservers {
if(observersRegistered) {
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.halveDSDVolume" context:kChunkListContext];
observersRegistered = NO;
}
}
- (void)dealloc { - (void)dealloc {
stopping = YES; stopping = YES;
while(inAdder || inRemover || inPeeker || inMerger || inConverter) { while(inAdder || inRemover || inPeeker || inMerger || inConverter) {
usleep(500); usleep(500);
} }
[self removeObservers];
if(hdcd_decoder) { if(hdcd_decoder) {
free(hdcd_decoder); free(hdcd_decoder);
hdcd_decoder = NULL; hdcd_decoder = NULL;
@ -786,6 +803,7 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
isFloat = YES; isFloat = YES;
inputBuffer = &tempData[buffer_adder]; inputBuffer = &tempData[buffer_adder];
inputChanged = YES; inputChanged = YES;
[self addObservers];
#if DSD_DECIMATE #if DSD_DECIMATE
if(halveDSDVolume) { if(halveDSDVolume) {
float scaleFactor = 2.0f; float scaleFactor = 2.0f;