Compare commits
4 Commits
4b37ffebee
...
72ee38ad14
Author | SHA1 | Date |
---|---|---|
Christopher Snowhill | 72ee38ad14 | |
Christopher Snowhill | 6daa0de425 | |
Christopher Snowhill | 1b9f460538 | |
Christopher Snowhill | 1de501a64a |
|
@ -677,14 +677,6 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
|||
break;
|
||||
}
|
||||
|
||||
if(status == CogStatusStopped) {
|
||||
status = CogStatusStopping;
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||||
if([self playbackStatus] == CogStatusStopping)
|
||||
[self setPlaybackStatus:CogStatusStopped];
|
||||
});
|
||||
}
|
||||
|
||||
[self setPlaybackStatus:status];
|
||||
// If we don't send it here, if we've stopped, then the NPIC will be stuck at the last file we played.
|
||||
[self sendMetaData];
|
||||
|
|
|
@ -315,6 +315,8 @@
|
|||
// if there's already one at the head of chainQueue... r-r-right?
|
||||
for(BufferChain *chain in chainQueue) {
|
||||
if([chain isRunning]) {
|
||||
if(output)
|
||||
[output setShouldPlayOutBuffer:YES];
|
||||
atomic_fetch_sub(&refCount, 1);
|
||||
return YES;
|
||||
}
|
||||
|
@ -338,6 +340,8 @@
|
|||
while(duration >= 30.0 && shouldContinue) {
|
||||
[semaphore wait];
|
||||
if(atomic_load_explicit(&resettingNow, memory_order_relaxed)) {
|
||||
if(output)
|
||||
[output setShouldPlayOutBuffer:YES];
|
||||
atomic_fetch_sub(&refCount, 1);
|
||||
return YES;
|
||||
}
|
||||
|
@ -357,6 +361,8 @@
|
|||
[self requestNextStream:nextStreamUserInfo];
|
||||
|
||||
if(!nextStream) {
|
||||
if(output)
|
||||
[output setShouldPlayOutBuffer:YES];
|
||||
atomic_fetch_sub(&refCount, 1);
|
||||
return YES;
|
||||
}
|
||||
|
@ -407,6 +413,8 @@
|
|||
while(shouldContinue && ![newChain open:url withUserInfo:nextStreamUserInfo withRGInfo:nextStreamRGInfo]) {
|
||||
if(nextStream == nil) {
|
||||
newChain = nil;
|
||||
if(output)
|
||||
[output setShouldPlayOutBuffer:YES];
|
||||
atomic_fetch_sub(&refCount, 1);
|
||||
return YES;
|
||||
}
|
||||
|
@ -416,6 +424,8 @@
|
|||
|
||||
if([nextStream isEqualTo:url]) {
|
||||
newChain = nil;
|
||||
if(output)
|
||||
[output setShouldPlayOutBuffer:YES];
|
||||
atomic_fetch_sub(&refCount, 1);
|
||||
return YES;
|
||||
}
|
||||
|
@ -442,6 +452,9 @@
|
|||
// - self.nextStreamUserInfo == next playlist entry
|
||||
// - head of chainQueue is the buffer chain for the next entry (which has launched its threads already)
|
||||
|
||||
if(output)
|
||||
[output setShouldPlayOutBuffer:YES];
|
||||
|
||||
atomic_fetch_sub(&refCount, 1);
|
||||
return YES;
|
||||
}
|
||||
|
|
|
@ -156,7 +156,8 @@
|
|||
[inputNode setShouldContinue:NO];
|
||||
[[inputNode exitAtTheEndOfTheStream] signal];
|
||||
[[inputNode semaphore] signal];
|
||||
[[inputNode exitAtTheEndOfTheStream] wait]; // wait for decoder to be closed (see InputNode's -(void)process )
|
||||
if(![inputNode threadExited])
|
||||
[[inputNode exitAtTheEndOfTheStream] wait]; // wait for decoder to be closed (see InputNode's -(void)process )
|
||||
|
||||
DLog(@"Bufferchain dealloc");
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
Semaphore *exitAtTheEndOfTheStream;
|
||||
}
|
||||
@property(readonly) Semaphore *exitAtTheEndOfTheStream;
|
||||
@property(readonly) BOOL threadExited;
|
||||
|
||||
- (BOOL)openWithSource:(id<CogSource>)source;
|
||||
- (BOOL)openWithDecoder:(id<CogDecoder>)d;
|
||||
|
|
|
@ -21,12 +21,14 @@
|
|||
|
||||
static void *kInputNodeContext = &kInputNodeContext;
|
||||
|
||||
@synthesize threadExited;
|
||||
@synthesize exitAtTheEndOfTheStream;
|
||||
|
||||
- (id)initWithController:(id)c previous:(id)p {
|
||||
self = [super initWithController:c previous:p];
|
||||
if(self) {
|
||||
exitAtTheEndOfTheStream = [[Semaphore alloc] init];
|
||||
threadExited = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -223,6 +225,7 @@ static void *kInputNodeContext = &kInputNodeContext;
|
|||
[decoder close];
|
||||
|
||||
[exitAtTheEndOfTheStream signal];
|
||||
threadExited = YES;
|
||||
|
||||
DLog("Input node thread stopping");
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
|
||||
- (void)setShouldContinue:(BOOL)s;
|
||||
|
||||
- (void)setShouldPlayOutBuffer:(BOOL)s;
|
||||
|
||||
- (void)pause;
|
||||
- (void)resume;
|
||||
|
||||
|
|
|
@ -170,6 +170,10 @@
|
|||
// [output stop];
|
||||
}
|
||||
|
||||
- (void)setShouldPlayOutBuffer:(BOOL)s {
|
||||
[output setShouldPlayOutBuffer:s];
|
||||
}
|
||||
|
||||
- (BOOL)isPaused {
|
||||
return paused;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,8 @@ using std::atomic_long;
|
|||
FSurroundFilter *fsurround;
|
||||
|
||||
BOOL resetStreamFormat;
|
||||
|
||||
BOOL shouldPlayOutBuffer;
|
||||
|
||||
float *samplePtr;
|
||||
float tempBuffer[512 * 32];
|
||||
|
@ -149,6 +151,8 @@ using std::atomic_long;
|
|||
|
||||
- (void)setEqualizerEnabled:(BOOL)enabled;
|
||||
|
||||
- (void)setShouldPlayOutBuffer:(BOOL)enabled;
|
||||
|
||||
- (void)sustainHDCD;
|
||||
|
||||
@end
|
||||
|
|
|
@ -342,6 +342,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
|||
- (void)threadEntry:(id)arg {
|
||||
running = YES;
|
||||
started = NO;
|
||||
shouldPlayOutBuffer = NO;
|
||||
secondsLatency = 1.0;
|
||||
|
||||
while(!stopping) {
|
||||
|
@ -940,6 +941,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
|||
stopInvoked = NO;
|
||||
stopCompleted = NO;
|
||||
commandStop = NO;
|
||||
shouldPlayOutBuffer = NO;
|
||||
|
||||
audioFormatDescription = NULL;
|
||||
|
||||
|
@ -1208,7 +1210,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
|||
}
|
||||
if(renderSynchronizer || audioRenderer) {
|
||||
if(renderSynchronizer) {
|
||||
if(!commandStop) {
|
||||
if(shouldPlayOutBuffer && !commandStop) {
|
||||
int compareVal = 0;
|
||||
double secondsLatency = self->secondsLatency >= 0 ? self->secondsLatency : 0;
|
||||
int compareMax = (((1000000 / 5000) * secondsLatency) + (10000 / 5000)); // latency plus 10ms, divide by sleep intervals
|
||||
|
@ -1302,4 +1304,8 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
|
|||
secondsHdcdSustained = 10.0;
|
||||
}
|
||||
|
||||
- (void)setShouldPlayOutBuffer:(BOOL)s {
|
||||
shouldPlayOutBuffer = s;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -218,10 +218,18 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
|||
}
|
||||
}
|
||||
|
||||
static inline void dispatch_async_reentrant(dispatch_queue_t queue, dispatch_block_t block) {
|
||||
if(dispatch_queue_get_label(queue) == dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)) {
|
||||
block();
|
||||
} else {
|
||||
dispatch_async(queue, block);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addFolderIfMissing:(NSURL *)folderUrl {
|
||||
if(![folderUrl isFileURL]) return;
|
||||
|
||||
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||
dispatch_async_reentrant(dispatch_get_main_queue(), ^{
|
||||
SandboxEntry *_entry = nil;
|
||||
|
||||
for(SandboxEntry *entry in self->storage) {
|
||||
|
@ -263,7 +271,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
|||
|
||||
NSURL *url = [SandboxBroker urlWithoutFragment:fileUrl];
|
||||
|
||||
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||
dispatch_async_reentrant(dispatch_get_main_queue(), ^{
|
||||
SandboxEntry *_entry = nil;
|
||||
|
||||
for(SandboxEntry *entry in self->storage) {
|
||||
|
@ -322,49 +330,47 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
|||
}
|
||||
|
||||
if(!_entry) {
|
||||
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||
static BOOL warnedYet = NO;
|
||||
static BOOL warnedYet = NO;
|
||||
|
||||
if(!warnedYet) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:NSLocalizedString(@"GrantPathTitle", @"Title of file dialog for granting folder access")];
|
||||
[alert setInformativeText:NSLocalizedString(@"GrantPathMessage", @"Message to new users regarding file permissions")];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"GrantPathOK", @"OK button text")];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"GrantPathStopWarning", @"Button to stop warnings for session")];
|
||||
if(!warnedYet) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:NSLocalizedString(@"GrantPathTitle", @"Title of file dialog for granting folder access")];
|
||||
[alert setInformativeText:NSLocalizedString(@"GrantPathMessage", @"Message to new users regarding file permissions")];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"GrantPathOK", @"OK button text")];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"GrantPathStopWarning", @"Button to stop warnings for session")];
|
||||
|
||||
if([alert runModal] == NSAlertSecondButtonReturn) {
|
||||
warnedYet = YES;
|
||||
}
|
||||
}
|
||||
|
||||
if([alert runModal] == NSAlertSecondButtonReturn) {
|
||||
warnedYet = YES;
|
||||
}
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setCanChooseDirectories:YES];
|
||||
[panel setCanChooseFiles:NO];
|
||||
[panel setFloatingPanel:YES];
|
||||
[panel setDirectoryURL:folderUrl];
|
||||
[panel setTitle:NSLocalizedString(@"GrantPathTitle", @"Title of file dialog for granting folder access")];
|
||||
NSInteger result = [panel runModal];
|
||||
if(result == NSModalResponseOK) {
|
||||
NSURL *folderUrl = [panel URL];
|
||||
NSError *err = nil;
|
||||
NSData *bookmark = [folderUrl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&err];
|
||||
if(!bookmark && err) {
|
||||
ALog(@"Failed to add bookmark for URL: %@, with error: %@", folderUrl, [err localizedDescription]);
|
||||
return;
|
||||
}
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setCanChooseDirectories:YES];
|
||||
[panel setCanChooseFiles:NO];
|
||||
[panel setFloatingPanel:YES];
|
||||
[panel setDirectoryURL:folderUrl];
|
||||
[panel setTitle:NSLocalizedString(@"GrantPathTitle", @"Title of file dialog for granting folder access")];
|
||||
NSInteger result = [panel runModal];
|
||||
if(result == NSModalResponseOK) {
|
||||
NSURL *folderUrl = [panel URL];
|
||||
NSError *err = nil;
|
||||
NSData *bookmark = [folderUrl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&err];
|
||||
if(!bookmark && err) {
|
||||
ALog(@"Failed to add bookmark for URL: %@, with error: %@", folderUrl, [err localizedDescription]);
|
||||
return;
|
||||
}
|
||||
NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer];
|
||||
|
||||
NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer];
|
||||
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
||||
|
||||
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
||||
|
||||
if(token) {
|
||||
token.path = [folderUrl path];
|
||||
token.bookmark = bookmark;
|
||||
[SandboxBroker cleanupFolderAccess];
|
||||
}
|
||||
if(token) {
|
||||
token.path = [folderUrl path];
|
||||
token.bookmark = bookmark;
|
||||
[SandboxBroker cleanupFolderAccess];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -376,7 +382,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
|||
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SandboxToken"];
|
||||
request.sortDescriptors = @[sortDescriptor];
|
||||
|
||||
[pc.viewContext performBlockAndWait:^{
|
||||
[pc.viewContext performBlock:^{
|
||||
NSError *error = nil;
|
||||
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
|
||||
NSMutableArray *resultsCopy = nil;
|
||||
|
@ -455,7 +461,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
|||
SandboxEntry *entry = CFBridgingRelease(handle);
|
||||
if(!entry) return;
|
||||
|
||||
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||
dispatch_async_reentrant(dispatch_get_main_queue(), ^{
|
||||
if(entry.refCount > 1) {
|
||||
entry.refCount -= 1;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue