Fixed crash, and in doing so introduced a huge memory leak!

Added patch from Eric Hanneken that improves shuffle.
This commit is contained in:
vspader 2008-02-16 02:46:19 +00:00
parent 35d4df9ca2
commit a4eb42eab0
7 changed files with 48 additions and 42 deletions

View file

@ -165,6 +165,7 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber
} }
if (callbackBuffer) { if (callbackBuffer) {
free(callbackBuffer); free(callbackBuffer);
callbackBuffer = NULL;
} }
} }

View file

@ -44,6 +44,7 @@
- (NSLock *)readLock; - (NSLock *)readLock;
- (NSLock *)writeLock; - (NSLock *)writeLock;
- (void)setPreviousNode:(id)p;
- (id)previousNode; - (id)previousNode;
- (BOOL)shouldContinue; - (BOOL)shouldContinue;

View file

@ -22,10 +22,11 @@
initialBufferFilled = NO; initialBufferFilled = NO;
controller = c; controller = [c retain];
previousNode = p;
endOfStream = NO; endOfStream = NO;
shouldContinue = YES; shouldContinue = YES;
[self setPreviousNode:p];
} }
return self; return self;
@ -88,7 +89,6 @@
[self process]; [self process];
[pool release]; [pool release];
[self release]; [self release];
@ -154,6 +154,13 @@
[NSThread detachNewThreadSelector:@selector(threadEntry:) toTarget:self withObject:nil]; [NSThread detachNewThreadSelector:@selector(threadEntry:) toTarget:self withObject:nil];
} }
- (void)setPreviousNode:(id)p
{
[p retain];
[previousNode release];
previousNode = p;
}
- (id)previousNode - (id)previousNode
{ {
return previousNode; return previousNode;
@ -221,6 +228,9 @@
- (void)dealloc - (void)dealloc
{ {
[controller release];
[previousNode release];
[buffer release]; [buffer release];
[semaphore release]; [semaphore release];
[readLock release]; [readLock release];

View file

@ -49,7 +49,7 @@
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int n; int n;
previousNode = [[controller bufferChain] finalNode]; [self setPreviousNode:[[controller bufferChain] finalNode]];
n = [super readData:ptr amount:amount]; n = [super readData:ptr amount:amount];
if (endOfStream == YES) if (endOfStream == YES)

View file

@ -3,10 +3,11 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 42; objectVersion = 44;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
07E18DF30D62B38400BB0E11 /* NSArray+ShuffleUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 07E18DF20D62B38400BB0E11 /* NSArray+ShuffleUtils.m */; };
170680630B950158006BA573 /* Growl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 170680620B950158006BA573 /* Growl.framework */; }; 170680630B950158006BA573 /* Growl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 170680620B950158006BA573 /* Growl.framework */; };
170680840B950164006BA573 /* Growl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 170680620B950158006BA573 /* Growl.framework */; }; 170680840B950164006BA573 /* Growl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 170680620B950158006BA573 /* Growl.framework */; };
171678C00AC8C39E00C28CF3 /* SmartFolderNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 171678BE0AC8C39E00C28CF3 /* SmartFolderNode.m */; }; 171678C00AC8C39E00C28CF3 /* SmartFolderNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 171678BE0AC8C39E00C28CF3 /* SmartFolderNode.m */; };
@ -462,6 +463,8 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
07E18DF10D62B38400BB0E11 /* NSArray+ShuffleUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+ShuffleUtils.h"; sourceTree = "<group>"; };
07E18DF20D62B38400BB0E11 /* NSArray+ShuffleUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+ShuffleUtils.m"; sourceTree = "<group>"; };
089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
1705F1420B8BCB0C00C8B40D /* English */ = {isa = PBXFileReference; lastKnownFileType = folder; name = English; path = English.lproj/Help; sourceTree = "<group>"; }; 1705F1420B8BCB0C00C8B40D /* English */ = {isa = PBXFileReference; lastKnownFileType = folder; name = English; path = English.lproj/Help; sourceTree = "<group>"; };
@ -812,6 +815,8 @@
177EC01D0B8BC2CF0000BC8C /* TrackingSlider.m */, 177EC01D0B8BC2CF0000BC8C /* TrackingSlider.m */,
8E9A30130BA792DC0091081B /* NSFileHandle+CreateFile.h */, 8E9A30130BA792DC0091081B /* NSFileHandle+CreateFile.h */,
8E9A30140BA792DC0091081B /* NSFileHandle+CreateFile.m */, 8E9A30140BA792DC0091081B /* NSFileHandle+CreateFile.m */,
07E18DF10D62B38400BB0E11 /* NSArray+ShuffleUtils.h */,
07E18DF20D62B38400BB0E11 /* NSArray+ShuffleUtils.m */,
); );
path = Utils; path = Utils;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1282,7 +1287,7 @@
29B97313FDCFA39411CA2CEA /* Project object */ = { 29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject; isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Cog" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Cog" */;
compatibilityVersion = "Xcode 2.4"; compatibilityVersion = "Xcode 3.0";
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
knownRegions = ( knownRegions = (
English, English,
@ -1643,6 +1648,7 @@
56462DDA0D61D71E000AB68C /* SpotlightPlaylistView.m in Sources */, 56462DDA0D61D71E000AB68C /* SpotlightPlaylistView.m in Sources */,
56462EAF0D6341F6000AB68C /* SpotlightTransformers.m in Sources */, 56462EAF0D6341F6000AB68C /* SpotlightTransformers.m in Sources */,
56462EB20D634206000AB68C /* SpotlightPlaylistController.m in Sources */, 56462EB20D634206000AB68C /* SpotlightPlaylistController.m in Sources */,
07E18DF30D62B38400BB0E11 /* NSArray+ShuffleUtils.m in Sources */,
56C63D910D647DF300EAE25A /* NSComparisonPredicate+CogPredicate.m in Sources */, 56C63D910D647DF300EAE25A /* NSComparisonPredicate+CogPredicate.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -1826,7 +1832,7 @@
CogAudio, CogAudio,
); );
PRODUCT_NAME = Cog; PRODUCT_NAME = Cog;
SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
WRAPPER_EXTENSION = app; WRAPPER_EXTENSION = app;
ZERO_LINK = NO; ZERO_LINK = NO;
}; };
@ -1855,7 +1861,7 @@
CogAudio, CogAudio,
); );
PRODUCT_NAME = Cog; PRODUCT_NAME = Cog;
SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
WRAPPER_EXTENSION = app; WRAPPER_EXTENSION = app;
}; };
name = Release; name = Release;
@ -1866,7 +1872,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO; PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
}; };
name = Debug; name = Debug;
}; };
@ -1876,7 +1882,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO; PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
}; };
name = Release; name = Release;
}; };

View file

@ -13,6 +13,7 @@
} }
+ (void)initialize;
+ (NSMutableArray *)shuffleList:(NSArray *)l; + (NSMutableArray *)shuffleList:(NSArray *)l;
@end @end

View file

@ -3,52 +3,39 @@
// Cog // Cog
// //
// Created by Vincent Spader on 1/14/06. // Created by Vincent Spader on 1/14/06.
// Copyright 2006 Vincent Spader. All rights reserved. // Revised by Eric Hanneken on 2/14/08.
// Copyright 2008 Vincent Spader. All rights reserved.
// //
#import "Shuffle.h" #import "Shuffle.h"
#import "NSArray+ShuffleUtils.h"
@implementation Shuffle @implementation Shuffle
int sum(int n) + (void)initialize
{ {
return (n*n+n)/2; static BOOL initialized = NO;
} if (!initialized) {
// Call srandom() exactly once.
int reverse_sum(int n) srandom((unsigned) time(NULL));
{ initialized = YES;
return (int)(ceil((-1.0 + sqrt(1.0 + 8.0*n))/2.0)); }
}
int randint(int low, int high)
{
return (random()%high)+low;
} }
+ (NSMutableArray *)shuffleList:(NSArray *)l + (NSMutableArray *)shuffleList:(NSArray *)l
{ {
srandom(time(NULL)); NSArray* randomLongs = [NSArray arrayWithRandomLongs:[l count]];
// randomLongs is an array of random integers, equal in length to l.
NSMutableArray *a = [l mutableCopy];
NSMutableArray *b = [[NSMutableArray alloc] init];
while([a count] > 0) NSArray* pairs = [NSArray zipArray:randomLongs withArray:l];
{ // randomLongs and l are paired.
int t, r, p;
t = sum([a count]);
r = randint(1, t);
p = reverse_sum(r) - 1;
//printf("%i, %i, %i, %i\n", [a count], t, r, p);
[b insertObject:[a objectAtIndex:p] atIndex:0];
[a removeObjectAtIndex:p];
}
[a release]; NSArray* shuffledPairs = [pairs sortedArrayUsingSelector:@selector(compareFirsts:)];
// The numbers from randomLongs are sorted in ascending order; the tracks from l
// are in random order.
return [b autorelease]; // Peel the tracks off and return them.
return [[NSArray unzipArray:shuffledPairs] objectAtIndex:1];
} }
@end @end