Invalid songs are now skipped
parent
caf949db90
commit
8835396171
|
@ -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.
|
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. ($)
|
Added a donation menu item. ($)
|
||||||
Clicking the text field now toggles Time Elapsed with Time Remaining.
|
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
|
0.05 alpha 1
|
||||||
------------
|
------------
|
||||||
|
|
|
@ -58,6 +58,6 @@
|
||||||
- (void)delegateNotifyStatusUpdate:(NSNumber *)status;
|
- (void)delegateNotifyStatusUpdate:(NSNumber *)status;
|
||||||
- (void)delegateNotifyBitrateUpdate:(float)bitrate;
|
- (void)delegateNotifyBitrateUpdate:(float)bitrate;
|
||||||
- (void)delegateNotifySongChanged;
|
- (void)delegateNotifySongChanged;
|
||||||
- (void)delegateRequestNextSong:(int)queueSize;
|
- (void)delegateRequestNextSong:(PlaylistEntry *)pe;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
|
|
||||||
[self updateTimeField:0.0f];
|
[self updateTimeField:0.0f];
|
||||||
|
|
||||||
[soundController play:[pe filename]];
|
[soundController play:pe];
|
||||||
[soundController setVolume:currentVolume];
|
[soundController setVolume:currentVolume];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,24 +186,23 @@
|
||||||
[self updateTimeField:[positionSlider doubleValue]];
|
[self updateTimeField:[positionSlider doubleValue]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)delegateRequestNextSong:(int)queueSize
|
- (void)delegateRequestNextEntry:(PlaylistEntry *)curEntry
|
||||||
{
|
{
|
||||||
PlaylistEntry *pe;
|
PlaylistEntry *pe;
|
||||||
pe = [playlistController entryAtOffset:(queueSize+1)];
|
pe = [playlistController entryAtIndex:[curEntry index]+1];
|
||||||
|
|
||||||
if (pe == nil)
|
if (pe == nil)
|
||||||
[soundController setNextSong:nil];
|
[soundController setNextEntry:nil];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBLog(@"NEXT SONG: %@", [pe filename]);
|
DBLog(@"NEXT SONG: %@", [pe filename]);
|
||||||
[soundController setNextSong:[pe filename]];
|
[soundController setNextEntry:pe];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)delegateNotifySongChanged
|
- (void)delegateNotifySongChanged:(PlaylistEntry *)pe
|
||||||
{
|
{
|
||||||
[playlistController next];
|
[playlistController setCurrentEntry:pe];
|
||||||
PlaylistEntry *pe = [playlistController currentEntry];;
|
|
||||||
|
|
||||||
[positionSlider setMaxValue:[pe length]];
|
[positionSlider setMaxValue:[pe length]];
|
||||||
[positionSlider setDoubleValue:0.0f];
|
[positionSlider setDoubleValue:0.0f];
|
||||||
|
|
|
@ -258,6 +258,29 @@
|
||||||
[self setRepeat: [sender state]];
|
[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
|
- (PlaylistEntry *)entryAtOffset:(int)offset
|
||||||
{
|
{
|
||||||
if (shuffle == YES)
|
if (shuffle == YES)
|
||||||
|
|
|
@ -31,7 +31,8 @@
|
||||||
|
|
||||||
BOOL current;
|
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;
|
-(void)setIndex:(int)i;
|
||||||
|
|
|
@ -11,10 +11,12 @@
|
||||||
#import "InputNode.h"
|
#import "InputNode.h"
|
||||||
#import "ConverterNode.h"
|
#import "ConverterNode.h"
|
||||||
#import "SoundController.h"
|
#import "SoundController.h"
|
||||||
|
#import "PlaylistEntry.h"
|
||||||
|
|
||||||
@interface BufferChain : NSObject {
|
@interface BufferChain : NSObject {
|
||||||
InputNode *inputNode;
|
InputNode *inputNode;
|
||||||
ConverterNode *converterNode;
|
ConverterNode *converterNode;
|
||||||
|
PlaylistEntry *playlistEntry;
|
||||||
|
|
||||||
NSArray *effects; //Not needed as of now, but for EFFECTS PLUGINS OF THE FUTURE!
|
NSArray *effects; //Not needed as of now, but for EFFECTS PLUGINS OF THE FUTURE!
|
||||||
|
|
||||||
|
@ -25,7 +27,7 @@
|
||||||
|
|
||||||
- (id)initWithController:(id)c;
|
- (id)initWithController:(id)c;
|
||||||
- (void)buildChain;
|
- (void)buildChain;
|
||||||
- (BOOL)open:(const char *)filename;
|
- (BOOL)open:(PlaylistEntry *)pe;
|
||||||
- (void)seek:(double)time;
|
- (void)seek:(double)time;
|
||||||
|
|
||||||
- (void)launchThreads;
|
- (void)launchThreads;
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
soundController = c;
|
soundController = c;
|
||||||
|
playlistEntry = nil;
|
||||||
|
inputNode = nil;
|
||||||
|
converterNode = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -27,17 +30,24 @@
|
||||||
[inputNode release];
|
[inputNode release];
|
||||||
[converterNode release];
|
[converterNode release];
|
||||||
|
|
||||||
inputNode = [[InputNode alloc] initWithController:soundController previous:nil];
|
inputNode = [[InputNode alloc] initWithController:self previous:nil];
|
||||||
converterNode = [[ConverterNode alloc] initWithController:soundController previous:inputNode];
|
converterNode = [[ConverterNode alloc] initWithController:self previous:inputNode];
|
||||||
|
|
||||||
finalNode = converterNode;
|
finalNode = converterNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)open:(NSString *)filename
|
- (BOOL)open:(PlaylistEntry *)pe
|
||||||
{
|
{
|
||||||
[self buildChain];
|
[pe retain];
|
||||||
|
[playlistEntry release];
|
||||||
|
NSLog(@"THEY ARE THE SAME?!");
|
||||||
|
playlistEntry = pe;
|
||||||
|
|
||||||
|
[self buildChain];
|
||||||
|
NSLog(@"Filename in bufferchain: %@, %i %i", [pe filename], playlistEntry, pe);
|
||||||
|
if (![inputNode open:[playlistEntry filename]])
|
||||||
|
return NO;
|
||||||
|
|
||||||
[inputNode open:filename];
|
|
||||||
[converterNode setupWithInputFormat:(AudioStreamBasicDescription)[inputNode format] outputFormat:[[soundController output] format] ];
|
[converterNode setupWithInputFormat:(AudioStreamBasicDescription)[inputNode format] outputFormat:[[soundController output] format] ];
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
|
@ -53,6 +63,8 @@
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
|
[playlistEntry release];
|
||||||
|
|
||||||
[inputNode release];
|
[inputNode release];
|
||||||
[converterNode release];
|
[converterNode release];
|
||||||
|
|
||||||
|
@ -66,12 +78,22 @@
|
||||||
[converterNode resetBuffer];
|
[converterNode resetBuffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)endOfInputReached
|
||||||
|
{
|
||||||
|
[soundController endOfInputReached:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (id)finalNode
|
- (id)finalNode
|
||||||
{
|
{
|
||||||
return finalNode;
|
return finalNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (PlaylistEntry *)playlistEntry
|
||||||
|
{
|
||||||
|
return playlistEntry;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setShouldContinue:(BOOL)s
|
- (void)setShouldContinue:(BOOL)s
|
||||||
{
|
{
|
||||||
[inputNode setShouldContinue:s];
|
[inputNode setShouldContinue:s];
|
||||||
|
|
|
@ -11,14 +11,27 @@
|
||||||
|
|
||||||
@implementation InputNode
|
@implementation InputNode
|
||||||
|
|
||||||
- (void)open:(NSString *)filename
|
- (BOOL)open:(NSString *)filename
|
||||||
{
|
{
|
||||||
|
NSLog(@"Opening: %@", filename);
|
||||||
soundFile = [SoundFile open: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];
|
[soundFile getFormat:&format];
|
||||||
|
|
||||||
shouldContinue = YES;
|
shouldContinue = YES;
|
||||||
shouldSeek = NO;
|
shouldSeek = NO;
|
||||||
|
|
||||||
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)process
|
- (void)process
|
||||||
|
|
|
@ -96,6 +96,7 @@
|
||||||
|
|
||||||
if (availInput <= amount && [previousNode endOfStream] == YES)
|
if (availInput <= amount && [previousNode endOfStream] == YES)
|
||||||
{
|
{
|
||||||
|
NSLog(@"END OF NODE");
|
||||||
// NSLog(@"RELEASING: %i %i %i", availInput, [previousNode endOfStream], shouldContinue);
|
// NSLog(@"RELEASING: %i %i %i", availInput, [previousNode endOfStream], shouldContinue);
|
||||||
// [previousNode release];
|
// [previousNode release];
|
||||||
//If it is the outputNode, [soundController newInputChain];
|
//If it is the outputNode, [soundController newInputChain];
|
||||||
|
|
|
@ -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).
|
Limit the number of queued elements (2 would probably be good, maybe 3).
|
||||||
|
|
||||||
Need to finish implementation of seekToTime, pause, play, resume, stop, etc.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#import "BufferChain.h"
|
#import "BufferChain.h"
|
||||||
#import "OutputNode.h"
|
#import "OutputNode.h"
|
||||||
|
#import "PlaylistEntry.h"
|
||||||
|
|
||||||
@class BufferChain;
|
@class BufferChain;
|
||||||
@class OutputNode;
|
@class OutputNode;
|
||||||
|
@ -20,7 +21,7 @@
|
||||||
|
|
||||||
NSMutableArray *chainQueue;
|
NSMutableArray *chainQueue;
|
||||||
|
|
||||||
NSString *nextSong; //Updated whenever the playlist changes?
|
PlaylistEntry *nextEntry; //Updated whenever the playlist changes?
|
||||||
|
|
||||||
id delegate;
|
id delegate;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +41,7 @@
|
||||||
- (double)amountPlayed;
|
- (double)amountPlayed;
|
||||||
|
|
||||||
|
|
||||||
- (void)setNextSong:(NSString *)s;
|
- (void)setNextEntry:(PlaylistEntry *)pe;
|
||||||
- (void)setPlaybackStatus:(int)s;
|
- (void)setPlaybackStatus:(int)s;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,8 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)play:(NSString *)filename
|
- (void)play:(PlaylistEntry *)pe
|
||||||
{
|
{
|
||||||
DBLog(@"OPENING FILE: %s\n", filename);
|
|
||||||
|
|
||||||
if (output)
|
if (output)
|
||||||
{
|
{
|
||||||
[output release];
|
[output release];
|
||||||
|
@ -55,7 +53,22 @@
|
||||||
[bufferChain release];
|
[bufferChain release];
|
||||||
}
|
}
|
||||||
bufferChain = [[BufferChain alloc] initWithController:self];
|
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];
|
[self setShouldContinue:YES];
|
||||||
DBLog(@"DETACHING THREADS");
|
DBLog(@"DETACHING THREADS");
|
||||||
|
@ -103,12 +116,11 @@
|
||||||
[output setVolume:v];
|
[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
|
[pe retain];
|
||||||
[s retain];
|
[nextEntry release];
|
||||||
[nextSong release];
|
nextEntry = pe;
|
||||||
nextSong = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,18 +135,34 @@
|
||||||
return [output amountPlayed];
|
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)
|
- (void)endOfInputReached:(id)sender
|
||||||
|
{
|
||||||
|
BufferChain *newChain = nil;
|
||||||
|
|
||||||
|
nextEntry = [sender playlistEntry];
|
||||||
|
|
||||||
|
do {
|
||||||
|
[newChain release];
|
||||||
|
[self requestNextEntry:nextEntry];
|
||||||
|
|
||||||
|
if (nextEntry == nil)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BufferChain *newChain = [[BufferChain alloc] initWithController:self];
|
newChain = [[BufferChain alloc] initWithController:self];
|
||||||
|
} while (![newChain open:nextEntry]);
|
||||||
[newChain open:nextSong];
|
|
||||||
|
|
||||||
[newChain setShouldContinue:YES];
|
[newChain setShouldContinue:YES];
|
||||||
[newChain launchThreads];
|
[newChain launchThreads];
|
||||||
|
@ -163,7 +191,7 @@
|
||||||
|
|
||||||
[chainQueue removeObjectAtIndex:0];
|
[chainQueue removeObjectAtIndex:0];
|
||||||
|
|
||||||
[delegate delegateNotifySongChanged];
|
[self notifySongChanged:[bufferChain playlistEntry]];
|
||||||
[output setEndOfStream:NO];
|
[output setEndOfStream:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue