diff --git a/Changelog b/Changelog index fc1290de7..222c742eb 100644 --- a/Changelog +++ b/Changelog @@ -8,6 +8,7 @@ Info button now turns off when manually dragging the info drawer closed. Fixed weirdness when displaying the info drawer after closing the window (via menu or keyboard shortcut). Performing Get info now makes the window visible. Added a donation menu item. ($) Clicking the text field now toggles Time Elapsed with Time Remaining. +Trying to play an invalid sound file now goes to the next file. Still need to do that when normally changing tracks. 0.05 alpha 1 ------------ diff --git a/PlaybackController.h b/PlaybackController.h index 66bdaa18f..71a82e939 100644 --- a/PlaybackController.h +++ b/PlaybackController.h @@ -58,6 +58,6 @@ - (void)delegateNotifyStatusUpdate:(NSNumber *)status; - (void)delegateNotifyBitrateUpdate:(float)bitrate; - (void)delegateNotifySongChanged; -- (void)delegateRequestNextSong:(int)queueSize; +- (void)delegateRequestNextSong:(PlaylistEntry *)pe; @end diff --git a/PlaybackController.m b/PlaybackController.m index 3a410f051..bd7b51515 100644 --- a/PlaybackController.m +++ b/PlaybackController.m @@ -93,7 +93,7 @@ [self updateTimeField:0.0f]; - [soundController play:[pe filename]]; + [soundController play:pe]; [soundController setVolume:currentVolume]; } @@ -186,24 +186,23 @@ [self updateTimeField:[positionSlider doubleValue]]; } -- (void)delegateRequestNextSong:(int)queueSize +- (void)delegateRequestNextEntry:(PlaylistEntry *)curEntry { PlaylistEntry *pe; - pe = [playlistController entryAtOffset:(queueSize+1)]; + pe = [playlistController entryAtIndex:[curEntry index]+1]; if (pe == nil) - [soundController setNextSong:nil]; + [soundController setNextEntry:nil]; else { DBLog(@"NEXT SONG: %@", [pe filename]); - [soundController setNextSong:[pe filename]]; + [soundController setNextEntry:pe]; } } -- (void)delegateNotifySongChanged +- (void)delegateNotifySongChanged:(PlaylistEntry *)pe { - [playlistController next]; - PlaylistEntry *pe = [playlistController currentEntry];; + [playlistController setCurrentEntry:pe]; [positionSlider setMaxValue:[pe length]]; [positionSlider setDoubleValue:0.0f]; diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index c63aecada..d5a7a72ff 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -258,6 +258,29 @@ [self setRepeat: [sender state]]; } +- (PlaylistEntry *)entryAtIndex:(int)i +{ + //Need to fix for SHUFFLE MODE! holy fix. + i--; + if (i < 0) + { + if (repeat == YES) + i += [[self arrangedObjects] count]; + else + return nil; + } + else if (i >= [[self arrangedObjects] count]) + { + if (repeat == YES) + i -= [[self arrangedObjects] count]; + else + return nil; + } + + return [[self arrangedObjects] objectAtIndex:i]; + +} + - (PlaylistEntry *)entryAtOffset:(int)offset { if (shuffle == YES) diff --git a/Playlist/PlaylistEntry.h b/Playlist/PlaylistEntry.h index 5ee9acfbf..6f49c7cf3 100644 --- a/Playlist/PlaylistEntry.h +++ b/Playlist/PlaylistEntry.h @@ -31,7 +31,8 @@ BOOL current; - int idx; + int idx; //Can't use index due to some weird bug...might be fixed...should test in the future...think it was a conflict with flac, which is now an external lib + int shuffleIdx; } -(void)setIndex:(int)i; diff --git a/Sound/BufferChain.h b/Sound/BufferChain.h index 0446b1589..b1c9729a9 100644 --- a/Sound/BufferChain.h +++ b/Sound/BufferChain.h @@ -11,11 +11,13 @@ #import "InputNode.h" #import "ConverterNode.h" #import "SoundController.h" +#import "PlaylistEntry.h" @interface BufferChain : NSObject { InputNode *inputNode; ConverterNode *converterNode; - + PlaylistEntry *playlistEntry; + NSArray *effects; //Not needed as of now, but for EFFECTS PLUGINS OF THE FUTURE! id finalNode; //Final buffer in the chain. @@ -25,7 +27,7 @@ - (id)initWithController:(id)c; - (void)buildChain; -- (BOOL)open:(const char *)filename; +- (BOOL)open:(PlaylistEntry *)pe; - (void)seek:(double)time; - (void)launchThreads; diff --git a/Sound/BufferChain.m b/Sound/BufferChain.m index e8e6a7c1e..6bb270dee 100644 --- a/Sound/BufferChain.m +++ b/Sound/BufferChain.m @@ -17,6 +17,9 @@ if (self) { soundController = c; + playlistEntry = nil; + inputNode = nil; + converterNode = nil; } return self; @@ -27,17 +30,24 @@ [inputNode release]; [converterNode release]; - inputNode = [[InputNode alloc] initWithController:soundController previous:nil]; - converterNode = [[ConverterNode alloc] initWithController:soundController previous:inputNode]; + inputNode = [[InputNode alloc] initWithController:self previous:nil]; + converterNode = [[ConverterNode alloc] initWithController:self previous:inputNode]; finalNode = converterNode; } -- (BOOL)open:(NSString *)filename +- (BOOL)open:(PlaylistEntry *)pe { + [pe retain]; + [playlistEntry release]; + NSLog(@"THEY ARE THE SAME?!"); + playlistEntry = pe; + [self buildChain]; - - [inputNode open:filename]; + NSLog(@"Filename in bufferchain: %@, %i %i", [pe filename], playlistEntry, pe); + if (![inputNode open:[playlistEntry filename]]) + return NO; + [converterNode setupWithInputFormat:(AudioStreamBasicDescription)[inputNode format] outputFormat:[[soundController output] format] ]; return YES; @@ -53,6 +63,8 @@ - (void)dealloc { + [playlistEntry release]; + [inputNode release]; [converterNode release]; @@ -66,12 +78,22 @@ [converterNode resetBuffer]; } +- (void)endOfInputReached +{ + [soundController endOfInputReached:self]; +} + - (id)finalNode { return finalNode; } +- (PlaylistEntry *)playlistEntry +{ + return playlistEntry; +} + - (void)setShouldContinue:(BOOL)s { [inputNode setShouldContinue:s]; diff --git a/Sound/ConverterNode.m b/Sound/ConverterNode.m index 447aaee18..de8ac2391 100644 --- a/Sound/ConverterNode.m +++ b/Sound/ConverterNode.m @@ -57,7 +57,7 @@ static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumber if (converter->callbackBuffer != NULL) free(converter->callbackBuffer); converter->callbackBuffer = malloc(amountToWrite); - + amountRead = [converter readData:converter->callbackBuffer amount:amountToWrite]; /* if ([converter endOfStream] == YES) { diff --git a/Sound/InputNode.m b/Sound/InputNode.m index f011d5850..e025a220f 100644 --- a/Sound/InputNode.m +++ b/Sound/InputNode.m @@ -11,14 +11,27 @@ @implementation InputNode -- (void)open:(NSString *)filename +- (BOOL)open:(NSString *)filename { + NSLog(@"Opening: %@", filename); soundFile = [SoundFile open:filename]; - + if (soundFile == nil) + return NO; +/* while (soundFile == nil) + { + NSString *nextSong = [controller invalidSoundFile]; + if (nextSong == nil) + return NO; + + soundFile = [SoundFile open:nextSong]; + } +*/ [soundFile getFormat:&format]; shouldContinue = YES; shouldSeek = NO; + + return YES; } - (void)process diff --git a/Sound/Node.m b/Sound/Node.m index 643c05ea5..e74932ca7 100644 --- a/Sound/Node.m +++ b/Sound/Node.m @@ -96,6 +96,7 @@ if (availInput <= amount && [previousNode endOfStream] == YES) { + NSLog(@"END OF NODE"); // NSLog(@"RELEASING: %i %i %i", availInput, [previousNode endOfStream], shouldContinue); // [previousNode release]; //If it is the outputNode, [soundController newInputChain]; diff --git a/Sound/SOUNDTODO b/Sound/SOUNDTODO index 722723cc3..c0e0f46c5 100644 --- a/Sound/SOUNDTODO +++ b/Sound/SOUNDTODO @@ -1,19 +1,5 @@ -Need to have soundcontroller or outputnode keep a count of how much was played. -Need to integrate with UI (AppController). Limit the number of queued elements (2 would probably be good, maybe 3). -Need to finish implementation of seekToTime, pause, play, resume, stop, etc. - - - - - - - - - - - ------------------------------------------------------------------------------------------------------ diff --git a/Sound/SoundController.h b/Sound/SoundController.h index 7573f68ff..4dadf492a 100644 --- a/Sound/SoundController.h +++ b/Sound/SoundController.h @@ -10,6 +10,7 @@ #import "BufferChain.h" #import "OutputNode.h" +#import "PlaylistEntry.h" @class BufferChain; @class OutputNode; @@ -20,7 +21,7 @@ NSMutableArray *chainQueue; - NSString *nextSong; //Updated whenever the playlist changes? + PlaylistEntry *nextEntry; //Updated whenever the playlist changes? id delegate; } @@ -40,7 +41,7 @@ - (double)amountPlayed; -- (void)setNextSong:(NSString *)s; +- (void)setNextEntry:(PlaylistEntry *)pe; - (void)setPlaybackStatus:(int)s; diff --git a/Sound/SoundController.m b/Sound/SoundController.m index b6a2ed162..940a25e1c 100644 --- a/Sound/SoundController.m +++ b/Sound/SoundController.m @@ -30,10 +30,8 @@ return self; } -- (void)play:(NSString *)filename +- (void)play:(PlaylistEntry *)pe { - DBLog(@"OPENING FILE: %s\n", filename); - if (output) { [output release]; @@ -48,15 +46,30 @@ [anObject setShouldContinue:NO]; } [chainQueue removeAllObjects]; - + if (bufferChain) { [bufferChain setShouldContinue:NO]; [bufferChain release]; } bufferChain = [[BufferChain alloc] initWithController:self]; - [bufferChain open:filename]; + + while (![bufferChain open:pe]) + { + [bufferChain release]; + + [self requestNextEntry:pe]; + + pe = nextEntry; + if (pe == nil) + { + return; + } + [self notifySongChanged:pe]; + bufferChain = [[BufferChain alloc] initWithController:self]; + } + [self setShouldContinue:YES]; DBLog(@"DETACHING THREADS"); @@ -103,12 +116,11 @@ [output setVolume:v]; } -- (void)setNextSong:(NSString *)s +- (void)setNextEntry:(PlaylistEntry *)pe { - //Need to lock things, and set it...this may be calling from any threads...also, if its nil then that signals end of playlist - [s retain]; - [nextSong release]; - nextSong = s; + [pe retain]; + [nextEntry release]; + nextEntry = pe; } @@ -123,19 +135,35 @@ return [output amountPlayed]; } -- (void)endOfInputReached + +- (void)requestNextEntry:(PlaylistEntry *)pe { - [delegate delegateRequestNextSong:[chainQueue count]]; + [delegate performSelectorOnMainThread:@selector(delegateRequestNextEntry:) withObject:pe waitUntilDone:YES]; +} - DBLog(@"END OF INPUT REACHED"); +- (void)notifySongChanged:(PlaylistEntry *)pe +{ + [delegate performSelectorOnMainThread:@selector(delegateNotifySongChanged:) withObject:pe waitUntilDone:NO]; +} - if (nextSong == nil) - return; +- (void)endOfInputReached:(id)sender +{ + BufferChain *newChain = nil; + + nextEntry = [sender playlistEntry]; - BufferChain *newChain = [[BufferChain alloc] initWithController:self]; - - [newChain open:nextSong]; + do { + [newChain release]; + [self requestNextEntry:nextEntry]; + if (nextEntry == nil) + { + return; + } + + newChain = [[BufferChain alloc] initWithController:self]; + } while (![newChain open:nextEntry]); + [newChain setShouldContinue:YES]; [newChain launchThreads]; @@ -163,7 +191,7 @@ [chainQueue removeObjectAtIndex:0]; - [delegate delegateNotifySongChanged]; + [self notifySongChanged:[bufferChain playlistEntry]]; [output setEndOfStream:NO]; }