Compare commits
1 commit
main
...
update-vgm
Author | SHA1 | Date | |
---|---|---|---|
|
dd585311df |
1610 changed files with 127809 additions and 80153 deletions
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -3,7 +3,7 @@ name: Feedback
|
||||||
about: Report bugs or suggest new features
|
about: Report bugs or suggest new features
|
||||||
title: ''
|
title: ''
|
||||||
labels:
|
labels:
|
||||||
assignees: kode54
|
assignees: kode54, nevack
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
10
.github/workflows/debug.yml
vendored
10
.github/workflows/debug.yml
vendored
|
@ -11,16 +11,16 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build Universal Cog.app
|
name: Build Universal Cog.app
|
||||||
runs-on: macos-15
|
runs-on: macos-13
|
||||||
env:
|
env:
|
||||||
XCODE_DERIVEDDATA_PATH: build
|
XCODE_DERIVEDDATA_PATH: build
|
||||||
steps:
|
steps:
|
||||||
- name: Switch to Xcode 16
|
- name: Switch to Xcode 15
|
||||||
uses: maxim-lobanov/setup-xcode@v1
|
uses: maxim-lobanov/setup-xcode@v1
|
||||||
with:
|
with:
|
||||||
xcode-version: 16
|
xcode-version: 15
|
||||||
- name: Check out repository
|
- name: Check out repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Unpack libraries
|
- name: Unpack libraries
|
||||||
|
@ -50,7 +50,7 @@ jobs:
|
||||||
$XCODE_DERIVEDDATA_PATH/Build/Products/Debug/Cog.app
|
$XCODE_DERIVEDDATA_PATH/Build/Products/Debug/Cog.app
|
||||||
$XCODE_DERIVEDDATA_PATH/Cog.zip
|
$XCODE_DERIVEDDATA_PATH/Cog.zip
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Cog
|
name: Cog
|
||||||
path: ${{ env.XCODE_DERIVEDDATA_PATH }}/Cog.zip
|
path: ${{ env.XCODE_DERIVEDDATA_PATH }}/Cog.zip
|
||||||
|
|
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -1,13 +1,12 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
xcuserdata
|
xcuserdata
|
||||||
/build
|
./build
|
||||||
|
|
||||||
# Special cog exceptions
|
# Special cog exceptions
|
||||||
!Frameworks/OpenMPT/OpenMPT/build
|
!Frameworks/OpenMPT/OpenMPT/build
|
||||||
|
|
||||||
# User-specific xcconfig files
|
# User-specific xcconfig files
|
||||||
Xcode-config/DEVELOPMENT_TEAM.xcconfig
|
Xcode-config/DEVELOPMENT_TEAM.xcconfig
|
||||||
Xcode-config/SENTRY_SETTINGS.xcconfig
|
|
||||||
|
|
||||||
# Plist derived from template at build time
|
# Plist derived from template at build time
|
||||||
/Info.plist
|
/Info.plist
|
||||||
|
@ -32,10 +31,10 @@ Xcode-config/SENTRY_SETTINGS.xcconfig
|
||||||
/ThirdParty/fdk-aac/lib/libfdk-aac.dylib
|
/ThirdParty/fdk-aac/lib/libfdk-aac.dylib
|
||||||
/ThirdParty/fdk-aac/lib/libfdk-aac.la
|
/ThirdParty/fdk-aac/lib/libfdk-aac.la
|
||||||
/ThirdParty/fdk-aac/lib/pkgconfig/fdk-aac.pc
|
/ThirdParty/fdk-aac/lib/pkgconfig/fdk-aac.pc
|
||||||
/ThirdParty/ffmpeg/lib/libavcodec.61.dylib
|
/ThirdParty/ffmpeg/lib/libavcodec.59.dylib
|
||||||
/ThirdParty/ffmpeg/lib/libavformat.61.dylib
|
/ThirdParty/ffmpeg/lib/libavformat.59.dylib
|
||||||
/ThirdParty/ffmpeg/lib/libavutil.59.dylib
|
/ThirdParty/ffmpeg/lib/libavutil.57.dylib
|
||||||
/ThirdParty/ffmpeg/lib/libswresample.5.dylib
|
/ThirdParty/ffmpeg/lib/libswresample.4.dylib
|
||||||
/ThirdParty/flac/lib/libFLAC.12.dylib
|
/ThirdParty/flac/lib/libFLAC.12.dylib
|
||||||
/ThirdParty/libid3tag/lib/libid3tag.a
|
/ThirdParty/libid3tag/lib/libid3tag.a
|
||||||
/ThirdParty/libmad/lib/libmad.a
|
/ThirdParty/libmad/lib/libmad.a
|
||||||
|
@ -48,9 +47,7 @@ Xcode-config/SENTRY_SETTINGS.xcconfig
|
||||||
/ThirdParty/ogg/lib/libogg.0.dylib
|
/ThirdParty/ogg/lib/libogg.0.dylib
|
||||||
/ThirdParty/opus/lib/libopus.0.dylib
|
/ThirdParty/opus/lib/libopus.0.dylib
|
||||||
/ThirdParty/opusfile/lib/libopusfile.0.dylib
|
/ThirdParty/opusfile/lib/libopusfile.0.dylib
|
||||||
/ThirdParty/rubberband/lib/librubberband.3.dylib
|
|
||||||
/ThirdParty/speex/libspeex.a
|
/ThirdParty/speex/libspeex.a
|
||||||
/ThirdParty/vorbis/lib/libvorbisfile.3.dylib
|
/ThirdParty/vorbis/lib/libvorbisfile.3.dylib
|
||||||
/ThirdParty/vorbis/lib/libvorbis.0.dylib
|
/ThirdParty/vorbis/lib/libvorbis.0.dylib
|
||||||
/ThirdParty/soxr/lib/libsoxr.0.dylib
|
/ThirdParty/soxr/lib/libsoxr.0.dylib
|
||||||
/ThirdParty/WavPack/lib/libwavpack.a
|
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
IBOutlet NSMenuItem *showArtistColumn;
|
IBOutlet NSMenuItem *showArtistColumn;
|
||||||
IBOutlet NSMenuItem *showAlbumColumn;
|
IBOutlet NSMenuItem *showAlbumColumn;
|
||||||
IBOutlet NSMenuItem *showGenreColumn;
|
IBOutlet NSMenuItem *showGenreColumn;
|
||||||
IBOutlet NSMenuItem *showPlayCountColumn;
|
|
||||||
IBOutlet NSMenuItem *showLengthColumn;
|
IBOutlet NSMenuItem *showLengthColumn;
|
||||||
IBOutlet NSMenuItem *showTrackColumn;
|
IBOutlet NSMenuItem *showTrackColumn;
|
||||||
IBOutlet NSMenuItem *showYearColumn;
|
IBOutlet NSMenuItem *showYearColumn;
|
||||||
|
@ -103,11 +102,6 @@
|
||||||
- (void)showPathSuggester;
|
- (void)showPathSuggester;
|
||||||
+ (void)globalShowPathSuggester;
|
+ (void)globalShowPathSuggester;
|
||||||
|
|
||||||
- (void)selectTrack:(id)sender;
|
|
||||||
|
|
||||||
- (IBAction)showRubberbandSettings:(id)sender;
|
|
||||||
+ (void)globalShowRubberbandSettings;
|
|
||||||
|
|
||||||
@property NSWindow *mainWindow;
|
@property NSWindow *mainWindow;
|
||||||
@property NSWindow *miniWindow;
|
@property NSWindow *miniWindow;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#import "PlaylistEntry.h"
|
#import "PlaylistEntry.h"
|
||||||
#import "PlaylistLoader.h"
|
#import "PlaylistLoader.h"
|
||||||
#import "PlaylistView.h"
|
#import "PlaylistView.h"
|
||||||
#import "RubberbandEngineTransformer.h"
|
|
||||||
#import "SQLiteStore.h"
|
#import "SQLiteStore.h"
|
||||||
#import "SandboxBroker.h"
|
#import "SandboxBroker.h"
|
||||||
#import "SpotlightWindowController.h"
|
#import "SpotlightWindowController.h"
|
||||||
|
@ -28,13 +27,10 @@
|
||||||
|
|
||||||
#import "Shortcuts.h"
|
#import "Shortcuts.h"
|
||||||
#import <MASShortcut/Shortcut.h>
|
#import <MASShortcut/Shortcut.h>
|
||||||
#import <MASShortcut/MASDictionaryTransformer.h>
|
|
||||||
|
|
||||||
#import "PreferencesController.h"
|
#import "PreferencesController.h"
|
||||||
|
|
||||||
#import "FeedbackController.h"
|
@import Firebase;
|
||||||
|
|
||||||
@import Sentry;
|
|
||||||
|
|
||||||
void *kAppControllerContext = &kAppControllerContext;
|
void *kAppControllerContext = &kAppControllerContext;
|
||||||
|
|
||||||
|
@ -75,14 +71,6 @@ static AppController *kAppController = nil;
|
||||||
NSValueTransformer *numberHertzToStringTransformer = [[NumberHertzToStringTransformer alloc] init];
|
NSValueTransformer *numberHertzToStringTransformer = [[NumberHertzToStringTransformer alloc] init];
|
||||||
[NSValueTransformer setValueTransformer:numberHertzToStringTransformer
|
[NSValueTransformer setValueTransformer:numberHertzToStringTransformer
|
||||||
forName:@"NumberHertzToStringTransformer"];
|
forName:@"NumberHertzToStringTransformer"];
|
||||||
|
|
||||||
NSValueTransformer *rubberbandEngineEnabledTransformer = [[RubberbandEngineEnabledTransformer alloc] init];
|
|
||||||
[NSValueTransformer setValueTransformer:rubberbandEngineEnabledTransformer
|
|
||||||
forName:@"RubberbandEngineEnabledTransformer"];
|
|
||||||
|
|
||||||
NSValueTransformer *rubberbandEngineHiddenTransformer = [[RubberbandEngineHiddenTransformer alloc] init];
|
|
||||||
[NSValueTransformer setValueTransformer:rubberbandEngineHiddenTransformer
|
|
||||||
forName:@"RubberbandEngineHiddenTransformer"];
|
|
||||||
}
|
}
|
||||||
- (id)init {
|
- (id)init {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
@ -169,13 +157,16 @@ static AppController *kAppController = nil;
|
||||||
return [key isEqualToString:@"currentEntry"];
|
return [key isEqualToString:@"currentEntry"];
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL consentLastEnabled = NO;
|
|
||||||
|
|
||||||
- (void)awakeFromNib {
|
- (void)awakeFromNib {
|
||||||
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"sentryConsented": @(NO),
|
#if DEBUG
|
||||||
@"sentryAskedConsent": @(NO) }];
|
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions": @(NO) }];
|
||||||
|
#else
|
||||||
|
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions": @(YES) }];
|
||||||
|
#endif
|
||||||
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.sentryConsented" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kAppControllerContext];
|
[FIRApp configure];
|
||||||
|
|
||||||
|
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.crashlyticsConsented" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kAppControllerContext];
|
||||||
|
|
||||||
[[totalTimeField cell] setBackgroundStyle:NSBackgroundStyleRaised];
|
[[totalTimeField cell] setBackgroundStyle:NSBackgroundStyleRaised];
|
||||||
|
|
||||||
|
@ -186,10 +177,6 @@ static BOOL consentLastEnabled = NO;
|
||||||
[randomizeButton setToolTip:NSLocalizedString(@"RandomizeButtonTooltip", @"")];
|
[randomizeButton setToolTip:NSLocalizedString(@"RandomizeButtonTooltip", @"")];
|
||||||
[fileButton setToolTip:NSLocalizedString(@"FileButtonTooltip", @"")];
|
[fileButton setToolTip:NSLocalizedString(@"FileButtonTooltip", @"")];
|
||||||
|
|
||||||
[self registerDefaultHotKeys];
|
|
||||||
|
|
||||||
[self migrateHotKeys];
|
|
||||||
|
|
||||||
[self registerHotKeys];
|
[self registerHotKeys];
|
||||||
|
|
||||||
(void)[spotlightWindowController init];
|
(void)[spotlightWindowController init];
|
||||||
|
@ -238,7 +225,7 @@ static BOOL consentLastEnabled = NO;
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSArray *results = [playlistController.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [playlistController.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
||||||
|
|
||||||
if(results && [results count] > 0) {
|
if(results && [results count] == 1) {
|
||||||
PlaylistEntry *pe = results[0];
|
PlaylistEntry *pe = results[0];
|
||||||
if([[NSUserDefaults standardUserDefaults] boolForKey:@"resumePlaybackOnStartup"]) {
|
if([[NSUserDefaults standardUserDefaults] boolForKey:@"resumePlaybackOnStartup"]) {
|
||||||
[playbackController playEntryAtIndex:pe.index startPaused:(lastStatus == CogStatusPaused) andSeekTo:@(pe.currentPosition)];
|
[playbackController playEntryAtIndex:pe.index startPaused:(lastStatus == CogStatusPaused) andSeekTo:@(pe.currentPosition)];
|
||||||
|
@ -249,13 +236,6 @@ static BOOL consentLastEnabled = NO;
|
||||||
pe.countAdded = NO;
|
pe.countAdded = NO;
|
||||||
[playlistController commitPersistentStore];
|
[playlistController commitPersistentStore];
|
||||||
}
|
}
|
||||||
// Bug fix
|
|
||||||
if([results count] > 1) {
|
|
||||||
for(size_t i = 1; i < [results count]; ++i) {
|
|
||||||
PlaylistEntry *pe = results[i];
|
|
||||||
[pe setCurrent:NO];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,45 +305,10 @@ static BOOL consentLastEnabled = NO;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if([keyPath isEqualToString:@"values.sentryConsented"]) {
|
if([keyPath isEqualToString:@"values.crashlyticsConsented"]) {
|
||||||
BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"sentryConsented"];
|
BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"crashlyticsConsented"];
|
||||||
if(enabled != consentLastEnabled) {
|
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:enabled];
|
||||||
if(enabled) {
|
[FIRAnalytics setAnalyticsCollectionEnabled:enabled];
|
||||||
[SentrySDK startWithConfigureOptions:^(SentryOptions *options) {
|
|
||||||
options.dsn = @"https://b5eda1c2390eb965a74dd735413b6392@cog-analytics.losno.co/3";
|
|
||||||
options.debug = YES; // Enabled debug when first installing is always helpful
|
|
||||||
|
|
||||||
// Temporary until there's a better solution
|
|
||||||
options.enableAppHangTracking = NO;
|
|
||||||
|
|
||||||
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
|
|
||||||
// We recommend adjusting this value in production.
|
|
||||||
options.tracesSampleRate = @1.0;
|
|
||||||
options.profilesSampleRate = @1.0;
|
|
||||||
|
|
||||||
// Adds IP for users.
|
|
||||||
// For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
|
|
||||||
options.sendDefaultPii = YES;
|
|
||||||
|
|
||||||
// And now to set up user feedback prompting
|
|
||||||
options.onCrashedLastRun = ^void(SentryEvent * _Nonnull event) {
|
|
||||||
// capture user feedback
|
|
||||||
FeedbackController *fbcon = [[FeedbackController alloc] init];
|
|
||||||
[fbcon performSelectorOnMainThread:@selector(showWindow:) withObject:nil waitUntilDone:YES];
|
|
||||||
if([fbcon waitForCompletion]) {
|
|
||||||
SentryFeedback *feedback = [[SentryFeedback alloc] initWithMessage:[fbcon comments] name:[fbcon name] email:[fbcon email] source:SentryFeedbackSourceCustom associatedEventId:event.eventId attachments:nil];
|
|
||||||
|
|
||||||
[SentrySDK captureFeedback:feedback];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}];
|
|
||||||
} else {
|
|
||||||
if([SentrySDK isEnabled]) {
|
|
||||||
[SentrySDK close];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
consentLastEnabled = enabled;
|
|
||||||
}
|
|
||||||
} else if([keyPath isEqualToString:@"playlistController.currentEntry"]) {
|
} else if([keyPath isEqualToString:@"playlistController.currentEntry"]) {
|
||||||
PlaylistEntry *entry = playlistController.currentEntry;
|
PlaylistEntry *entry = playlistController.currentEntry;
|
||||||
NSString *appTitle = NSLocalizedString(@"CogTitle", @"");
|
NSString *appTitle = NSLocalizedString(@"CogTitle", @"");
|
||||||
|
@ -636,7 +581,7 @@ static BOOL consentLastEnabled = NO;
|
||||||
|
|
||||||
[userDefaultsValuesDict setObject:@(CogStatusStopped) forKey:@"lastPlaybackStatus"];
|
[userDefaultsValuesDict setObject:@(CogStatusStopped) forKey:@"lastPlaybackStatus"];
|
||||||
|
|
||||||
[userDefaultsValuesDict setObject:@"BASSMIDI" forKey:@"midiPlugin"];
|
[userDefaultsValuesDict setObject:@"dls appl" forKey:@"midiPlugin"];
|
||||||
|
|
||||||
[userDefaultsValuesDict setObject:@"default" forKey:@"midi.flavor"];
|
[userDefaultsValuesDict setObject:@"default" forKey:@"midi.flavor"];
|
||||||
|
|
||||||
|
@ -661,9 +606,6 @@ static BOOL consentLastEnabled = NO;
|
||||||
[userDefaultsValuesDict setObject:@(2) forKey:@"synthDefaultLoopCount"];
|
[userDefaultsValuesDict setObject:@(2) forKey:@"synthDefaultLoopCount"];
|
||||||
[userDefaultsValuesDict setObject:@(44100) forKey:@"synthSampleRate"];
|
[userDefaultsValuesDict setObject:@(44100) forKey:@"synthSampleRate"];
|
||||||
|
|
||||||
[userDefaultsValuesDict setObject:@NO forKey:@"alwaysStopAfterCurrent"];
|
|
||||||
[userDefaultsValuesDict setObject:@YES forKey:@"selectionFollowsPlayback"];
|
|
||||||
|
|
||||||
// Register and sync defaults
|
// Register and sync defaults
|
||||||
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
|
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
|
@ -692,100 +634,9 @@ static BOOL consentLastEnabled = NO;
|
||||||
if([[[NSUserDefaults standardUserDefaults] stringForKey:@"midiPlugin"] isEqualToString:@"FluidSynth"]) {
|
if([[[NSUserDefaults standardUserDefaults] stringForKey:@"midiPlugin"] isEqualToString:@"FluidSynth"]) {
|
||||||
[[NSUserDefaults standardUserDefaults] setValue:@"BASSMIDI" forKey:@"midiPlugin"];
|
[[NSUserDefaults standardUserDefaults] setValue:@"BASSMIDI" forKey:@"midiPlugin"];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *midiPlugin = [[NSUserDefaults standardUserDefaults] stringForKey:@"midiPlugin"];
|
|
||||||
if([midiPlugin length] == 8 && [[midiPlugin substringFromIndex:4] isEqualToString:@"appl"]) {
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:@"BASSMIDI" forKey:@"midiPlugin"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MASShortcut *shortcutWithMigration(NSString *oldKeyCodePrefName,
|
|
||||||
NSString *oldKeyModifierPrefName,
|
|
||||||
NSString *newShortcutPrefName,
|
|
||||||
NSInteger newDefaultKeyCode) {
|
|
||||||
NSEventModifierFlags defaultModifiers = NSEventModifierFlagControl | NSEventModifierFlagCommand;
|
|
||||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
||||||
if([defaults objectForKey:oldKeyCodePrefName]) {
|
|
||||||
NSInteger oldKeyCode = [defaults integerForKey:oldKeyCodePrefName];
|
|
||||||
NSEventModifierFlags oldKeyModifiers = [defaults integerForKey:oldKeyModifierPrefName];
|
|
||||||
// Should we consider temporarily save these values for further migration?
|
|
||||||
[defaults removeObjectForKey:oldKeyCodePrefName];
|
|
||||||
[defaults removeObjectForKey:oldKeyModifierPrefName];
|
|
||||||
return [MASShortcut shortcutWithKeyCode:oldKeyCode modifierFlags:oldKeyModifiers];
|
|
||||||
} else {
|
|
||||||
return [MASShortcut shortcutWithKeyCode:newDefaultKeyCode modifierFlags:defaultModifiers];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NSDictionary *shortcutDefaults = nil;
|
|
||||||
|
|
||||||
- (void)registerDefaultHotKeys {
|
|
||||||
MASShortcut *playShortcut = shortcutWithMigration(@"hotKeyPlayKeyCode",
|
|
||||||
@"hotKeyPlayModifiers",
|
|
||||||
CogPlayShortcutKey,
|
|
||||||
kVK_ANSI_P);
|
|
||||||
MASShortcut *nextShortcut = shortcutWithMigration(@"hotKeyNextKeyCode",
|
|
||||||
@"hotKeyNextModifiers",
|
|
||||||
CogNextShortcutKey,
|
|
||||||
kVK_ANSI_N);
|
|
||||||
MASShortcut *prevShortcut = shortcutWithMigration(@"hotKeyPreviousKeyCode",
|
|
||||||
@"hotKeyPreviousModifiers",
|
|
||||||
CogPrevShortcutKey,
|
|
||||||
kVK_ANSI_R);
|
|
||||||
MASShortcut *spamShortcut = [MASShortcut shortcutWithKeyCode:kVK_ANSI_C
|
|
||||||
modifierFlags:NSEventModifierFlagControl | NSEventModifierFlagCommand];
|
|
||||||
MASShortcut *fadeShortcut = [MASShortcut shortcutWithKeyCode:kVK_ANSI_O
|
|
||||||
modifierFlags:NSEventModifierFlagControl | NSEventModifierFlagCommand];
|
|
||||||
MASShortcut *seekBkwdShortcut = [MASShortcut shortcutWithKeyCode:kVK_LeftArrow
|
|
||||||
modifierFlags:NSEventModifierFlagControl | NSEventModifierFlagCommand];
|
|
||||||
MASShortcut *seekFwdShortcut = [MASShortcut shortcutWithKeyCode:kVK_RightArrow
|
|
||||||
modifierFlags:NSEventModifierFlagControl | NSEventModifierFlagCommand];
|
|
||||||
|
|
||||||
MASDictionaryTransformer *transformer = [MASDictionaryTransformer new];
|
|
||||||
NSDictionary *playShortcutDict = [transformer reverseTransformedValue:playShortcut];
|
|
||||||
NSDictionary *nextShortcutDict = [transformer reverseTransformedValue:nextShortcut];
|
|
||||||
NSDictionary *prevShortcutDict = [transformer reverseTransformedValue:prevShortcut];
|
|
||||||
NSDictionary *spamShortcutDict = [transformer reverseTransformedValue:spamShortcut];
|
|
||||||
NSDictionary *fadeShortcutDict = [transformer reverseTransformedValue:fadeShortcut];
|
|
||||||
NSDictionary *seekBkwdShortcutDict = [transformer reverseTransformedValue:seekBkwdShortcut];
|
|
||||||
NSDictionary *seekFwdShortcutDict = [transformer reverseTransformedValue:seekFwdShortcut];
|
|
||||||
|
|
||||||
// Register default values to be used for the first app start
|
|
||||||
NSDictionary<NSString *, NSDictionary *> *defaultShortcuts = @{
|
|
||||||
CogPlayShortcutKey: playShortcutDict,
|
|
||||||
CogNextShortcutKey: nextShortcutDict,
|
|
||||||
CogPrevShortcutKey: prevShortcutDict,
|
|
||||||
CogSpamShortcutKey: spamShortcutDict,
|
|
||||||
CogFadeShortcutKey: fadeShortcutDict,
|
|
||||||
CogSeekBackwardShortcutKey: seekBkwdShortcutDict,
|
|
||||||
CogSeekForwardShortcutKey: seekFwdShortcutDict
|
|
||||||
};
|
|
||||||
|
|
||||||
shortcutDefaults = defaultShortcuts;
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultShortcuts];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)resetHotkeys:(id)sender {
|
|
||||||
[shortcutDefaults enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:obj forKey:key];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)migrateHotKeys {
|
|
||||||
NSArray *inKeys = @[CogPlayShortcutKeyV1, CogNextShortcutKeyV1, CogPrevShortcutKeyV1, CogSpamShortcutKeyV1, CogFadeShortcutKeyV1, CogSeekBackwardShortcutKeyV1, CogSeekForwardShortcutKeyV1];
|
|
||||||
NSArray *outKeys = @[CogPlayShortcutKey, CogNextShortcutKey, CogPrevShortcutKey, CogSpamShortcutKey, CogFadeShortcutKey, CogSeekBackwardShortcutKey, CogSeekForwardShortcutKey];
|
|
||||||
for(size_t i = 0, j = [inKeys count]; i < j; ++i) {
|
|
||||||
NSString *inKey = inKeys[i];
|
|
||||||
NSString *outKey = outKeys[i];
|
|
||||||
id value = [[NSUserDefaults standardUserDefaults] objectForKey:inKey];
|
|
||||||
if(value && value != [NSNull null]) {
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:value forKey:outKey];
|
|
||||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:inKey];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unassign previous handler first, so dealloc can unregister it from the global map before the new instances are assigned */
|
||||||
- (void)registerHotKeys {
|
- (void)registerHotKeys {
|
||||||
MASShortcutBinder *binder = [MASShortcutBinder sharedBinder];
|
MASShortcutBinder *binder = [MASShortcutBinder sharedBinder];
|
||||||
[binder bindShortcutWithDefaultsKey:CogPlayShortcutKey
|
[binder bindShortcutWithDefaultsKey:CogPlayShortcutKey
|
||||||
|
@ -812,16 +663,6 @@ static NSDictionary *shortcutDefaults = nil;
|
||||||
toAction:^{
|
toAction:^{
|
||||||
[self clickFade];
|
[self clickFade];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[binder bindShortcutWithDefaultsKey:CogSeekBackwardShortcutKey
|
|
||||||
toAction:^{
|
|
||||||
[self clickSeekBack];
|
|
||||||
}];
|
|
||||||
|
|
||||||
[binder bindShortcutWithDefaultsKey:CogSeekForwardShortcutKey
|
|
||||||
toAction:^{
|
|
||||||
[self clickSeekForward];
|
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clickPlay {
|
- (void)clickPlay {
|
||||||
|
@ -856,14 +697,6 @@ static NSDictionary *shortcutDefaults = nil;
|
||||||
[playbackController seek:self toTime:position];
|
[playbackController seek:self toTime:position];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)clickSeekBack {
|
|
||||||
[playbackController seekBackward:10.0];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)clickSeekForward {
|
|
||||||
[playbackController seekForward:10.0];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)changeFontSize:(float)size {
|
- (void)changeFontSize:(float)size {
|
||||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||||
float fCurrentSize = [defaults floatForKey:@"fontSize"];
|
float fCurrentSize = [defaults floatForKey:@"fontSize"];
|
||||||
|
@ -959,21 +792,4 @@ static NSDictionary *shortcutDefaults = nil;
|
||||||
[kAppController showPathSuggester];
|
[kAppController showPathSuggester];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showRubberbandSettings:(id)sender {
|
|
||||||
[preferencesController showRubberbandSettings:sender];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)globalShowRubberbandSettings {
|
|
||||||
[kAppController showRubberbandSettings:kAppController];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)selectTrack:(id)sender {
|
|
||||||
PlaylistEntry *pe = (PlaylistEntry *)sender;
|
|
||||||
@try {
|
|
||||||
[playlistView selectRowIndexes:[NSIndexSet indexSetWithIndex:pe.index] byExtendingSelection:NO];
|
|
||||||
}
|
|
||||||
@catch(NSException *e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -13,13 +13,6 @@
|
||||||
@interface DockIconController : NSObject {
|
@interface DockIconController : NSObject {
|
||||||
NSImage *dockImage;
|
NSImage *dockImage;
|
||||||
|
|
||||||
NSInteger lastDockCustom;
|
|
||||||
NSInteger lastDockCustomPlaque;
|
|
||||||
NSInteger dockCustomLoaded;
|
|
||||||
NSImage *dockCustomStop;
|
|
||||||
NSImage *dockCustomPlay;
|
|
||||||
NSImage *dockCustomPause;
|
|
||||||
|
|
||||||
IBOutlet PlaybackController *playbackController;
|
IBOutlet PlaybackController *playbackController;
|
||||||
|
|
||||||
NSInteger lastPlaybackStatus;
|
NSInteger lastPlaybackStatus;
|
||||||
|
|
|
@ -14,24 +14,16 @@
|
||||||
|
|
||||||
static NSString *DockIconPlaybackStatusObservationContext = @"DockIconPlaybackStatusObservationContext";
|
static NSString *DockIconPlaybackStatusObservationContext = @"DockIconPlaybackStatusObservationContext";
|
||||||
|
|
||||||
static NSString *CogCustomDockIconsReloadNotification = @"CogCustomDockIconsReloadNotification";
|
|
||||||
|
|
||||||
- (void)startObserving {
|
- (void)startObserving {
|
||||||
[playbackController addObserver:self forKeyPath:@"playbackStatus" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
[playbackController addObserver:self forKeyPath:@"playbackStatus" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||||
[playbackController addObserver:self forKeyPath:@"progressOverall" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionOld) context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
[playbackController addObserver:self forKeyPath:@"progressOverall" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionOld) context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.colorfulDockIcons" options:0 context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.colorfulDockIcons" options:0 context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.customDockIcons" options:0 context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.customDockIconsPlaque" options:0 context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshDockIcons:) name:CogCustomDockIconsReloadNotification object:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stopObserving {
|
- (void)stopObserving {
|
||||||
[playbackController removeObserver:self forKeyPath:@"playbackStatus" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
[playbackController removeObserver:self forKeyPath:@"playbackStatus" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||||
[playbackController removeObserver:self forKeyPath:@"progressOverall" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
[playbackController removeObserver:self forKeyPath:@"progressOverall" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.colorfulDockIcons" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.colorfulDockIcons" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.customDockIcons" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.customDockIconsPlaque" context:(__bridge void *_Nullable)(DockIconPlaybackStatusObservationContext)];
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:CogCustomDockIconsReloadNotification object:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startObservingProgress:(NSProgress *)progress {
|
- (void)startObservingProgress:(NSProgress *)progress {
|
||||||
|
@ -50,34 +42,6 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSString *getCustomIconName(NSString *baseName) {
|
|
||||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
|
||||||
NSString *basePath = [[paths firstObject] stringByAppendingPathComponent:@"Cog"];
|
|
||||||
basePath = [basePath stringByAppendingPathComponent:@"Icons"];
|
|
||||||
basePath = [basePath stringByAppendingPathComponent:baseName];
|
|
||||||
return [basePath stringByAppendingPathExtension:@"png"];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)loadCustomDockIcons {
|
|
||||||
NSError *error = nil;
|
|
||||||
NSData *dataStopIcon = [NSData dataWithContentsOfFile:getCustomIconName(@"Stop") options:(NSDataReadingMappedIfSafe) error:&error];
|
|
||||||
if(!dataStopIcon || error) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
NSData *dataPlayIcon = [NSData dataWithContentsOfFile:getCustomIconName(@"Play") options:(NSDataReadingMappedIfSafe) error:&error];
|
|
||||||
if(!dataPlayIcon || error) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
NSData *dataPauseIcon = [NSData dataWithContentsOfFile:getCustomIconName(@"Pause") options:(NSDataReadingMappedIfSafe) error:&error];
|
|
||||||
if(!dataPauseIcon || error) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
dockCustomStop = [[NSImage alloc] initWithData:dataStopIcon];
|
|
||||||
dockCustomPlay = [[NSImage alloc] initWithData:dataPlayIcon];
|
|
||||||
dockCustomPause = [[NSImage alloc] initWithData:dataPauseIcon];
|
|
||||||
return (dockCustomStop && dockCustomPlay && dockCustomPause);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)refreshDockIcon:(NSInteger)playbackStatus withProgress:(double)progressStatus {
|
- (void)refreshDockIcon:(NSInteger)playbackStatus withProgress:(double)progressStatus {
|
||||||
// Really weird crash user experienced because the plaque image didn't load?
|
// Really weird crash user experienced because the plaque image didn't load?
|
||||||
if(!dockImage || dockImage.size.width == 0 || dockImage.size.height == 0) return;
|
if(!dockImage || dockImage.size.width == 0 || dockImage.size.height == 0) return;
|
||||||
|
@ -86,30 +50,6 @@ static NSString *getCustomIconName(NSString *baseName) {
|
||||||
BOOL drawIcon = NO;
|
BOOL drawIcon = NO;
|
||||||
BOOL removeProgress = NO;
|
BOOL removeProgress = NO;
|
||||||
|
|
||||||
BOOL useCustomDockIcons = [[NSUserDefaults standardUserDefaults] boolForKey:@"customDockIcons"];
|
|
||||||
BOOL useCustomDockIconsPlaque = [[NSUserDefaults standardUserDefaults] boolForKey:@"customDockIconsPlaque"];
|
|
||||||
|
|
||||||
if(useCustomDockIcons && !dockCustomLoaded) {
|
|
||||||
dockCustomLoaded = [self loadCustomDockIcons];
|
|
||||||
if(!dockCustomLoaded) {
|
|
||||||
useCustomDockIcons = NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(useCustomDockIcons != lastDockCustom ||
|
|
||||||
useCustomDockIconsPlaque != lastDockCustomPlaque) {
|
|
||||||
lastDockCustom = useCustomDockIcons;
|
|
||||||
lastDockCustomPlaque = useCustomDockIconsPlaque;
|
|
||||||
drawIcon = YES;
|
|
||||||
|
|
||||||
if(!useCustomDockIcons) {
|
|
||||||
dockCustomLoaded = NO;
|
|
||||||
dockCustomStop = nil;
|
|
||||||
dockCustomPlay = nil;
|
|
||||||
dockCustomPause = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(playbackStatus < 0)
|
if(playbackStatus < 0)
|
||||||
playbackStatus = lastPlaybackStatus;
|
playbackStatus = lastPlaybackStatus;
|
||||||
else {
|
else {
|
||||||
|
@ -142,20 +82,20 @@ static NSString *getCustomIconName(NSString *baseName) {
|
||||||
if(drawIcon) {
|
if(drawIcon) {
|
||||||
switch(playbackStatus) {
|
switch(playbackStatus) {
|
||||||
case CogStatusPlaying:
|
case CogStatusPlaying:
|
||||||
badgeImage = useCustomDockIcons ? dockCustomPlay : [NSImage imageNamed:getBadgeName(@"Play", colorfulIcons)];
|
badgeImage = [NSImage imageNamed:getBadgeName(@"Play", colorfulIcons)];
|
||||||
break;
|
break;
|
||||||
case CogStatusPaused:
|
case CogStatusPaused:
|
||||||
badgeImage = useCustomDockIcons ? dockCustomPause : [NSImage imageNamed:getBadgeName(@"Pause", colorfulIcons)];
|
badgeImage = [NSImage imageNamed:getBadgeName(@"Pause", colorfulIcons)];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
badgeImage = useCustomDockIcons ? dockCustomStop : [NSImage imageNamed:getBadgeName(@"Stop", colorfulIcons)];
|
badgeImage = [NSImage imageNamed:getBadgeName(@"Stop", colorfulIcons)];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSSize badgeSize = [badgeImage size];
|
NSSize badgeSize = [badgeImage size];
|
||||||
|
|
||||||
NSImage *newDockImage = (useCustomDockIcons && !useCustomDockIconsPlaque) ? [[NSImage alloc] initWithSize:NSMakeSize(1024, 1024)] : [dockImage copy];
|
NSImage *newDockImage = [dockImage copy];
|
||||||
[newDockImage lockFocus];
|
[newDockImage lockFocus];
|
||||||
|
|
||||||
[badgeImage drawInRect:NSMakeRect(0, 0, 1024, 1024)
|
[badgeImage drawInRect:NSMakeRect(0, 0, 1024, 1024)
|
||||||
|
@ -246,9 +186,7 @@ static NSString *getCustomIconName(NSString *baseName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
[self refreshDockIcon:-1 withProgress:progressStatus];
|
[self refreshDockIcon:-1 withProgress:progressStatus];
|
||||||
} else if([keyPath isEqualToString:@"values.colorfulDockIcons"] ||
|
} else if([keyPath isEqualToString:@"values.colorfulDockIcons"]) {
|
||||||
[keyPath isEqualToString:@"values.customDockIcons"] ||
|
|
||||||
[keyPath isEqualToString:@"values.customDockIconsPlaque"]) {
|
|
||||||
[self refreshDockIcon:-1 withProgress:-10];
|
[self refreshDockIcon:-1 withProgress:-10];
|
||||||
} else if([keyPath isEqualToString:@"fractionCompleted"]) {
|
} else if([keyPath isEqualToString:@"fractionCompleted"]) {
|
||||||
double progressStatus = [(NSProgress *)object fractionCompleted];
|
double progressStatus = [(NSProgress *)object fractionCompleted];
|
||||||
|
@ -259,12 +197,6 @@ static NSString *getCustomIconName(NSString *baseName) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refreshDockIcons:(NSNotification *)notification {
|
|
||||||
lastDockCustom = NO;
|
|
||||||
dockCustomLoaded = NO;
|
|
||||||
[self refreshDockIcon:-1 withProgress:-10];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)awakeFromNib {
|
- (void)awakeFromNib {
|
||||||
dockImage = [[NSImage imageNamed:@"Plaque"] copy];
|
dockImage = [[NSImage imageNamed:@"Plaque"] copy];
|
||||||
lastColorfulStatus = -1;
|
lastColorfulStatus = -1;
|
||||||
|
|
|
@ -19,12 +19,6 @@
|
||||||
#define DEFAULT_VOLUME_DOWN 5
|
#define DEFAULT_VOLUME_DOWN 5
|
||||||
#define DEFAULT_VOLUME_UP DEFAULT_VOLUME_DOWN
|
#define DEFAULT_VOLUME_UP DEFAULT_VOLUME_DOWN
|
||||||
|
|
||||||
#define DEFAULT_PITCH_DOWN 0.2
|
|
||||||
#define DEFAULT_PITCH_UP DEFAULT_PITCH_DOWN
|
|
||||||
|
|
||||||
#define DEFAULT_TEMPO_DOWN 0.2
|
|
||||||
#define DEFAULT_TEMPO_UP DEFAULT_TEMPO_DOWN
|
|
||||||
|
|
||||||
extern NSString *CogPlaybackDidBeginNotificiation;
|
extern NSString *CogPlaybackDidBeginNotificiation;
|
||||||
extern NSString *CogPlaybackDidPauseNotificiation;
|
extern NSString *CogPlaybackDidPauseNotificiation;
|
||||||
extern NSString *CogPlaybackDidResumeNotificiation;
|
extern NSString *CogPlaybackDidResumeNotificiation;
|
||||||
|
@ -46,9 +40,6 @@ extern NSDictionary *makeRGInfo(PlaylistEntry *pe);
|
||||||
IBOutlet EqualizerWindowController *equalizerWindowController;
|
IBOutlet EqualizerWindowController *equalizerWindowController;
|
||||||
|
|
||||||
IBOutlet NSSlider *volumeSlider;
|
IBOutlet NSSlider *volumeSlider;
|
||||||
IBOutlet NSSlider *pitchSlider;
|
|
||||||
IBOutlet NSSlider *tempoSlider;
|
|
||||||
IBOutlet NSButton *lockButton;
|
|
||||||
|
|
||||||
IBOutlet NSArrayController *outputDevices;
|
IBOutlet NSArrayController *outputDevices;
|
||||||
|
|
||||||
|
@ -78,14 +69,6 @@ extern NSDictionary *makeRGInfo(PlaylistEntry *pe);
|
||||||
- (IBAction)volumeDown:(id)sender;
|
- (IBAction)volumeDown:(id)sender;
|
||||||
- (IBAction)volumeUp:(id)sender;
|
- (IBAction)volumeUp:(id)sender;
|
||||||
|
|
||||||
- (IBAction)changePitch:(id)sender;
|
|
||||||
- (IBAction)pitchDown:(id)sender;
|
|
||||||
- (IBAction)pitchUp:(id)sender;
|
|
||||||
|
|
||||||
- (IBAction)changeTempo:(id)sender;
|
|
||||||
- (IBAction)tempoDown:(id)sender;
|
|
||||||
- (IBAction)tempoUp:(id)sender;
|
|
||||||
|
|
||||||
- (IBAction)playPauseResume:(id)sender;
|
- (IBAction)playPauseResume:(id)sender;
|
||||||
- (IBAction)pauseResume:(id)sender;
|
- (IBAction)pauseResume:(id)sender;
|
||||||
- (IBAction)skipToNextAlbum:(id)sender;
|
- (IBAction)skipToNextAlbum:(id)sender;
|
||||||
|
|
|
@ -19,15 +19,12 @@
|
||||||
|
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
|
|
||||||
@import Sentry;
|
@import Firebase;
|
||||||
|
|
||||||
// Sentry captureMessage is too spammy to use for anything but actual errors
|
|
||||||
|
|
||||||
extern BOOL kAppControllerShuttingDown;
|
extern BOOL kAppControllerShuttingDown;
|
||||||
|
|
||||||
@implementation NSObject (NxAdditions)
|
@implementation NSObject (NxAdditions)
|
||||||
|
|
||||||
#if 0
|
|
||||||
-(void)performSelectorInBackground:(SEL)selector withObjects:(id)object, ...
|
-(void)performSelectorInBackground:(SEL)selector withObjects:(id)object, ...
|
||||||
{
|
{
|
||||||
NSMethodSignature *signature = [self methodSignatureForSelector:selector];
|
NSMethodSignature *signature = [self methodSignatureForSelector:selector];
|
||||||
|
@ -52,32 +49,6 @@ extern BOOL kAppControllerShuttingDown;
|
||||||
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
|
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
|
||||||
[backgroundQueue addOperation:operation];
|
[backgroundQueue addOperation:operation];
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
-(void)performSelectorOnMainThread:(SEL)selector withObjects:(id)object, ...
|
|
||||||
{
|
|
||||||
NSMethodSignature *signature = [self methodSignatureForSelector:selector];
|
|
||||||
|
|
||||||
// Setup the invocation
|
|
||||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
|
||||||
invocation.target = self;
|
|
||||||
invocation.selector = selector;
|
|
||||||
|
|
||||||
// Associate the arguments
|
|
||||||
va_list objects;
|
|
||||||
va_start(objects, object);
|
|
||||||
unsigned int objectCounter = 2;
|
|
||||||
for (id obj = object; obj != nil; obj = va_arg(objects, id))
|
|
||||||
{
|
|
||||||
[invocation setArgument:&obj atIndex:objectCounter++];
|
|
||||||
}
|
|
||||||
va_end(objects);
|
|
||||||
|
|
||||||
// Invoke on the main operation queue
|
|
||||||
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithInvocation:invocation];
|
|
||||||
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
|
|
||||||
[mainQueue addOperation:operation];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -120,51 +91,15 @@ NSString *CogPlaybackDidStopNotificiation = @"CogPlaybackDidStopNotificiation";
|
||||||
|
|
||||||
- (void)initDefaults {
|
- (void)initDefaults {
|
||||||
NSDictionary *defaultsDictionary = @{ @"volume": @(75.0),
|
NSDictionary *defaultsDictionary = @{ @"volume": @(75.0),
|
||||||
@"pitch": @(1.0),
|
|
||||||
@"tempo": @(1.0),
|
|
||||||
@"speedLock": @(YES),
|
|
||||||
@"GraphicEQenable": @(NO),
|
@"GraphicEQenable": @(NO),
|
||||||
@"GraphicEQpreset": @(-1),
|
@"GraphicEQpreset": @(-1),
|
||||||
@"GraphicEQtrackgenre": @(NO),
|
@"GraphicEQtrackgenre": @(NO),
|
||||||
@"volumeLimit": @(YES),
|
@"volumeLimit": @(YES),
|
||||||
@"enableHrtf": @(NO),
|
@"headphoneVirtualization": @(NO) };
|
||||||
@"enableHeadTracking": @(NO),
|
|
||||||
@"enableHDCD": @(NO),
|
|
||||||
/*@"rubberbandEngine": @"faster",*/
|
|
||||||
@"rubberbandTransients": @"crisp",
|
|
||||||
@"rubberbandDetector": @"compound",
|
|
||||||
@"rubberbandPhase": @"laminar",
|
|
||||||
@"rubberbandWindow": @"standard",
|
|
||||||
@"rubberbandSmoothing": @"off",
|
|
||||||
@"rubberbandFormant": @"shifted",
|
|
||||||
@"rubberbandPitch": @"highspeed",
|
|
||||||
@"rubberbandChannels": @"apart"
|
|
||||||
};
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsDictionary];
|
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsDictionary];
|
||||||
}
|
}
|
||||||
|
|
||||||
static double speedScale(double input, double min, double max) {
|
|
||||||
input = (input - min) * 100.0 / (max - min);
|
|
||||||
return ((input * input) * (5.0 - 0.2) / 10000.0) + 0.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static double reverseSpeedScale(double input, double min, double max) {
|
|
||||||
input = sqrtf((input - 0.2) * 10000.0 / (5.0 - 0.2));
|
|
||||||
return (input * (max - min) / 100.0) + min;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)snapSpeeds {
|
|
||||||
double pitch = [[NSUserDefaults standardUserDefaults] doubleForKey:@"pitch"];
|
|
||||||
double tempo = [[NSUserDefaults standardUserDefaults] doubleForKey:@"tempo"];
|
|
||||||
if(fabs(pitch - 1.0) < 1e-6) {
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:1.0 forKey:@"pitch"];
|
|
||||||
}
|
|
||||||
if(fabs(tempo - 1.0) < 1e-6) {
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:1.0 forKey:@"tempo"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)awakeFromNib {
|
- (void)awakeFromNib {
|
||||||
BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"];
|
BOOL volumeLimit = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"volumeLimit"];
|
||||||
const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0;
|
const double MAX_VOLUME = (volumeLimit) ? 100.0 : 800.0;
|
||||||
|
@ -174,16 +109,6 @@ static double reverseSpeedScale(double input, double min, double max) {
|
||||||
[volumeSlider setDoubleValue:logarithmicToLinear(volume, MAX_VOLUME)];
|
[volumeSlider setDoubleValue:logarithmicToLinear(volume, MAX_VOLUME)];
|
||||||
[audioPlayer setVolume:volume];
|
[audioPlayer setVolume:volume];
|
||||||
|
|
||||||
double pitch = [[NSUserDefaults standardUserDefaults] doubleForKey:@"pitch"];
|
|
||||||
[pitchSlider setDoubleValue:reverseSpeedScale(pitch, [pitchSlider minValue], [pitchSlider maxValue])];
|
|
||||||
double tempo = [[NSUserDefaults standardUserDefaults] doubleForKey:@"tempo"];
|
|
||||||
[tempoSlider setDoubleValue:reverseSpeedScale(tempo, [tempoSlider minValue], [tempoSlider maxValue])];
|
|
||||||
|
|
||||||
[self snapSpeeds];
|
|
||||||
|
|
||||||
BOOL speedLock = [[NSUserDefaults standardUserDefaults] boolForKey:@"speedLock"];
|
|
||||||
[lockButton setTitle:speedLock ? @"🔒" : @"🔓"];
|
|
||||||
|
|
||||||
[self setSeekable:NO];
|
[self setSeekable:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,9 +130,8 @@ static double reverseSpeedScale(double input, double min, double max) {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)pause:(id)sender {
|
- (IBAction)pause:(id)sender {
|
||||||
if(![self seekable]) {
|
if(!([playlistController currentEntry].seekable)) {
|
||||||
[self stop:sender];
|
return [self stop:sender];
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setInteger:CogStatusPaused forKey:@"lastPlaybackStatus"];
|
[[NSUserDefaults standardUserDefaults] setInteger:CogStatusPaused forKey:@"lastPlaybackStatus"];
|
||||||
|
@ -301,11 +225,11 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
if(!pe.url) {
|
if(!pe.url) {
|
||||||
pe.error = YES;
|
pe.error = YES;
|
||||||
pe.errorMessage = NSLocalizedStringFromTableInBundle(@"ErrorMessageBadFile", nil, [NSBundle bundleForClass:[self class]], @"");
|
pe.errorMessage = NSLocalizedStringFromTableInBundle(@"ErrorMessageBadFile", nil, [NSBundle bundleForClass:[self class]], @"");
|
||||||
[SentrySDK captureMessage:@"Attempted to play a bad file with no URL"];
|
[[FIRCrashlytics crashlytics] log:@"Attempting to play bad file."];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//[SentrySDK captureMessage:[NSString stringWithFormat:@"Playing track: %@", pe.url]];
|
[[FIRCrashlytics crashlytics] logWithFormat:@"Playing track: %@", pe.url];
|
||||||
|
|
||||||
DLog(@"PLAYLIST CONTROLLER: %@", [playlistController class]);
|
DLog(@"PLAYLIST CONTROLLER: %@", [playlistController class]);
|
||||||
[playlistController setCurrentEntry:pe];
|
[playlistController setCurrentEntry:pe];
|
||||||
|
@ -325,7 +249,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Race here, but the worst that could happen is we re-read the data
|
// Race here, but the worst that could happen is we re-read the data
|
||||||
if([pe metadataLoaded] != YES) {
|
if ([pe metadataLoaded] != YES) {
|
||||||
[pe performSelectorOnMainThread:@selector(setMetadata:) withObject:[playlistLoader readEntryInfo:pe] waitUntilDone:YES];
|
[pe performSelectorOnMainThread:@selector(setMetadata:) withObject:[playlistLoader readEntryInfo:pe] waitUntilDone:YES];
|
||||||
}
|
}
|
||||||
#elif 0
|
#elif 0
|
||||||
|
@ -346,7 +270,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
|
|
||||||
double seekTime = pe.seekable ? [offset doubleValue] : 0.0;
|
double seekTime = pe.seekable ? [offset doubleValue] : 0.0;
|
||||||
|
|
||||||
[audioPlayer performSelectorOnMainThread:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(seekTime), nil];
|
[audioPlayer performSelectorInBackground:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(seekTime), nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)next:(id)sender {
|
- (IBAction)next:(id)sender {
|
||||||
|
@ -357,12 +281,8 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)prev:(id)sender {
|
- (IBAction)prev:(id)sender {
|
||||||
double pos = [audioPlayer amountPlayed];
|
|
||||||
|
|
||||||
if(pos < 5.0) {
|
|
||||||
if([playlistController prev] == NO)
|
if([playlistController prev] == NO)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
[self playEntry:[playlistController currentEntry]];
|
[self playEntry:[playlistController currentEntry]];
|
||||||
}
|
}
|
||||||
|
@ -381,7 +301,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
- (IBAction)seek:(id)sender {
|
- (IBAction)seek:(id)sender {
|
||||||
double time = [sender doubleValue];
|
double time = [sender doubleValue];
|
||||||
|
|
||||||
[audioPlayer performSelectorOnMainThread:@selector(seekToTimeBG:) withObjects:@(time), nil];
|
[audioPlayer performSelectorInBackground:@selector(seekToTimeBG:) withObject:@(time)];
|
||||||
|
|
||||||
lastPosition = -10;
|
lastPosition = -10;
|
||||||
|
|
||||||
|
@ -398,7 +318,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
|
|
||||||
lastPosition = -10;
|
lastPosition = -10;
|
||||||
|
|
||||||
[audioPlayer performSelectorOnMainThread:@selector(seekToTimeBG:) withObjects:@(time), nil];
|
[audioPlayer performSelectorInBackground:@selector(seekToTimeBG:) withObject:@(time)];
|
||||||
|
|
||||||
[self setPosition:time];
|
[self setPosition:time];
|
||||||
|
|
||||||
|
@ -424,17 +344,15 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)seekForward:(double)amount {
|
- (void)seekForward:(double)amount {
|
||||||
if([self seekable]) {
|
|
||||||
double seekTo = [audioPlayer amountPlayed] + amount;
|
double seekTo = [audioPlayer amountPlayed] + amount;
|
||||||
|
|
||||||
if(seekTo > [[[playlistController currentEntry] length] doubleValue]) {
|
if(seekTo > [[[playlistController currentEntry] length] doubleValue]) {
|
||||||
[self next:self];
|
[self next:self];
|
||||||
} else {
|
} else {
|
||||||
lastPosition = -10;
|
lastPosition = -10;
|
||||||
[audioPlayer performSelectorOnMainThread:@selector(seekToTimeBG:) withObjects:@(seekTo), nil];
|
[audioPlayer performSelectorInBackground:@selector(seekToTimeBG:) withObject:@(seekTo)];
|
||||||
[self setPosition:seekTo];
|
[self setPosition:seekTo];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)eventSeekBackward:(id)sender {
|
- (IBAction)eventSeekBackward:(id)sender {
|
||||||
|
@ -442,7 +360,6 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)seekBackward:(double)amount {
|
- (void)seekBackward:(double)amount {
|
||||||
if([self seekable]) {
|
|
||||||
double seekTo = [audioPlayer amountPlayed] - amount;
|
double seekTo = [audioPlayer amountPlayed] - amount;
|
||||||
|
|
||||||
if(seekTo < 0)
|
if(seekTo < 0)
|
||||||
|
@ -450,9 +367,8 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
|
|
||||||
lastPosition = -10;
|
lastPosition = -10;
|
||||||
|
|
||||||
[audioPlayer performSelectorOnMainThread:@selector(seekToTimeBG:) withObjects:@(seekTo), nil];
|
[audioPlayer performSelectorInBackground:@selector(seekToTimeBG:) withObject:@(seekTo)];
|
||||||
[self setPosition:seekTo];
|
[self setPosition:seekTo];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -461,7 +377,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
NSImage *img = [NSImage imageNamed:name];
|
NSImage *img = [NSImage imageNamed:name];
|
||||||
// [img retain];
|
// [img retain];
|
||||||
|
|
||||||
if(img == nil)
|
if (img == nil)
|
||||||
{
|
{
|
||||||
DLog(@"Error loading image!");
|
DLog(@"Error loading image!");
|
||||||
}
|
}
|
||||||
|
@ -562,32 +478,6 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)changePitch:(id)sender {
|
|
||||||
const double pitch = speedScale([sender doubleValue], [pitchSlider minValue], [pitchSlider maxValue]);
|
|
||||||
DLog(@"PITCH: %lf", pitch);
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:pitch forKey:@"pitch"];
|
|
||||||
|
|
||||||
if([[NSUserDefaults standardUserDefaults] boolForKey:@"speedLock"]) {
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:pitch forKey:@"tempo"];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self snapSpeeds];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)changeTempo:(id)sender {
|
|
||||||
const double tempo = speedScale([sender doubleValue], [tempoSlider minValue], [tempoSlider maxValue]);
|
|
||||||
DLog(@"TEMPO: %lf", tempo);
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:tempo forKey:@"tempo"];
|
|
||||||
|
|
||||||
if([[NSUserDefaults standardUserDefaults] boolForKey:@"speedLock"]) {
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:tempo forKey:@"pitch"];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self snapSpeeds];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)skipToNextAlbum:(id)sender {
|
- (IBAction)skipToNextAlbum:(id)sender {
|
||||||
BOOL found = NO;
|
BOOL found = NO;
|
||||||
|
|
||||||
|
@ -689,75 +579,8 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:[audioPlayer volume] forKey:@"volume"];
|
[[NSUserDefaults standardUserDefaults] setDouble:[audioPlayer volume] forKey:@"volume"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)pitchDown:(id)sender {
|
|
||||||
double pitch = speedScale([pitchSlider doubleValue], [pitchSlider minValue], [pitchSlider maxValue]);
|
|
||||||
double newPitch = pitch - DEFAULT_PITCH_DOWN;
|
|
||||||
if(newPitch < 0.2) {
|
|
||||||
newPitch = 0.2;
|
|
||||||
}
|
|
||||||
[pitchSlider setDoubleValue:reverseSpeedScale(newPitch, [pitchSlider minValue], [pitchSlider maxValue])];
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:newPitch forKey:@"pitch"];
|
|
||||||
|
|
||||||
if([[NSUserDefaults standardUserDefaults] boolForKey:@"speedLock"]) {
|
|
||||||
[tempoSlider setDoubleValue:reverseSpeedScale(newPitch, [tempoSlider minValue], [tempoSlider maxValue])];
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:newPitch forKey:@"tempo"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)pitchUp:(id)sender {
|
|
||||||
double pitch = speedScale([pitchSlider doubleValue], [pitchSlider minValue], [pitchSlider maxValue]);
|
|
||||||
double newPitch = pitch + DEFAULT_PITCH_UP;
|
|
||||||
if(newPitch > 5.0) {
|
|
||||||
newPitch = 5.0;
|
|
||||||
}
|
|
||||||
[pitchSlider setDoubleValue:reverseSpeedScale(newPitch, [pitchSlider minValue], [pitchSlider maxValue])];
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:newPitch forKey:@"pitch"];
|
|
||||||
|
|
||||||
if([[NSUserDefaults standardUserDefaults] boolForKey:@"speedLock"]) {
|
|
||||||
[tempoSlider setDoubleValue:reverseSpeedScale(newPitch, [tempoSlider minValue], [tempoSlider maxValue])];
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:newPitch forKey:@"tempo"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)tempoDown:(id)sender {
|
|
||||||
double tempo = speedScale([tempoSlider doubleValue], [tempoSlider minValue], [tempoSlider maxValue]);
|
|
||||||
double newTempo = tempo - DEFAULT_TEMPO_DOWN;
|
|
||||||
if(newTempo < 0.2) {
|
|
||||||
newTempo = 0.2;
|
|
||||||
}
|
|
||||||
[tempoSlider setDoubleValue:reverseSpeedScale(newTempo, [tempoSlider minValue], [tempoSlider maxValue])];
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:newTempo forKey:@"tempo"];
|
|
||||||
|
|
||||||
if([[NSUserDefaults standardUserDefaults] boolForKey:@"speedLock"]) {
|
|
||||||
[pitchSlider setDoubleValue:reverseSpeedScale(newTempo, [pitchSlider minValue], [pitchSlider maxValue])];
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:newTempo forKey:@"pitch"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (IBAction)tempoUp:(id)sender {
|
|
||||||
double tempo = speedScale([tempoSlider doubleValue], [tempoSlider minValue], [tempoSlider maxValue]);
|
|
||||||
double newTempo = tempo + DEFAULT_TEMPO_UP;
|
|
||||||
if(newTempo > 5.0) {
|
|
||||||
newTempo = 5.0;
|
|
||||||
}
|
|
||||||
[tempoSlider setDoubleValue:reverseSpeedScale(newTempo, [tempoSlider minValue], [tempoSlider maxValue])];
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:newTempo forKey:@"tempo"];
|
|
||||||
|
|
||||||
if([[NSUserDefaults standardUserDefaults] boolForKey:@"speedLock"]) {
|
|
||||||
[pitchSlider setDoubleValue:reverseSpeedScale(newTempo, [pitchSlider minValue], [pitchSlider maxValue])];
|
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setDouble:newTempo forKey:@"pitch"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)audioPlayer:(AudioPlayer *)player displayEqualizer:(AudioUnit)eq {
|
- (void)audioPlayer:(AudioPlayer *)player displayEqualizer:(AudioUnit)eq {
|
||||||
|
|
||||||
if(_eq && _eq != eq) {
|
if(_eq && _eq != eq) {
|
||||||
[equalizerWindowController setEQ:nil];
|
[equalizerWindowController setEQ:nil];
|
||||||
}
|
}
|
||||||
|
@ -796,15 +619,15 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pe && pe.url) {
|
if(pe && pe.url) {
|
||||||
//[SentrySDK captureMessage:[NSString stringWithFormat:@"Beginning decoding track: %@", pe.url]];
|
[[FIRCrashlytics crashlytics] logWithFormat:@"Beginning decoding track: %@", pe.url];
|
||||||
[player setNextStream:pe.url withUserInfo:pe withRGInfo:makeRGInfo(pe)];
|
[player setNextStream:pe.url withUserInfo:pe withRGInfo:makeRGInfo(pe)];
|
||||||
} else if(pe) {
|
} else if(pe) {
|
||||||
[SentrySDK captureMessage:@"Invalid playlist entry reached"];
|
[[FIRCrashlytics crashlytics] log:@"Invalid playlist entry reached."];
|
||||||
[player setNextStream:nil];
|
[player setNextStream:nil];
|
||||||
pe.error = YES;
|
pe.error = YES;
|
||||||
pe.errorMessage = NSLocalizedStringFromTableInBundle(@"ErrorMessageBadFile", nil, [NSBundle bundleForClass:[self class]], @"");
|
pe.errorMessage = NSLocalizedStringFromTableInBundle(@"ErrorMessageBadFile", nil, [NSBundle bundleForClass:[self class]], @"");
|
||||||
} else {
|
} else {
|
||||||
//[SentrySDK captureMessage:@"End of playlist reached"];
|
[[FIRCrashlytics crashlytics] log:@"End of playlist reached."];
|
||||||
[player setNextStream:nil];
|
[player setNextStream:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -815,7 +638,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
// Delay the action until this function has returned to the audio thread
|
// Delay the action until this function has returned to the audio thread
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
|
||||||
if(pe) {
|
if(pe) {
|
||||||
//[SentrySDK captureMessage:[NSString stringWithFormat:@"Updating UI with track: %@", pe.url]];
|
[[FIRCrashlytics crashlytics] logWithFormat:@"Updating UI with track: %@", pe.url];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self->playlistController setCurrentEntry:pe];
|
[self->playlistController setCurrentEntry:pe];
|
||||||
|
@ -846,7 +669,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(status == CogStatusStopped) {
|
if(status == CogStatusStopped) {
|
||||||
//[SentrySDK captureMessage:@"Playback stopped"];
|
[[FIRCrashlytics crashlytics] log:@"Stopped."];
|
||||||
|
|
||||||
[self setPosition:0];
|
[self setPosition:0];
|
||||||
[self setSeekable:NO]; // the player stopped, disable the slider
|
[self setSeekable:NO]; // the player stopped, disable the slider
|
||||||
|
@ -854,11 +677,11 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:CogPlaybackDidStopNotificiation object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:CogPlaybackDidStopNotificiation object:nil];
|
||||||
} else // paused
|
} else // paused
|
||||||
{
|
{
|
||||||
//[SentrySDK captureMessage:@"Playback paused"];
|
[[FIRCrashlytics crashlytics] log:@"Paused."];
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:CogPlaybackDidPauseNotificiation object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:CogPlaybackDidPauseNotificiation object:nil];
|
||||||
}
|
}
|
||||||
} else if(status == CogStatusPlaying) {
|
} else if(status == CogStatusPlaying) {
|
||||||
//[SentrySDK captureMessage:@"Playback started"];
|
[[FIRCrashlytics crashlytics] log:@"Started playing."];
|
||||||
|
|
||||||
if(!positionTimer) {
|
if(!positionTimer) {
|
||||||
positionTimer = [NSTimer timerWithTimeInterval:0.2 target:self selector:@selector(updatePosition:) userInfo:nil repeats:YES];
|
positionTimer = [NSTimer timerWithTimeInterval:0.2 target:self selector:@selector(updatePosition:) userInfo:nil repeats:YES];
|
||||||
|
@ -894,7 +717,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
|
|
||||||
- (void)audioPlayer:(AudioPlayer *)player didStopNaturally:(id)userInfo {
|
- (void)audioPlayer:(AudioPlayer *)player didStopNaturally:(id)userInfo {
|
||||||
if([[NSUserDefaults standardUserDefaults] boolForKey:@"quitOnNaturalStop"]) {
|
if([[NSUserDefaults standardUserDefaults] boolForKey:@"quitOnNaturalStop"]) {
|
||||||
//[SentrySDK captureMessage:@"Playback stopped naturally, terminating app"];
|
[[FIRCrashlytics crashlytics] log:@"Terminating due to natural stop."];
|
||||||
[NSApp terminate:nil];
|
[NSApp terminate:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -909,13 +732,13 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
- (void)audioPlayer:(AudioPlayer *)player restartPlaybackAtCurrentPosition:(id)userInfo {
|
- (void)audioPlayer:(AudioPlayer *)player restartPlaybackAtCurrentPosition:(id)userInfo {
|
||||||
PlaylistEntry *pe = [playlistController currentEntry];
|
PlaylistEntry *pe = [playlistController currentEntry];
|
||||||
BOOL paused = playbackStatus == CogStatusPaused;
|
BOOL paused = playbackStatus == CogStatusPaused;
|
||||||
//[SentrySDK captureMessage:[NSString stringWithFormat:@"Playback restarting for track: %@", pe.url]];
|
[[FIRCrashlytics crashlytics] logWithFormat:@"Restarting playback of track: %@", pe.url];
|
||||||
[player performSelectorOnMainThread:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(pe.seekable ? pe.currentPosition : 0.0), nil];
|
[player performSelectorInBackground:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(pe.seekable ? pe.currentPosition : 0.0), nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)audioPlayer:(AudioPlayer *)player pushInfo:(NSDictionary *)info toTrack:(id)userInfo {
|
- (void)audioPlayer:(AudioPlayer *)player pushInfo:(NSDictionary *)info toTrack:(id)userInfo {
|
||||||
PlaylistEntry *pe = (PlaylistEntry *)userInfo;
|
PlaylistEntry *pe = (PlaylistEntry *)userInfo;
|
||||||
if(!pe) pe = [playlistController currentEntry];
|
if (!pe) pe = [playlistController currentEntry];
|
||||||
[pe setMetadata:info];
|
[pe setMetadata:info];
|
||||||
[playlistView refreshTrack:pe];
|
[playlistView refreshTrack:pe];
|
||||||
// Delay the action until this function has returned to the audio thread
|
// Delay the action until this function has returned to the audio thread
|
||||||
|
@ -933,15 +756,6 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)audioPlayer:(AudioPlayer *)player updatePosition:(id)userInfo {
|
|
||||||
if(userInfo) {
|
|
||||||
PlaylistEntry *pe = (PlaylistEntry *)userInfo;
|
|
||||||
if([pe current]) {
|
|
||||||
[self updatePosition:userInfo];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)audioPlayer:(AudioPlayer *)player setError:(NSNumber *)status toTrack:(id)userInfo {
|
- (void)audioPlayer:(AudioPlayer *)player setError:(NSNumber *)status toTrack:(id)userInfo {
|
||||||
PlaylistEntry *pe = (PlaylistEntry *)userInfo;
|
PlaylistEntry *pe = (PlaylistEntry *)userInfo;
|
||||||
[pe setError:[status boolValue]];
|
[pe setError:[status boolValue]];
|
||||||
|
@ -1021,11 +835,9 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
|
||||||
if(entry.year) {
|
if(entry.year) {
|
||||||
// If PlaylistEntry can represent a full date like some tag formats can do, change it
|
// If PlaylistEntry can represent a full date like some tag formats can do, change it
|
||||||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||||||
NSDate *releaseYear = [calendar dateWithEra:1 year:entry.year month:1 day:1 hour:0 minute:0 second:0 nanosecond:0];
|
NSDate *releaseYear = [calendar dateWithEra:1 year:entry.year month:0 day:0 hour:0 minute:0 second:0 nanosecond:0];
|
||||||
if(releaseYear) {
|
|
||||||
[songInfo setObject:releaseYear forKey:MPMediaItemPropertyReleaseDate];
|
[songInfo setObject:releaseYear forKey:MPMediaItemPropertyReleaseDate];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
[songInfo setObject:@(entry.currentPosition) forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
|
[songInfo setObject:@(entry.currentPosition) forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
|
||||||
[songInfo setObject:entry.length forKey:MPMediaItemPropertyPlaybackDuration];
|
[songInfo setObject:entry.length forKey:MPMediaItemPropertyPlaybackDuration];
|
||||||
[songInfo setObject:@(entry.index) forKey:MPMediaItemPropertyPersistentID];
|
[songInfo setObject:@(entry.index) forKey:MPMediaItemPropertyPersistentID];
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#import <CogAudio/Plugin.h>
|
#import "Plugin.h"
|
||||||
|
|
||||||
@interface AudioDecoder : NSObject {
|
@interface AudioDecoder : NSObject {
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
OutputNode *output;
|
OutputNode *output;
|
||||||
|
|
||||||
double volume;
|
double volume;
|
||||||
double pitch;
|
|
||||||
double tempo;
|
|
||||||
|
|
||||||
NSMutableArray *chainQueue;
|
NSMutableArray *chainQueue;
|
||||||
|
|
||||||
|
@ -138,6 +136,5 @@
|
||||||
- (void)audioPlayer:(AudioPlayer *)player restartPlaybackAtCurrentPosition:(id)userInfo;
|
- (void)audioPlayer:(AudioPlayer *)player restartPlaybackAtCurrentPosition:(id)userInfo;
|
||||||
- (void)audioPlayer:(AudioPlayer *)player pushInfo:(NSDictionary *)info toTrack:(id)userInfo;
|
- (void)audioPlayer:(AudioPlayer *)player pushInfo:(NSDictionary *)info toTrack:(id)userInfo;
|
||||||
- (void)audioPlayer:(AudioPlayer *)player reportPlayCountForTrack:(id)userInfo;
|
- (void)audioPlayer:(AudioPlayer *)player reportPlayCountForTrack:(id)userInfo;
|
||||||
- (void)audioPlayer:(AudioPlayer *)player updatePosition:(id)userInfo;
|
|
||||||
- (void)audioPlayer:(AudioPlayer *)player setError:(NSNumber *)status toTrack:(id)userInfo;
|
- (void)audioPlayer:(AudioPlayer *)player setError:(NSNumber *)status toTrack:(id)userInfo;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -25,10 +25,6 @@
|
||||||
outputLaunched = NO;
|
outputLaunched = NO;
|
||||||
endOfInputReached = NO;
|
endOfInputReached = NO;
|
||||||
|
|
||||||
// Safety
|
|
||||||
pitch = 1.0;
|
|
||||||
tempo = 1.0;
|
|
||||||
|
|
||||||
chainQueue = [[NSMutableArray alloc] init];
|
chainQueue = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
semaphore = [[Semaphore alloc] init];
|
semaphore = [[Semaphore alloc] init];
|
||||||
|
@ -67,20 +63,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)play:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi startPaused:(BOOL)paused andSeekTo:(double)time {
|
- (void)play:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi startPaused:(BOOL)paused andSeekTo:(double)time {
|
||||||
[self play:url withUserInfo:userInfo withRGInfo:rgi startPaused:paused andSeekTo:time andResumeInterval:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)play:(NSURL *)url withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi startPaused:(BOOL)paused andSeekTo:(double)time andResumeInterval:(BOOL)resumeInterval {
|
|
||||||
ALog(@"Opening file for playback: %@ at seek offset %f%@", url, time, (paused) ? @", starting paused" : @"");
|
ALog(@"Opening file for playback: %@ at seek offset %f%@", url, time, (paused) ? @", starting paused" : @"");
|
||||||
|
|
||||||
[self waitUntilCallbacksExit];
|
[self waitUntilCallbacksExit];
|
||||||
if(output) {
|
if(output) {
|
||||||
[output fadeOutBackground];
|
[output setShouldContinue:NO];
|
||||||
|
[output close];
|
||||||
}
|
}
|
||||||
if(!output) {
|
if(!output) {
|
||||||
output = [[OutputNode alloc] initWithController:self previous:nil];
|
output = [[OutputNode alloc] initWithController:self previous:nil];
|
||||||
[output setupWithInterval:resumeInterval];
|
|
||||||
}
|
}
|
||||||
|
[output setup];
|
||||||
[output setVolume:volume];
|
[output setVolume:volume];
|
||||||
@synchronized(chainQueue) {
|
@synchronized(chainQueue) {
|
||||||
for(id anObject in chainQueue) {
|
for(id anObject in chainQueue) {
|
||||||
|
@ -96,9 +89,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bufferChain = [[BufferChain alloc] initWithController:self];
|
bufferChain = [[BufferChain alloc] initWithController:self];
|
||||||
if(!resumeInterval) {
|
|
||||||
[self notifyStreamChanged:userInfo];
|
[self notifyStreamChanged:userInfo];
|
||||||
}
|
|
||||||
|
|
||||||
while(![bufferChain open:url withOutputFormat:[output format] withUserInfo:userInfo withRGInfo:rgi]) {
|
while(![bufferChain open:url withOutputFormat:[output format] withUserInfo:userInfo withRGInfo:rgi]) {
|
||||||
bufferChain = nil;
|
bufferChain = nil;
|
||||||
|
@ -129,23 +120,15 @@
|
||||||
|
|
||||||
[self setShouldContinue:YES];
|
[self setShouldContinue:YES];
|
||||||
|
|
||||||
if(!resumeInterval) {
|
|
||||||
outputLaunched = NO;
|
outputLaunched = NO;
|
||||||
}
|
|
||||||
startedPaused = paused;
|
startedPaused = paused;
|
||||||
initialBufferFilled = NO;
|
initialBufferFilled = NO;
|
||||||
previousUserInfo = userInfo;
|
previousUserInfo = userInfo;
|
||||||
|
|
||||||
[bufferChain launchThreads];
|
[bufferChain launchThreads];
|
||||||
|
|
||||||
if(paused) {
|
if(paused)
|
||||||
[self setPlaybackStatus:CogStatusPaused waitUntilDone:YES];
|
[self setPlaybackStatus:CogStatusPaused waitUntilDone:YES];
|
||||||
if(time > 0.0) {
|
|
||||||
[self updatePosition:userInfo];
|
|
||||||
}
|
|
||||||
} else if(resumeInterval) {
|
|
||||||
[output fadeIn];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stop {
|
- (void)stop {
|
||||||
|
@ -171,7 +154,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)pause {
|
- (void)pause {
|
||||||
[output fadeOut];
|
[output pause];
|
||||||
|
|
||||||
[self setPlaybackStatus:CogStatusPaused waitUntilDone:YES];
|
[self setPlaybackStatus:CogStatusPaused waitUntilDone:YES];
|
||||||
}
|
}
|
||||||
|
@ -183,7 +166,6 @@
|
||||||
[self launchOutputThread];
|
[self launchOutputThread];
|
||||||
}
|
}
|
||||||
|
|
||||||
[output fadeIn];
|
|
||||||
[output resume];
|
[output resume];
|
||||||
|
|
||||||
[self setPlaybackStatus:CogStatusPlaying waitUntilDone:YES];
|
[self setPlaybackStatus:CogStatusPlaying waitUntilDone:YES];
|
||||||
|
@ -194,6 +176,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)seekToTime:(double)time {
|
- (void)seekToTime:(double)time {
|
||||||
|
if(endOfInputReached) {
|
||||||
|
// This is a dirty hack in case the playback has finished with the track
|
||||||
|
// that the user thinks they're seeking into
|
||||||
CogStatus status = (CogStatus)currentPlaybackStatus;
|
CogStatus status = (CogStatus)currentPlaybackStatus;
|
||||||
NSURL *url;
|
NSURL *url;
|
||||||
id userInfo;
|
id userInfo;
|
||||||
|
@ -205,7 +190,14 @@
|
||||||
rgi = [bufferChain rgInfo];
|
rgi = [bufferChain rgInfo];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self play:url withUserInfo:userInfo withRGInfo:rgi startPaused:(status == CogStatusPaused) andSeekTo:time andResumeInterval:YES];
|
[self stop];
|
||||||
|
|
||||||
|
[self play:url withUserInfo:userInfo withRGInfo:rgi startPaused:(status == CogStatusPaused) andSeekTo:time];
|
||||||
|
} else {
|
||||||
|
// Still decoding the current file, safe to seek within it
|
||||||
|
[output seek:time];
|
||||||
|
[bufferChain seek:time];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setVolume:(double)v {
|
- (void)setVolume:(double)v {
|
||||||
|
@ -251,10 +243,6 @@
|
||||||
[self sendDelegateMethod:@selector(audioPlayer:restartPlaybackAtCurrentPosition:) withObject:previousUserInfo waitUntilDone:NO];
|
[self sendDelegateMethod:@selector(audioPlayer:restartPlaybackAtCurrentPosition:) withObject:previousUserInfo waitUntilDone:NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updatePosition:(id)userInfo {
|
|
||||||
[self sendDelegateMethod:@selector(audioPlayer:updatePosition:) withObject:userInfo waitUntilDone:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)pushInfo:(NSDictionary *)info toTrack:(id)userInfo {
|
- (void)pushInfo:(NSDictionary *)info toTrack:(id)userInfo {
|
||||||
[self sendDelegateMethod:@selector(audioPlayer:pushInfo:toTrack:) withObject:info withObject:userInfo waitUntilDone:NO];
|
[self sendDelegateMethod:@selector(audioPlayer:pushInfo:toTrack:) withObject:info withObject:userInfo waitUntilDone:NO];
|
||||||
}
|
}
|
||||||
|
@ -410,30 +398,9 @@
|
||||||
|
|
||||||
if([unixPathNext isEqualToString:unixPathPrev])
|
if([unixPathNext isEqualToString:unixPathPrev])
|
||||||
pathsEqual = YES;
|
pathsEqual = YES;
|
||||||
} else if(![nextStream isFileURL] && ![[lastChain streamURL] isFileURL]) {
|
|
||||||
@try {
|
|
||||||
NSURL *lastURL = [lastChain streamURL];
|
|
||||||
NSString *nextScheme = [nextStream scheme];
|
|
||||||
NSString *lastScheme = [lastURL scheme];
|
|
||||||
NSString *nextHost = [nextStream host];
|
|
||||||
NSString *lastHost = [lastURL host];
|
|
||||||
NSString *nextPath = [nextStream path];
|
|
||||||
NSString *lastPath = [lastURL path];
|
|
||||||
if(nextScheme && lastScheme && [nextScheme isEqualToString:lastScheme]) {
|
|
||||||
if((!nextHost && !lastHost) ||
|
|
||||||
(nextHost && lastHost && [nextHost isEqualToString:lastHost])) {
|
|
||||||
if(nextPath && lastPath && [nextPath isEqualToString:lastPath]) {
|
|
||||||
pathsEqual = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@catch(NSException *e) {
|
|
||||||
DLog(@"Exception thrown checking file match: %@", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pathsEqual) {
|
if(pathsEqual || ([[nextStream scheme] isEqualToString:[[lastChain streamURL] scheme]] && (([nextStream host] == nil && [[lastChain streamURL] host] == nil) || [[nextStream host] isEqualToString:[[lastChain streamURL] host]]) && [[nextStream path] isEqualToString:[[lastChain streamURL] path]])) {
|
||||||
if([lastChain setTrack:nextStream] && [newChain openWithInput:[lastChain inputNode] withOutputFormat:[output format] withUserInfo:nextStreamUserInfo withRGInfo:nextStreamRGInfo]) {
|
if([lastChain setTrack:nextStream] && [newChain openWithInput:[lastChain inputNode] withOutputFormat:[output format] withUserInfo:nextStreamUserInfo withRGInfo:nextStreamRGInfo]) {
|
||||||
[newChain setStreamURL:nextStream];
|
[newChain setStreamURL:nextStream];
|
||||||
|
|
||||||
|
@ -518,7 +485,6 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[bufferChain setShouldContinue:NO];
|
|
||||||
bufferChain = nil;
|
bufferChain = nil;
|
||||||
bufferChain = [chainQueue objectAtIndex:0];
|
bufferChain = [chainQueue objectAtIndex:0];
|
||||||
|
|
||||||
|
|
|
@ -65,8 +65,6 @@ enum {
|
||||||
AudioStreamBasicDescription format;
|
AudioStreamBasicDescription format;
|
||||||
NSMutableData *chunkData;
|
NSMutableData *chunkData;
|
||||||
uint32_t channelConfig;
|
uint32_t channelConfig;
|
||||||
double streamTimestamp;
|
|
||||||
double streamTimeRatio;
|
|
||||||
BOOL formatAssigned;
|
BOOL formatAssigned;
|
||||||
BOOL lossless;
|
BOOL lossless;
|
||||||
BOOL hdcd;
|
BOOL hdcd;
|
||||||
|
@ -74,8 +72,6 @@ enum {
|
||||||
|
|
||||||
@property AudioStreamBasicDescription format;
|
@property AudioStreamBasicDescription format;
|
||||||
@property uint32_t channelConfig;
|
@property uint32_t channelConfig;
|
||||||
@property double streamTimestamp;
|
|
||||||
@property double streamTimeRatio;
|
|
||||||
@property BOOL lossless;
|
@property BOOL lossless;
|
||||||
|
|
||||||
+ (uint32_t)guessChannelConfig:(uint32_t)channelCount;
|
+ (uint32_t)guessChannelConfig:(uint32_t)channelCount;
|
||||||
|
@ -87,7 +83,7 @@ enum {
|
||||||
- (id)init;
|
- (id)init;
|
||||||
- (id)initWithProperties:(NSDictionary *)properties;
|
- (id)initWithProperties:(NSDictionary *)properties;
|
||||||
|
|
||||||
- (void)assignSamples:(const void *_Nonnull)data frameCount:(size_t)count;
|
- (void)assignSamples:(const void *)data frameCount:(size_t)count;
|
||||||
- (void)assignData:(NSData *)data;
|
- (void)assignData:(NSData *)data;
|
||||||
|
|
||||||
- (NSData *)removeSamples:(size_t)frameCount;
|
- (NSData *)removeSamples:(size_t)frameCount;
|
||||||
|
@ -98,13 +94,10 @@ enum {
|
||||||
- (void)setFrameCount:(size_t)count; // For truncation only
|
- (void)setFrameCount:(size_t)count; // For truncation only
|
||||||
|
|
||||||
- (double)duration;
|
- (double)duration;
|
||||||
- (double)durationRatioed;
|
|
||||||
|
|
||||||
- (BOOL)isHDCD;
|
- (BOOL)isHDCD;
|
||||||
- (void)setHDCD;
|
- (void)setHDCD;
|
||||||
|
|
||||||
- (AudioChunk *)copy;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
formatAssigned = NO;
|
formatAssigned = NO;
|
||||||
lossless = NO;
|
lossless = NO;
|
||||||
hdcd = NO;
|
hdcd = NO;
|
||||||
streamTimestamp = 0.0;
|
|
||||||
streamTimeRatio = 1.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -33,25 +31,11 @@
|
||||||
chunkData = [[NSMutableData alloc] init];
|
chunkData = [[NSMutableData alloc] init];
|
||||||
[self setFormat:propertiesToASBD(properties)];
|
[self setFormat:propertiesToASBD(properties)];
|
||||||
lossless = [[properties objectForKey:@"encoding"] isEqualToString:@"lossless"];
|
lossless = [[properties objectForKey:@"encoding"] isEqualToString:@"lossless"];
|
||||||
hdcd = NO;
|
|
||||||
streamTimestamp = 0.0;
|
|
||||||
streamTimeRatio = 1.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AudioChunk *)copy {
|
|
||||||
AudioChunk *outputChunk = [[AudioChunk alloc] init];
|
|
||||||
[outputChunk setFormat:format];
|
|
||||||
[outputChunk setChannelConfig:channelConfig];
|
|
||||||
if(hdcd) [outputChunk setHDCD];
|
|
||||||
[outputChunk setStreamTimestamp:streamTimestamp];
|
|
||||||
[outputChunk setStreamTimeRatio:streamTimeRatio];
|
|
||||||
[outputChunk assignData:chunkData];
|
|
||||||
return outputChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint32_t AudioChannelConfigTable[] = {
|
static const uint32_t AudioChannelConfigTable[] = {
|
||||||
0,
|
0,
|
||||||
AudioConfigMono,
|
AudioConfigMono,
|
||||||
|
@ -133,8 +117,6 @@ static const uint32_t AudioChannelConfigTable[] = {
|
||||||
}
|
}
|
||||||
|
|
||||||
@synthesize lossless;
|
@synthesize lossless;
|
||||||
@synthesize streamTimestamp;
|
|
||||||
@synthesize streamTimeRatio;
|
|
||||||
|
|
||||||
- (AudioStreamBasicDescription)format {
|
- (AudioStreamBasicDescription)format {
|
||||||
return format;
|
return format;
|
||||||
|
@ -159,7 +141,7 @@ static const uint32_t AudioChannelConfigTable[] = {
|
||||||
channelConfig = config;
|
channelConfig = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)assignSamples:(const void *_Nonnull)data frameCount:(size_t)count {
|
- (void)assignSamples:(const void *)data frameCount:(size_t)count {
|
||||||
if(formatAssigned) {
|
if(formatAssigned) {
|
||||||
const size_t bytesPerPacket = format.mBytesPerPacket;
|
const size_t bytesPerPacket = format.mBytesPerPacket;
|
||||||
[chunkData appendBytes:data length:bytesPerPacket * count];
|
[chunkData appendBytes:data length:bytesPerPacket * count];
|
||||||
|
@ -173,13 +155,10 @@ static const uint32_t AudioChannelConfigTable[] = {
|
||||||
- (NSData *)removeSamples:(size_t)frameCount {
|
- (NSData *)removeSamples:(size_t)frameCount {
|
||||||
if(formatAssigned) {
|
if(formatAssigned) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
const double secondsDuration = (double)(frameCount) / format.mSampleRate;
|
|
||||||
const double DSDrate = (format.mBitsPerChannel == 1) ? 8.0 : 1.0;
|
|
||||||
const size_t bytesPerPacket = format.mBytesPerPacket;
|
const size_t bytesPerPacket = format.mBytesPerPacket;
|
||||||
const size_t byteCount = bytesPerPacket * frameCount;
|
const size_t byteCount = bytesPerPacket * frameCount;
|
||||||
NSData *ret = [chunkData subdataWithRange:NSMakeRange(0, byteCount)];
|
NSData *ret = [chunkData subdataWithRange:NSMakeRange(0, byteCount)];
|
||||||
[chunkData replaceBytesInRange:NSMakeRange(0, byteCount) withBytes:NULL length:0];
|
[chunkData replaceBytesInRange:NSMakeRange(0, byteCount) withBytes:NULL length:0];
|
||||||
streamTimestamp += secondsDuration * streamTimeRatio * DSDrate;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,19 +188,14 @@ static const uint32_t AudioChannelConfigTable[] = {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (double)duration {
|
- (double)duration {
|
||||||
if(formatAssigned && [chunkData length]) {
|
if(formatAssigned) {
|
||||||
const size_t bytesPerPacket = format.mBytesPerPacket;
|
const size_t bytesPerPacket = format.mBytesPerPacket;
|
||||||
const double sampleRate = format.mSampleRate;
|
const double sampleRate = format.mSampleRate;
|
||||||
const double DSDrate = (format.mBitsPerChannel == 1) ? 8.0 : 1.0;
|
return (double)([chunkData length] / bytesPerPacket) / sampleRate;
|
||||||
return ((double)([chunkData length] / bytesPerPacket) / sampleRate) * DSDrate;
|
|
||||||
}
|
}
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (double)durationRatioed {
|
|
||||||
return [self duration] * streamTimeRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isHDCD {
|
- (BOOL)isHDCD {
|
||||||
return hdcd;
|
return hdcd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#import <CogAudio/AudioPlayer.h>
|
#import "AudioPlayer.h"
|
||||||
#import <CogAudio/ConverterNode.h>
|
#import "ConverterNode.h"
|
||||||
#import <CogAudio/InputNode.h>
|
#import "InputNode.h"
|
||||||
|
|
||||||
@interface BufferChain : NSObject {
|
@interface BufferChain : NSObject {
|
||||||
InputNode *inputNode;
|
InputNode *inputNode;
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithController:(id)c;
|
- (id)initWithController:(id)c;
|
||||||
- (BOOL)buildChain;
|
- (void)buildChain;
|
||||||
|
|
||||||
- (BOOL)open:(NSURL *)url withOutputFormat:(AudioStreamBasicDescription)outputFormat withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi;
|
- (BOOL)open:(NSURL *)url withOutputFormat:(AudioStreamBasicDescription)outputFormat withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi;
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,8 @@
|
||||||
#import "BufferChain.h"
|
#import "BufferChain.h"
|
||||||
#import "AudioSource.h"
|
#import "AudioSource.h"
|
||||||
#import "CoreAudioUtils.h"
|
#import "CoreAudioUtils.h"
|
||||||
#import "DSPDownmixNode.h"
|
|
||||||
#import "OutputNode.h"
|
#import "OutputNode.h"
|
||||||
|
|
||||||
#import "AudioPlayer.h"
|
|
||||||
|
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
|
|
||||||
@implementation BufferChain
|
@implementation BufferChain
|
||||||
|
@ -33,32 +30,21 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)buildChain {
|
- (void)buildChain {
|
||||||
// Cut off output source
|
|
||||||
finalNode = nil;
|
|
||||||
|
|
||||||
// Tear them down in reverse
|
|
||||||
converterNode = nil;
|
|
||||||
inputNode = nil;
|
inputNode = nil;
|
||||||
|
converterNode = nil;
|
||||||
|
|
||||||
inputNode = [[InputNode alloc] initWithController:self previous:nil];
|
inputNode = [[InputNode alloc] initWithController:self previous:nil];
|
||||||
if(!inputNode) return NO;
|
|
||||||
converterNode = [[ConverterNode alloc] initWithController:self previous:inputNode];
|
converterNode = [[ConverterNode alloc] initWithController:self previous:inputNode];
|
||||||
if(!converterNode) return NO;
|
|
||||||
|
|
||||||
finalNode = converterNode;
|
finalNode = converterNode;
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)open:(NSURL *)url withOutputFormat:(AudioStreamBasicDescription)outputFormat withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi {
|
- (BOOL)open:(NSURL *)url withOutputFormat:(AudioStreamBasicDescription)outputFormat withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi {
|
||||||
[self setStreamURL:url];
|
[self setStreamURL:url];
|
||||||
[self setUserInfo:userInfo];
|
[self setUserInfo:userInfo];
|
||||||
|
|
||||||
if (![self buildChain]) {
|
[self buildChain];
|
||||||
DLog(@"Couldn't build processing chain...");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
id<CogSource> source = [AudioSource audioSourceForURL:url];
|
id<CogSource> source = [AudioSource audioSourceForURL:url];
|
||||||
DLog(@"Opening: %@", url);
|
DLog(@"Opening: %@", url);
|
||||||
|
@ -73,66 +59,8 @@
|
||||||
if(![inputNode openWithSource:source])
|
if(![inputNode openWithSource:source])
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
if(![self initConverter:outputFormat])
|
|
||||||
return NO;
|
|
||||||
[self initDownmixer];
|
|
||||||
|
|
||||||
[self setRGInfo:rgi];
|
|
||||||
|
|
||||||
// return NO;
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)openWithInput:(InputNode *)i withOutputFormat:(AudioStreamBasicDescription)outputFormat withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi {
|
|
||||||
DLog(@"New buffer chain!");
|
|
||||||
[self setUserInfo:userInfo];
|
|
||||||
if(![self buildChain]) {
|
|
||||||
DLog(@"Couldn't build processing chain...");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(![inputNode openWithDecoder:[i decoder]])
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
if(![self initConverter:outputFormat])
|
|
||||||
return NO;
|
|
||||||
[self initDownmixer];
|
|
||||||
|
|
||||||
[self setRGInfo:rgi];
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)openWithDecoder:(id<CogDecoder>)decoder
|
|
||||||
withOutputFormat:(AudioStreamBasicDescription)outputFormat
|
|
||||||
withUserInfo:(id)userInfo
|
|
||||||
withRGInfo:(NSDictionary *)rgi;
|
|
||||||
{
|
|
||||||
DLog(@"New buffer chain!");
|
|
||||||
[self setUserInfo:userInfo];
|
|
||||||
if(![self buildChain]) {
|
|
||||||
DLog(@"Couldn't build processing chain...");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(![inputNode openWithDecoder:decoder])
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
if(![self initConverter:outputFormat])
|
|
||||||
return NO;
|
|
||||||
[self initDownmixer];
|
|
||||||
|
|
||||||
[self setRGInfo:rgi];
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)initConverter:(AudioStreamBasicDescription)outputFormat {
|
|
||||||
NSDictionary *properties = [inputNode properties];
|
NSDictionary *properties = [inputNode properties];
|
||||||
|
|
||||||
DLog(@"Input Properties: %@", properties);
|
|
||||||
|
|
||||||
AudioStreamBasicDescription inputFormat = [inputNode nodeFormat];
|
AudioStreamBasicDescription inputFormat = [inputNode nodeFormat];
|
||||||
uint32_t inputChannelConfig = 0;
|
uint32_t inputChannelConfig = 0;
|
||||||
if([properties valueForKey:@"channelConfig"])
|
if([properties valueForKey:@"channelConfig"])
|
||||||
|
@ -145,14 +73,72 @@
|
||||||
if(![converterNode setupWithInputFormat:inputFormat withInputConfig:inputChannelConfig outputFormat:outputFormat isLossless:[[properties valueForKey:@"encoding"] isEqualToString:@"lossless"]])
|
if(![converterNode setupWithInputFormat:inputFormat withInputConfig:inputChannelConfig outputFormat:outputFormat isLossless:[[properties valueForKey:@"encoding"] isEqualToString:@"lossless"]])
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
|
[self setRGInfo:rgi];
|
||||||
|
|
||||||
|
// return NO;
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)initDownmixer {
|
- (BOOL)openWithInput:(InputNode *)i withOutputFormat:(AudioStreamBasicDescription)outputFormat withUserInfo:(id)userInfo withRGInfo:(NSDictionary *)rgi {
|
||||||
AudioPlayer * audioPlayer = controller;
|
DLog(@"New buffer chain!");
|
||||||
OutputNode *outputNode = [audioPlayer output];
|
[self setUserInfo:userInfo];
|
||||||
DSPDownmixNode *downmixNode = [outputNode downmix];
|
[self buildChain];
|
||||||
[downmixNode setOutputFormat:[outputNode deviceFormat] withChannelConfig:[outputNode deviceChannelConfig]];
|
|
||||||
|
if(![inputNode openWithDecoder:[i decoder]])
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
NSDictionary *properties = [inputNode properties];
|
||||||
|
|
||||||
|
AudioStreamBasicDescription inputFormat = [inputNode nodeFormat];
|
||||||
|
uint32_t inputChannelConfig = 0;
|
||||||
|
if([properties valueForKey:@"channelConfig"])
|
||||||
|
inputChannelConfig = [[properties valueForKey:@"channelConfig"] unsignedIntValue];
|
||||||
|
|
||||||
|
outputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame;
|
||||||
|
outputFormat.mBytesPerFrame = ((outputFormat.mBitsPerChannel + 7) / 8) * outputFormat.mChannelsPerFrame;
|
||||||
|
outputFormat.mBytesPerPacket = outputFormat.mBytesPerFrame * outputFormat.mFramesPerPacket;
|
||||||
|
|
||||||
|
DLog(@"Input Properties: %@", properties);
|
||||||
|
if(![converterNode setupWithInputFormat:inputFormat withInputConfig:inputChannelConfig outputFormat:outputFormat isLossless:[[properties objectForKey:@"encoding"] isEqualToString:@"lossless"]])
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
[self setRGInfo:rgi];
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)openWithDecoder:(id<CogDecoder>)decoder
|
||||||
|
withOutputFormat:(AudioStreamBasicDescription)outputFormat
|
||||||
|
withUserInfo:(id)userInfo
|
||||||
|
withRGInfo:(NSDictionary *)rgi;
|
||||||
|
{
|
||||||
|
DLog(@"New buffer chain!");
|
||||||
|
[self setUserInfo:userInfo];
|
||||||
|
[self buildChain];
|
||||||
|
|
||||||
|
if(![inputNode openWithDecoder:decoder])
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
NSDictionary *properties = [inputNode properties];
|
||||||
|
|
||||||
|
DLog(@"Input Properties: %@", properties);
|
||||||
|
|
||||||
|
AudioStreamBasicDescription inputFormat = [inputNode nodeFormat];
|
||||||
|
uint32_t inputChannelConfig = 0;
|
||||||
|
if([properties valueForKey:@"channelConfig"])
|
||||||
|
inputChannelConfig = [[properties valueForKey:@"channelConfig"] unsignedIntValue];
|
||||||
|
|
||||||
|
outputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame;
|
||||||
|
outputFormat.mBytesPerFrame = ((outputFormat.mBitsPerChannel + 7) / 8) * outputFormat.mChannelsPerFrame;
|
||||||
|
outputFormat.mBytesPerPacket = outputFormat.mBytesPerFrame * outputFormat.mFramesPerPacket;
|
||||||
|
|
||||||
|
if(![converterNode setupWithInputFormat:inputFormat withInputConfig:inputChannelConfig outputFormat:outputFormat isLossless:[[properties objectForKey:@"encoding"] isEqualToString:@"lossless"]])
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
[self setRGInfo:rgi];
|
||||||
|
|
||||||
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)launchThreads {
|
- (void)launchThreads {
|
||||||
|
@ -182,7 +168,7 @@
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
[inputNode setShouldContinue:NO];
|
[inputNode setShouldContinue:NO];
|
||||||
[[inputNode exitAtTheEndOfTheStream] signal];
|
[[inputNode exitAtTheEndOfTheStream] signal];
|
||||||
[[inputNode writeSemaphore] signal];
|
[[inputNode semaphore] signal];
|
||||||
if(![inputNode threadExited])
|
if(![inputNode threadExited])
|
||||||
[[inputNode exitAtTheEndOfTheStream] wait]; // wait for decoder to be closed (see InputNode's -(void)process )
|
[[inputNode exitAtTheEndOfTheStream] wait]; // wait for decoder to be closed (see InputNode's -(void)process )
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#import <CoreAudio/CoreAudio.h>
|
#import <CoreAudio/CoreAudio.h>
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#import <CogAudio/AudioChunk.h>
|
#import "AudioChunk.h"
|
||||||
|
|
||||||
#import <CogAudio/CogSemaphore.h>
|
#import <CogAudio/CogSemaphore.h>
|
||||||
|
|
||||||
|
@ -19,14 +19,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
@interface ChunkList : NSObject {
|
@interface ChunkList : NSObject {
|
||||||
NSMutableArray<AudioChunk *> *chunkList;
|
NSMutableArray<AudioChunk *> *chunkList;
|
||||||
double listDuration;
|
double listDuration;
|
||||||
double listDurationRatioed;
|
|
||||||
double maxDuration;
|
double maxDuration;
|
||||||
|
|
||||||
BOOL inAdder;
|
BOOL inAdder;
|
||||||
BOOL inRemover;
|
BOOL inRemover;
|
||||||
BOOL inPeeker;
|
BOOL inPeeker;
|
||||||
BOOL inMerger;
|
|
||||||
BOOL inConverter;
|
|
||||||
BOOL stopping;
|
BOOL stopping;
|
||||||
|
|
||||||
// For format converter
|
// For format converter
|
||||||
|
@ -39,10 +36,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
int dsd2pcmLatency;
|
int dsd2pcmLatency;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOL observersRegistered;
|
|
||||||
BOOL halveDSDVolume;
|
BOOL halveDSDVolume;
|
||||||
|
|
||||||
BOOL enableHDCD;
|
|
||||||
void *hdcd_decoder;
|
void *hdcd_decoder;
|
||||||
|
|
||||||
BOOL formatRead;
|
BOOL formatRead;
|
||||||
|
@ -58,7 +53,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
}
|
}
|
||||||
|
|
||||||
@property(readonly) double listDuration;
|
@property(readonly) double listDuration;
|
||||||
@property(readonly) double listDurationRatioed;
|
|
||||||
@property(readonly) double maxDuration;
|
@property(readonly) double maxDuration;
|
||||||
|
|
||||||
- (id)initWithMaximumDuration:(double)duration;
|
- (id)initWithMaximumDuration:(double)duration;
|
||||||
|
@ -75,12 +69,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
- (BOOL)peekFormat:(nonnull AudioStreamBasicDescription *)format channelConfig:(nonnull uint32_t *)config;
|
- (BOOL)peekFormat:(nonnull AudioStreamBasicDescription *)format channelConfig:(nonnull uint32_t *)config;
|
||||||
|
|
||||||
- (BOOL)peekTimestamp:(nonnull double *)timestamp timeRatio:(nonnull double *)timeRatio;
|
|
||||||
|
|
||||||
// Helpers
|
|
||||||
- (AudioChunk *)removeAndMergeSamples:(size_t)maxFrameCount callBlock:(BOOL(NS_NOESCAPE ^ _Nonnull)(void))block;
|
|
||||||
- (AudioChunk *)removeAndMergeSamplesAsFloat32:(size_t)maxFrameCount callBlock:(BOOL(NS_NOESCAPE ^ _Nonnull)(void))block;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -369,7 +369,6 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
@implementation ChunkList
|
@implementation ChunkList
|
||||||
|
|
||||||
@synthesize listDuration;
|
@synthesize listDuration;
|
||||||
@synthesize listDurationRatioed;
|
|
||||||
@synthesize maxDuration;
|
@synthesize maxDuration;
|
||||||
|
|
||||||
- (id)initWithMaximumDuration:(double)duration {
|
- (id)initWithMaximumDuration:(double)duration {
|
||||||
|
@ -378,14 +377,11 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
if(self) {
|
if(self) {
|
||||||
chunkList = [[NSMutableArray alloc] init];
|
chunkList = [[NSMutableArray alloc] init];
|
||||||
listDuration = 0.0;
|
listDuration = 0.0;
|
||||||
listDurationRatioed = 0.0;
|
|
||||||
maxDuration = duration;
|
maxDuration = duration;
|
||||||
|
|
||||||
inAdder = NO;
|
inAdder = NO;
|
||||||
inRemover = NO;
|
inRemover = NO;
|
||||||
inPeeker = NO;
|
inPeeker = NO;
|
||||||
inMerger = NO;
|
|
||||||
inConverter = NO;
|
|
||||||
stopping = NO;
|
stopping = NO;
|
||||||
|
|
||||||
formatRead = NO;
|
formatRead = NO;
|
||||||
|
@ -399,39 +395,19 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
dsd2pcmLatency = 0;
|
dsd2pcmLatency = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
observersRegistered = NO;
|
halveDSDVolume = NO;
|
||||||
|
|
||||||
|
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.halveDSDVolume" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kChunkListContext];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addObservers {
|
|
||||||
if(!observersRegistered) {
|
|
||||||
halveDSDVolume = NO;
|
|
||||||
enableHDCD = NO;
|
|
||||||
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.halveDSDVolume" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kChunkListContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.enableHDCD" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kChunkListContext];
|
|
||||||
|
|
||||||
observersRegistered = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObservers {
|
|
||||||
if(observersRegistered) {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.halveDSDVolume" context:kChunkListContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.enableHDCD" context:kChunkListContext];
|
|
||||||
|
|
||||||
observersRegistered = NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
stopping = YES;
|
stopping = YES;
|
||||||
while(inAdder || inRemover || inPeeker || inMerger || inConverter) {
|
while(inAdder || inRemover || inPeeker) {
|
||||||
usleep(500);
|
usleep(500);
|
||||||
}
|
}
|
||||||
[self removeObservers];
|
|
||||||
if(hdcd_decoder) {
|
if(hdcd_decoder) {
|
||||||
free(hdcd_decoder);
|
free(hdcd_decoder);
|
||||||
hdcd_decoder = NULL;
|
hdcd_decoder = NULL;
|
||||||
|
@ -449,6 +425,8 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
if(tempData) {
|
if(tempData) {
|
||||||
free(tempData);
|
free(tempData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.halveDSDVolume" context:kChunkListContext];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
||||||
|
@ -459,8 +437,6 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
|
|
||||||
if([keyPath isEqualToString:@"values.halveDSDVolume"]) {
|
if([keyPath isEqualToString:@"values.halveDSDVolume"]) {
|
||||||
halveDSDVolume = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"halveDSDVolume"];
|
halveDSDVolume = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"halveDSDVolume"];
|
||||||
} else if([keyPath isEqualToString:@"values.enableHDCD"]) {
|
|
||||||
enableHDCD = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] boolForKey:@"enableHDCD"];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +444,6 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
@synchronized(chunkList) {
|
@synchronized(chunkList) {
|
||||||
[chunkList removeAllObjects];
|
[chunkList removeAllObjects];
|
||||||
listDuration = 0.0;
|
listDuration = 0.0;
|
||||||
listDurationRatioed = 0.0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,9 +454,7 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isFull {
|
- (BOOL)isFull {
|
||||||
@synchronized (chunkList) {
|
return (maxDuration - listDuration) < 0.05;
|
||||||
return (maxDuration - listDuration) < 0.001;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addChunk:(AudioChunk *)chunk {
|
- (void)addChunk:(AudioChunk *)chunk {
|
||||||
|
@ -490,12 +463,10 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
inAdder = YES;
|
inAdder = YES;
|
||||||
|
|
||||||
const double chunkDuration = [chunk duration];
|
const double chunkDuration = [chunk duration];
|
||||||
const double chunkDurationRatioed = [chunk durationRatioed];
|
|
||||||
|
|
||||||
@synchronized(chunkList) {
|
@synchronized(chunkList) {
|
||||||
[chunkList addObject:chunk];
|
[chunkList addObject:chunk];
|
||||||
listDuration += chunkDuration;
|
listDuration += chunkDuration;
|
||||||
listDurationRatioed += chunkDurationRatioed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inAdder = NO;
|
inAdder = NO;
|
||||||
|
@ -516,21 +487,16 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
if([chunk frameCount] <= maxFrameCount) {
|
if([chunk frameCount] <= maxFrameCount) {
|
||||||
[chunkList removeObjectAtIndex:0];
|
[chunkList removeObjectAtIndex:0];
|
||||||
listDuration -= [chunk duration];
|
listDuration -= [chunk duration];
|
||||||
listDurationRatioed -= [chunk durationRatioed];
|
|
||||||
inRemover = NO;
|
inRemover = NO;
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
double streamTimestamp = [chunk streamTimestamp];
|
|
||||||
NSData *removedData = [chunk removeSamples:maxFrameCount];
|
NSData *removedData = [chunk removeSamples:maxFrameCount];
|
||||||
AudioChunk *ret = [[AudioChunk alloc] init];
|
AudioChunk *ret = [[AudioChunk alloc] init];
|
||||||
[ret setFormat:[chunk format]];
|
[ret setFormat:[chunk format]];
|
||||||
[ret setChannelConfig:[chunk channelConfig]];
|
[ret setChannelConfig:[chunk channelConfig]];
|
||||||
[ret setLossless:[chunk lossless]];
|
[ret setLossless:[chunk lossless]];
|
||||||
[ret setStreamTimestamp:streamTimestamp];
|
|
||||||
[ret setStreamTimeRatio:[chunk streamTimeRatio]];
|
|
||||||
[ret assignData:removedData];
|
[ret assignData:removedData];
|
||||||
listDuration -= [ret duration];
|
listDuration -= [ret duration];
|
||||||
listDurationRatioed -= [ret durationRatioed];
|
|
||||||
inRemover = NO;
|
inRemover = NO;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -557,126 +523,23 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
if([chunk frameCount] <= maxFrameCount) {
|
if([chunk frameCount] <= maxFrameCount) {
|
||||||
[chunkList removeObjectAtIndex:0];
|
[chunkList removeObjectAtIndex:0];
|
||||||
listDuration -= [chunk duration];
|
listDuration -= [chunk duration];
|
||||||
listDurationRatioed -= [chunk durationRatioed];
|
|
||||||
inRemover = NO;
|
inRemover = NO;
|
||||||
return [self convertChunk:chunk];
|
return [self convertChunk:chunk];
|
||||||
}
|
}
|
||||||
double streamTimestamp = [chunk streamTimestamp];
|
|
||||||
NSData *removedData = [chunk removeSamples:maxFrameCount];
|
NSData *removedData = [chunk removeSamples:maxFrameCount];
|
||||||
AudioChunk *ret = [[AudioChunk alloc] init];
|
AudioChunk *ret = [[AudioChunk alloc] init];
|
||||||
[ret setFormat:[chunk format]];
|
[ret setFormat:[chunk format]];
|
||||||
[ret setChannelConfig:[chunk channelConfig]];
|
[ret setChannelConfig:[chunk channelConfig]];
|
||||||
[ret setLossless:[chunk lossless]];
|
[ret setLossless:[chunk lossless]];
|
||||||
[ret setStreamTimestamp:streamTimestamp];
|
|
||||||
[ret setStreamTimeRatio:[chunk streamTimeRatio]];
|
|
||||||
[ret assignData:removedData];
|
[ret assignData:removedData];
|
||||||
listDuration -= [ret duration];
|
listDuration -= [ret duration];
|
||||||
listDurationRatioed -= [ret durationRatioed];
|
|
||||||
inRemover = NO;
|
inRemover = NO;
|
||||||
return [self convertChunk:ret];
|
return [self convertChunk:ret];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AudioChunk *)removeAndMergeSamples:(size_t)maxFrameCount callBlock:(BOOL(NS_NOESCAPE ^ _Nonnull)(void))block {
|
|
||||||
if(stopping) {
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
inMerger = YES;
|
|
||||||
|
|
||||||
BOOL formatSet = NO;
|
|
||||||
AudioStreamBasicDescription currentFormat;
|
|
||||||
uint32_t currentChannelConfig = 0;
|
|
||||||
|
|
||||||
double streamTimestamp = 0.0;
|
|
||||||
double streamTimeRatio = 1.0;
|
|
||||||
BOOL blocked = NO;
|
|
||||||
while(![self peekTimestamp:&streamTimestamp timeRatio:&streamTimeRatio]) {
|
|
||||||
if((blocked = block())) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(blocked) {
|
|
||||||
inMerger = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioChunk *chunk;
|
|
||||||
size_t totalFrameCount = 0;
|
|
||||||
AudioChunk *outputChunk = [[AudioChunk alloc] init];
|
|
||||||
|
|
||||||
[outputChunk setStreamTimestamp:streamTimestamp];
|
|
||||||
[outputChunk setStreamTimeRatio:streamTimeRatio];
|
|
||||||
|
|
||||||
while(!stopping && totalFrameCount < maxFrameCount) {
|
|
||||||
AudioStreamBasicDescription newFormat;
|
|
||||||
uint32_t newChannelConfig;
|
|
||||||
if(![self peekFormat:&newFormat channelConfig:&newChannelConfig]) {
|
|
||||||
if(block()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(formatSet &&
|
|
||||||
(memcmp(&newFormat, ¤tFormat, sizeof(newFormat)) != 0 ||
|
|
||||||
newChannelConfig != currentChannelConfig)) {
|
|
||||||
break;
|
|
||||||
} else if(!formatSet) {
|
|
||||||
[outputChunk setFormat:newFormat];
|
|
||||||
[outputChunk setChannelConfig:newChannelConfig];
|
|
||||||
currentFormat = newFormat;
|
|
||||||
currentChannelConfig = newChannelConfig;
|
|
||||||
formatSet = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk = [self removeSamples:maxFrameCount - totalFrameCount];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
if(block()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if([chunk isHDCD]) {
|
|
||||||
[outputChunk setHDCD];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t frameCount = [chunk frameCount];
|
|
||||||
NSData *sampleData = [chunk removeSamples:frameCount];
|
|
||||||
|
|
||||||
[outputChunk assignData:sampleData];
|
|
||||||
|
|
||||||
totalFrameCount += frameCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!totalFrameCount) {
|
|
||||||
inMerger = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
inMerger = NO;
|
|
||||||
return outputChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)removeAndMergeSamplesAsFloat32:(size_t)maxFrameCount callBlock:(BOOL(NS_NOESCAPE ^ _Nonnull)(void))block {
|
|
||||||
AudioChunk *ret = [self removeAndMergeSamples:maxFrameCount callBlock:block];
|
|
||||||
return [self convertChunk:ret];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)convertChunk:(AudioChunk *)inChunk {
|
- (AudioChunk *)convertChunk:(AudioChunk *)inChunk {
|
||||||
if(stopping) return [[AudioChunk alloc] init];
|
|
||||||
|
|
||||||
inConverter = YES;
|
|
||||||
|
|
||||||
AudioStreamBasicDescription chunkFormat = [inChunk format];
|
AudioStreamBasicDescription chunkFormat = [inChunk format];
|
||||||
if(![inChunk frameCount] ||
|
|
||||||
(chunkFormat.mFormatFlags == kAudioFormatFlagsNativeFloatPacked &&
|
|
||||||
chunkFormat.mBitsPerChannel == 32)) {
|
|
||||||
inConverter = NO;
|
|
||||||
return inChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t chunkConfig = [inChunk channelConfig];
|
uint32_t chunkConfig = [inChunk channelConfig];
|
||||||
BOOL chunkLossless = [inChunk lossless];
|
BOOL chunkLossless = [inChunk lossless];
|
||||||
if(!formatRead || memcmp(&chunkFormat, &inputFormat, sizeof(chunkFormat)) != 0 ||
|
if(!formatRead || memcmp(&chunkFormat, &inputFormat, sizeof(chunkFormat)) != 0 ||
|
||||||
|
@ -687,10 +550,8 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
inputLossless = chunkLossless;
|
inputLossless = chunkLossless;
|
||||||
|
|
||||||
BOOL isFloat = !!(inputFormat.mFormatFlags & kAudioFormatFlagIsFloat);
|
BOOL isFloat = !!(inputFormat.mFormatFlags & kAudioFormatFlagIsFloat);
|
||||||
if((!isFloat && !(inputFormat.mBitsPerChannel >= 1 && inputFormat.mBitsPerChannel <= 32)) || (isFloat && !(inputFormat.mBitsPerChannel == 32 || inputFormat.mBitsPerChannel == 64))) {
|
if((!isFloat && !(inputFormat.mBitsPerChannel >= 1 && inputFormat.mBitsPerChannel <= 32)) || (isFloat && !(inputFormat.mBitsPerChannel == 32 || inputFormat.mBitsPerChannel == 64)))
|
||||||
inConverter = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
return [[AudioChunk alloc] init];
|
||||||
}
|
|
||||||
|
|
||||||
// These are really placeholders, as we're doing everything internally now
|
// These are really placeholders, as we're doing everything internally now
|
||||||
if(inputLossless &&
|
if(inputLossless &&
|
||||||
|
@ -698,7 +559,6 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
inputFormat.mChannelsPerFrame == 2 &&
|
inputFormat.mChannelsPerFrame == 2 &&
|
||||||
inputFormat.mSampleRate == 44100) {
|
inputFormat.mSampleRate == 44100) {
|
||||||
// possibly HDCD, run through decoder
|
// possibly HDCD, run through decoder
|
||||||
[self addObservers];
|
|
||||||
if(hdcd_decoder) {
|
if(hdcd_decoder) {
|
||||||
free(hdcd_decoder);
|
free(hdcd_decoder);
|
||||||
hdcd_decoder = NULL;
|
hdcd_decoder = NULL;
|
||||||
|
@ -739,7 +599,6 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
NSUInteger samplesRead = [inChunk frameCount];
|
NSUInteger samplesRead = [inChunk frameCount];
|
||||||
|
|
||||||
if(!samplesRead) {
|
if(!samplesRead) {
|
||||||
inConverter = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
return [[AudioChunk alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,8 +607,6 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
size_t bitsPerSample = inputFormat.mBitsPerChannel;
|
size_t bitsPerSample = inputFormat.mBitsPerChannel;
|
||||||
BOOL isBigEndian = !!(inputFormat.mFormatFlags & kAudioFormatFlagIsBigEndian);
|
BOOL isBigEndian = !!(inputFormat.mFormatFlags & kAudioFormatFlagIsBigEndian);
|
||||||
|
|
||||||
double streamTimestamp = [inChunk streamTimestamp];
|
|
||||||
|
|
||||||
NSData *inputData = [inChunk removeSamples:samplesRead];
|
NSData *inputData = [inChunk removeSamples:samplesRead];
|
||||||
|
|
||||||
#if DSD_DECIMATE
|
#if DSD_DECIMATE
|
||||||
|
@ -809,7 +666,6 @@ 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;
|
||||||
|
@ -837,35 +693,21 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
if(hdcd_decoder) { // implied bits per sample is 16, produces 32 bit int scale
|
if(hdcd_decoder) { // implied bits per sample is 16, produces 32 bit int scale
|
||||||
samplesRead = bytesReadFromInput / 2;
|
samplesRead = bytesReadFromInput / 2;
|
||||||
const size_t buffer_adder = (inputBuffer == &tempData[0]) ? buffer_adder_base : 0;
|
const size_t buffer_adder = (inputBuffer == &tempData[0]) ? buffer_adder_base : 0;
|
||||||
if(isUnsigned) {
|
if(isUnsigned)
|
||||||
if(!inputChanged) {
|
|
||||||
memcpy(&tempData[buffer_adder], inputBuffer, samplesRead * 2);
|
|
||||||
inputBuffer = &tempData[buffer_adder];
|
|
||||||
inputChanged = YES;
|
|
||||||
}
|
|
||||||
convert_u16_to_s16((int16_t *)inputBuffer, samplesRead);
|
convert_u16_to_s16((int16_t *)inputBuffer, samplesRead);
|
||||||
isUnsigned = NO;
|
convert_s16_to_hdcd_input((int32_t *)(&tempData[buffer_adder]), (int16_t *)inputBuffer, samplesRead);
|
||||||
}
|
hdcd_process_stereo((hdcd_state_stereo_t *)hdcd_decoder, (int32_t *)(&tempData[buffer_adder]), (int)(samplesRead / 2));
|
||||||
const size_t buffer_adder2 = (inputBuffer == &tempData[0]) ? buffer_adder_base : 0;
|
|
||||||
convert_s16_to_hdcd_input((int32_t *)(&tempData[buffer_adder2]), (int16_t *)inputBuffer, samplesRead);
|
|
||||||
hdcd_process_stereo((hdcd_state_stereo_t *)hdcd_decoder, (int32_t *)(&tempData[buffer_adder2]), (int)(samplesRead / 2));
|
|
||||||
if(((hdcd_state_stereo_t *)hdcd_decoder)->channel[0].sustain &&
|
if(((hdcd_state_stereo_t *)hdcd_decoder)->channel[0].sustain &&
|
||||||
((hdcd_state_stereo_t *)hdcd_decoder)->channel[1].sustain) {
|
((hdcd_state_stereo_t *)hdcd_decoder)->channel[1].sustain) {
|
||||||
hdcdSustained = YES;
|
hdcdSustained = YES;
|
||||||
}
|
}
|
||||||
if(enableHDCD) {
|
|
||||||
gain = 2.0;
|
gain = 2.0;
|
||||||
bitsPerSample = 32;
|
bitsPerSample = 32;
|
||||||
bytesReadFromInput = samplesRead * 4;
|
bytesReadFromInput = samplesRead * 4;
|
||||||
isUnsigned = NO;
|
isUnsigned = NO;
|
||||||
inputBuffer = &tempData[buffer_adder2];
|
inputBuffer = &tempData[buffer_adder];
|
||||||
inputChanged = YES;
|
inputChanged = YES;
|
||||||
} else {
|
|
||||||
// Discard the output of the decoder and process again
|
|
||||||
goto process16bit;
|
|
||||||
}
|
|
||||||
} else if(bitsPerSample <= 16) {
|
} else if(bitsPerSample <= 16) {
|
||||||
process16bit:
|
|
||||||
samplesRead = bytesReadFromInput / 2;
|
samplesRead = bytesReadFromInput / 2;
|
||||||
const size_t buffer_adder = (inputBuffer == &tempData[0]) ? buffer_adder_base : 0;
|
const size_t buffer_adder = (inputBuffer == &tempData[0]) ? buffer_adder_base : 0;
|
||||||
if(isUnsigned) {
|
if(isUnsigned) {
|
||||||
|
@ -930,47 +772,23 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
|
||||||
[outChunk setFormat:floatFormat];
|
[outChunk setFormat:floatFormat];
|
||||||
[outChunk setChannelConfig:inputChannelConfig];
|
[outChunk setChannelConfig:inputChannelConfig];
|
||||||
[outChunk setLossless:inputLossless];
|
[outChunk setLossless:inputLossless];
|
||||||
[outChunk setStreamTimestamp:streamTimestamp];
|
|
||||||
[outChunk setStreamTimeRatio:[inChunk streamTimeRatio]];
|
|
||||||
if(hdcdSustained) [outChunk setHDCD];
|
if(hdcdSustained) [outChunk setHDCD];
|
||||||
|
|
||||||
[outChunk assignSamples:inputBuffer frameCount:bytesReadFromInput / floatFormat.mBytesPerPacket];
|
[outChunk assignSamples:inputBuffer frameCount:bytesReadFromInput / floatFormat.mBytesPerPacket];
|
||||||
|
|
||||||
inConverter = NO;
|
|
||||||
return outChunk;
|
return outChunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)peekFormat:(AudioStreamBasicDescription *)format channelConfig:(uint32_t *)config {
|
- (BOOL)peekFormat:(AudioStreamBasicDescription *)format channelConfig:(uint32_t *)config {
|
||||||
if(stopping) return NO;
|
if(stopping) return NO;
|
||||||
inPeeker = YES;
|
|
||||||
@synchronized(chunkList) {
|
@synchronized(chunkList) {
|
||||||
if([chunkList count]) {
|
if([chunkList count]) {
|
||||||
AudioChunk *chunk = [chunkList objectAtIndex:0];
|
AudioChunk *chunk = [chunkList objectAtIndex:0];
|
||||||
*format = [chunk format];
|
*format = [chunk format];
|
||||||
*config = [chunk channelConfig];
|
*config = [chunk channelConfig];
|
||||||
inPeeker = NO;
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inPeeker = NO;
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)peekTimestamp:(double *)timestamp timeRatio:(double *)timeRatio {
|
|
||||||
if(stopping) return NO;
|
|
||||||
inPeeker = YES;
|
|
||||||
@synchronized (chunkList) {
|
|
||||||
if([chunkList count]) {
|
|
||||||
AudioChunk *chunk = [chunkList objectAtIndex:0];
|
|
||||||
*timestamp = [chunk streamTimestamp];
|
|
||||||
*timeRatio = [chunk streamTimeRatio];
|
|
||||||
inPeeker = NO;
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*timestamp = 0.0;
|
|
||||||
*timeRatio = 1.0;
|
|
||||||
inPeeker = NO;
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
#import <AudioUnit/AudioUnit.h>
|
#import <AudioUnit/AudioUnit.h>
|
||||||
#import <CoreAudio/AudioHardware.h>
|
#import <CoreAudio/AudioHardware.h>
|
||||||
|
|
||||||
#import <CogAudio/soxr.h>
|
#import <soxr.h>
|
||||||
|
|
||||||
#import <CogAudio/Node.h>
|
#import "Node.h"
|
||||||
|
|
||||||
@interface ConverterNode : Node {
|
@interface ConverterNode : Node {
|
||||||
NSDictionary *rgInfo;
|
NSDictionary *rgInfo;
|
||||||
|
@ -25,8 +25,6 @@
|
||||||
size_t inputBufferSize;
|
size_t inputBufferSize;
|
||||||
size_t inpSize, inpOffset;
|
size_t inpSize, inpOffset;
|
||||||
|
|
||||||
double streamTimestamp, streamTimeRatio;
|
|
||||||
|
|
||||||
BOOL stopping;
|
BOOL stopping;
|
||||||
BOOL convertEntered;
|
BOOL convertEntered;
|
||||||
BOOL paused;
|
BOOL paused;
|
||||||
|
@ -45,8 +43,6 @@
|
||||||
|
|
||||||
double sampleRatio;
|
double sampleRatio;
|
||||||
|
|
||||||
BOOL observersAdded;
|
|
||||||
|
|
||||||
float volumeScale;
|
float volumeScale;
|
||||||
|
|
||||||
void *floatBuffer;
|
void *floatBuffer;
|
||||||
|
@ -75,8 +71,6 @@
|
||||||
- (BOOL)setupWithInputFormat:(AudioStreamBasicDescription)inputFormat withInputConfig:(uint32_t)inputConfig outputFormat:(AudioStreamBasicDescription)outputFormat isLossless:(BOOL)lossless;
|
- (BOOL)setupWithInputFormat:(AudioStreamBasicDescription)inputFormat withInputConfig:(uint32_t)inputConfig outputFormat:(AudioStreamBasicDescription)outputFormat isLossless:(BOOL)lossless;
|
||||||
- (void)cleanUp;
|
- (void)cleanUp;
|
||||||
|
|
||||||
- (BOOL)paused;
|
|
||||||
|
|
||||||
- (void)process;
|
- (void)process;
|
||||||
- (AudioChunk *)convert;
|
- (AudioChunk *)convert;
|
||||||
|
|
||||||
|
|
|
@ -66,28 +66,12 @@ static void *kConverterNodeContext = &kConverterNodeContext;
|
||||||
extrapolateBuffer = NULL;
|
extrapolateBuffer = NULL;
|
||||||
extrapolateBufferSize = 0;
|
extrapolateBufferSize = 0;
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.volumeScaling" options:0 context:kConverterNodeContext];
|
||||||
[self initLogFiles];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addObservers {
|
|
||||||
if(!observersAdded) {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.volumeScaling" options:(NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew) context:kConverterNodeContext];
|
|
||||||
observersAdded = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObservers {
|
|
||||||
if(observersAdded) {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.volumeScaling" context:kConverterNodeContext];
|
|
||||||
observersAdded = NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void scale_by_volume(float *buffer, size_t count, float volume) {
|
void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
if(volume != 1.0) {
|
if(volume != 1.0) {
|
||||||
size_t unaligned = (uintptr_t)buffer & 15;
|
size_t unaligned = (uintptr_t)buffer & 15;
|
||||||
|
@ -106,10 +90,6 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)paused {
|
|
||||||
return paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)process {
|
- (void)process {
|
||||||
// Removed endOfStream check from here, since we want to be able to flush the converter
|
// Removed endOfStream check from here, since we want to be able to flush the converter
|
||||||
// when the end of stream is reached. Convert function instead processes what it can,
|
// when the end of stream is reached. Convert function instead processes what it can,
|
||||||
|
@ -121,15 +101,13 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
AudioChunk *chunk = nil;
|
AudioChunk *chunk = nil;
|
||||||
chunk = [self convert];
|
chunk = [self convert];
|
||||||
if(!chunk || ![chunk frameCount]) {
|
if(!chunk) {
|
||||||
if([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) {
|
if([self endOfStream] == YES) {
|
||||||
endOfStream = YES;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(paused || !streamFormatChanged) {
|
if(paused || !streamFormatChanged) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
usleep(500);
|
|
||||||
} else {
|
} else {
|
||||||
[self writeChunk:chunk];
|
[self writeChunk:chunk];
|
||||||
chunk = nil;
|
chunk = nil;
|
||||||
|
@ -140,7 +118,6 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endOfStream = YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AudioChunk *)convert {
|
- (AudioChunk *)convert {
|
||||||
|
@ -156,15 +133,6 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inpOffset == inpSize) {
|
|
||||||
streamTimestamp = 0.0;
|
|
||||||
streamTimeRatio = 1.0;
|
|
||||||
if(![self peekTimestamp:&streamTimestamp timeRatio:&streamTimeRatio]) {
|
|
||||||
convertEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while(inpOffset == inpSize) {
|
while(inpOffset == inpSize) {
|
||||||
// Approximately the most we want on input
|
// Approximately the most we want on input
|
||||||
ioNumberPackets = 4096;
|
ioNumberPackets = 4096;
|
||||||
|
@ -177,7 +145,7 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
|
|
||||||
ssize_t bytesReadFromInput = 0;
|
ssize_t bytesReadFromInput = 0;
|
||||||
|
|
||||||
while(bytesReadFromInput < amountToWrite && !stopping && !paused && !streamFormatChanged && [self shouldContinue] == YES && !([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES)) {
|
while(bytesReadFromInput < amountToWrite && !stopping && !paused && !streamFormatChanged && [self shouldContinue] == YES && [self endOfStream] == NO) {
|
||||||
AudioStreamBasicDescription inf;
|
AudioStreamBasicDescription inf;
|
||||||
uint32_t config;
|
uint32_t config;
|
||||||
if([self peekFormat:&inf channelConfig:&config]) {
|
if([self peekFormat:&inf channelConfig:&config]) {
|
||||||
|
@ -217,7 +185,7 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stopping || paused || streamFormatChanged || [self shouldContinue] == NO || ([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES)) {
|
if(stopping || paused || streamFormatChanged || [self shouldContinue] == NO || [self endOfStream] == YES) {
|
||||||
if(!skipResampler) {
|
if(!skipResampler) {
|
||||||
if(!is_postextrapolated_) {
|
if(!is_postextrapolated_) {
|
||||||
is_postextrapolated_ = 1;
|
is_postextrapolated_ = 1;
|
||||||
|
@ -281,7 +249,6 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
size_t inputSamples = ioNumberPackets / floatFormat.mBytesPerPacket;
|
size_t inputSamples = ioNumberPackets / floatFormat.mBytesPerPacket;
|
||||||
ioNumberPackets = (UInt32)inputSamples;
|
ioNumberPackets = (UInt32)inputSamples;
|
||||||
ioNumberPackets = (UInt32)ceil((float)ioNumberPackets * sampleRatio);
|
ioNumberPackets = (UInt32)ceil((float)ioNumberPackets * sampleRatio);
|
||||||
ioNumberPackets += soxr_delay(soxr);
|
|
||||||
ioNumberPackets = (ioNumberPackets + 255) & ~255;
|
ioNumberPackets = (ioNumberPackets + 255) & ~255;
|
||||||
|
|
||||||
size_t newSize = ioNumberPackets * floatFormat.mBytesPerPacket;
|
size_t newSize = ioNumberPackets * floatFormat.mBytesPerPacket;
|
||||||
|
@ -298,6 +265,7 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
size_t outputDone = 0;
|
size_t outputDone = 0;
|
||||||
|
|
||||||
if(!skipResampler) {
|
if(!skipResampler) {
|
||||||
|
ioNumberPackets += soxr_delay(soxr);
|
||||||
soxr_process(soxr, (float *)(((uint8_t *)inputBuffer) + inpOffset), inputSamples, &inputDone, floatBuffer, ioNumberPackets, &outputDone);
|
soxr_process(soxr, (float *)(((uint8_t *)inputBuffer) + inpOffset), inputSamples, &inputDone, floatBuffer, ioNumberPackets, &outputDone);
|
||||||
|
|
||||||
if(latencyEatenPost) {
|
if(latencyEatenPost) {
|
||||||
|
@ -346,12 +314,8 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
|
||||||
if(nodeChannelConfig) {
|
if(nodeChannelConfig) {
|
||||||
[chunk setChannelConfig:nodeChannelConfig];
|
[chunk setChannelConfig:nodeChannelConfig];
|
||||||
}
|
}
|
||||||
[self addObservers];
|
|
||||||
scale_by_volume(floatBuffer, ioNumberPackets / sizeof(float), volumeScale);
|
scale_by_volume(floatBuffer, ioNumberPackets / sizeof(float), volumeScale);
|
||||||
[chunk setStreamTimestamp:streamTimestamp];
|
|
||||||
[chunk setStreamTimeRatio:streamTimeRatio];
|
|
||||||
[chunk assignSamples:floatBuffer frameCount:ioNumberPackets / floatFormat.mBytesPerPacket];
|
[chunk assignSamples:floatBuffer frameCount:ioNumberPackets / floatFormat.mBytesPerPacket];
|
||||||
streamTimestamp += [chunk durationRatioed];
|
|
||||||
convertEntered = NO;
|
convertEntered = NO;
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
@ -499,13 +463,12 @@ static float db_to_scale(float db) {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
DLog(@"Converter dealloc");
|
DLog(@"Decoder dealloc");
|
||||||
|
|
||||||
[self removeObservers];
|
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.volumeScaling" context:kConverterNodeContext];
|
||||||
|
|
||||||
paused = NO;
|
paused = NO;
|
||||||
[self cleanUp];
|
[self cleanUp];
|
||||||
[super cleanUp];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setOutputFormat:(AudioStreamBasicDescription)format {
|
- (void)setOutputFormat:(AudioStreamBasicDescription)format {
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
//
|
|
||||||
// DSPDownmixNode.h
|
|
||||||
// CogAudio
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/13/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef DSPDownmixNode_h
|
|
||||||
#define DSPDownmixNode_h
|
|
||||||
|
|
||||||
#import <AudioToolbox/AudioToolbox.h>
|
|
||||||
|
|
||||||
#import <CogAudio/DSPNode.h>
|
|
||||||
|
|
||||||
@interface DSPDownmixNode : DSPNode {
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency;
|
|
||||||
|
|
||||||
- (BOOL)setup;
|
|
||||||
- (void)cleanUp;
|
|
||||||
|
|
||||||
- (void)resetBuffer;
|
|
||||||
|
|
||||||
- (BOOL)paused;
|
|
||||||
|
|
||||||
- (void)process;
|
|
||||||
- (AudioChunk * _Nullable)convert;
|
|
||||||
|
|
||||||
- (void)setOutputFormat:(AudioStreamBasicDescription)format withChannelConfig:(uint32_t)config;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* DSPDownmixNode_h */
|
|
|
@ -1,201 +0,0 @@
|
||||||
//
|
|
||||||
// DSPDownmixNode.m
|
|
||||||
// CogAudio Framework
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/13/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
#import "Downmix.h"
|
|
||||||
|
|
||||||
#import "Logging.h"
|
|
||||||
|
|
||||||
#import "DSPDownmixNode.h"
|
|
||||||
|
|
||||||
@implementation DSPDownmixNode {
|
|
||||||
DownmixProcessor *downmix;
|
|
||||||
|
|
||||||
BOOL stopping, paused;
|
|
||||||
BOOL processEntered;
|
|
||||||
BOOL formatSet;
|
|
||||||
|
|
||||||
AudioStreamBasicDescription lastInputFormat;
|
|
||||||
AudioStreamBasicDescription inputFormat;
|
|
||||||
AudioStreamBasicDescription outputFormat;
|
|
||||||
|
|
||||||
uint32_t lastInputChannelConfig, inputChannelConfig;
|
|
||||||
uint32_t outputChannelConfig;
|
|
||||||
|
|
||||||
float outBuffer[4096 * 32];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency {
|
|
||||||
self = [super initWithController:c previous:p latency:latency];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
DLog(@"Downmix dealloc");
|
|
||||||
[self setShouldContinue:NO];
|
|
||||||
[self cleanUp];
|
|
||||||
[super cleanUp];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)fullInit {
|
|
||||||
if(formatSet) {
|
|
||||||
downmix = [[DownmixProcessor alloc] initWithInputFormat:inputFormat inputConfig:inputChannelConfig andOutputFormat:outputFormat outputConfig:outputChannelConfig];
|
|
||||||
if(!downmix) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)fullShutdown {
|
|
||||||
downmix = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setup {
|
|
||||||
if(stopping)
|
|
||||||
return NO;
|
|
||||||
[self fullShutdown];
|
|
||||||
return [self fullInit];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cleanUp {
|
|
||||||
stopping = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[self fullShutdown];
|
|
||||||
formatSet = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resetBuffer {
|
|
||||||
paused = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[buffer reset];
|
|
||||||
paused = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setOutputFormat:(AudioStreamBasicDescription)format withChannelConfig:(uint32_t)config {
|
|
||||||
if(memcmp(&outputFormat, &format, sizeof(outputFormat)) != 0 ||
|
|
||||||
outputChannelConfig != config) {
|
|
||||||
paused = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[buffer reset];
|
|
||||||
[self fullShutdown];
|
|
||||||
paused = NO;
|
|
||||||
}
|
|
||||||
outputFormat = format;
|
|
||||||
outputChannelConfig = config;
|
|
||||||
formatSet = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)paused {
|
|
||||||
return paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)process {
|
|
||||||
while([self shouldContinue] == YES) {
|
|
||||||
if(paused || endOfStream) {
|
|
||||||
usleep(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
@autoreleasepool {
|
|
||||||
AudioChunk *chunk = nil;
|
|
||||||
chunk = [self convert];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
if([previousNode endOfStream] == YES) {
|
|
||||||
usleep(500);
|
|
||||||
endOfStream = YES;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(paused) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
usleep(500);
|
|
||||||
} else {
|
|
||||||
[self writeChunk:chunk];
|
|
||||||
chunk = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)convert {
|
|
||||||
if(stopping)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
processEntered = YES;
|
|
||||||
|
|
||||||
if(stopping || ([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) || [self shouldContinue] == NO) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(![self peekFormat:&inputFormat channelConfig:&inputChannelConfig]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!inputFormat.mSampleRate ||
|
|
||||||
!inputFormat.mBitsPerChannel ||
|
|
||||||
!inputFormat.mChannelsPerFrame ||
|
|
||||||
!inputFormat.mBytesPerFrame ||
|
|
||||||
!inputFormat.mFramesPerPacket ||
|
|
||||||
!inputFormat.mBytesPerPacket) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((formatSet && !downmix) ||
|
|
||||||
memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 ||
|
|
||||||
inputChannelConfig != lastInputChannelConfig) {
|
|
||||||
lastInputFormat = inputFormat;
|
|
||||||
lastInputChannelConfig = inputChannelConfig;
|
|
||||||
[self fullShutdown];
|
|
||||||
if(formatSet && ![self setup]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!downmix) {
|
|
||||||
processEntered = NO;
|
|
||||||
return [self readChunk:4096];
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioChunk *chunk = [self readChunkAsFloat32:4096];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
double streamTimestamp = [chunk streamTimestamp];
|
|
||||||
|
|
||||||
size_t frameCount = [chunk frameCount];
|
|
||||||
NSData *sampleData = [chunk removeSamples:frameCount];
|
|
||||||
|
|
||||||
[downmix process:[sampleData bytes] frameCount:frameCount output:&outBuffer[0]];
|
|
||||||
|
|
||||||
AudioChunk *outputChunk = [[AudioChunk alloc] init];
|
|
||||||
[outputChunk setFormat:outputFormat];
|
|
||||||
if(outputChannelConfig) {
|
|
||||||
[outputChunk setChannelConfig:outputChannelConfig];
|
|
||||||
}
|
|
||||||
if([chunk isHDCD]) [outputChunk setHDCD];
|
|
||||||
[outputChunk setStreamTimestamp:streamTimestamp];
|
|
||||||
[outputChunk setStreamTimeRatio:[chunk streamTimeRatio]];
|
|
||||||
[outputChunk assignSamples:&outBuffer[0] frameCount:frameCount];
|
|
||||||
|
|
||||||
processEntered = NO;
|
|
||||||
return outputChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,31 +0,0 @@
|
||||||
//
|
|
||||||
// DSPEqualizerNode.h
|
|
||||||
// CogAudio
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/11/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef DSPEqualizerNode_h
|
|
||||||
#define DSPEqualizerNode_h
|
|
||||||
|
|
||||||
#import <CogAudio/DSPNode.h>
|
|
||||||
|
|
||||||
@interface DSPEqualizerNode : DSPNode {
|
|
||||||
float *samplePtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency;
|
|
||||||
|
|
||||||
- (BOOL)setup;
|
|
||||||
- (void)cleanUp;
|
|
||||||
|
|
||||||
- (void)resetBuffer;
|
|
||||||
|
|
||||||
- (BOOL)paused;
|
|
||||||
|
|
||||||
- (void)process;
|
|
||||||
- (AudioChunk * _Nullable)convert;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* DSPEqualizerNode_h */
|
|
|
@ -1,401 +0,0 @@
|
||||||
//
|
|
||||||
// DSPEqualizerNode.m
|
|
||||||
// CogAudio Framework
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/11/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
#import <AudioToolbox/AudioToolbox.h>
|
|
||||||
#import <AudioUnit/AudioUnit.h>
|
|
||||||
|
|
||||||
#import <Accelerate/Accelerate.h>
|
|
||||||
|
|
||||||
#import "DSPEqualizerNode.h"
|
|
||||||
|
|
||||||
#import "OutputNode.h"
|
|
||||||
|
|
||||||
#import "Logging.h"
|
|
||||||
|
|
||||||
#import "AudioPlayer.h"
|
|
||||||
|
|
||||||
extern void scale_by_volume(float *buffer, size_t count, float volume);
|
|
||||||
|
|
||||||
static void * kDSPEqualizerNodeContext = &kDSPEqualizerNodeContext;
|
|
||||||
|
|
||||||
@implementation DSPEqualizerNode {
|
|
||||||
BOOL enableEqualizer;
|
|
||||||
BOOL equalizerInitialized;
|
|
||||||
|
|
||||||
double equalizerPreamp;
|
|
||||||
|
|
||||||
__weak AudioPlayer *audioPlayer;
|
|
||||||
|
|
||||||
AudioUnit _eq;
|
|
||||||
|
|
||||||
AudioTimeStamp timeStamp;
|
|
||||||
|
|
||||||
BOOL stopping, paused;
|
|
||||||
BOOL processEntered;
|
|
||||||
|
|
||||||
BOOL observersapplied;
|
|
||||||
|
|
||||||
AudioStreamBasicDescription lastInputFormat;
|
|
||||||
AudioStreamBasicDescription inputFormat;
|
|
||||||
|
|
||||||
uint32_t lastInputChannelConfig, inputChannelConfig;
|
|
||||||
uint32_t outputChannelConfig;
|
|
||||||
|
|
||||||
float inBuffer[4096 * 32];
|
|
||||||
float eqBuffer[4096 * 32];
|
|
||||||
float outBuffer[4096 * 32];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fillBuffers(AudioBufferList *ioData, const float *inbuffer, size_t count, size_t offset) {
|
|
||||||
const size_t channels = ioData->mNumberBuffers;
|
|
||||||
for(int i = 0; i < channels; ++i) {
|
|
||||||
const size_t maxCount = (ioData->mBuffers[i].mDataByteSize / sizeof(float)) - offset;
|
|
||||||
float *output = ((float *)ioData->mBuffers[i].mData) + offset;
|
|
||||||
const float *input = inbuffer + i;
|
|
||||||
cblas_scopy((int)((count > maxCount) ? maxCount : count), input, (int)channels, output, 1);
|
|
||||||
ioData->mBuffers[i].mNumberChannels = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clearBuffers(AudioBufferList *ioData, size_t count, size_t offset) {
|
|
||||||
for(int i = 0; i < ioData->mNumberBuffers; ++i) {
|
|
||||||
memset((uint8_t *)ioData->mBuffers[i].mData + offset * sizeof(float), 0, count * sizeof(float));
|
|
||||||
ioData->mBuffers[i].mNumberChannels = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static OSStatus eqRenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) {
|
|
||||||
if(inNumberFrames > 4096 || !inRefCon) {
|
|
||||||
clearBuffers(ioData, inNumberFrames, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DSPEqualizerNode *_self = (__bridge DSPEqualizerNode *)inRefCon;
|
|
||||||
|
|
||||||
fillBuffers(ioData, _self->samplePtr, inNumberFrames, 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency {
|
|
||||||
self = [super initWithController:c previous:p latency:latency];
|
|
||||||
if(self) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
enableEqualizer = [defaults boolForKey:@"GraphicEQenable"];
|
|
||||||
|
|
||||||
float preamp = [defaults floatForKey:@"eqPreamp"];
|
|
||||||
equalizerPreamp = pow(10.0, preamp / 20.0);
|
|
||||||
|
|
||||||
OutputNode *outputNode = c;
|
|
||||||
audioPlayer = [outputNode controller];
|
|
||||||
|
|
||||||
[self addObservers];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
DLog(@"Equalizer dealloc");
|
|
||||||
[self setShouldContinue:NO];
|
|
||||||
[self cleanUp];
|
|
||||||
[self removeObservers];
|
|
||||||
[super cleanUp];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addObservers {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.GraphicEQenable" options:0 context:kDSPEqualizerNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.eqPreamp" options:0 context:kDSPEqualizerNodeContext];
|
|
||||||
|
|
||||||
observersapplied = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObservers {
|
|
||||||
if(observersapplied) {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.GraphicEQenable" context:kDSPEqualizerNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.eqPreamp" context:kDSPEqualizerNodeContext];
|
|
||||||
observersapplied = NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
|
||||||
if(context != kDSPEqualizerNodeContext) {
|
|
||||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if([keyPath isEqualToString:@"values.GraphicEQenable"]) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
enableEqualizer = [defaults boolForKey:@"GraphicEQenable"];
|
|
||||||
} else if([keyPath isEqualToString:@"values.eqPreamp"]) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
float preamp = [defaults floatForKey:@"eqPreamp"];
|
|
||||||
equalizerPreamp = pow(10.0, preamp / 20.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioPlayer *)audioPlayer {
|
|
||||||
return audioPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)fullInit {
|
|
||||||
if(enableEqualizer) {
|
|
||||||
AudioComponentDescription desc;
|
|
||||||
NSError *err;
|
|
||||||
|
|
||||||
desc.componentType = kAudioUnitType_Effect;
|
|
||||||
desc.componentSubType = kAudioUnitSubType_GraphicEQ;
|
|
||||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
|
||||||
desc.componentFlags = 0;
|
|
||||||
desc.componentFlagsMask = 0;
|
|
||||||
|
|
||||||
AudioComponent comp = NULL;
|
|
||||||
|
|
||||||
comp = AudioComponentFindNext(comp, &desc);
|
|
||||||
if(!comp) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSStatus _err = AudioComponentInstanceNew(comp, &_eq);
|
|
||||||
if(err) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 value;
|
|
||||||
UInt32 size = sizeof(value);
|
|
||||||
|
|
||||||
value = 4096;
|
|
||||||
AudioUnitSetProperty(_eq, kAudioUnitProperty_MaximumFramesPerSlice,
|
|
||||||
kAudioUnitScope_Global, 0, &value, size);
|
|
||||||
|
|
||||||
value = 127;
|
|
||||||
AudioUnitSetProperty(_eq, kAudioUnitProperty_RenderQuality,
|
|
||||||
kAudioUnitScope_Global, 0, &value, size);
|
|
||||||
|
|
||||||
AURenderCallbackStruct callbackStruct;
|
|
||||||
callbackStruct.inputProcRefCon = (__bridge void *)self;
|
|
||||||
callbackStruct.inputProc = eqRenderCallback;
|
|
||||||
AudioUnitSetProperty(_eq, kAudioUnitProperty_SetRenderCallback,
|
|
||||||
kAudioUnitScope_Input, 0, &callbackStruct, sizeof(callbackStruct));
|
|
||||||
|
|
||||||
AudioUnitReset(_eq, kAudioUnitScope_Input, 0);
|
|
||||||
AudioUnitReset(_eq, kAudioUnitScope_Output, 0);
|
|
||||||
|
|
||||||
AudioUnitReset(_eq, kAudioUnitScope_Global, 0);
|
|
||||||
|
|
||||||
AudioStreamBasicDescription asbd = inputFormat;
|
|
||||||
|
|
||||||
// Of course, non-interleaved has only one sample per frame/packet, per buffer
|
|
||||||
asbd.mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
|
||||||
asbd.mBytesPerFrame = sizeof(float);
|
|
||||||
asbd.mBytesPerPacket = sizeof(float);
|
|
||||||
asbd.mFramesPerPacket = 1;
|
|
||||||
|
|
||||||
UInt32 maximumFrames = 4096;
|
|
||||||
AudioUnitSetProperty(_eq, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maximumFrames, sizeof(maximumFrames));
|
|
||||||
|
|
||||||
AudioUnitSetProperty(_eq, kAudioUnitProperty_StreamFormat,
|
|
||||||
kAudioUnitScope_Input, 0, &asbd, sizeof(asbd));
|
|
||||||
|
|
||||||
AudioUnitSetProperty(_eq, kAudioUnitProperty_StreamFormat,
|
|
||||||
kAudioUnitScope_Output, 0, &asbd, sizeof(asbd));
|
|
||||||
AudioUnitReset(_eq, kAudioUnitScope_Input, 0);
|
|
||||||
AudioUnitReset(_eq, kAudioUnitScope_Output, 0);
|
|
||||||
|
|
||||||
AudioUnitReset(_eq, kAudioUnitScope_Global, 0);
|
|
||||||
|
|
||||||
_err = AudioUnitInitialize(_eq);
|
|
||||||
if(_err != noErr) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
bzero(&timeStamp, sizeof(timeStamp));
|
|
||||||
timeStamp.mFlags = kAudioTimeStampSampleTimeValid;
|
|
||||||
|
|
||||||
equalizerInitialized = YES;
|
|
||||||
|
|
||||||
[[self audioPlayer] beginEqualizer:_eq];
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)fullShutdown {
|
|
||||||
if(_eq) {
|
|
||||||
if(equalizerInitialized) {
|
|
||||||
[[self audioPlayer] endEqualizer:_eq];
|
|
||||||
AudioUnitUninitialize(_eq);
|
|
||||||
equalizerInitialized = NO;
|
|
||||||
}
|
|
||||||
AudioComponentInstanceDispose(_eq);
|
|
||||||
_eq = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setup {
|
|
||||||
if(stopping)
|
|
||||||
return NO;
|
|
||||||
[self fullShutdown];
|
|
||||||
return [self fullInit];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cleanUp {
|
|
||||||
stopping = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[self fullShutdown];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resetBuffer {
|
|
||||||
paused = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[buffer reset];
|
|
||||||
[self fullShutdown];
|
|
||||||
paused = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)paused {
|
|
||||||
return paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)process {
|
|
||||||
while([self shouldContinue] == YES) {
|
|
||||||
if(paused || endOfStream) {
|
|
||||||
usleep(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
@autoreleasepool {
|
|
||||||
AudioChunk *chunk = nil;
|
|
||||||
chunk = [self convert];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
if([previousNode endOfStream] == YES) {
|
|
||||||
usleep(500);
|
|
||||||
endOfStream = YES;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(paused) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
usleep(500);
|
|
||||||
} else {
|
|
||||||
[self writeChunk:chunk];
|
|
||||||
chunk = nil;
|
|
||||||
}
|
|
||||||
if(!enableEqualizer && equalizerInitialized) {
|
|
||||||
[self fullShutdown];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)convert {
|
|
||||||
if(stopping)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
processEntered = YES;
|
|
||||||
|
|
||||||
if(stopping || ([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) || [self shouldContinue] == NO) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(![self peekFormat:&inputFormat channelConfig:&inputChannelConfig]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!inputFormat.mSampleRate ||
|
|
||||||
!inputFormat.mBitsPerChannel ||
|
|
||||||
!inputFormat.mChannelsPerFrame ||
|
|
||||||
!inputFormat.mBytesPerFrame ||
|
|
||||||
!inputFormat.mFramesPerPacket ||
|
|
||||||
!inputFormat.mBytesPerPacket) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((enableEqualizer && !equalizerInitialized) ||
|
|
||||||
memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 ||
|
|
||||||
inputChannelConfig != lastInputChannelConfig) {
|
|
||||||
lastInputFormat = inputFormat;
|
|
||||||
lastInputChannelConfig = inputChannelConfig;
|
|
||||||
[self fullShutdown];
|
|
||||||
if(enableEqualizer && ![self setup]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!equalizerInitialized) {
|
|
||||||
processEntered = NO;
|
|
||||||
return [self readChunk:4096];
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioChunk *chunk = [self readChunkAsFloat32:4096];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
double streamTimestamp = [chunk streamTimestamp];
|
|
||||||
|
|
||||||
samplePtr = &inBuffer[0];
|
|
||||||
size_t channels = inputFormat.mChannelsPerFrame;
|
|
||||||
|
|
||||||
size_t frameCount = [chunk frameCount];
|
|
||||||
NSData *sampleData = [chunk removeSamples:frameCount];
|
|
||||||
|
|
||||||
cblas_scopy((int)(frameCount * channels), [sampleData bytes], 1, &inBuffer[0], 1);
|
|
||||||
|
|
||||||
const size_t channelsminusone = channels - 1;
|
|
||||||
uint8_t tempBuffer[sizeof(AudioBufferList) + sizeof(AudioBuffer) * channelsminusone];
|
|
||||||
AudioBufferList *ioData = (AudioBufferList *)&tempBuffer[0];
|
|
||||||
|
|
||||||
ioData->mNumberBuffers = (UInt32)channels;
|
|
||||||
for(size_t i = 0; i < channels; ++i) {
|
|
||||||
ioData->mBuffers[i].mData = &eqBuffer[4096 * i];
|
|
||||||
ioData->mBuffers[i].mDataByteSize = (UInt32)(frameCount * sizeof(float));
|
|
||||||
ioData->mBuffers[i].mNumberChannels = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSStatus status = AudioUnitRender(_eq, NULL, &timeStamp, 0, (UInt32)frameCount, ioData);
|
|
||||||
|
|
||||||
if(status != noErr) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeStamp.mSampleTime += ((double)frameCount) / inputFormat.mSampleRate;
|
|
||||||
|
|
||||||
for(int i = 0; i < channels; ++i) {
|
|
||||||
cblas_scopy((int)frameCount, &eqBuffer[4096 * i], 1, &outBuffer[i], (int)channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioChunk *outputChunk = nil;
|
|
||||||
if(frameCount) {
|
|
||||||
scale_by_volume(&outBuffer[0], frameCount * channels, equalizerPreamp);
|
|
||||||
|
|
||||||
outputChunk = [[AudioChunk alloc] init];
|
|
||||||
[outputChunk setFormat:inputFormat];
|
|
||||||
if(outputChannelConfig) {
|
|
||||||
[outputChunk setChannelConfig:inputChannelConfig];
|
|
||||||
}
|
|
||||||
if([chunk isHDCD]) [outputChunk setHDCD];
|
|
||||||
[outputChunk setStreamTimestamp:streamTimestamp];
|
|
||||||
[outputChunk setStreamTimeRatio:[chunk streamTimeRatio]];
|
|
||||||
[outputChunk assignSamples:&outBuffer[0] frameCount:frameCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
processEntered = NO;
|
|
||||||
return outputChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,30 +0,0 @@
|
||||||
//
|
|
||||||
// DSPFSurroundNode.h
|
|
||||||
// CogAudio
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/11/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef DSPFSurroundNode_h
|
|
||||||
#define DSPFSurroundNode_h
|
|
||||||
|
|
||||||
#import <CogAudio/DSPNode.h>
|
|
||||||
|
|
||||||
@interface DSPFSurroundNode : DSPNode {
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency;
|
|
||||||
|
|
||||||
- (BOOL)setup;
|
|
||||||
- (void)cleanUp;
|
|
||||||
|
|
||||||
- (void)resetBuffer;
|
|
||||||
|
|
||||||
- (BOOL)paused;
|
|
||||||
|
|
||||||
- (void)process;
|
|
||||||
- (AudioChunk * _Nullable)convert;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* DSPFSurroundNode_h */
|
|
|
@ -1,275 +0,0 @@
|
||||||
//
|
|
||||||
// DSPFSurroundNode.m
|
|
||||||
// CogAudio Framework
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/11/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
#import <Accelerate/Accelerate.h>
|
|
||||||
|
|
||||||
#import "DSPFSurroundNode.h"
|
|
||||||
|
|
||||||
#import "Logging.h"
|
|
||||||
|
|
||||||
#import "FSurroundFilter.h"
|
|
||||||
|
|
||||||
#define OCTAVES 5
|
|
||||||
|
|
||||||
static void * kDSPFSurroundNodeContext = &kDSPFSurroundNodeContext;
|
|
||||||
|
|
||||||
@implementation DSPFSurroundNode {
|
|
||||||
BOOL enableFSurround;
|
|
||||||
BOOL FSurroundDelayRemoved;
|
|
||||||
FSurroundFilter *fsurround;
|
|
||||||
|
|
||||||
BOOL stopping, paused;
|
|
||||||
BOOL processEntered;
|
|
||||||
|
|
||||||
BOOL observersapplied;
|
|
||||||
|
|
||||||
AudioStreamBasicDescription lastInputFormat;
|
|
||||||
AudioStreamBasicDescription inputFormat;
|
|
||||||
AudioStreamBasicDescription outputFormat;
|
|
||||||
|
|
||||||
uint32_t lastInputChannelConfig, inputChannelConfig;
|
|
||||||
uint32_t outputChannelConfig;
|
|
||||||
|
|
||||||
float inBuffer[4096 * 2];
|
|
||||||
float outBuffer[8192 * 6];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency {
|
|
||||||
self = [super initWithController:c previous:p latency:latency];
|
|
||||||
if(self) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
enableFSurround = [defaults boolForKey:@"enableFSurround"];
|
|
||||||
|
|
||||||
[self addObservers];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
DLog(@"FreeSurround dealloc");
|
|
||||||
[self setShouldContinue:NO];
|
|
||||||
[self cleanUp];
|
|
||||||
[self removeObservers];
|
|
||||||
[super cleanUp];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addObservers {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.enableFSurround" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPFSurroundNodeContext];
|
|
||||||
|
|
||||||
observersapplied = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObservers {
|
|
||||||
if(observersapplied) {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.enableFSurround" context:kDSPFSurroundNodeContext];
|
|
||||||
observersapplied = NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
|
||||||
if(context != kDSPFSurroundNodeContext) {
|
|
||||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if([keyPath isEqualToString:@"values.enableFSurround"]) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
enableFSurround = [defaults boolForKey:@"enableFSurround"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)fullInit {
|
|
||||||
if(enableFSurround && inputFormat.mChannelsPerFrame == 2) {
|
|
||||||
fsurround = [[FSurroundFilter alloc] initWithSampleRate:inputFormat.mSampleRate];
|
|
||||||
if(!fsurround) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
outputFormat = inputFormat;
|
|
||||||
outputFormat.mChannelsPerFrame = [fsurround channelCount];
|
|
||||||
outputFormat.mBytesPerFrame = sizeof(float) * outputFormat.mChannelsPerFrame;
|
|
||||||
outputFormat.mBytesPerPacket = outputFormat.mBytesPerFrame * outputFormat.mFramesPerPacket;
|
|
||||||
outputChannelConfig = [fsurround channelConfig];
|
|
||||||
|
|
||||||
FSurroundDelayRemoved = NO;
|
|
||||||
} else {
|
|
||||||
fsurround = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)fullShutdown {
|
|
||||||
fsurround = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setup {
|
|
||||||
if(stopping)
|
|
||||||
return NO;
|
|
||||||
[self fullShutdown];
|
|
||||||
return [self fullInit];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cleanUp {
|
|
||||||
stopping = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[self fullShutdown];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resetBuffer {
|
|
||||||
paused = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[buffer reset];
|
|
||||||
[self fullShutdown];
|
|
||||||
paused = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)paused {
|
|
||||||
return paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)process {
|
|
||||||
while([self shouldContinue] == YES) {
|
|
||||||
if(paused || endOfStream) {
|
|
||||||
usleep(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
@autoreleasepool {
|
|
||||||
AudioChunk *chunk = nil;
|
|
||||||
chunk = [self convert];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
if([previousNode endOfStream] == YES) {
|
|
||||||
usleep(500);
|
|
||||||
endOfStream = YES;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(paused) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
usleep(500);
|
|
||||||
} else {
|
|
||||||
[self writeChunk:chunk];
|
|
||||||
chunk = nil;
|
|
||||||
}
|
|
||||||
if(!enableFSurround && fsurround) {
|
|
||||||
[self fullShutdown];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)convert {
|
|
||||||
if(stopping)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
processEntered = YES;
|
|
||||||
|
|
||||||
if(stopping || ([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) || [self shouldContinue] == NO) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(![self peekFormat:&inputFormat channelConfig:&inputChannelConfig]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!inputFormat.mSampleRate ||
|
|
||||||
!inputFormat.mBitsPerChannel ||
|
|
||||||
!inputFormat.mChannelsPerFrame ||
|
|
||||||
!inputFormat.mBytesPerFrame ||
|
|
||||||
!inputFormat.mFramesPerPacket ||
|
|
||||||
!inputFormat.mBytesPerPacket) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((enableFSurround && !fsurround) ||
|
|
||||||
memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 ||
|
|
||||||
inputChannelConfig != lastInputChannelConfig) {
|
|
||||||
lastInputFormat = inputFormat;
|
|
||||||
lastInputChannelConfig = inputChannelConfig;
|
|
||||||
[self fullShutdown];
|
|
||||||
if(enableFSurround && ![self setup]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!fsurround) {
|
|
||||||
processEntered = NO;
|
|
||||||
return [self readChunk:4096];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t totalRequestedSamples = 4096;
|
|
||||||
|
|
||||||
size_t totalFrameCount = 0;
|
|
||||||
AudioChunk *chunk = [self readAndMergeChunksAsFloat32:totalRequestedSamples];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
double streamTimestamp = [chunk streamTimestamp];
|
|
||||||
|
|
||||||
float *samplePtr = &inBuffer[0];
|
|
||||||
|
|
||||||
size_t frameCount = [chunk frameCount];
|
|
||||||
NSData *sampleData = [chunk removeSamples:frameCount];
|
|
||||||
|
|
||||||
cblas_scopy((int)frameCount * 2, [sampleData bytes], 1, &samplePtr[0], 1);
|
|
||||||
|
|
||||||
totalFrameCount = frameCount;
|
|
||||||
|
|
||||||
size_t countToProcess = totalFrameCount;
|
|
||||||
size_t samplesRendered;
|
|
||||||
if(countToProcess < 4096) {
|
|
||||||
bzero(&inBuffer[countToProcess * 2], (4096 - countToProcess) * 2 * sizeof(float));
|
|
||||||
countToProcess = 4096;
|
|
||||||
}
|
|
||||||
|
|
||||||
[fsurround process:&inBuffer[0] output:&outBuffer[0] count:(int)countToProcess];
|
|
||||||
samplePtr = &outBuffer[0];
|
|
||||||
samplesRendered = totalFrameCount;
|
|
||||||
|
|
||||||
if(totalFrameCount < 4096) {
|
|
||||||
bzero(&outBuffer[4096 * 6], 4096 * 2 * sizeof(float));
|
|
||||||
[fsurround process:&outBuffer[4096 * 6] output:&outBuffer[4096 * 6] count:4096];
|
|
||||||
samplesRendered += 2048;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!FSurroundDelayRemoved) {
|
|
||||||
FSurroundDelayRemoved = YES;
|
|
||||||
if(samplesRendered > 2048) {
|
|
||||||
samplePtr += 2048 * 6;
|
|
||||||
samplesRendered -= 2048;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioChunk *outputChunk = nil;
|
|
||||||
if(samplesRendered) {
|
|
||||||
outputChunk = [[AudioChunk alloc] init];
|
|
||||||
[outputChunk setFormat:outputFormat];
|
|
||||||
if(outputChannelConfig) {
|
|
||||||
[outputChunk setChannelConfig:outputChannelConfig];
|
|
||||||
}
|
|
||||||
if([chunk isHDCD]) [outputChunk setHDCD];
|
|
||||||
[outputChunk setStreamTimestamp:streamTimestamp];
|
|
||||||
[outputChunk setStreamTimeRatio:[chunk streamTimeRatio]];
|
|
||||||
[outputChunk assignSamples:samplePtr frameCount:samplesRendered];
|
|
||||||
}
|
|
||||||
|
|
||||||
processEntered = NO;
|
|
||||||
return outputChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,35 +0,0 @@
|
||||||
//
|
|
||||||
// DSPHRTFNode.h
|
|
||||||
// CogAudio
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/11/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef DSPHRTFNode_h
|
|
||||||
#define DSPHRTFNode_h
|
|
||||||
|
|
||||||
#import <simd/types.h>
|
|
||||||
|
|
||||||
#import <CogAudio/DSPNode.h>
|
|
||||||
|
|
||||||
@interface DSPHRTFNode : DSPNode {
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency;
|
|
||||||
|
|
||||||
- (BOOL)setup;
|
|
||||||
- (void)cleanUp;
|
|
||||||
|
|
||||||
- (void)resetBuffer;
|
|
||||||
|
|
||||||
- (BOOL)paused;
|
|
||||||
|
|
||||||
- (void)process;
|
|
||||||
- (AudioChunk * _Nullable)convert;
|
|
||||||
|
|
||||||
- (void)reportMotion:(simd_float4x4)matrix;
|
|
||||||
- (void)resetReferencePosition:(NSNotification *_Nullable)notification;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* DSPHRTFNode_h */
|
|
|
@ -1,434 +0,0 @@
|
||||||
//
|
|
||||||
// DSPHRTFNode.m
|
|
||||||
// CogAudio Framework
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/11/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
#import <CoreMotion/CoreMotion.h>
|
|
||||||
|
|
||||||
#import "Logging.h"
|
|
||||||
|
|
||||||
#import "DSPHRTFNode.h"
|
|
||||||
|
|
||||||
#import "lpc.h"
|
|
||||||
|
|
||||||
#import "HeadphoneFilter.h"
|
|
||||||
|
|
||||||
#include <AvailabilityMacros.h>
|
|
||||||
|
|
||||||
#if defined(MAC_OS_X_VERSION_14_0) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_14_0
|
|
||||||
#define MOTION_MANAGER 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void * kDSPHRTFNodeContext = &kDSPHRTFNodeContext;
|
|
||||||
|
|
||||||
static NSString *CogPlaybackDidResetHeadTracking = @"CogPlaybackDigResetHeadTracking";
|
|
||||||
|
|
||||||
static simd_float4x4 convertMatrix(CMRotationMatrix r) {
|
|
||||||
simd_float4x4 matrix = {
|
|
||||||
simd_make_float4(r.m33, -r.m31, r.m32, 0.0f),
|
|
||||||
simd_make_float4(r.m13, -r.m11, r.m12, 0.0f),
|
|
||||||
simd_make_float4(r.m23, -r.m21, r.m22, 0.0f),
|
|
||||||
simd_make_float4(0.0f, 0.0f, 0.0f, 1.0f)
|
|
||||||
};
|
|
||||||
return matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOTION_MANAGER
|
|
||||||
static NSLock *motionManagerLock = nil;
|
|
||||||
API_AVAILABLE(macos(14.0)) static CMHeadphoneMotionManager *motionManager = nil;
|
|
||||||
static DSPHRTFNode *registeredMotionListener = nil;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void registerMotionListener(DSPHRTFNode *listener) {
|
|
||||||
#ifdef MOTION_MANAGER
|
|
||||||
if(@available(macOS 14, *)) {
|
|
||||||
[motionManagerLock lock];
|
|
||||||
if([motionManager isDeviceMotionActive]) {
|
|
||||||
[motionManager stopDeviceMotionUpdates];
|
|
||||||
}
|
|
||||||
if([motionManager isDeviceMotionAvailable]) {
|
|
||||||
registeredMotionListener = listener;
|
|
||||||
[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
|
|
||||||
if(motion) {
|
|
||||||
[motionManagerLock lock];
|
|
||||||
[registeredMotionListener reportMotion:convertMatrix(motion.attitude.rotationMatrix)];
|
|
||||||
[motionManagerLock unlock];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
[motionManagerLock unlock];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void unregisterMotionListener(void) {
|
|
||||||
#ifdef MOTION_MANAGER
|
|
||||||
if(@available(macOS 14, *)) {
|
|
||||||
[motionManagerLock lock];
|
|
||||||
if([motionManager isDeviceMotionActive]) {
|
|
||||||
[motionManager stopDeviceMotionUpdates];
|
|
||||||
}
|
|
||||||
registeredMotionListener = nil;
|
|
||||||
[motionManagerLock unlock];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@implementation DSPHRTFNode {
|
|
||||||
BOOL enableHrtf;
|
|
||||||
BOOL enableHeadTracking;
|
|
||||||
BOOL lastEnableHeadTracking;
|
|
||||||
|
|
||||||
HeadphoneFilter *hrtf;
|
|
||||||
|
|
||||||
BOOL stopping, paused;
|
|
||||||
BOOL processEntered;
|
|
||||||
BOOL resetFilter;
|
|
||||||
|
|
||||||
size_t needPrefill;
|
|
||||||
|
|
||||||
BOOL observersapplied;
|
|
||||||
|
|
||||||
AudioStreamBasicDescription lastInputFormat;
|
|
||||||
AudioStreamBasicDescription inputFormat;
|
|
||||||
AudioStreamBasicDescription outputFormat;
|
|
||||||
|
|
||||||
uint32_t lastInputChannelConfig, inputChannelConfig;
|
|
||||||
uint32_t outputChannelConfig;
|
|
||||||
|
|
||||||
BOOL referenceMatrixSet;
|
|
||||||
BOOL rotationMatrixUpdated;
|
|
||||||
simd_float4x4 rotationMatrix;
|
|
||||||
simd_float4x4 referenceMatrix;
|
|
||||||
|
|
||||||
float prefillBuffer[4096 * 32];
|
|
||||||
float outBuffer[4096 * 2];
|
|
||||||
|
|
||||||
void *extrapolate_buffer;
|
|
||||||
size_t extrapolate_buffer_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)initialize {
|
|
||||||
#ifdef MOTION_MANAGER
|
|
||||||
motionManagerLock = [[NSLock alloc] init];
|
|
||||||
|
|
||||||
if(@available(macOS 14, *)) {
|
|
||||||
CMAuthorizationStatus status = [CMHeadphoneMotionManager authorizationStatus];
|
|
||||||
if(status == CMAuthorizationStatusDenied) {
|
|
||||||
ALog(@"Headphone motion not authorized");
|
|
||||||
return;
|
|
||||||
} else if(status == CMAuthorizationStatusAuthorized) {
|
|
||||||
ALog(@"Headphone motion authorized");
|
|
||||||
} else if(status == CMAuthorizationStatusRestricted) {
|
|
||||||
ALog(@"Headphone motion restricted");
|
|
||||||
} else if(status == CMAuthorizationStatusNotDetermined) {
|
|
||||||
ALog(@"Headphone motion status not determined; will prompt for access");
|
|
||||||
}
|
|
||||||
|
|
||||||
motionManager = [[CMHeadphoneMotionManager alloc] init];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency {
|
|
||||||
self = [super initWithController:c previous:p latency:latency];
|
|
||||||
if(self) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
enableHrtf = [defaults boolForKey:@"enableHrtf"];
|
|
||||||
enableHeadTracking = [defaults boolForKey:@"enableHeadTracking"];
|
|
||||||
|
|
||||||
rotationMatrix = matrix_identity_float4x4;
|
|
||||||
|
|
||||||
[self addObservers];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
DLog(@"HRTF dealloc");
|
|
||||||
[self setShouldContinue:NO];
|
|
||||||
[self cleanUp];
|
|
||||||
[self removeObservers];
|
|
||||||
[super cleanUp];
|
|
||||||
if(extrapolate_buffer) {
|
|
||||||
free(extrapolate_buffer);
|
|
||||||
extrapolate_buffer = NULL;
|
|
||||||
extrapolate_buffer_size = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addObservers {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.enableHrtf" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPHRTFNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.enableHeadTracking" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPHRTFNodeContext];
|
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resetReferencePosition:) name:CogPlaybackDidResetHeadTracking object:nil];
|
|
||||||
|
|
||||||
observersapplied = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObservers {
|
|
||||||
if(observersapplied) {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.enableHrtf" context:kDSPHRTFNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.enableHeadTracking" context:kDSPHRTFNodeContext];
|
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:CogPlaybackDidResetHeadTracking object:nil];
|
|
||||||
|
|
||||||
observersapplied = NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
|
||||||
if(context != kDSPHRTFNodeContext) {
|
|
||||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if([keyPath isEqualToString:@"values.enableHrtf"] ||
|
|
||||||
[keyPath isEqualToString:@"values.enableHeadTracking"]) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
enableHrtf = [defaults boolForKey:@"enableHrtf"];
|
|
||||||
enableHeadTracking = [defaults boolForKey:@"enableHeadTracking"];
|
|
||||||
resetFilter = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)fullInit {
|
|
||||||
if(enableHrtf) {
|
|
||||||
NSURL *presetUrl = [[NSBundle mainBundle] URLForResource:@"SADIE_D02-96000" withExtension:@"mhr"];
|
|
||||||
|
|
||||||
rotationMatrixUpdated = NO;
|
|
||||||
|
|
||||||
simd_float4x4 matrix;
|
|
||||||
if(!referenceMatrixSet || !enableHeadTracking) {
|
|
||||||
referenceMatrixSet = NO;
|
|
||||||
matrix = matrix_identity_float4x4;
|
|
||||||
self->referenceMatrix = matrix;
|
|
||||||
if(enableHeadTracking) {
|
|
||||||
lastEnableHeadTracking = YES;
|
|
||||||
registerMotionListener(self);
|
|
||||||
} else if(lastEnableHeadTracking) {
|
|
||||||
lastEnableHeadTracking = NO;
|
|
||||||
unregisterMotionListener();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
simd_float4x4 mirrorTransform = {
|
|
||||||
simd_make_float4(-1.0, 0.0, 0.0, 0.0),
|
|
||||||
simd_make_float4(0.0, 1.0, 0.0, 0.0),
|
|
||||||
simd_make_float4(0.0, 0.0, 1.0, 0.0),
|
|
||||||
simd_make_float4(0.0, 0.0, 0.0, 1.0)
|
|
||||||
};
|
|
||||||
|
|
||||||
matrix = simd_mul(mirrorTransform, rotationMatrix);
|
|
||||||
matrix = simd_mul(matrix, referenceMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
hrtf = [[HeadphoneFilter alloc] initWithImpulseFile:presetUrl forSampleRate:inputFormat.mSampleRate withInputChannels:inputFormat.mChannelsPerFrame withConfig:inputChannelConfig withMatrix:matrix];
|
|
||||||
if(!hrtf) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
outputFormat = inputFormat;
|
|
||||||
outputFormat.mChannelsPerFrame = 2;
|
|
||||||
outputFormat.mBytesPerFrame = sizeof(float) * outputFormat.mChannelsPerFrame;
|
|
||||||
outputFormat.mBytesPerPacket = outputFormat.mBytesPerFrame * outputFormat.mFramesPerPacket;
|
|
||||||
outputChannelConfig = AudioChannelSideLeft | AudioChannelSideRight;
|
|
||||||
|
|
||||||
resetFilter = NO;
|
|
||||||
|
|
||||||
needPrefill = [hrtf needPrefill];
|
|
||||||
} else {
|
|
||||||
if(lastEnableHeadTracking) {
|
|
||||||
lastEnableHeadTracking = NO;
|
|
||||||
unregisterMotionListener();
|
|
||||||
}
|
|
||||||
referenceMatrixSet = NO;
|
|
||||||
|
|
||||||
hrtf = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)fullShutdown {
|
|
||||||
hrtf = nil;
|
|
||||||
if(lastEnableHeadTracking) {
|
|
||||||
lastEnableHeadTracking = NO;
|
|
||||||
unregisterMotionListener();
|
|
||||||
}
|
|
||||||
resetFilter = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setup {
|
|
||||||
if(stopping)
|
|
||||||
return NO;
|
|
||||||
[self fullShutdown];
|
|
||||||
return [self fullInit];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cleanUp {
|
|
||||||
stopping = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[self fullShutdown];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resetBuffer {
|
|
||||||
paused = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[buffer reset];
|
|
||||||
[self fullShutdown];
|
|
||||||
paused = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)paused {
|
|
||||||
return paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)process {
|
|
||||||
while([self shouldContinue] == YES) {
|
|
||||||
if(paused || endOfStream) {
|
|
||||||
usleep(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
@autoreleasepool {
|
|
||||||
AudioChunk *chunk = nil;
|
|
||||||
chunk = [self convert];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
if([previousNode endOfStream] == YES) {
|
|
||||||
usleep(500);
|
|
||||||
endOfStream = YES;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(paused) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
usleep(500);
|
|
||||||
} else {
|
|
||||||
[self writeChunk:chunk];
|
|
||||||
chunk = nil;
|
|
||||||
}
|
|
||||||
if(resetFilter || (!enableHrtf && hrtf)) {
|
|
||||||
[self fullShutdown];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)convert {
|
|
||||||
if(stopping)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
processEntered = YES;
|
|
||||||
|
|
||||||
if(stopping || ([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) || [self shouldContinue] == NO) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(![self peekFormat:&inputFormat channelConfig:&inputChannelConfig]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!inputFormat.mSampleRate ||
|
|
||||||
!inputFormat.mBitsPerChannel ||
|
|
||||||
!inputFormat.mChannelsPerFrame ||
|
|
||||||
!inputFormat.mBytesPerFrame ||
|
|
||||||
!inputFormat.mFramesPerPacket ||
|
|
||||||
!inputFormat.mBytesPerPacket) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((enableHrtf && !hrtf) ||
|
|
||||||
memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 ||
|
|
||||||
inputChannelConfig != lastInputChannelConfig) {
|
|
||||||
lastInputFormat = inputFormat;
|
|
||||||
lastInputChannelConfig = inputChannelConfig;
|
|
||||||
[self fullShutdown];
|
|
||||||
if(enableHrtf && ![self setup]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!hrtf) {
|
|
||||||
processEntered = NO;
|
|
||||||
return [self readChunk:4096];
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioChunk *chunk = [self readChunkAsFloat32:4096];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rotationMatrixUpdated) {
|
|
||||||
rotationMatrixUpdated = NO;
|
|
||||||
simd_float4x4 mirrorTransform = {
|
|
||||||
simd_make_float4(-1.0, 0.0, 0.0, 0.0),
|
|
||||||
simd_make_float4(0.0, 1.0, 0.0, 0.0),
|
|
||||||
simd_make_float4(0.0, 0.0, 1.0, 0.0),
|
|
||||||
simd_make_float4(0.0, 0.0, 0.0, 1.0)
|
|
||||||
};
|
|
||||||
|
|
||||||
simd_float4x4 matrix = simd_mul(mirrorTransform, rotationMatrix);
|
|
||||||
matrix = simd_mul(matrix, referenceMatrix);
|
|
||||||
|
|
||||||
[hrtf reloadWithMatrix:matrix];
|
|
||||||
}
|
|
||||||
|
|
||||||
double streamTimestamp = [chunk streamTimestamp];
|
|
||||||
|
|
||||||
size_t frameCount = [chunk frameCount];
|
|
||||||
NSData *sampleData = [chunk removeSamples:frameCount];
|
|
||||||
|
|
||||||
if(needPrefill) {
|
|
||||||
size_t maxToUse = 4096 - needPrefill;
|
|
||||||
if(maxToUse > frameCount) {
|
|
||||||
maxToUse = frameCount;
|
|
||||||
}
|
|
||||||
size_t channels = inputFormat.mChannelsPerFrame;
|
|
||||||
memcpy(&prefillBuffer[needPrefill * channels], [sampleData bytes], maxToUse * sizeof(float) * channels);
|
|
||||||
lpc_extrapolate_bkwd(&prefillBuffer[needPrefill * channels], maxToUse, maxToUse, (int)channels, LPC_ORDER, needPrefill, &extrapolate_buffer, &extrapolate_buffer_size);
|
|
||||||
[hrtf process:&prefillBuffer[0] sampleCount:(int)needPrefill toBuffer:&outBuffer[0]];
|
|
||||||
needPrefill = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[hrtf process:(const float *)[sampleData bytes] sampleCount:(int)frameCount toBuffer:&outBuffer[0]];
|
|
||||||
|
|
||||||
AudioChunk *outputChunk = [[AudioChunk alloc] init];
|
|
||||||
[outputChunk setFormat:outputFormat];
|
|
||||||
if(outputChannelConfig) {
|
|
||||||
[outputChunk setChannelConfig:outputChannelConfig];
|
|
||||||
}
|
|
||||||
if([chunk isHDCD]) [outputChunk setHDCD];
|
|
||||||
[outputChunk setStreamTimestamp:streamTimestamp];
|
|
||||||
[outputChunk setStreamTimeRatio:[chunk streamTimeRatio]];
|
|
||||||
[outputChunk assignSamples:&outBuffer[0] frameCount:frameCount];
|
|
||||||
|
|
||||||
processEntered = NO;
|
|
||||||
return outputChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)reportMotion:(simd_float4x4)matrix {
|
|
||||||
rotationMatrix = matrix;
|
|
||||||
if(!referenceMatrixSet) {
|
|
||||||
referenceMatrix = simd_inverse(matrix);
|
|
||||||
referenceMatrixSet = YES;
|
|
||||||
}
|
|
||||||
rotationMatrixUpdated = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resetReferencePosition:(NSNotification *)notification {
|
|
||||||
referenceMatrixSet = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,32 +0,0 @@
|
||||||
//
|
|
||||||
// DSPRubberbandNode.h
|
|
||||||
// CogAudio
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/10/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef DSPRubberbandNode_h
|
|
||||||
#define DSPRubberbandNode_h
|
|
||||||
|
|
||||||
#import <CogAudio/DSPNode.h>
|
|
||||||
|
|
||||||
@interface DSPRubberbandNode : DSPNode {
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency;
|
|
||||||
|
|
||||||
- (BOOL)setup;
|
|
||||||
- (void)cleanUp;
|
|
||||||
|
|
||||||
- (void)resetBuffer;
|
|
||||||
|
|
||||||
- (BOOL)paused;
|
|
||||||
|
|
||||||
- (void)process;
|
|
||||||
- (AudioChunk * _Nullable)convert;
|
|
||||||
|
|
||||||
- (double)secondsBuffered;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* DSPRubberbandNode_h */
|
|
|
@ -1,560 +0,0 @@
|
||||||
//
|
|
||||||
// DSPRubberbandNode.m
|
|
||||||
// CogAudio Framework
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/10/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
#import <Accelerate/Accelerate.h>
|
|
||||||
|
|
||||||
#import "DSPRubberbandNode.h"
|
|
||||||
|
|
||||||
#import "Logging.h"
|
|
||||||
|
|
||||||
#import <rubberband/rubberband-c.h>
|
|
||||||
|
|
||||||
static void * kDSPRubberbandNodeContext = &kDSPRubberbandNodeContext;
|
|
||||||
|
|
||||||
@implementation DSPRubberbandNode {
|
|
||||||
BOOL enableRubberband;
|
|
||||||
|
|
||||||
RubberBandState ts;
|
|
||||||
RubberBandOptions tslastoptions, tsnewoptions;
|
|
||||||
size_t tschannels;
|
|
||||||
ssize_t blockSize, toDrop, samplesBuffered;
|
|
||||||
BOOL tsapplynewoptions;
|
|
||||||
BOOL tsrestartengine;
|
|
||||||
double tempo, pitch;
|
|
||||||
double lastTempo, lastPitch;
|
|
||||||
double countIn;
|
|
||||||
uint64_t countOut;
|
|
||||||
|
|
||||||
double streamTimestamp;
|
|
||||||
double streamTimeRatio;
|
|
||||||
BOOL isHDCD;
|
|
||||||
|
|
||||||
BOOL stopping, paused;
|
|
||||||
BOOL processEntered;
|
|
||||||
|
|
||||||
BOOL flushed;
|
|
||||||
|
|
||||||
BOOL observersapplied;
|
|
||||||
|
|
||||||
AudioStreamBasicDescription lastInputFormat;
|
|
||||||
AudioStreamBasicDescription inputFormat;
|
|
||||||
|
|
||||||
uint32_t lastInputChannelConfig, inputChannelConfig;
|
|
||||||
|
|
||||||
float *rsPtrs[32];
|
|
||||||
float rsInBuffer[4096 * 32];
|
|
||||||
float rsOutBuffer[65536 * 32];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency {
|
|
||||||
self = [super initWithController:c previous:p latency:latency];
|
|
||||||
if(self) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
enableRubberband = ![[defaults stringForKey:@"rubberbandEngine"] isEqualToString:@"disabled"];
|
|
||||||
|
|
||||||
pitch = [defaults doubleForKey:@"pitch"];
|
|
||||||
tempo = [defaults doubleForKey:@"tempo"];
|
|
||||||
|
|
||||||
lastPitch = pitch;
|
|
||||||
lastTempo = tempo;
|
|
||||||
|
|
||||||
[self addObservers];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
DLog(@"Rubber Band dealloc");
|
|
||||||
[self setShouldContinue:NO];
|
|
||||||
[self cleanUp];
|
|
||||||
[self removeObservers];
|
|
||||||
[super cleanUp];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addObservers {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.pitch" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.tempo" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.rubberbandEngine" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.rubberbandTransients" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.rubberbandDetector" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.rubberbandPhase" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.rubberbandWindow" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.rubberbandSmoothing" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.rubberbandFormant" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.rubberbandPitch" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.rubberbandChannels" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kDSPRubberbandNodeContext];
|
|
||||||
|
|
||||||
observersapplied = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObservers {
|
|
||||||
if(observersapplied) {
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.pitch" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.tempo" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.rubberbandEngine" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.rubberbandTransients" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.rubberbandDetector" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.rubberbandPhase" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.rubberbandWindow" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.rubberbandSmoothing" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.rubberbandFormant" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.rubberbandPitch" context:kDSPRubberbandNodeContext];
|
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.rubberbandChannels" context:kDSPRubberbandNodeContext];
|
|
||||||
observersapplied = NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
|
||||||
if(context != kDSPRubberbandNodeContext) {
|
|
||||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if([keyPath isEqualToString:@"values.pitch"] ||
|
|
||||||
[keyPath isEqualToString:@"values.tempo"]) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
pitch = [defaults doubleForKey:@"pitch"];
|
|
||||||
tempo = [defaults doubleForKey:@"tempo"];
|
|
||||||
tsapplynewoptions = YES;
|
|
||||||
} else if([[keyPath substringToIndex:17] isEqualToString:@"values.rubberband"]) {
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
enableRubberband = ![[defaults stringForKey:@"rubberbandEngine"] isEqualToString:@"disabled"];
|
|
||||||
if(enableRubberband && ts) {
|
|
||||||
RubberBandOptions options = [self getRubberbandOptions];
|
|
||||||
RubberBandOptions changed = options ^ tslastoptions;
|
|
||||||
if(changed) {
|
|
||||||
BOOL engineR3 = !!(options & RubberBandOptionEngineFiner);
|
|
||||||
// Options which require a restart of the engine
|
|
||||||
const RubberBandOptions mustRestart = RubberBandOptionEngineFaster | RubberBandOptionEngineFiner | RubberBandOptionWindowStandard | RubberBandOptionWindowShort | RubberBandOptionWindowLong | RubberBandOptionSmoothingOff | RubberBandOptionSmoothingOn | (engineR3 ? RubberBandOptionPitchHighSpeed | RubberBandOptionPitchHighQuality | RubberBandOptionPitchHighConsistency : 0) | RubberBandOptionChannelsApart | RubberBandOptionChannelsTogether;
|
|
||||||
if(changed & mustRestart) {
|
|
||||||
tsrestartengine = YES;
|
|
||||||
} else {
|
|
||||||
tsnewoptions = options;
|
|
||||||
tsapplynewoptions = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (RubberBandOptions)getRubberbandOptions {
|
|
||||||
RubberBandOptions options = RubberBandOptionProcessRealTime;
|
|
||||||
|
|
||||||
NSUserDefaults *defaults = [[NSUserDefaultsController sharedUserDefaultsController] defaults];
|
|
||||||
NSString *value = [defaults stringForKey:@"rubberbandEngine"];
|
|
||||||
BOOL engineR3 = NO;
|
|
||||||
if([value isEqualToString:@"faster"]) {
|
|
||||||
options |= RubberBandOptionEngineFaster;
|
|
||||||
} else if([value isEqualToString:@"finer"]) {
|
|
||||||
options |= RubberBandOptionEngineFiner;
|
|
||||||
engineR3 = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!engineR3) {
|
|
||||||
value = [defaults stringForKey:@"rubberbandTransients"];
|
|
||||||
if([value isEqualToString:@"crisp"]) {
|
|
||||||
options |= RubberBandOptionTransientsCrisp;
|
|
||||||
} else if([value isEqualToString:@"mixed"]) {
|
|
||||||
options |= RubberBandOptionTransientsMixed;
|
|
||||||
} else if([value isEqualToString:@"smooth"]) {
|
|
||||||
options |= RubberBandOptionTransientsSmooth;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = [defaults stringForKey:@"rubberbandDetector"];
|
|
||||||
if([value isEqualToString:@"compound"]) {
|
|
||||||
options |= RubberBandOptionDetectorCompound;
|
|
||||||
} else if([value isEqualToString:@"percussive"]) {
|
|
||||||
options |= RubberBandOptionDetectorPercussive;
|
|
||||||
} else if([value isEqualToString:@"soft"]) {
|
|
||||||
options |= RubberBandOptionDetectorSoft;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = [defaults stringForKey:@"rubberbandPhase"];
|
|
||||||
if([value isEqualToString:@"laminar"]) {
|
|
||||||
options |= RubberBandOptionPhaseLaminar;
|
|
||||||
} else if([value isEqualToString:@"independent"]) {
|
|
||||||
options |= RubberBandOptionPhaseIndependent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value = [defaults stringForKey:@"rubberbandWindow"];
|
|
||||||
if([value isEqualToString:@"standard"]) {
|
|
||||||
options |= RubberBandOptionWindowStandard;
|
|
||||||
} else if([value isEqualToString:@"short"]) {
|
|
||||||
options |= RubberBandOptionWindowShort;
|
|
||||||
} else if([value isEqualToString:@"long"]) {
|
|
||||||
if(engineR3) {
|
|
||||||
options |= RubberBandOptionWindowStandard;
|
|
||||||
} else {
|
|
||||||
options |= RubberBandOptionWindowLong;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!engineR3) {
|
|
||||||
value = [defaults stringForKey:@"rubberbandSmoothing"];
|
|
||||||
if([value isEqualToString:@"off"]) {
|
|
||||||
options |= RubberBandOptionSmoothingOff;
|
|
||||||
} else if([value isEqualToString:@"on"]) {
|
|
||||||
options |= RubberBandOptionSmoothingOn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value = [defaults stringForKey:@"rubberbandFormant"];
|
|
||||||
if([value isEqualToString:@"shifted"]) {
|
|
||||||
options |= RubberBandOptionFormantShifted;
|
|
||||||
} else if([value isEqualToString:@"preserved"]) {
|
|
||||||
options |= RubberBandOptionFormantPreserved;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = [defaults stringForKey:@"rubberbandPitch"];
|
|
||||||
if([value isEqualToString:@"highspeed"]) {
|
|
||||||
options |= RubberBandOptionPitchHighSpeed;
|
|
||||||
} else if([value isEqualToString:@"highquality"]) {
|
|
||||||
options |= RubberBandOptionPitchHighQuality;
|
|
||||||
} else if([value isEqualToString:@"highconsistency"]) {
|
|
||||||
options |= RubberBandOptionPitchHighConsistency;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = [defaults stringForKey:@"rubberbandChannels"];
|
|
||||||
if([value isEqualToString:@"apart"]) {
|
|
||||||
options |= RubberBandOptionChannelsApart;
|
|
||||||
} else if([value isEqualToString:@"together"]) {
|
|
||||||
options |= RubberBandOptionChannelsTogether;
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)fullInit {
|
|
||||||
RubberBandOptions options = [self getRubberbandOptions];
|
|
||||||
tslastoptions = options;
|
|
||||||
tschannels = inputFormat.mChannelsPerFrame;
|
|
||||||
ts = rubberband_new(inputFormat.mSampleRate, (int)tschannels, options, 1.0 / tempo, pitch);
|
|
||||||
if(!ts)
|
|
||||||
return NO;
|
|
||||||
|
|
||||||
blockSize = rubberband_get_process_size_limit(ts);
|
|
||||||
toDrop = rubberband_get_start_delay(ts);
|
|
||||||
samplesBuffered = 0;
|
|
||||||
if(blockSize > 4096)
|
|
||||||
blockSize = 4096;
|
|
||||||
rubberband_set_max_process_size(ts, (unsigned int)blockSize);
|
|
||||||
|
|
||||||
for(size_t i = 0; i < 32; ++i) {
|
|
||||||
rsPtrs[i] = &rsInBuffer[4096 * i];
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t toPad = rubberband_get_preferred_start_pad(ts);
|
|
||||||
if(toPad > 0) {
|
|
||||||
for(size_t i = 0; i < tschannels; ++i) {
|
|
||||||
memset(rsPtrs[i], 0, 4096 * sizeof(float));
|
|
||||||
}
|
|
||||||
while(toPad > 0) {
|
|
||||||
ssize_t p = toPad;
|
|
||||||
if(p > blockSize) p = blockSize;
|
|
||||||
rubberband_process(ts, (const float * const *)rsPtrs, (int)p, false);
|
|
||||||
toPad -= p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tsapplynewoptions = NO;
|
|
||||||
tsrestartengine = NO;
|
|
||||||
flushed = NO;
|
|
||||||
|
|
||||||
countIn = 0.0;
|
|
||||||
countOut = 0;
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)partialInit {
|
|
||||||
if(stopping || paused || !ts) return;
|
|
||||||
|
|
||||||
processEntered = YES;
|
|
||||||
|
|
||||||
RubberBandOptions changed = tslastoptions ^ tsnewoptions;
|
|
||||||
|
|
||||||
if(changed) {
|
|
||||||
tslastoptions = tsnewoptions;
|
|
||||||
|
|
||||||
BOOL engineR3 = !!(tsnewoptions & RubberBandOptionEngineFiner);
|
|
||||||
const RubberBandOptions transientsmask = RubberBandOptionTransientsCrisp | RubberBandOptionTransientsMixed | RubberBandOptionTransientsSmooth;
|
|
||||||
const RubberBandOptions detectormask = RubberBandOptionDetectorCompound | RubberBandOptionDetectorPercussive | RubberBandOptionDetectorSoft;
|
|
||||||
const RubberBandOptions phasemask = RubberBandOptionPhaseLaminar | RubberBandOptionPhaseIndependent;
|
|
||||||
const RubberBandOptions formantmask = RubberBandOptionFormantShifted | RubberBandOptionFormantPreserved;
|
|
||||||
const RubberBandOptions pitchmask = RubberBandOptionPitchHighSpeed | RubberBandOptionPitchHighQuality | RubberBandOptionPitchHighConsistency;
|
|
||||||
if(changed & transientsmask)
|
|
||||||
rubberband_set_transients_option(ts, tsnewoptions & transientsmask);
|
|
||||||
if(!engineR3) {
|
|
||||||
if(changed & detectormask)
|
|
||||||
rubberband_set_detector_option(ts, tsnewoptions & detectormask);
|
|
||||||
if(changed & phasemask)
|
|
||||||
rubberband_set_phase_option(ts, tsnewoptions & phasemask);
|
|
||||||
}
|
|
||||||
if(changed & formantmask)
|
|
||||||
rubberband_set_formant_option(ts, tsnewoptions & formantmask);
|
|
||||||
if(!engineR3 && (changed & pitchmask))
|
|
||||||
rubberband_set_pitch_option(ts, tsnewoptions & pitchmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fabs(pitch - lastPitch) > 1e-5 ||
|
|
||||||
fabs(tempo - lastTempo) > 1e-5) {
|
|
||||||
lastPitch = pitch;
|
|
||||||
lastTempo = tempo;
|
|
||||||
rubberband_set_pitch_scale(ts, pitch);
|
|
||||||
rubberband_set_time_ratio(ts, 1.0 / tempo);
|
|
||||||
}
|
|
||||||
|
|
||||||
tsapplynewoptions = NO;
|
|
||||||
|
|
||||||
processEntered = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)fullShutdown {
|
|
||||||
if(ts) {
|
|
||||||
rubberband_delete(ts);
|
|
||||||
ts = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setup {
|
|
||||||
if(stopping)
|
|
||||||
return NO;
|
|
||||||
[self fullShutdown];
|
|
||||||
return [self fullInit];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cleanUp {
|
|
||||||
stopping = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[self fullShutdown];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resetBuffer {
|
|
||||||
paused = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[buffer reset];
|
|
||||||
[self fullShutdown];
|
|
||||||
paused = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)paused {
|
|
||||||
return paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setPreviousNode:(id)p {
|
|
||||||
if(previousNode != p) {
|
|
||||||
paused = YES;
|
|
||||||
while(processEntered);
|
|
||||||
previousNode = p;
|
|
||||||
paused = NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setEndOfStream:(BOOL)e {
|
|
||||||
if(endOfStream && !e) {
|
|
||||||
[self fullShutdown];
|
|
||||||
}
|
|
||||||
[super setEndOfStream:e];
|
|
||||||
flushed = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)process {
|
|
||||||
while([self shouldContinue] == YES) {
|
|
||||||
if(paused || endOfStream) {
|
|
||||||
usleep(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
@autoreleasepool {
|
|
||||||
AudioChunk *chunk = nil;
|
|
||||||
chunk = [self convert];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
if(!ts) {
|
|
||||||
flushed = previousNode && [[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES;
|
|
||||||
}
|
|
||||||
if(flushed) {
|
|
||||||
usleep(500);
|
|
||||||
endOfStream = YES;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(paused) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
usleep(500);
|
|
||||||
} else {
|
|
||||||
[self writeChunk:chunk];
|
|
||||||
chunk = nil;
|
|
||||||
}
|
|
||||||
if(!enableRubberband && ts) {
|
|
||||||
[self fullShutdown];
|
|
||||||
} else if(tsrestartengine) {
|
|
||||||
[self fullShutdown];
|
|
||||||
} else if(tsapplynewoptions) {
|
|
||||||
[self partialInit];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)convert {
|
|
||||||
if(stopping)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
processEntered = YES;
|
|
||||||
|
|
||||||
if(stopping || flushed || !previousNode || ([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) || [self shouldContinue] == NO) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(![self peekFormat:&inputFormat channelConfig:&inputChannelConfig]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!inputFormat.mSampleRate ||
|
|
||||||
!inputFormat.mBitsPerChannel ||
|
|
||||||
!inputFormat.mChannelsPerFrame ||
|
|
||||||
!inputFormat.mBytesPerFrame ||
|
|
||||||
!inputFormat.mFramesPerPacket ||
|
|
||||||
!inputFormat.mBytesPerPacket) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((enableRubberband && !ts) ||
|
|
||||||
memcmp(&inputFormat, &lastInputFormat, sizeof(inputFormat)) != 0 ||
|
|
||||||
inputChannelConfig != lastInputChannelConfig) {
|
|
||||||
lastInputFormat = inputFormat;
|
|
||||||
lastInputChannelConfig = inputChannelConfig;
|
|
||||||
[self fullShutdown];
|
|
||||||
if(enableRubberband && ![self setup]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ts) {
|
|
||||||
processEntered = NO;
|
|
||||||
return [self readChunk:4096];
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t samplesToProcess = rubberband_get_samples_required(ts);
|
|
||||||
if(samplesToProcess > blockSize)
|
|
||||||
samplesToProcess = blockSize;
|
|
||||||
|
|
||||||
int channels = (int)(inputFormat.mChannelsPerFrame);
|
|
||||||
|
|
||||||
if(samplesToProcess > 0) {
|
|
||||||
AudioChunk *chunk = [self readAndMergeChunksAsFloat32:samplesToProcess];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
streamTimestamp = [chunk streamTimestamp];
|
|
||||||
streamTimeRatio = [chunk streamTimeRatio];
|
|
||||||
isHDCD = [chunk isHDCD];
|
|
||||||
|
|
||||||
size_t frameCount = [chunk frameCount];
|
|
||||||
countIn += ((double)frameCount) / tempo;
|
|
||||||
|
|
||||||
NSData *sampleData = [chunk removeSamples:frameCount];
|
|
||||||
|
|
||||||
for (size_t i = 0; i < channels; ++i) {
|
|
||||||
cblas_scopy((int)frameCount, ((const float *)[sampleData bytes]) + i, channels, rsPtrs[i], 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
flushed = [[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES;
|
|
||||||
|
|
||||||
int len = (int)frameCount;
|
|
||||||
|
|
||||||
rubberband_process(ts, (const float * const *)rsPtrs, len, flushed);
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t samplesAvailable;
|
|
||||||
while(!stopping && (samplesAvailable = rubberband_available(ts)) > 0) {
|
|
||||||
if(toDrop > 0) {
|
|
||||||
ssize_t blockDrop = toDrop;
|
|
||||||
if(blockDrop > samplesAvailable) blockDrop = samplesAvailable;
|
|
||||||
if(blockDrop > blockSize) blockDrop = blockSize;
|
|
||||||
rubberband_retrieve(ts, (float * const *)rsPtrs, (int)blockDrop);
|
|
||||||
toDrop -= blockDrop;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ssize_t maxAvailable = 65536 - samplesBuffered;
|
|
||||||
ssize_t samplesOut = samplesAvailable;
|
|
||||||
if(samplesOut > maxAvailable) {
|
|
||||||
samplesOut = maxAvailable;
|
|
||||||
if(samplesOut <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(samplesOut > blockSize) samplesOut = blockSize;
|
|
||||||
rubberband_retrieve(ts, (float * const *)rsPtrs, (int)samplesOut);
|
|
||||||
for(size_t i = 0; i < channels; ++i) {
|
|
||||||
cblas_scopy((int)samplesOut, rsPtrs[i], 1, &rsOutBuffer[samplesBuffered * channels + i], channels);
|
|
||||||
}
|
|
||||||
samplesBuffered += samplesOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(flushed) {
|
|
||||||
if(samplesBuffered > 0) {
|
|
||||||
ssize_t ideal = (ssize_t)floor(countIn + 0.5);
|
|
||||||
if(countOut + samplesBuffered > ideal) {
|
|
||||||
// Rubber Band does not account for flushing duration in real time mode
|
|
||||||
samplesBuffered = ideal - countOut;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioChunk *outputChunk = nil;
|
|
||||||
if(samplesBuffered > 0) {
|
|
||||||
outputChunk = [[AudioChunk alloc] init];
|
|
||||||
[outputChunk setFormat:inputFormat];
|
|
||||||
if(inputChannelConfig) {
|
|
||||||
[outputChunk setChannelConfig:inputChannelConfig];
|
|
||||||
}
|
|
||||||
if(isHDCD) [outputChunk setHDCD];
|
|
||||||
[outputChunk setStreamTimestamp:streamTimestamp];
|
|
||||||
[outputChunk setStreamTimeRatio:streamTimeRatio * tempo];
|
|
||||||
[outputChunk assignSamples:&rsOutBuffer[0] frameCount:samplesBuffered];
|
|
||||||
countOut += samplesBuffered;
|
|
||||||
samplesBuffered = 0;
|
|
||||||
double chunkDuration = [outputChunk duration];
|
|
||||||
streamTimestamp += chunkDuration * [outputChunk streamTimeRatio];
|
|
||||||
}
|
|
||||||
|
|
||||||
processEntered = NO;
|
|
||||||
return outputChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (double)secondsBuffered {
|
|
||||||
double rbBuffered = 0.0;
|
|
||||||
if(ts) {
|
|
||||||
// We don't use Rubber Band's latency function, because at least in Cog's case,
|
|
||||||
// by the time we call this function, and also, because it doesn't account for
|
|
||||||
// how much audio will be lopped off at the end of the process.
|
|
||||||
//
|
|
||||||
// Tested once, this tends to be close to zero when actually called.
|
|
||||||
rbBuffered = countIn - (double)(countOut);
|
|
||||||
if(rbBuffered < 0) {
|
|
||||||
rbBuffered = 0.0;
|
|
||||||
} else {
|
|
||||||
rbBuffered /= inputFormat.mSampleRate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [buffer listDuration] + rbBuffered;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -1,26 +0,0 @@
|
||||||
//
|
|
||||||
// DSPNode.h
|
|
||||||
// CogAudio
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/10/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef DSPNode_h
|
|
||||||
#define DSPNode_h
|
|
||||||
|
|
||||||
#import <CogAudio/Node.h>
|
|
||||||
|
|
||||||
@interface DSPNode : Node {
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency;
|
|
||||||
|
|
||||||
- (void)threadEntry:(id _Nullable)arg;
|
|
||||||
|
|
||||||
- (void)setShouldContinue:(BOOL)s;
|
|
||||||
|
|
||||||
- (double)secondsBuffered;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* DSPNode_h */
|
|
|
@ -1,76 +0,0 @@
|
||||||
//
|
|
||||||
// DSPNode.m
|
|
||||||
// CogAudio Framework
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/10/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
#import "DSPNode.h"
|
|
||||||
|
|
||||||
@implementation DSPNode {
|
|
||||||
BOOL threadTerminated;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency {
|
|
||||||
self = [super init];
|
|
||||||
if(self) {
|
|
||||||
buffer = [[ChunkList alloc] initWithMaximumDuration:latency];
|
|
||||||
|
|
||||||
writeSemaphore = [[Semaphore alloc] init];
|
|
||||||
readSemaphore = [[Semaphore alloc] init];
|
|
||||||
|
|
||||||
accessLock = [[NSLock alloc] init];
|
|
||||||
|
|
||||||
initialBufferFilled = NO;
|
|
||||||
|
|
||||||
controller = c;
|
|
||||||
endOfStream = NO;
|
|
||||||
shouldContinue = YES;
|
|
||||||
|
|
||||||
nodeChannelConfig = 0;
|
|
||||||
nodeLossless = NO;
|
|
||||||
|
|
||||||
durationPrebuffer = latency * 0.25;
|
|
||||||
|
|
||||||
inWrite = NO;
|
|
||||||
inPeek = NO;
|
|
||||||
inRead = NO;
|
|
||||||
inMerge = NO;
|
|
||||||
|
|
||||||
[self setPreviousNode:p];
|
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
[self initLogFiles];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DSP threads buffer for low latency, and therefore should have high priority
|
|
||||||
- (void)threadEntry:(id _Nullable)arg {
|
|
||||||
@autoreleasepool {
|
|
||||||
NSThread *currentThread = [NSThread currentThread];
|
|
||||||
[currentThread setThreadPriority:0.75];
|
|
||||||
[currentThread setQualityOfService:NSQualityOfServiceUserInitiated];
|
|
||||||
threadTerminated = NO;
|
|
||||||
[self process];
|
|
||||||
threadTerminated = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setShouldContinue:(BOOL)s {
|
|
||||||
BOOL currentShouldContinue = shouldContinue;
|
|
||||||
shouldContinue = s;
|
|
||||||
if(!currentShouldContinue && s && threadTerminated) {
|
|
||||||
[self launchThread];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (double)secondsBuffered {
|
|
||||||
return [buffer listDuration];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -283,11 +283,7 @@ static void *kDownmixProcessorContext = &kDownmixProcessorContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)process:(const void *)inBuffer frameCount:(size_t)frames output:(void *)outBuffer {
|
- (void)process:(const void *)inBuffer frameCount:(size_t)frames output:(void *)outBuffer {
|
||||||
if(inputFormat.mChannelsPerFrame == 2 && outConfig == AudioConfigStereo &&
|
if(inputFormat.mChannelsPerFrame > 2 && outConfig == AudioConfigStereo) {
|
||||||
inConfig == (AudioChannelSideLeft | AudioChannelSideRight)) {
|
|
||||||
// Workaround for HRTF output
|
|
||||||
memcpy(outBuffer, inBuffer, frames * outputFormat.mBytesPerPacket);
|
|
||||||
} else if(inputFormat.mChannelsPerFrame > 2 && outConfig == AudioConfigStereo) {
|
|
||||||
downmix_to_stereo((const float *)inBuffer, inputFormat.mChannelsPerFrame, inConfig, (float *)outBuffer, frames);
|
downmix_to_stereo((const float *)inBuffer, inputFormat.mChannelsPerFrame, inConfig, (float *)outBuffer, frames);
|
||||||
} else if(inputFormat.mChannelsPerFrame > 1 && outConfig == AudioConfigMono) {
|
} else if(inputFormat.mChannelsPerFrame > 1 && outConfig == AudioConfigMono) {
|
||||||
downmix_to_mono((const float *)inBuffer, inputFormat.mChannelsPerFrame, inConfig, (float *)outBuffer, frames);
|
downmix_to_mono((const float *)inBuffer, inputFormat.mChannelsPerFrame, inConfig, (float *)outBuffer, frames);
|
|
@ -12,9 +12,9 @@
|
||||||
#import <AudioUnit/AudioUnit.h>
|
#import <AudioUnit/AudioUnit.h>
|
||||||
#import <CoreAudio/AudioHardware.h>
|
#import <CoreAudio/AudioHardware.h>
|
||||||
|
|
||||||
#import <CogAudio/AudioDecoder.h>
|
#import "AudioDecoder.h"
|
||||||
#import <CogAudio/Node.h>
|
#import "Node.h"
|
||||||
#import <CogAudio/Plugin.h>
|
#import "Plugin.h"
|
||||||
|
|
||||||
#define INPUT_NODE_SEEK
|
#define INPUT_NODE_SEEK
|
||||||
|
|
||||||
|
@ -33,22 +33,20 @@
|
||||||
|
|
||||||
Semaphore *exitAtTheEndOfTheStream;
|
Semaphore *exitAtTheEndOfTheStream;
|
||||||
}
|
}
|
||||||
@property(readonly) Semaphore * _Nonnull exitAtTheEndOfTheStream;
|
@property(readonly) Semaphore *exitAtTheEndOfTheStream;
|
||||||
@property(readonly) BOOL threadExited;
|
@property(readonly) BOOL threadExited;
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p;
|
- (BOOL)openWithSource:(id<CogSource>)source;
|
||||||
|
- (BOOL)openWithDecoder:(id<CogDecoder>)d;
|
||||||
- (BOOL)openWithSource:(id<CogSource>_Nonnull)source;
|
|
||||||
- (BOOL)openWithDecoder:(id<CogDecoder>_Nonnull)d;
|
|
||||||
|
|
||||||
- (void)process;
|
- (void)process;
|
||||||
- (NSDictionary *_Nonnull)properties;
|
- (NSDictionary *)properties;
|
||||||
- (void)seek:(long)frame;
|
- (void)seek:(long)frame;
|
||||||
|
|
||||||
- (void)registerObservers;
|
- (void)registerObservers;
|
||||||
|
|
||||||
- (BOOL)setTrack:(NSURL *_Nonnull)track;
|
- (BOOL)setTrack:(NSURL *)track;
|
||||||
|
|
||||||
- (id<CogDecoder>_Nonnull)decoder;
|
- (id<CogDecoder>)decoder;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -159,12 +159,14 @@ static void *kInputNodeContext = &kInputNodeContext;
|
||||||
|
|
||||||
while([self shouldContinue] == YES && [self endOfStream] == NO) {
|
while([self shouldContinue] == YES && [self endOfStream] == NO) {
|
||||||
if(shouldSeek == YES) {
|
if(shouldSeek == YES) {
|
||||||
BufferChain *bufferChain = controller;
|
BufferChain *bufferChain = [[controller controller] bufferChain];
|
||||||
AudioPlayer *audioPlayer = [bufferChain controller];
|
ConverterNode *converter = [bufferChain converter];
|
||||||
OutputNode *outputNode = [audioPlayer output];
|
|
||||||
|
|
||||||
DLog(@"SEEKING! Resetting Buffer");
|
DLog(@"SEEKING! Resetting Buffer");
|
||||||
[outputNode resetBackwards];
|
|
||||||
|
// This resets the converter's buffer
|
||||||
|
[self resetBuffer];
|
||||||
|
[converter resetBuffer];
|
||||||
|
[converter inputFormatDidChange:[bufferChain inputFormat] inputConfig:[bufferChain inputConfig]];
|
||||||
|
|
||||||
DLog(@"Reset buffer!");
|
DLog(@"Reset buffer!");
|
||||||
|
|
||||||
|
@ -193,11 +195,6 @@ static void *kInputNodeContext = &kInputNodeContext;
|
||||||
chunk = nil;
|
chunk = nil;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(chunk) {
|
|
||||||
@autoreleasepool {
|
|
||||||
chunk = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DLog(@"End of stream? %@", [self properties]);
|
DLog(@"End of stream? %@", [self properties]);
|
||||||
|
|
||||||
endOfStream = YES;
|
endOfStream = YES;
|
||||||
|
@ -237,8 +234,7 @@ static void *kInputNodeContext = &kInputNodeContext;
|
||||||
seekFrame = frame;
|
seekFrame = frame;
|
||||||
shouldSeek = YES;
|
shouldSeek = YES;
|
||||||
DLog(@"Should seek!");
|
DLog(@"Should seek!");
|
||||||
[self resetBuffer];
|
[semaphore signal];
|
||||||
[writeSemaphore signal];
|
|
||||||
|
|
||||||
if(endOfStream) {
|
if(endOfStream) {
|
||||||
[exitAtTheEndOfTheStream signal];
|
[exitAtTheEndOfTheStream signal];
|
||||||
|
@ -272,7 +268,6 @@ static void *kInputNodeContext = &kInputNodeContext;
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
DLog(@"Input Node dealloc");
|
DLog(@"Input Node dealloc");
|
||||||
[self removeObservers];
|
[self removeObservers];
|
||||||
[super cleanUp];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *)properties {
|
- (NSDictionary *)properties {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// Copyright 2006 Vincent Spader. All rights reserved.
|
// Copyright 2006 Vincent Spader. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <CogAudio/ChunkList.h>
|
#import "ChunkList.h"
|
||||||
#import <CogAudio/CogSemaphore.h>
|
#import <CogAudio/CogSemaphore.h>
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@ -15,12 +15,9 @@
|
||||||
#define BUFFER_SIZE 1024 * 1024
|
#define BUFFER_SIZE 1024 * 1024
|
||||||
#define CHUNK_SIZE 16 * 1024
|
#define CHUNK_SIZE 16 * 1024
|
||||||
|
|
||||||
//#define LOG_CHAINS 1
|
|
||||||
|
|
||||||
@interface Node : NSObject {
|
@interface Node : NSObject {
|
||||||
ChunkList *buffer;
|
ChunkList *buffer;
|
||||||
Semaphore *writeSemaphore;
|
Semaphore *semaphore;
|
||||||
Semaphore *readSemaphore;
|
|
||||||
|
|
||||||
NSLock *accessLock;
|
NSLock *accessLock;
|
||||||
|
|
||||||
|
@ -29,11 +26,6 @@
|
||||||
|
|
||||||
BOOL shouldReset;
|
BOOL shouldReset;
|
||||||
|
|
||||||
BOOL inWrite;
|
|
||||||
BOOL inPeek;
|
|
||||||
BOOL inRead;
|
|
||||||
BOOL inMerge;
|
|
||||||
|
|
||||||
BOOL shouldContinue;
|
BOOL shouldContinue;
|
||||||
BOOL endOfStream; // All data is now in buffer
|
BOOL endOfStream; // All data is now in buffer
|
||||||
BOOL initialBufferFilled;
|
BOOL initialBufferFilled;
|
||||||
|
@ -43,32 +35,15 @@
|
||||||
BOOL nodeLossless;
|
BOOL nodeLossless;
|
||||||
|
|
||||||
double durationPrebuffer;
|
double durationPrebuffer;
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
NSFileHandle *logFileOut;
|
|
||||||
NSFileHandle *logFileIn;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p;
|
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p;
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
- (void)initLogFiles;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- (void)cleanUp;
|
|
||||||
|
|
||||||
- (BOOL)paused;
|
|
||||||
|
|
||||||
- (void)writeData:(const void *_Nonnull)ptr amount:(size_t)a;
|
- (void)writeData:(const void *_Nonnull)ptr amount:(size_t)a;
|
||||||
- (void)writeChunk:(AudioChunk *_Nonnull)chunk;
|
- (void)writeChunk:(AudioChunk *_Nonnull)chunk;
|
||||||
- (AudioChunk *_Nonnull)readChunk:(size_t)maxFrames;
|
- (AudioChunk *_Nonnull)readChunk:(size_t)maxFrames;
|
||||||
- (AudioChunk *_Nonnull)readChunkAsFloat32:(size_t)maxFrames;
|
- (AudioChunk *_Nonnull)readChunkAsFloat32:(size_t)maxFrames;
|
||||||
|
|
||||||
- (AudioChunk *_Nonnull)readAndMergeChunks:(size_t)maxFrames;
|
|
||||||
- (AudioChunk *_Nonnull)readAndMergeChunksAsFloat32:(size_t)maxFrames;
|
|
||||||
|
|
||||||
- (BOOL)peekFormat:(AudioStreamBasicDescription *_Nonnull)format channelConfig:(uint32_t *_Nonnull)config;
|
- (BOOL)peekFormat:(AudioStreamBasicDescription *_Nonnull)format channelConfig:(uint32_t *_Nonnull)config;
|
||||||
- (BOOL)peekTimestamp:(double *_Nonnull)timestamp timeRatio:(double *_Nonnull)timeRatio;
|
|
||||||
|
|
||||||
- (void)process; // Should be overwriten by subclass
|
- (void)process; // Should be overwriten by subclass
|
||||||
- (void)threadEntry:(id _Nullable)arg;
|
- (void)threadEntry:(id _Nullable)arg;
|
||||||
|
@ -77,7 +52,6 @@
|
||||||
|
|
||||||
- (void)setShouldReset:(BOOL)s;
|
- (void)setShouldReset:(BOOL)s;
|
||||||
- (BOOL)shouldReset;
|
- (BOOL)shouldReset;
|
||||||
- (void)resetBackwards;
|
|
||||||
|
|
||||||
- (void)setPreviousNode:(id _Nullable)p;
|
- (void)setPreviousNode:(id _Nullable)p;
|
||||||
- (id _Nullable)previousNode;
|
- (id _Nullable)previousNode;
|
||||||
|
@ -92,8 +66,7 @@
|
||||||
- (uint32_t)nodeChannelConfig;
|
- (uint32_t)nodeChannelConfig;
|
||||||
- (BOOL)nodeLossless;
|
- (BOOL)nodeLossless;
|
||||||
|
|
||||||
- (Semaphore *_Nonnull)writeSemaphore;
|
- (Semaphore *_Nonnull)semaphore;
|
||||||
- (Semaphore *_Nonnull)readSemaphore;
|
|
||||||
|
|
||||||
//-(void)resetBuffer;
|
//-(void)resetBuffer;
|
||||||
|
|
||||||
|
|
|
@ -17,39 +17,13 @@
|
||||||
|
|
||||||
#import <mach/mach_time.h>
|
#import <mach/mach_time.h>
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
#import "NSFileHandle+CreateFile.h"
|
|
||||||
|
|
||||||
static NSLock * _Node_lock = nil;
|
|
||||||
static uint64_t _Node_serial;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@implementation Node
|
@implementation Node
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
+ (void)initialize {
|
|
||||||
@synchronized (_Node_lock) {
|
|
||||||
if(!_Node_lock) {
|
|
||||||
_Node_lock = [[NSLock alloc] init];
|
|
||||||
_Node_serial = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)initLogFiles {
|
|
||||||
[_Node_lock lock];
|
|
||||||
logFileOut = [NSFileHandle fileHandleForWritingAtPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_output_%08lld.raw", [self className], _Node_serial++]] createFile:YES];
|
|
||||||
logFileIn = [NSFileHandle fileHandleForWritingAtPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_input_%08lld.raw", [self className], _Node_serial++]] createFile:YES];
|
|
||||||
[_Node_lock unlock];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- (id)initWithController:(id)c previous:(id)p {
|
- (id)initWithController:(id)c previous:(id)p {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
buffer = [[ChunkList alloc] initWithMaximumDuration:10.0];
|
buffer = [[ChunkList alloc] initWithMaximumDuration:10.0];
|
||||||
writeSemaphore = [[Semaphore alloc] init];
|
semaphore = [[Semaphore alloc] init];
|
||||||
readSemaphore = [[Semaphore alloc] init];
|
|
||||||
|
|
||||||
accessLock = [[NSLock alloc] init];
|
accessLock = [[NSLock alloc] init];
|
||||||
|
|
||||||
|
@ -64,36 +38,12 @@ static uint64_t _Node_serial;
|
||||||
|
|
||||||
durationPrebuffer = 2.0;
|
durationPrebuffer = 2.0;
|
||||||
|
|
||||||
inWrite = NO;
|
|
||||||
inPeek = NO;
|
|
||||||
inRead = NO;
|
|
||||||
inMerge = NO;
|
|
||||||
|
|
||||||
[self setPreviousNode:p];
|
[self setPreviousNode:p];
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
[self initLogFiles];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
[self cleanUp];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cleanUp {
|
|
||||||
[self setShouldContinue:NO];
|
|
||||||
while(inWrite || inPeek || inRead || inMerge) {
|
|
||||||
[writeSemaphore signal];
|
|
||||||
if(previousNode) {
|
|
||||||
[[previousNode readSemaphore] signal];
|
|
||||||
}
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioStreamBasicDescription)nodeFormat {
|
- (AudioStreamBasicDescription)nodeFormat {
|
||||||
return nodeFormat;
|
return nodeFormat;
|
||||||
}
|
}
|
||||||
|
@ -107,12 +57,6 @@ static uint64_t _Node_serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)writeData:(const void *)ptr amount:(size_t)amount {
|
- (void)writeData:(const void *)ptr amount:(size_t)amount {
|
||||||
inWrite = YES;
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
inWrite = NO;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock lock];
|
[accessLock lock];
|
||||||
|
|
||||||
AudioChunk *chunk = [[AudioChunk alloc] init];
|
AudioChunk *chunk = [[AudioChunk alloc] init];
|
||||||
|
@ -123,16 +67,11 @@ static uint64_t _Node_serial;
|
||||||
[chunk setLossless:nodeLossless];
|
[chunk setLossless:nodeLossless];
|
||||||
[chunk assignSamples:ptr frameCount:amount / nodeFormat.mBytesPerPacket];
|
[chunk assignSamples:ptr frameCount:amount / nodeFormat.mBytesPerPacket];
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
const double chunkDuration = [chunk duration];
|
||||||
if(logFileOut) {
|
|
||||||
[logFileOut writeData:[NSData dataWithBytes:ptr length:amount]];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
double durationList = [buffer listDuration];
|
double durationList = [buffer listDuration];
|
||||||
double durationLeft = [buffer maxDuration] - durationList;
|
double durationLeft = [buffer maxDuration] - durationList;
|
||||||
|
|
||||||
if(shouldContinue == YES && durationList >= durationPrebuffer) {
|
if(shouldContinue == YES && durationList > durationPrebuffer) {
|
||||||
if(initialBufferFilled == NO) {
|
if(initialBufferFilled == NO) {
|
||||||
initialBufferFilled = YES;
|
initialBufferFilled = YES;
|
||||||
if([controller respondsToSelector:@selector(initialBufferFilled:)])
|
if([controller respondsToSelector:@selector(initialBufferFilled:)])
|
||||||
|
@ -140,44 +79,29 @@ static uint64_t _Node_serial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while(shouldContinue == YES && ![self paused] && durationLeft < 0.0) {
|
while(shouldContinue == YES && chunkDuration > durationLeft) {
|
||||||
if(durationLeft < 0.0 || shouldReset) {
|
if(durationLeft < chunkDuration || shouldReset) {
|
||||||
[accessLock unlock];
|
[accessLock unlock];
|
||||||
[writeSemaphore timedWait:2000];
|
[semaphore wait];
|
||||||
[accessLock lock];
|
[accessLock lock];
|
||||||
}
|
}
|
||||||
|
|
||||||
durationLeft = [buffer maxDuration] - [buffer listDuration];
|
durationLeft = [buffer maxDuration] - [buffer listDuration];
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL doSignal = NO;
|
|
||||||
if([chunk frameCount]) {
|
|
||||||
[buffer addChunk:chunk];
|
[buffer addChunk:chunk];
|
||||||
doSignal = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock unlock];
|
[accessLock unlock];
|
||||||
|
|
||||||
if(doSignal) {
|
|
||||||
[readSemaphore signal];
|
|
||||||
}
|
|
||||||
|
|
||||||
inWrite = NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)writeChunk:(AudioChunk *)chunk {
|
- (void)writeChunk:(AudioChunk *)chunk {
|
||||||
inWrite = YES;
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
inWrite = NO;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock lock];
|
[accessLock lock];
|
||||||
|
|
||||||
|
const double chunkDuration = [chunk duration];
|
||||||
double durationList = [buffer listDuration];
|
double durationList = [buffer listDuration];
|
||||||
double durationLeft = [buffer maxDuration] - durationList;
|
double durationLeft = [buffer maxDuration] - durationList;
|
||||||
|
|
||||||
if(shouldContinue == YES && durationList >= durationPrebuffer) {
|
if(shouldContinue == YES && durationList > durationPrebuffer) {
|
||||||
if(initialBufferFilled == NO) {
|
if(initialBufferFilled == NO) {
|
||||||
initialBufferFilled = YES;
|
initialBufferFilled = YES;
|
||||||
if([controller respondsToSelector:@selector(initialBufferFilled:)])
|
if([controller respondsToSelector:@selector(initialBufferFilled:)])
|
||||||
|
@ -185,42 +109,19 @@ static uint64_t _Node_serial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while(shouldContinue == YES && ![self paused] && durationLeft < 0.0) {
|
while(shouldContinue == YES && chunkDuration > durationLeft) {
|
||||||
if(previousNode && [previousNode shouldContinue] == NO) {
|
if(durationLeft < chunkDuration || shouldReset) {
|
||||||
shouldContinue = NO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(durationLeft < 0.0 || shouldReset) {
|
|
||||||
[accessLock unlock];
|
[accessLock unlock];
|
||||||
[writeSemaphore timedWait:2000];
|
[semaphore wait];
|
||||||
[accessLock lock];
|
[accessLock lock];
|
||||||
}
|
}
|
||||||
|
|
||||||
durationLeft = [buffer maxDuration] - [buffer listDuration];
|
durationLeft = [buffer maxDuration] - [buffer listDuration];
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL doSignal = NO;
|
|
||||||
if([chunk frameCount]) {
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
if(logFileOut) {
|
|
||||||
AudioChunk *chunkCopy = [chunk copy];
|
|
||||||
size_t frameCount = [chunkCopy frameCount];
|
|
||||||
NSData *chunkData = [chunkCopy removeSamples:frameCount];
|
|
||||||
[logFileOut writeData:chunkData];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
[buffer addChunk:chunk];
|
[buffer addChunk:chunk];
|
||||||
doSignal = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock unlock];
|
[accessLock unlock];
|
||||||
|
|
||||||
if(doSignal) {
|
|
||||||
[readSemaphore signal];
|
|
||||||
}
|
|
||||||
|
|
||||||
inWrite = NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be overwriten by subclass.
|
// Should be overwriten by subclass.
|
||||||
|
@ -234,110 +135,21 @@ static uint64_t _Node_serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)peekFormat:(nonnull AudioStreamBasicDescription *)format channelConfig:(nonnull uint32_t *)config {
|
- (BOOL)peekFormat:(nonnull AudioStreamBasicDescription *)format channelConfig:(nonnull uint32_t *)config {
|
||||||
inPeek = YES;
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
inPeek = NO;
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock lock];
|
[accessLock lock];
|
||||||
|
|
||||||
while(shouldContinue && ![self paused] &&
|
|
||||||
[[previousNode buffer] isEmpty] && [previousNode endOfStream] == NO) {
|
|
||||||
[accessLock unlock];
|
|
||||||
[writeSemaphore signal];
|
|
||||||
[[previousNode readSemaphore] timedWait:2000];
|
|
||||||
[accessLock lock];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
[accessLock unlock];
|
|
||||||
inPeek = NO;
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) {
|
|
||||||
[accessLock unlock];
|
|
||||||
inPeek = NO;
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL ret = [[previousNode buffer] peekFormat:format channelConfig:config];
|
BOOL ret = [[previousNode buffer] peekFormat:format channelConfig:config];
|
||||||
|
|
||||||
[accessLock unlock];
|
[accessLock unlock];
|
||||||
|
|
||||||
inPeek = NO;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)peekTimestamp:(double *_Nonnull)timestamp timeRatio:(double *_Nonnull)timeRatio {
|
|
||||||
inPeek = YES;
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
inPeek = NO;
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock lock];
|
|
||||||
|
|
||||||
while(shouldContinue && ![self paused] &&
|
|
||||||
[[previousNode buffer] isEmpty] && [previousNode endOfStream] == NO) {
|
|
||||||
[accessLock unlock];
|
|
||||||
[writeSemaphore signal];
|
|
||||||
[[previousNode readSemaphore] timedWait:2000];
|
|
||||||
[accessLock lock];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
[accessLock unlock];
|
|
||||||
inPeek = NO;
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) {
|
|
||||||
[accessLock unlock];
|
|
||||||
inPeek = NO;
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL ret = [[previousNode buffer] peekTimestamp:timestamp timeRatio:timeRatio];
|
|
||||||
|
|
||||||
[accessLock unlock];
|
|
||||||
|
|
||||||
inPeek = NO;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AudioChunk *)readChunk:(size_t)maxFrames {
|
- (AudioChunk *)readChunk:(size_t)maxFrames {
|
||||||
inRead = YES;
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
inRead = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock lock];
|
[accessLock lock];
|
||||||
|
|
||||||
while(shouldContinue && ![self paused] &&
|
|
||||||
[[previousNode buffer] isEmpty] && [previousNode endOfStream] == NO) {
|
|
||||||
[accessLock unlock];
|
|
||||||
[writeSemaphore signal];
|
|
||||||
[[previousNode readSemaphore] timedWait:2000];
|
|
||||||
[accessLock lock];
|
|
||||||
if([previousNode shouldReset] == YES) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
[accessLock unlock];
|
|
||||||
inRead = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
if([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) {
|
if([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) {
|
||||||
|
endOfStream = YES;
|
||||||
[accessLock unlock];
|
[accessLock unlock];
|
||||||
inRead = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
return [[AudioChunk alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +161,7 @@ static uint64_t _Node_serial;
|
||||||
shouldReset = YES;
|
shouldReset = YES;
|
||||||
[previousNode setShouldReset:NO];
|
[previousNode setShouldReset:NO];
|
||||||
|
|
||||||
[[previousNode writeSemaphore] signal];
|
[[previousNode semaphore] signal];
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioChunk *ret;
|
AudioChunk *ret;
|
||||||
|
@ -361,52 +173,18 @@ static uint64_t _Node_serial;
|
||||||
[accessLock unlock];
|
[accessLock unlock];
|
||||||
|
|
||||||
if([ret frameCount]) {
|
if([ret frameCount]) {
|
||||||
[[previousNode writeSemaphore] signal];
|
[[previousNode semaphore] signal];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
if(logFileIn) {
|
|
||||||
AudioChunk *chunkCopy = [ret copy];
|
|
||||||
size_t frameCount = [chunkCopy frameCount];
|
|
||||||
NSData *chunkData = [chunkCopy removeSamples:frameCount];
|
|
||||||
[logFileIn writeData:chunkData];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inRead = NO;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AudioChunk *)readChunkAsFloat32:(size_t)maxFrames {
|
- (AudioChunk *)readChunkAsFloat32:(size_t)maxFrames {
|
||||||
inRead = YES;
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
inRead = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock lock];
|
[accessLock lock];
|
||||||
|
|
||||||
while(shouldContinue && ![self paused] &&
|
|
||||||
[[previousNode buffer] isEmpty] && [previousNode endOfStream] == NO) {
|
|
||||||
[accessLock unlock];
|
|
||||||
[writeSemaphore signal];
|
|
||||||
[[previousNode readSemaphore] timedWait:2000];
|
|
||||||
[accessLock lock];
|
|
||||||
if([previousNode shouldReset] == YES) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
[accessLock unlock];
|
|
||||||
inRead = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
if([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) {
|
if([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) {
|
||||||
|
endOfStream = YES;
|
||||||
[accessLock unlock];
|
[accessLock unlock];
|
||||||
inRead = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
return [[AudioChunk alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +196,7 @@ static uint64_t _Node_serial;
|
||||||
shouldReset = YES;
|
shouldReset = YES;
|
||||||
[previousNode setShouldReset:NO];
|
[previousNode setShouldReset:NO];
|
||||||
|
|
||||||
[[previousNode writeSemaphore] signal];
|
[[previousNode semaphore] signal];
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioChunk *ret;
|
AudioChunk *ret;
|
||||||
|
@ -430,134 +208,9 @@ static uint64_t _Node_serial;
|
||||||
[accessLock unlock];
|
[accessLock unlock];
|
||||||
|
|
||||||
if([ret frameCount]) {
|
if([ret frameCount]) {
|
||||||
[[previousNode writeSemaphore] signal];
|
[[previousNode semaphore] signal];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
if(logFileIn) {
|
|
||||||
AudioChunk *chunkCopy = [ret copy];
|
|
||||||
size_t frameCount = [chunkCopy frameCount];
|
|
||||||
NSData *chunkData = [chunkCopy removeSamples:frameCount];
|
|
||||||
[logFileIn writeData:chunkData];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inRead = NO;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)readAndMergeChunks:(size_t)maxFrames {
|
|
||||||
inMerge = YES;
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
inMerge = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock lock];
|
|
||||||
|
|
||||||
if([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) {
|
|
||||||
[accessLock unlock];
|
|
||||||
inMerge = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioChunk *ret;
|
|
||||||
|
|
||||||
@autoreleasepool {
|
|
||||||
ret = [[previousNode buffer] removeAndMergeSamples:maxFrames callBlock:^BOOL{
|
|
||||||
if([previousNode shouldReset] == YES) {
|
|
||||||
@autoreleasepool {
|
|
||||||
[buffer reset];
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldReset = YES;
|
|
||||||
[previousNode setShouldReset:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock unlock];
|
|
||||||
[[previousNode writeSemaphore] signal];
|
|
||||||
[[previousNode readSemaphore] timedWait:2000];
|
|
||||||
[accessLock lock];
|
|
||||||
|
|
||||||
return !shouldContinue || [self paused] || ([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES);
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock unlock];
|
|
||||||
|
|
||||||
if([ret frameCount]) {
|
|
||||||
[[previousNode writeSemaphore] signal];
|
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
if(logFileIn) {
|
|
||||||
AudioChunk *chunkCopy = [ret copy];
|
|
||||||
size_t frameCount = [chunkCopy frameCount];
|
|
||||||
NSData *chunkData = [chunkCopy removeSamples:frameCount];
|
|
||||||
[logFileIn writeData:chunkData];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inMerge = NO;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)readAndMergeChunksAsFloat32:(size_t)maxFrames {
|
|
||||||
inMerge = YES;
|
|
||||||
if(!shouldContinue || [self paused]) {
|
|
||||||
inMerge = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock lock];
|
|
||||||
|
|
||||||
if([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES) {
|
|
||||||
[accessLock unlock];
|
|
||||||
inMerge = NO;
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioChunk *ret;
|
|
||||||
|
|
||||||
@autoreleasepool {
|
|
||||||
ret = [[previousNode buffer] removeAndMergeSamplesAsFloat32:maxFrames callBlock:^BOOL{
|
|
||||||
if([previousNode shouldReset] == YES) {
|
|
||||||
@autoreleasepool {
|
|
||||||
[buffer reset];
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldReset = YES;
|
|
||||||
[previousNode setShouldReset:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock unlock];
|
|
||||||
[[previousNode writeSemaphore] signal];
|
|
||||||
[[previousNode readSemaphore] timedWait:2000];
|
|
||||||
[accessLock lock];
|
|
||||||
|
|
||||||
return !shouldContinue || [self paused] || ([[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES);
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
[accessLock unlock];
|
|
||||||
|
|
||||||
if([ret frameCount]) {
|
|
||||||
[[previousNode writeSemaphore] signal];
|
|
||||||
|
|
||||||
#ifdef LOG_CHAINS
|
|
||||||
if(logFileIn) {
|
|
||||||
AudioChunk *chunkCopy = [ret copy];
|
|
||||||
size_t frameCount = [chunkCopy frameCount];
|
|
||||||
NSData *chunkData = [chunkCopy removeSamples:frameCount];
|
|
||||||
[logFileIn writeData:chunkData];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inMerge = NO;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,31 +249,8 @@ static uint64_t _Node_serial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)lockedResetBuffer {
|
- (Semaphore *)semaphore {
|
||||||
@autoreleasepool {
|
return semaphore;
|
||||||
[buffer reset];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)unlockedResetBuffer {
|
|
||||||
@autoreleasepool {
|
|
||||||
[accessLock lock];
|
|
||||||
[buffer reset];
|
|
||||||
[accessLock unlock];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementations should override
|
|
||||||
- (BOOL)paused {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (Semaphore *)writeSemaphore {
|
|
||||||
return writeSemaphore;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (Semaphore *)readSemaphore {
|
|
||||||
return readSemaphore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)endOfStream {
|
- (BOOL)endOfStream {
|
||||||
|
@ -643,23 +273,4 @@ static uint64_t _Node_serial;
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset everything in the chain
|
|
||||||
- (void)resetBackwards {
|
|
||||||
[accessLock lock];
|
|
||||||
if(buffer) {
|
|
||||||
[self lockedResetBuffer];
|
|
||||||
[writeSemaphore signal];
|
|
||||||
[readSemaphore signal];
|
|
||||||
}
|
|
||||||
Node *node = previousNode;
|
|
||||||
while(node) {
|
|
||||||
[node unlockedResetBuffer];
|
|
||||||
[node setShouldReset:YES];
|
|
||||||
[[node writeSemaphore] signal];
|
|
||||||
[[node readSemaphore] signal];
|
|
||||||
node = [node previousNode];
|
|
||||||
}
|
|
||||||
[accessLock unlock];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
#import <AudioUnit/AudioUnit.h>
|
#import <AudioUnit/AudioUnit.h>
|
||||||
#import <CoreAudio/AudioHardware.h>
|
#import <CoreAudio/AudioHardware.h>
|
||||||
|
|
||||||
#import <CogAudio/Node.h>
|
#import "Node.h"
|
||||||
#import <CogAudio/OutputCoreAudio.h>
|
#import "OutputCoreAudio.h"
|
||||||
|
|
||||||
@interface OutputNode : Node {
|
@interface OutputNode : Node {
|
||||||
AudioStreamBasicDescription format;
|
AudioStreamBasicDescription format;
|
||||||
|
@ -28,32 +28,30 @@
|
||||||
BOOL intervalReported;
|
BOOL intervalReported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)beginEqualizer:(AudioUnit)eq;
|
||||||
|
- (void)refreshEqualizer:(AudioUnit)eq;
|
||||||
|
- (void)endEqualizer:(AudioUnit)eq;
|
||||||
|
|
||||||
- (double)amountPlayed;
|
- (double)amountPlayed;
|
||||||
- (double)amountPlayedInterval;
|
- (double)amountPlayedInterval;
|
||||||
|
|
||||||
- (void)incrementAmountPlayed:(double)seconds;
|
- (void)incrementAmountPlayed:(double)seconds;
|
||||||
- (void)setAmountPlayed:(double)seconds;
|
|
||||||
- (void)resetAmountPlayed;
|
- (void)resetAmountPlayed;
|
||||||
- (void)resetAmountPlayedInterval;
|
- (void)resetAmountPlayedInterval;
|
||||||
|
|
||||||
- (BOOL)selectNextBuffer;
|
- (BOOL)selectNextBuffer;
|
||||||
- (void)endOfInputPlayed;
|
- (void)endOfInputPlayed;
|
||||||
|
|
||||||
- (BOOL)endOfStream;
|
|
||||||
|
|
||||||
- (BOOL)chainQueueHasTracks;
|
- (BOOL)chainQueueHasTracks;
|
||||||
|
|
||||||
- (double)secondsBuffered;
|
- (double)secondsBuffered;
|
||||||
|
|
||||||
- (void)setup;
|
- (void)setup;
|
||||||
- (void)setupWithInterval:(BOOL)resumeInterval;
|
|
||||||
- (void)process;
|
- (void)process;
|
||||||
- (void)close;
|
- (void)close;
|
||||||
- (void)seek:(double)time;
|
- (void)seek:(double)time;
|
||||||
|
|
||||||
- (void)fadeOut;
|
- (double)latency;
|
||||||
- (void)fadeOutBackground;
|
|
||||||
- (void)fadeIn;
|
|
||||||
|
|
||||||
- (AudioChunk *)readChunk:(size_t)amount;
|
- (AudioChunk *)readChunk:(size_t)amount;
|
||||||
|
|
||||||
|
@ -61,10 +59,6 @@
|
||||||
- (AudioStreamBasicDescription)format;
|
- (AudioStreamBasicDescription)format;
|
||||||
- (uint32_t)config;
|
- (uint32_t)config;
|
||||||
|
|
||||||
- (AudioStreamBasicDescription)deviceFormat;
|
|
||||||
- (uint32_t)deviceChannelConfig;
|
|
||||||
|
|
||||||
- (double)volume;
|
|
||||||
- (void)setVolume:(double)v;
|
- (void)setVolume:(double)v;
|
||||||
|
|
||||||
- (void)setShouldContinue:(BOOL)s;
|
- (void)setShouldContinue:(BOOL)s;
|
||||||
|
@ -80,12 +74,4 @@
|
||||||
|
|
||||||
- (void)restartPlaybackAtCurrentPosition;
|
- (void)restartPlaybackAtCurrentPosition;
|
||||||
|
|
||||||
- (double)latency;
|
|
||||||
- (double)getVisLatency;
|
|
||||||
- (double)getTotalLatency;
|
|
||||||
|
|
||||||
- (id)controller;
|
|
||||||
|
|
||||||
- (id)downmix;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -11,70 +11,21 @@
|
||||||
#import "BufferChain.h"
|
#import "BufferChain.h"
|
||||||
#import "OutputCoreAudio.h"
|
#import "OutputCoreAudio.h"
|
||||||
|
|
||||||
#import "DSPRubberbandNode.h"
|
|
||||||
#import "DSPFSurroundNode.h"
|
|
||||||
#import "DSPHRTFNode.h"
|
|
||||||
#import "DSPEqualizerNode.h"
|
|
||||||
#import "VisualizationNode.h"
|
|
||||||
#import "DSPDownmixNode.h"
|
|
||||||
|
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
|
|
||||||
@implementation OutputNode {
|
@implementation OutputNode
|
||||||
BOOL DSPsLaunched;
|
|
||||||
|
|
||||||
Node *previousInput;
|
|
||||||
|
|
||||||
DSPRubberbandNode *rubberbandNode;
|
|
||||||
DSPFSurroundNode *fsurroundNode;
|
|
||||||
DSPHRTFNode *hrtfNode;
|
|
||||||
DSPEqualizerNode *equalizerNode;
|
|
||||||
DSPDownmixNode *downmixNode;
|
|
||||||
VisualizationNode *visualizationNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setup {
|
- (void)setup {
|
||||||
[self setupWithInterval:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setupWithInterval:(BOOL)resumeInterval {
|
|
||||||
if(!resumeInterval) {
|
|
||||||
amountPlayed = 0.0;
|
amountPlayed = 0.0;
|
||||||
amountPlayedInterval = 0.0;
|
amountPlayedInterval = 0.0;
|
||||||
intervalReported = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
paused = YES;
|
paused = YES;
|
||||||
started = NO;
|
started = NO;
|
||||||
|
intervalReported = NO;
|
||||||
|
|
||||||
output = [[OutputCoreAudio alloc] initWithController:self];
|
output = [[OutputCoreAudio alloc] initWithController:self];
|
||||||
|
|
||||||
[output setup];
|
[output setup];
|
||||||
|
|
||||||
if(!DSPsLaunched) {
|
|
||||||
rubberbandNode = [[DSPRubberbandNode alloc] initWithController:self previous:nil latency:0.1];
|
|
||||||
if(!rubberbandNode) return;
|
|
||||||
fsurroundNode = [[DSPFSurroundNode alloc] initWithController:self previous:rubberbandNode latency:0.03];
|
|
||||||
if(!fsurroundNode) return;
|
|
||||||
equalizerNode = [[DSPEqualizerNode alloc] initWithController:self previous:fsurroundNode latency:0.03];
|
|
||||||
if(!equalizerNode) return;
|
|
||||||
hrtfNode = [[DSPHRTFNode alloc] initWithController:self previous:equalizerNode latency:0.03];
|
|
||||||
if(!hrtfNode) return;
|
|
||||||
downmixNode = [[DSPDownmixNode alloc] initWithController:self previous:hrtfNode latency:0.03];
|
|
||||||
if(!downmixNode) return;
|
|
||||||
|
|
||||||
// Approximately double the chunk size for Vis at 44100Hz
|
|
||||||
visualizationNode = [[VisualizationNode alloc] initWithController:self previous:downmixNode latency:8192.0 / 44100.0];
|
|
||||||
if(!visualizationNode) return;
|
|
||||||
|
|
||||||
[self setPreviousNode:visualizationNode];
|
|
||||||
|
|
||||||
DSPsLaunched = YES;
|
|
||||||
|
|
||||||
[self launchDSPs];
|
|
||||||
|
|
||||||
previousInput = nil;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)seek:(double)time {
|
- (void)seek:(double)time {
|
||||||
|
@ -99,19 +50,6 @@
|
||||||
[output resume];
|
[output resume];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)fadeOut {
|
|
||||||
[output fadeOut];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)fadeOutBackground {
|
|
||||||
[output fadeOutBackground];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)fadeIn {
|
|
||||||
[self reconnectInputAndReplumb];
|
|
||||||
[output fadeIn];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)incrementAmountPlayed:(double)seconds {
|
- (void)incrementAmountPlayed:(double)seconds {
|
||||||
amountPlayed += seconds;
|
amountPlayed += seconds;
|
||||||
amountPlayedInterval += seconds;
|
amountPlayedInterval += seconds;
|
||||||
|
@ -121,15 +59,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAmountPlayed:(double)seconds {
|
|
||||||
double delta = seconds - amountPlayed;
|
|
||||||
if(delta > 0.0 && delta < 5.0) {
|
|
||||||
[self incrementAmountPlayed:delta];
|
|
||||||
} else if(delta) {
|
|
||||||
amountPlayed = seconds;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resetAmountPlayed {
|
- (void)resetAmountPlayed {
|
||||||
amountPlayed = 0;
|
amountPlayed = 0;
|
||||||
}
|
}
|
||||||
|
@ -140,11 +69,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)selectNextBuffer {
|
- (BOOL)selectNextBuffer {
|
||||||
BOOL ret = [controller selectNextBuffer];
|
return [controller selectNextBuffer];
|
||||||
if(!ret) {
|
|
||||||
[self reconnectInputAndReplumb];
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)endOfInputPlayed {
|
- (void)endOfInputPlayed {
|
||||||
|
@ -164,74 +89,25 @@
|
||||||
return [buffer listDuration];
|
return [buffer listDuration];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)DSPs {
|
|
||||||
if(DSPsLaunched) {
|
|
||||||
return @[rubberbandNode, fsurroundNode, equalizerNode, hrtfNode, downmixNode, visualizationNode];
|
|
||||||
} else {
|
|
||||||
return @[];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)reconnectInput {
|
|
||||||
Node *finalNode = nil;
|
|
||||||
if(rubberbandNode) {
|
|
||||||
finalNode = [[controller bufferChain] finalNode];
|
|
||||||
[rubberbandNode setPreviousNode:finalNode];
|
|
||||||
}
|
|
||||||
|
|
||||||
return !!finalNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)reconnectInputAndReplumb {
|
|
||||||
Node *finalNode = nil;
|
|
||||||
if(rubberbandNode) {
|
|
||||||
finalNode = [[controller bufferChain] finalNode];
|
|
||||||
[rubberbandNode setPreviousNode:finalNode];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSArray *DSPs = [self DSPs];
|
|
||||||
|
|
||||||
for (Node *node in DSPs) {
|
|
||||||
[node setEndOfStream:NO];
|
|
||||||
[node setShouldContinue:YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)launchDSPs {
|
|
||||||
NSArray *DSPs = [self DSPs];
|
|
||||||
|
|
||||||
for (Node *node in DSPs) {
|
|
||||||
[node launchThread];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (AudioChunk *)readChunk:(size_t)amount {
|
- (AudioChunk *)readChunk:(size_t)amount {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
if([self reconnectInput]) {
|
[self setPreviousNode:[[controller bufferChain] finalNode]];
|
||||||
|
|
||||||
AudioChunk *ret = [super readChunk:amount];
|
AudioChunk *ret = [super readChunk:amount];
|
||||||
|
|
||||||
if((!ret || ![ret frameCount]) && [previousNode endOfStream]) {
|
/* if (n == 0) {
|
||||||
endOfStream = YES;
|
DLog(@"Output Buffer dry!");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
|
||||||
return [[AudioChunk alloc] init];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)peekFormat:(nonnull AudioStreamBasicDescription *)format channelConfig:(nonnull uint32_t *)config {
|
- (BOOL)peekFormat:(nonnull AudioStreamBasicDescription *)format channelConfig:(nonnull uint32_t *)config {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
if([self reconnectInput]) {
|
[self setPreviousNode:[[controller bufferChain] finalNode]];
|
||||||
BOOL ret = [super peekFormat:format channelConfig:config];
|
|
||||||
if(!ret && [previousNode endOfStream]) {
|
return [super peekFormat:format channelConfig:config];
|
||||||
endOfStream = YES;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
} else {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,59 +127,30 @@
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AudioStreamBasicDescription)deviceFormat {
|
|
||||||
return [output deviceFormat];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (uint32_t)deviceChannelConfig {
|
|
||||||
return [output deviceChannelConfig];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setFormat:(AudioStreamBasicDescription *)f channelConfig:(uint32_t)channelConfig {
|
- (void)setFormat:(AudioStreamBasicDescription *)f channelConfig:(uint32_t)channelConfig {
|
||||||
if(!shouldContinue) return;
|
|
||||||
|
|
||||||
format = *f;
|
format = *f;
|
||||||
config = channelConfig;
|
config = channelConfig;
|
||||||
// Calculate a ratio and add to double(seconds) instead, as format may change
|
// Calculate a ratio and add to double(seconds) instead, as format may change
|
||||||
// double oldSampleRatio = sampleRatio;
|
// double oldSampleRatio = sampleRatio;
|
||||||
AudioPlayer *audioPlayer = controller;
|
BufferChain *bufferChain = [controller bufferChain];
|
||||||
BufferChain *bufferChain = [audioPlayer bufferChain];
|
|
||||||
if(bufferChain) {
|
if(bufferChain) {
|
||||||
ConverterNode *converter = [bufferChain converter];
|
ConverterNode *converter = [bufferChain converter];
|
||||||
AudioStreamBasicDescription outputFormat;
|
|
||||||
uint32_t outputChannelConfig;
|
|
||||||
BOOL formatChanged = NO;
|
|
||||||
if(converter) {
|
|
||||||
AudioStreamBasicDescription converterFormat = [converter nodeFormat];
|
|
||||||
if(memcmp(&converterFormat, &format, sizeof(converterFormat)) != 0) {
|
|
||||||
formatChanged = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(downmixNode && output && !formatChanged) {
|
|
||||||
outputFormat = [output deviceFormat];
|
|
||||||
outputChannelConfig = [output deviceChannelConfig];
|
|
||||||
AudioStreamBasicDescription currentOutputFormat = [downmixNode nodeFormat];
|
|
||||||
uint32_t currentOutputChannelConfig = [downmixNode nodeChannelConfig];
|
|
||||||
if(memcmp(¤tOutputFormat, &outputFormat, sizeof(currentOutputFormat)) != 0 ||
|
|
||||||
currentOutputChannelConfig != outputChannelConfig) {
|
|
||||||
formatChanged = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(formatChanged) {
|
|
||||||
InputNode *inputNode = [bufferChain inputNode];
|
|
||||||
if(converter) {
|
if(converter) {
|
||||||
|
// This clears the resampler buffer, but not the input buffer
|
||||||
|
// We also have to jump the play position ahead accounting for
|
||||||
|
// the data we are flushing
|
||||||
|
amountPlayed += [[converter buffer] listDuration];
|
||||||
|
|
||||||
|
AudioStreamBasicDescription inf = [bufferChain inputFormat];
|
||||||
|
uint32_t config = [bufferChain inputConfig];
|
||||||
|
|
||||||
|
format.mChannelsPerFrame = inf.mChannelsPerFrame;
|
||||||
|
format.mBytesPerFrame = ((inf.mBitsPerChannel + 7) / 8) * format.mChannelsPerFrame;
|
||||||
|
format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket;
|
||||||
|
channelConfig = config;
|
||||||
|
|
||||||
[converter setOutputFormat:format];
|
[converter setOutputFormat:format];
|
||||||
}
|
[converter inputFormatDidChange:[bufferChain inputFormat] inputConfig:[bufferChain inputConfig]];
|
||||||
if(downmixNode && output) {
|
|
||||||
[downmixNode setOutputFormat:[output deviceFormat] withChannelConfig:[output deviceChannelConfig]];
|
|
||||||
}
|
|
||||||
if(inputNode) {
|
|
||||||
AudioStreamBasicDescription inputFormat = [inputNode nodeFormat];
|
|
||||||
if(converter) {
|
|
||||||
[converter inputFormatDidChange:inputFormat inputConfig:[inputNode nodeChannelConfig]];
|
|
||||||
}
|
|
||||||
[inputNode seek:(long)(amountPlayed * inputFormat.mSampleRate)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -311,24 +158,6 @@
|
||||||
- (void)close {
|
- (void)close {
|
||||||
[output stop];
|
[output stop];
|
||||||
output = nil;
|
output = nil;
|
||||||
if(DSPsLaunched) {
|
|
||||||
NSArray *DSPs = [self DSPs];
|
|
||||||
for(Node *node in DSPs) {
|
|
||||||
[node setShouldContinue:NO];
|
|
||||||
}
|
|
||||||
previousNode = nil;
|
|
||||||
visualizationNode = nil;
|
|
||||||
downmixNode = nil;
|
|
||||||
hrtfNode = nil;
|
|
||||||
fsurroundNode = nil;
|
|
||||||
rubberbandNode = nil;
|
|
||||||
previousInput = nil;
|
|
||||||
DSPsLaunched = NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (double)volume {
|
|
||||||
return [output volume];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setVolume:(double)v {
|
- (void)setVolume:(double)v {
|
||||||
|
@ -338,10 +167,6 @@
|
||||||
- (void)setShouldContinue:(BOOL)s {
|
- (void)setShouldContinue:(BOOL)s {
|
||||||
[super setShouldContinue:s];
|
[super setShouldContinue:s];
|
||||||
|
|
||||||
NSArray *DSPs = [self DSPs];
|
|
||||||
for(Node *node in DSPs) {
|
|
||||||
[node setShouldContinue:s];
|
|
||||||
}
|
|
||||||
// if (s == NO)
|
// if (s == NO)
|
||||||
// [output stop];
|
// [output stop];
|
||||||
}
|
}
|
||||||
|
@ -354,6 +179,18 @@
|
||||||
return paused;
|
return paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)beginEqualizer:(AudioUnit)eq {
|
||||||
|
[controller beginEqualizer:eq];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)refreshEqualizer:(AudioUnit)eq {
|
||||||
|
[controller refreshEqualizer:eq];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)endEqualizer:(AudioUnit)eq {
|
||||||
|
[controller endEqualizer:eq];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)sustainHDCD {
|
- (void)sustainHDCD {
|
||||||
[output sustainHDCD];
|
[output sustainHDCD];
|
||||||
}
|
}
|
||||||
|
@ -363,28 +200,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (double)latency {
|
- (double)latency {
|
||||||
double latency = 0.0;
|
return [output latency];
|
||||||
NSArray *DSPs = [self DSPs];
|
|
||||||
for(Node *node in DSPs) {
|
|
||||||
latency += [node secondsBuffered];
|
|
||||||
}
|
|
||||||
return [output latency] + latency;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (double)getVisLatency {
|
|
||||||
return [output latency] + [visualizationNode secondsBuffered];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (double)getTotalLatency {
|
|
||||||
return [[controller bufferChain] secondsBuffered] + [self latency];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)controller {
|
|
||||||
return controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)downmix {
|
|
||||||
return downmixNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
//
|
|
||||||
// VisualizationNode.h
|
|
||||||
// CogAudio
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/12/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VisualizationNode_h
|
|
||||||
#define VisualizationNode_h
|
|
||||||
|
|
||||||
#import <CogAudio/Node.h>
|
|
||||||
|
|
||||||
@interface VisualizationNode : Node {
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency;
|
|
||||||
|
|
||||||
- (void)threadEntry:(id _Nullable)arg;
|
|
||||||
|
|
||||||
- (BOOL)setup;
|
|
||||||
- (void)cleanUp;
|
|
||||||
|
|
||||||
- (BOOL)paused;
|
|
||||||
|
|
||||||
- (void)resetBuffer;
|
|
||||||
|
|
||||||
- (void)setShouldContinue:(BOOL)s;
|
|
||||||
|
|
||||||
- (void)process;
|
|
||||||
|
|
||||||
- (double)secondsBuffered;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* VisualizationNode_h */
|
|
|
@ -1,273 +0,0 @@
|
||||||
//
|
|
||||||
// VisualizationNode.m
|
|
||||||
// CogAudio Framework
|
|
||||||
//
|
|
||||||
// Created by Christopher Snowhill on 2/12/25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
#import <AudioToolbox/AudioToolbox.h>
|
|
||||||
|
|
||||||
#import <Accelerate/Accelerate.h>
|
|
||||||
|
|
||||||
#import "Downmix.h"
|
|
||||||
|
|
||||||
#import <CogAudio/VisualizationController.h>
|
|
||||||
|
|
||||||
#import "BufferChain.h"
|
|
||||||
|
|
||||||
#import "Logging.h"
|
|
||||||
|
|
||||||
#import "rsstate.h"
|
|
||||||
|
|
||||||
#import "VisualizationNode.h"
|
|
||||||
|
|
||||||
@implementation VisualizationNode {
|
|
||||||
void *rs;
|
|
||||||
double lastVisRate;
|
|
||||||
|
|
||||||
BOOL processEntered;
|
|
||||||
BOOL stopping;
|
|
||||||
BOOL paused;
|
|
||||||
BOOL threadTerminated;
|
|
||||||
|
|
||||||
AudioStreamBasicDescription inputFormat;
|
|
||||||
AudioStreamBasicDescription visFormat; // Mono format for vis
|
|
||||||
|
|
||||||
uint32_t inputChannelConfig;
|
|
||||||
uint32_t visChannelConfig;
|
|
||||||
|
|
||||||
size_t resamplerRemain;
|
|
||||||
|
|
||||||
DownmixProcessor *downmixer;
|
|
||||||
|
|
||||||
VisualizationController *visController;
|
|
||||||
|
|
||||||
float visAudio[512];
|
|
||||||
float resamplerInput[8192];
|
|
||||||
float visTemp[8192];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p latency:(double)latency {
|
|
||||||
self = [super init];
|
|
||||||
if(self) {
|
|
||||||
buffer = [[ChunkList alloc] initWithMaximumDuration:latency];
|
|
||||||
|
|
||||||
writeSemaphore = [[Semaphore alloc] init];
|
|
||||||
readSemaphore = [[Semaphore alloc] init];
|
|
||||||
|
|
||||||
accessLock = [[NSLock alloc] init];
|
|
||||||
|
|
||||||
initialBufferFilled = NO;
|
|
||||||
|
|
||||||
controller = c;
|
|
||||||
endOfStream = NO;
|
|
||||||
shouldContinue = YES;
|
|
||||||
|
|
||||||
nodeChannelConfig = 0;
|
|
||||||
nodeLossless = NO;
|
|
||||||
|
|
||||||
durationPrebuffer = latency * 0.25;
|
|
||||||
|
|
||||||
visController = [VisualizationController sharedController];
|
|
||||||
|
|
||||||
inWrite = NO;
|
|
||||||
inPeek = NO;
|
|
||||||
inRead = NO;
|
|
||||||
inMerge = NO;
|
|
||||||
|
|
||||||
[self setPreviousNode:p];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc {
|
|
||||||
DLog(@"Visualization node dealloc");
|
|
||||||
[self setShouldContinue:NO];
|
|
||||||
[self cleanUp];
|
|
||||||
[super cleanUp];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visualization thread should be fairly high priority, too
|
|
||||||
- (void)threadEntry:(id _Nullable)arg {
|
|
||||||
@autoreleasepool {
|
|
||||||
NSThread *currentThread = [NSThread currentThread];
|
|
||||||
[currentThread setThreadPriority:0.75];
|
|
||||||
[currentThread setQualityOfService:NSQualityOfServiceUserInitiated];
|
|
||||||
threadTerminated = NO;
|
|
||||||
[self process];
|
|
||||||
threadTerminated = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)resetBuffer {
|
|
||||||
paused = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[buffer reset];
|
|
||||||
[self fullShutdown];
|
|
||||||
paused = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (double)secondsBuffered {
|
|
||||||
return [buffer listDuration];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setShouldContinue:(BOOL)s {
|
|
||||||
BOOL currentShouldContinue = shouldContinue;
|
|
||||||
shouldContinue = s;
|
|
||||||
if(!currentShouldContinue && s && threadTerminated) {
|
|
||||||
[self launchThread];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setup {
|
|
||||||
if(fabs(inputFormat.mSampleRate - 44100.0) > 1e-6) {
|
|
||||||
rs = rsstate_new(1, inputFormat.mSampleRate, 44100.0);
|
|
||||||
if(!rs) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
resamplerRemain = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
visFormat = inputFormat;
|
|
||||||
visFormat.mChannelsPerFrame = 1;
|
|
||||||
visFormat.mBytesPerFrame = sizeof(float);
|
|
||||||
visFormat.mBytesPerPacket = visFormat.mBytesPerFrame * visFormat.mFramesPerPacket;
|
|
||||||
visChannelConfig = AudioChannelFrontCenter;
|
|
||||||
|
|
||||||
downmixer = [[DownmixProcessor alloc] initWithInputFormat:inputFormat inputConfig:inputChannelConfig andOutputFormat:visFormat outputConfig:visChannelConfig];
|
|
||||||
if(!downmixer) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cleanUp {
|
|
||||||
stopping = YES;
|
|
||||||
while(processEntered) {
|
|
||||||
usleep(500);
|
|
||||||
}
|
|
||||||
[self fullShutdown];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)fullShutdown {
|
|
||||||
if(rs) {
|
|
||||||
rsstate_delete(rs);
|
|
||||||
rs = NULL;
|
|
||||||
}
|
|
||||||
downmixer = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)paused {
|
|
||||||
return paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)process {
|
|
||||||
while([self shouldContinue] == YES) {
|
|
||||||
if(paused || endOfStream) {
|
|
||||||
usleep(500);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
@autoreleasepool {
|
|
||||||
AudioChunk *chunk = nil;
|
|
||||||
chunk = [self readAndMergeChunksAsFloat32:512];
|
|
||||||
if(!chunk || ![chunk frameCount]) {
|
|
||||||
if([previousNode endOfStream] == YES) {
|
|
||||||
usleep(500);
|
|
||||||
endOfStream = YES;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
[self processVis:[chunk copy]];
|
|
||||||
[self writeChunk:chunk];
|
|
||||||
chunk = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endOfStream = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)postVisPCM:(const float *)visTemp amount:(size_t)samples {
|
|
||||||
[visController postVisPCM:visTemp amount:(int)samples];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)processVis:(AudioChunk *)chunk {
|
|
||||||
processEntered = YES;
|
|
||||||
|
|
||||||
if(paused) {
|
|
||||||
processEntered = NO;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioStreamBasicDescription format = [chunk format];
|
|
||||||
uint32_t channelConfig = [chunk channelConfig];
|
|
||||||
|
|
||||||
[visController postSampleRate:44100.0];
|
|
||||||
|
|
||||||
if(!rs || !downmixer ||
|
|
||||||
memcmp(&format, &inputFormat, sizeof(format)) != 0 ||
|
|
||||||
channelConfig != inputChannelConfig) {
|
|
||||||
if(rs) {
|
|
||||||
while(!stopping) {
|
|
||||||
int samplesFlushed;
|
|
||||||
samplesFlushed = (int)rsstate_flush(rs, &visTemp[0], 8192);
|
|
||||||
if(samplesFlushed > 1) {
|
|
||||||
[self postVisPCM:visTemp amount:samplesFlushed];
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[self fullShutdown];
|
|
||||||
inputFormat = format;
|
|
||||||
inputChannelConfig = channelConfig;
|
|
||||||
if(![self setup]) {
|
|
||||||
processEntered = NO;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t frameCount = [chunk frameCount];
|
|
||||||
NSData *sampleData = [chunk removeSamples:frameCount];
|
|
||||||
|
|
||||||
[downmixer process:[sampleData bytes] frameCount:frameCount output:&visAudio[0]];
|
|
||||||
|
|
||||||
if(rs) {
|
|
||||||
int samplesProcessed;
|
|
||||||
size_t totalDone = 0;
|
|
||||||
size_t inDone = 0;
|
|
||||||
size_t visFrameCount = frameCount;
|
|
||||||
do {
|
|
||||||
if(stopping) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int visTodo = (int)MIN(visFrameCount, resamplerRemain + visFrameCount - 8192);
|
|
||||||
if(visTodo) {
|
|
||||||
cblas_scopy(visTodo, &visAudio[0], 1, &resamplerInput[resamplerRemain], 1);
|
|
||||||
}
|
|
||||||
visTodo += resamplerRemain;
|
|
||||||
resamplerRemain = 0;
|
|
||||||
samplesProcessed = (int)rsstate_resample(rs, &resamplerInput[0], visTodo, &inDone, &visTemp[0], 8192);
|
|
||||||
resamplerRemain = (int)(visTodo - inDone);
|
|
||||||
if(resamplerRemain && inDone) {
|
|
||||||
memmove(&resamplerInput[0], &resamplerInput[inDone], resamplerRemain * sizeof(float));
|
|
||||||
}
|
|
||||||
if(samplesProcessed) {
|
|
||||||
[self postVisPCM:&visTemp[0] amount:samplesProcessed];
|
|
||||||
}
|
|
||||||
totalDone += inDone;
|
|
||||||
visFrameCount -= inDone;
|
|
||||||
} while(samplesProcessed && visFrameCount);
|
|
||||||
} else {
|
|
||||||
[self postVisPCM:&visAudio[0] amount:frameCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
processEntered = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -47,72 +47,57 @@
|
||||||
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */ = {isa = PBXBuildFile; fileRef = 8328995527CB51B700D7F028 /* SHA256Digest.h */; };
|
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */ = {isa = PBXBuildFile; fileRef = 8328995527CB51B700D7F028 /* SHA256Digest.h */; };
|
||||||
8328995827CB51B700D7F028 /* SHA256Digest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8328995627CB51B700D7F028 /* SHA256Digest.m */; };
|
8328995827CB51B700D7F028 /* SHA256Digest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8328995627CB51B700D7F028 /* SHA256Digest.m */; };
|
||||||
8328995A27CB51C900D7F028 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8328995927CB51C900D7F028 /* Security.framework */; };
|
8328995A27CB51C900D7F028 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8328995927CB51C900D7F028 /* Security.framework */; };
|
||||||
833442422D6EFA6700C51D38 /* VisualizationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 833442402D6EFA6700C51D38 /* VisualizationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
833442432D6EFA6700C51D38 /* VisualizationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 833442412D6EFA6700C51D38 /* VisualizationController.m */; };
|
|
||||||
833738EA2D5EA52500278628 /* DSPDownmixNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 833738E92D5EA52500278628 /* DSPDownmixNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
833738EC2D5EA53500278628 /* DSPDownmixNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 833738EB2D5EA53500278628 /* DSPDownmixNode.m */; };
|
|
||||||
833738EF2D5EA5B700278628 /* Downmix.m in Sources */ = {isa = PBXBuildFile; fileRef = 833738EE2D5EA5B700278628 /* Downmix.m */; };
|
|
||||||
833738F02D5EA5B700278628 /* Downmix.h in Headers */ = {isa = PBXBuildFile; fileRef = 833738ED2D5EA5B700278628 /* Downmix.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */; };
|
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */; };
|
||||||
8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */; };
|
8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */; };
|
||||||
834A41A9287A90AB00EB9D9B /* freesurround_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 834A41A5287A90AB00EB9D9B /* freesurround_decoder.h */; };
|
834A41A9287A90AB00EB9D9B /* freesurround_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 834A41A5287A90AB00EB9D9B /* freesurround_decoder.h */; };
|
||||||
834A41AA287A90AB00EB9D9B /* freesurround_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 834A41A6287A90AB00EB9D9B /* freesurround_decoder.cpp */; };
|
834A41AA287A90AB00EB9D9B /* freesurround_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 834A41A6287A90AB00EB9D9B /* freesurround_decoder.cpp */; };
|
||||||
834A41AB287A90AB00EB9D9B /* channelmaps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 834A41A7287A90AB00EB9D9B /* channelmaps.cpp */; };
|
834A41AB287A90AB00EB9D9B /* channelmaps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 834A41A7287A90AB00EB9D9B /* channelmaps.cpp */; };
|
||||||
834A41AC287A90AB00EB9D9B /* channelmaps.h in Headers */ = {isa = PBXBuildFile; fileRef = 834A41A8287A90AB00EB9D9B /* channelmaps.h */; };
|
834A41AC287A90AB00EB9D9B /* channelmaps.h in Headers */ = {isa = PBXBuildFile; fileRef = 834A41A8287A90AB00EB9D9B /* channelmaps.h */; };
|
||||||
834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 834FD4EA27AF8F380063BC83 /* AudioChunk.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
834A41AF287ABD6F00EB9D9B /* FSurroundFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 834A41AD287ABD6F00EB9D9B /* FSurroundFilter.h */; };
|
||||||
|
834A41B0287ABD6F00EB9D9B /* FSurroundFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 834A41AE287ABD6F00EB9D9B /* FSurroundFilter.mm */; };
|
||||||
|
834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 834FD4EA27AF8F380063BC83 /* AudioChunk.h */; };
|
||||||
834FD4ED27AF91220063BC83 /* AudioChunk.m in Sources */ = {isa = PBXBuildFile; fileRef = 834FD4EC27AF91220063BC83 /* AudioChunk.m */; };
|
834FD4ED27AF91220063BC83 /* AudioChunk.m in Sources */ = {isa = PBXBuildFile; fileRef = 834FD4EC27AF91220063BC83 /* AudioChunk.m */; };
|
||||||
834FD4F027AF93680063BC83 /* ChunkList.h in Headers */ = {isa = PBXBuildFile; fileRef = 834FD4EE27AF93680063BC83 /* ChunkList.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
834FD4F027AF93680063BC83 /* ChunkList.h in Headers */ = {isa = PBXBuildFile; fileRef = 834FD4EE27AF93680063BC83 /* ChunkList.h */; };
|
||||||
834FD4F127AF93680063BC83 /* ChunkList.m in Sources */ = {isa = PBXBuildFile; fileRef = 834FD4EF27AF93680063BC83 /* ChunkList.m */; };
|
834FD4F127AF93680063BC83 /* ChunkList.m in Sources */ = {isa = PBXBuildFile; fileRef = 834FD4EF27AF93680063BC83 /* ChunkList.m */; };
|
||||||
|
83504165286447DA006B32CC /* Downmix.h in Headers */ = {isa = PBXBuildFile; fileRef = 83504163286447DA006B32CC /* Downmix.h */; };
|
||||||
|
83504166286447DA006B32CC /* Downmix.m in Sources */ = {isa = PBXBuildFile; fileRef = 83504164286447DA006B32CC /* Downmix.m */; };
|
||||||
8350416D28646149006B32CC /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8350416C28646149006B32CC /* CoreMedia.framework */; };
|
8350416D28646149006B32CC /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8350416C28646149006B32CC /* CoreMedia.framework */; };
|
||||||
835C88B1279811A500E28EAE /* hdcd_decode2.h in Headers */ = {isa = PBXBuildFile; fileRef = 835C88AF279811A500E28EAE /* hdcd_decode2.h */; };
|
835C88B1279811A500E28EAE /* hdcd_decode2.h in Headers */ = {isa = PBXBuildFile; fileRef = 835C88AF279811A500E28EAE /* hdcd_decode2.h */; };
|
||||||
835C88B2279811A500E28EAE /* hdcd_decode2.c in Sources */ = {isa = PBXBuildFile; fileRef = 835C88B0279811A500E28EAE /* hdcd_decode2.c */; };
|
835C88B2279811A500E28EAE /* hdcd_decode2.c in Sources */ = {isa = PBXBuildFile; fileRef = 835C88B0279811A500E28EAE /* hdcd_decode2.c */; };
|
||||||
835DD2672ACAF1D90057E319 /* OutputCoreAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 835DD2652ACAF1D90057E319 /* OutputCoreAudio.m */; };
|
835DD2672ACAF1D90057E319 /* OutputCoreAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 835DD2652ACAF1D90057E319 /* OutputCoreAudio.m */; };
|
||||||
835DD2682ACAF1D90057E319 /* OutputCoreAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 835DD2662ACAF1D90057E319 /* OutputCoreAudio.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
835DD2682ACAF1D90057E319 /* OutputCoreAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 835DD2662ACAF1D90057E319 /* OutputCoreAudio.h */; };
|
||||||
|
835DD2702ACAF5AD0057E319 /* LICENSE.LGPL in Resources */ = {isa = PBXBuildFile; fileRef = 835DD26B2ACAF5AD0057E319 /* LICENSE.LGPL */; };
|
||||||
|
835DD2712ACAF5AD0057E319 /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 835DD26C2ACAF5AD0057E319 /* License.txt */; };
|
||||||
835DD2722ACAF5AD0057E319 /* lpc.h in Headers */ = {isa = PBXBuildFile; fileRef = 835DD26D2ACAF5AD0057E319 /* lpc.h */; };
|
835DD2722ACAF5AD0057E319 /* lpc.h in Headers */ = {isa = PBXBuildFile; fileRef = 835DD26D2ACAF5AD0057E319 /* lpc.h */; };
|
||||||
835DD2732ACAF5AD0057E319 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 835DD26E2ACAF5AD0057E319 /* util.h */; };
|
835DD2732ACAF5AD0057E319 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 835DD26E2ACAF5AD0057E319 /* util.h */; };
|
||||||
835DD2742ACAF5AD0057E319 /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 835DD26F2ACAF5AD0057E319 /* lpc.c */; };
|
835DD2742ACAF5AD0057E319 /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 835DD26F2ACAF5AD0057E319 /* lpc.c */; };
|
||||||
835FAC5E27BCA14D00BA8562 /* BadSampleCleaner.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FAC5C27BCA14D00BA8562 /* BadSampleCleaner.h */; };
|
835FAC5E27BCA14D00BA8562 /* BadSampleCleaner.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FAC5C27BCA14D00BA8562 /* BadSampleCleaner.h */; };
|
||||||
835FAC5F27BCA14D00BA8562 /* BadSampleCleaner.m in Sources */ = {isa = PBXBuildFile; fileRef = 835FAC5D27BCA14D00BA8562 /* BadSampleCleaner.m */; };
|
835FAC5F27BCA14D00BA8562 /* BadSampleCleaner.m in Sources */ = {isa = PBXBuildFile; fileRef = 835FAC5D27BCA14D00BA8562 /* BadSampleCleaner.m */; };
|
||||||
|
836DF618298F6F5F00CD0580 /* libsoxr.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 836DF615298F6E8900CD0580 /* libsoxr.0.dylib */; };
|
||||||
83725A9027AA16C90003F694 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83725A7B27AA0D8A0003F694 /* Accelerate.framework */; };
|
83725A9027AA16C90003F694 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83725A7B27AA0D8A0003F694 /* Accelerate.framework */; };
|
||||||
83725A9127AA16D50003F694 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83725A7C27AA0D8E0003F694 /* AVFoundation.framework */; };
|
83725A9127AA16D50003F694 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83725A7C27AA0D8E0003F694 /* AVFoundation.framework */; };
|
||||||
8377C64C27B8C51500E8BC0F /* fft_accelerate.c in Sources */ = {isa = PBXBuildFile; fileRef = 8377C64B27B8C51500E8BC0F /* fft_accelerate.c */; };
|
8377C64C27B8C51500E8BC0F /* fft_accelerate.c in Sources */ = {isa = PBXBuildFile; fileRef = 8377C64B27B8C51500E8BC0F /* fft_accelerate.c */; };
|
||||||
8377C64E27B8C54400E8BC0F /* fft.h in Headers */ = {isa = PBXBuildFile; fileRef = 8377C64D27B8C54400E8BC0F /* fft.h */; };
|
8377C64E27B8C54400E8BC0F /* fft.h in Headers */ = {isa = PBXBuildFile; fileRef = 8377C64D27B8C54400E8BC0F /* fft.h */; };
|
||||||
8384912718080FF100E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384912618080FF100E7332D /* Logging.h */; };
|
8384912718080FF100E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384912618080FF100E7332D /* Logging.h */; };
|
||||||
838A33722D06A97D00D0D770 /* librubberband.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 838A33712D06A97D00D0D770 /* librubberband.3.dylib */; };
|
|
||||||
839065F32853338700636FBB /* dsd2float.h in Headers */ = {isa = PBXBuildFile; fileRef = 839065F22853338700636FBB /* dsd2float.h */; };
|
839065F32853338700636FBB /* dsd2float.h in Headers */ = {isa = PBXBuildFile; fileRef = 839065F22853338700636FBB /* dsd2float.h */; };
|
||||||
839366671815923C006DD712 /* CogPluginMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 839366651815923C006DD712 /* CogPluginMulti.h */; };
|
839366671815923C006DD712 /* CogPluginMulti.h in Headers */ = {isa = PBXBuildFile; fileRef = 839366651815923C006DD712 /* CogPluginMulti.h */; };
|
||||||
839366681815923C006DD712 /* CogPluginMulti.m in Sources */ = {isa = PBXBuildFile; fileRef = 839366661815923C006DD712 /* CogPluginMulti.m */; };
|
839366681815923C006DD712 /* CogPluginMulti.m in Sources */ = {isa = PBXBuildFile; fileRef = 839366661815923C006DD712 /* CogPluginMulti.m */; };
|
||||||
8399CF2C27B5D1D5008751F1 /* NSDictionary+Merge.h in Headers */ = {isa = PBXBuildFile; fileRef = 8399CF2A27B5D1D4008751F1 /* NSDictionary+Merge.h */; };
|
8399CF2C27B5D1D5008751F1 /* NSDictionary+Merge.h in Headers */ = {isa = PBXBuildFile; fileRef = 8399CF2A27B5D1D4008751F1 /* NSDictionary+Merge.h */; };
|
||||||
8399CF2D27B5D1D5008751F1 /* NSDictionary+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = 8399CF2B27B5D1D4008751F1 /* NSDictionary+Merge.m */; };
|
8399CF2D27B5D1D5008751F1 /* NSDictionary+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = 8399CF2B27B5D1D4008751F1 /* NSDictionary+Merge.m */; };
|
||||||
|
839B83FA286D91ED00F529EE /* VisualizationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839B83F9286D91ED00F529EE /* VisualizationController.swift */; };
|
||||||
839E56E52879450300DFB5F4 /* HrtfData.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56E12879450300DFB5F4 /* HrtfData.h */; };
|
839E56E52879450300DFB5F4 /* HrtfData.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56E12879450300DFB5F4 /* HrtfData.h */; };
|
||||||
839E56E62879450300DFB5F4 /* Endianness.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56E22879450300DFB5F4 /* Endianness.h */; };
|
839E56E62879450300DFB5F4 /* Endianness.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56E22879450300DFB5F4 /* Endianness.h */; };
|
||||||
839E56E72879450300DFB5F4 /* HrtfData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 839E56E32879450300DFB5F4 /* HrtfData.cpp */; };
|
839E56E72879450300DFB5F4 /* HrtfData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 839E56E32879450300DFB5F4 /* HrtfData.cpp */; };
|
||||||
839E56E82879450300DFB5F4 /* IHrtfData.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56E42879450300DFB5F4 /* IHrtfData.h */; };
|
839E56E82879450300DFB5F4 /* IHrtfData.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56E42879450300DFB5F4 /* IHrtfData.h */; };
|
||||||
839E56EA28794F6300DFB5F4 /* HrtfTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56E928794F6300DFB5F4 /* HrtfTypes.h */; };
|
839E56EA28794F6300DFB5F4 /* HrtfTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56E928794F6300DFB5F4 /* HrtfTypes.h */; };
|
||||||
|
839E56ED2879515D00DFB5F4 /* HeadphoneFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56EB2879515D00DFB5F4 /* HeadphoneFilter.h */; };
|
||||||
|
839E56EE2879515D00DFB5F4 /* HeadphoneFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839E56EC2879515D00DFB5F4 /* HeadphoneFilter.mm */; };
|
||||||
839E56F7287974A100DFB5F4 /* SandboxBroker.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56F6287974A100DFB5F4 /* SandboxBroker.h */; };
|
839E56F7287974A100DFB5F4 /* SandboxBroker.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E56F6287974A100DFB5F4 /* SandboxBroker.h */; };
|
||||||
839E899E2D5DB9D500A13526 /* VisualizationNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 839E899D2D5DB9D500A13526 /* VisualizationNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
839E89A02D5DBA1700A13526 /* VisualizationNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E899F2D5DBA1700A13526 /* VisualizationNode.m */; };
|
|
||||||
83A3496A2D5C3F430096D530 /* DSPRubberbandNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A349682D5C3F430096D530 /* DSPRubberbandNode.m */; };
|
|
||||||
83A3496B2D5C3F430096D530 /* DSPRubberbandNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A349672D5C3F430096D530 /* DSPRubberbandNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
83A3496D2D5C40490096D530 /* DSPFSurroundNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A3496C2D5C40490096D530 /* DSPFSurroundNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
83A3496F2D5C405E0096D530 /* DSPFSurroundNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A3496E2D5C405E0096D530 /* DSPFSurroundNode.m */; };
|
|
||||||
83A349722D5C41810096D530 /* FSurroundFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83A349712D5C41810096D530 /* FSurroundFilter.mm */; };
|
|
||||||
83A349732D5C41810096D530 /* FSurroundFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A349702D5C41810096D530 /* FSurroundFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
83A349752D5C50A10096D530 /* DSPHRTFNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A349742D5C50A10096D530 /* DSPHRTFNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
83A349772D5C50B20096D530 /* DSPHRTFNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A349762D5C50B20096D530 /* DSPHRTFNode.m */; };
|
|
||||||
83B74281289E027F005AAC28 /* CogAudio-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B74280289E027F005AAC28 /* CogAudio-Bridging-Header.h */; };
|
83B74281289E027F005AAC28 /* CogAudio-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B74280289E027F005AAC28 /* CogAudio-Bridging-Header.h */; };
|
||||||
83F843202D5C6272008C123B /* HeadphoneFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F8431E2D5C6272008C123B /* HeadphoneFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
83F843212D5C6272008C123B /* HeadphoneFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83F8431F2D5C6272008C123B /* HeadphoneFilter.mm */; };
|
|
||||||
83F843232D5C66DA008C123B /* DSPEqualizerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F843222D5C66DA008C123B /* DSPEqualizerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
83F843252D5C66E9008C123B /* DSPEqualizerNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 83F843242D5C66E9008C123B /* DSPEqualizerNode.m */; };
|
|
||||||
83F9FFF62D6EC43900026576 /* soxr.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F9FFF02D6EC43900026576 /* soxr.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
83F9FFF82D6EC43900026576 /* libsoxr.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83F9FFF22D6EC43900026576 /* libsoxr.0.dylib */; };
|
|
||||||
83FFED512D5B08BC0044CCAF /* DSPNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FFED502D5B08BC0044CCAF /* DSPNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
83FFED532D5B09320044CCAF /* DSPNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 83FFED522D5B09320044CCAF /* DSPNode.m */; };
|
|
||||||
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; };
|
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; };
|
||||||
8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */; };
|
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */; };
|
||||||
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EC1225D0B993BD500C5B3AD /* ConverterNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EC1225D0B993BD500C5B3AD /* ConverterNode.h */; };
|
||||||
8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC1225E0B993BD500C5B3AD /* ConverterNode.m */; };
|
8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC1225E0B993BD500C5B3AD /* ConverterNode.m */; };
|
||||||
B0575F2D0D687A0800411D77 /* Helper.h in Headers */ = {isa = PBXBuildFile; fileRef = B0575F2C0D687A0800411D77 /* Helper.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
B0575F2D0D687A0800411D77 /* Helper.h in Headers */ = {isa = PBXBuildFile; fileRef = B0575F2C0D687A0800411D77 /* Helper.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
B0575F300D687A4000411D77 /* Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = B0575F2F0D687A4000411D77 /* Helper.m */; };
|
B0575F300D687A4000411D77 /* Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = B0575F2F0D687A4000411D77 /* Helper.m */; };
|
||||||
|
@ -175,22 +160,20 @@
|
||||||
8328995527CB51B700D7F028 /* SHA256Digest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHA256Digest.h; path = ../../Utils/SHA256Digest.h; sourceTree = "<group>"; };
|
8328995527CB51B700D7F028 /* SHA256Digest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHA256Digest.h; path = ../../Utils/SHA256Digest.h; sourceTree = "<group>"; };
|
||||||
8328995627CB51B700D7F028 /* SHA256Digest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHA256Digest.m; path = ../../Utils/SHA256Digest.m; sourceTree = "<group>"; };
|
8328995627CB51B700D7F028 /* SHA256Digest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHA256Digest.m; path = ../../Utils/SHA256Digest.m; sourceTree = "<group>"; };
|
||||||
8328995927CB51C900D7F028 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
8328995927CB51C900D7F028 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||||
833442402D6EFA6700C51D38 /* VisualizationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VisualizationController.h; sourceTree = "<group>"; };
|
|
||||||
833442412D6EFA6700C51D38 /* VisualizationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VisualizationController.m; sourceTree = "<group>"; };
|
|
||||||
833738E92D5EA52500278628 /* DSPDownmixNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPDownmixNode.h; sourceTree = "<group>"; };
|
|
||||||
833738EB2D5EA53500278628 /* DSPDownmixNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DSPDownmixNode.m; sourceTree = "<group>"; };
|
|
||||||
833738ED2D5EA5B700278628 /* Downmix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Downmix.h; sourceTree = "<group>"; };
|
|
||||||
833738EE2D5EA5B700278628 /* Downmix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Downmix.m; sourceTree = "<group>"; };
|
|
||||||
8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSFileHandle+CreateFile.h"; path = "../../Utils/NSFileHandle+CreateFile.h"; sourceTree = "<group>"; };
|
8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSFileHandle+CreateFile.h"; path = "../../Utils/NSFileHandle+CreateFile.h"; sourceTree = "<group>"; };
|
||||||
8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSFileHandle+CreateFile.m"; path = "../../Utils/NSFileHandle+CreateFile.m"; sourceTree = "<group>"; };
|
8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSFileHandle+CreateFile.m"; path = "../../Utils/NSFileHandle+CreateFile.m"; sourceTree = "<group>"; };
|
||||||
834A41A5287A90AB00EB9D9B /* freesurround_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = freesurround_decoder.h; sourceTree = "<group>"; };
|
834A41A5287A90AB00EB9D9B /* freesurround_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = freesurround_decoder.h; sourceTree = "<group>"; };
|
||||||
834A41A6287A90AB00EB9D9B /* freesurround_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = freesurround_decoder.cpp; sourceTree = "<group>"; };
|
834A41A6287A90AB00EB9D9B /* freesurround_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = freesurround_decoder.cpp; sourceTree = "<group>"; };
|
||||||
834A41A7287A90AB00EB9D9B /* channelmaps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = channelmaps.cpp; sourceTree = "<group>"; };
|
834A41A7287A90AB00EB9D9B /* channelmaps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = channelmaps.cpp; sourceTree = "<group>"; };
|
||||||
834A41A8287A90AB00EB9D9B /* channelmaps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = channelmaps.h; sourceTree = "<group>"; };
|
834A41A8287A90AB00EB9D9B /* channelmaps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = channelmaps.h; sourceTree = "<group>"; };
|
||||||
|
834A41AD287ABD6F00EB9D9B /* FSurroundFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSurroundFilter.h; sourceTree = "<group>"; };
|
||||||
|
834A41AE287ABD6F00EB9D9B /* FSurroundFilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FSurroundFilter.mm; sourceTree = "<group>"; };
|
||||||
834FD4EA27AF8F380063BC83 /* AudioChunk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioChunk.h; sourceTree = "<group>"; };
|
834FD4EA27AF8F380063BC83 /* AudioChunk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioChunk.h; sourceTree = "<group>"; };
|
||||||
834FD4EC27AF91220063BC83 /* AudioChunk.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AudioChunk.m; sourceTree = "<group>"; };
|
834FD4EC27AF91220063BC83 /* AudioChunk.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AudioChunk.m; sourceTree = "<group>"; };
|
||||||
834FD4EE27AF93680063BC83 /* ChunkList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChunkList.h; sourceTree = "<group>"; };
|
834FD4EE27AF93680063BC83 /* ChunkList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChunkList.h; sourceTree = "<group>"; };
|
||||||
834FD4EF27AF93680063BC83 /* ChunkList.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChunkList.m; sourceTree = "<group>"; };
|
834FD4EF27AF93680063BC83 /* ChunkList.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChunkList.m; sourceTree = "<group>"; };
|
||||||
|
83504163286447DA006B32CC /* Downmix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Downmix.h; sourceTree = "<group>"; };
|
||||||
|
83504164286447DA006B32CC /* Downmix.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Downmix.m; sourceTree = "<group>"; };
|
||||||
8350416C28646149006B32CC /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
|
8350416C28646149006B32CC /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
|
||||||
835C88AF279811A500E28EAE /* hdcd_decode2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hdcd_decode2.h; sourceTree = "<group>"; };
|
835C88AF279811A500E28EAE /* hdcd_decode2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hdcd_decode2.h; sourceTree = "<group>"; };
|
||||||
835C88B0279811A500E28EAE /* hdcd_decode2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hdcd_decode2.c; sourceTree = "<group>"; };
|
835C88B0279811A500E28EAE /* hdcd_decode2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hdcd_decode2.c; sourceTree = "<group>"; };
|
||||||
|
@ -203,43 +186,27 @@
|
||||||
835DD26F2ACAF5AD0057E319 /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = "<group>"; };
|
835DD26F2ACAF5AD0057E319 /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = "<group>"; };
|
||||||
835FAC5C27BCA14D00BA8562 /* BadSampleCleaner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BadSampleCleaner.h; path = Utils/BadSampleCleaner.h; sourceTree = SOURCE_ROOT; };
|
835FAC5C27BCA14D00BA8562 /* BadSampleCleaner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BadSampleCleaner.h; path = Utils/BadSampleCleaner.h; sourceTree = SOURCE_ROOT; };
|
||||||
835FAC5D27BCA14D00BA8562 /* BadSampleCleaner.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = BadSampleCleaner.m; path = Utils/BadSampleCleaner.m; sourceTree = SOURCE_ROOT; };
|
835FAC5D27BCA14D00BA8562 /* BadSampleCleaner.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = BadSampleCleaner.m; path = Utils/BadSampleCleaner.m; sourceTree = SOURCE_ROOT; };
|
||||||
|
836DF615298F6E8900CD0580 /* libsoxr.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsoxr.0.dylib; path = ../ThirdParty/soxr/lib/libsoxr.0.dylib; sourceTree = "<group>"; };
|
||||||
83725A7B27AA0D8A0003F694 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
83725A7B27AA0D8A0003F694 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||||
83725A7C27AA0D8E0003F694 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
|
83725A7C27AA0D8E0003F694 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
|
||||||
8377C64B27B8C51500E8BC0F /* fft_accelerate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fft_accelerate.c; sourceTree = "<group>"; };
|
8377C64B27B8C51500E8BC0F /* fft_accelerate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fft_accelerate.c; sourceTree = "<group>"; };
|
||||||
8377C64D27B8C54400E8BC0F /* fft.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fft.h; sourceTree = "<group>"; };
|
8377C64D27B8C54400E8BC0F /* fft.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fft.h; sourceTree = "<group>"; };
|
||||||
8384912618080FF100E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
|
8384912618080FF100E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
|
||||||
838A33712D06A97D00D0D770 /* librubberband.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = librubberband.3.dylib; path = ../ThirdParty/rubberband/lib/librubberband.3.dylib; sourceTree = SOURCE_ROOT; };
|
|
||||||
839065F22853338700636FBB /* dsd2float.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsd2float.h; sourceTree = "<group>"; };
|
839065F22853338700636FBB /* dsd2float.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsd2float.h; sourceTree = "<group>"; };
|
||||||
839366651815923C006DD712 /* CogPluginMulti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogPluginMulti.h; sourceTree = "<group>"; };
|
839366651815923C006DD712 /* CogPluginMulti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogPluginMulti.h; sourceTree = "<group>"; };
|
||||||
839366661815923C006DD712 /* CogPluginMulti.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CogPluginMulti.m; sourceTree = "<group>"; };
|
839366661815923C006DD712 /* CogPluginMulti.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CogPluginMulti.m; sourceTree = "<group>"; };
|
||||||
8399CF2A27B5D1D4008751F1 /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; };
|
8399CF2A27B5D1D4008751F1 /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; };
|
||||||
8399CF2B27B5D1D4008751F1 /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+Merge.m"; path = "../../Utils/NSDictionary+Merge.m"; sourceTree = "<group>"; };
|
8399CF2B27B5D1D4008751F1 /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+Merge.m"; path = "../../Utils/NSDictionary+Merge.m"; sourceTree = "<group>"; };
|
||||||
|
839B83F9286D91ED00F529EE /* VisualizationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisualizationController.swift; sourceTree = "<group>"; };
|
||||||
839E56E12879450300DFB5F4 /* HrtfData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HrtfData.h; sourceTree = "<group>"; };
|
839E56E12879450300DFB5F4 /* HrtfData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HrtfData.h; sourceTree = "<group>"; };
|
||||||
839E56E22879450300DFB5F4 /* Endianness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Endianness.h; sourceTree = "<group>"; };
|
839E56E22879450300DFB5F4 /* Endianness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Endianness.h; sourceTree = "<group>"; };
|
||||||
839E56E32879450300DFB5F4 /* HrtfData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HrtfData.cpp; sourceTree = "<group>"; };
|
839E56E32879450300DFB5F4 /* HrtfData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HrtfData.cpp; sourceTree = "<group>"; };
|
||||||
839E56E42879450300DFB5F4 /* IHrtfData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IHrtfData.h; sourceTree = "<group>"; };
|
839E56E42879450300DFB5F4 /* IHrtfData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IHrtfData.h; sourceTree = "<group>"; };
|
||||||
839E56E928794F6300DFB5F4 /* HrtfTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HrtfTypes.h; sourceTree = "<group>"; };
|
839E56E928794F6300DFB5F4 /* HrtfTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HrtfTypes.h; sourceTree = "<group>"; };
|
||||||
|
839E56EB2879515D00DFB5F4 /* HeadphoneFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeadphoneFilter.h; sourceTree = "<group>"; };
|
||||||
|
839E56EC2879515D00DFB5F4 /* HeadphoneFilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HeadphoneFilter.mm; sourceTree = "<group>"; };
|
||||||
839E56F6287974A100DFB5F4 /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../Utils/SandboxBroker.h; sourceTree = "<group>"; };
|
839E56F6287974A100DFB5F4 /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../Utils/SandboxBroker.h; sourceTree = "<group>"; };
|
||||||
839E899D2D5DB9D500A13526 /* VisualizationNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VisualizationNode.h; sourceTree = "<group>"; };
|
|
||||||
839E899F2D5DBA1700A13526 /* VisualizationNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VisualizationNode.m; sourceTree = "<group>"; };
|
|
||||||
83A349672D5C3F430096D530 /* DSPRubberbandNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPRubberbandNode.h; sourceTree = "<group>"; };
|
|
||||||
83A349682D5C3F430096D530 /* DSPRubberbandNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DSPRubberbandNode.m; sourceTree = "<group>"; };
|
|
||||||
83A3496C2D5C40490096D530 /* DSPFSurroundNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPFSurroundNode.h; sourceTree = "<group>"; };
|
|
||||||
83A3496E2D5C405E0096D530 /* DSPFSurroundNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DSPFSurroundNode.m; sourceTree = "<group>"; };
|
|
||||||
83A349702D5C41810096D530 /* FSurroundFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FSurroundFilter.h; sourceTree = "<group>"; };
|
|
||||||
83A349712D5C41810096D530 /* FSurroundFilter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FSurroundFilter.mm; sourceTree = "<group>"; };
|
|
||||||
83A349742D5C50A10096D530 /* DSPHRTFNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPHRTFNode.h; sourceTree = "<group>"; };
|
|
||||||
83A349762D5C50B20096D530 /* DSPHRTFNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DSPHRTFNode.m; sourceTree = "<group>"; };
|
|
||||||
83B74280289E027F005AAC28 /* CogAudio-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CogAudio-Bridging-Header.h"; sourceTree = "<group>"; };
|
83B74280289E027F005AAC28 /* CogAudio-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CogAudio-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
83F8431E2D5C6272008C123B /* HeadphoneFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HeadphoneFilter.h; sourceTree = "<group>"; };
|
|
||||||
83F8431F2D5C6272008C123B /* HeadphoneFilter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = HeadphoneFilter.mm; sourceTree = "<group>"; };
|
|
||||||
83F843222D5C66DA008C123B /* DSPEqualizerNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPEqualizerNode.h; sourceTree = "<group>"; };
|
|
||||||
83F843242D5C66E9008C123B /* DSPEqualizerNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DSPEqualizerNode.m; sourceTree = "<group>"; };
|
|
||||||
83F9FFF02D6EC43900026576 /* soxr.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = soxr.h; sourceTree = "<group>"; };
|
|
||||||
83F9FFF22D6EC43900026576 /* libsoxr.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libsoxr.0.dylib; sourceTree = "<group>"; };
|
|
||||||
83F9FFF42D6EC43900026576 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
|
||||||
83FFED502D5B08BC0044CCAF /* DSPNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPNode.h; sourceTree = "<group>"; };
|
|
||||||
83FFED522D5B09320044CCAF /* DSPNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DSPNode.m; sourceTree = "<group>"; };
|
|
||||||
8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
8DC2EF5B0486A6940098B216 /* CogAudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CogAudio.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
8DC2EF5B0486A6940098B216 /* CogAudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CogAudio.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContainer.h; sourceTree = "<group>"; };
|
8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContainer.h; sourceTree = "<group>"; };
|
||||||
|
@ -258,15 +225,14 @@
|
||||||
files = (
|
files = (
|
||||||
8328995A27CB51C900D7F028 /* Security.framework in Frameworks */,
|
8328995A27CB51C900D7F028 /* Security.framework in Frameworks */,
|
||||||
83725A9127AA16D50003F694 /* AVFoundation.framework in Frameworks */,
|
83725A9127AA16D50003F694 /* AVFoundation.framework in Frameworks */,
|
||||||
83F9FFF82D6EC43900026576 /* libsoxr.0.dylib in Frameworks */,
|
|
||||||
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */,
|
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */,
|
||||||
8350416D28646149006B32CC /* CoreMedia.framework in Frameworks */,
|
8350416D28646149006B32CC /* CoreMedia.framework in Frameworks */,
|
||||||
83725A9027AA16C90003F694 /* Accelerate.framework in Frameworks */,
|
83725A9027AA16C90003F694 /* Accelerate.framework in Frameworks */,
|
||||||
17D21DAD0B8BE76800D1EBDE /* AudioToolbox.framework in Frameworks */,
|
17D21DAD0B8BE76800D1EBDE /* AudioToolbox.framework in Frameworks */,
|
||||||
|
836DF618298F6F5F00CD0580 /* libsoxr.0.dylib in Frameworks */,
|
||||||
17D21DAE0B8BE76800D1EBDE /* AudioUnit.framework in Frameworks */,
|
17D21DAE0B8BE76800D1EBDE /* AudioUnit.framework in Frameworks */,
|
||||||
17D21DAF0B8BE76800D1EBDE /* CoreAudio.framework in Frameworks */,
|
17D21DAF0B8BE76800D1EBDE /* CoreAudio.framework in Frameworks */,
|
||||||
17D21DB00B8BE76800D1EBDE /* CoreAudioKit.framework in Frameworks */,
|
17D21DB00B8BE76800D1EBDE /* CoreAudioKit.framework in Frameworks */,
|
||||||
838A33722D06A97D00D0D770 /* librubberband.3.dylib in Frameworks */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -358,7 +324,7 @@
|
||||||
1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = {
|
1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
838A33712D06A97D00D0D770 /* librubberband.3.dylib */,
|
836DF615298F6E8900CD0580 /* libsoxr.0.dylib */,
|
||||||
83725A7B27AA0D8A0003F694 /* Accelerate.framework */,
|
83725A7B27AA0D8A0003F694 /* Accelerate.framework */,
|
||||||
17D21DAA0B8BE76800D1EBDE /* AudioUnit.framework */,
|
17D21DAA0B8BE76800D1EBDE /* AudioUnit.framework */,
|
||||||
17D21DA90B8BE76800D1EBDE /* AudioToolbox.framework */,
|
17D21DA90B8BE76800D1EBDE /* AudioToolbox.framework */,
|
||||||
|
@ -375,7 +341,6 @@
|
||||||
17D21C750B8BE4BA00D1EBDE /* Chain */ = {
|
17D21C750B8BE4BA00D1EBDE /* Chain */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
83A349692D5C3F430096D530 /* DSP */,
|
|
||||||
834FD4EA27AF8F380063BC83 /* AudioChunk.h */,
|
834FD4EA27AF8F380063BC83 /* AudioChunk.h */,
|
||||||
834FD4EC27AF91220063BC83 /* AudioChunk.m */,
|
834FD4EC27AF91220063BC83 /* AudioChunk.m */,
|
||||||
17D21C760B8BE4BA00D1EBDE /* BufferChain.h */,
|
17D21C760B8BE4BA00D1EBDE /* BufferChain.h */,
|
||||||
|
@ -384,16 +349,14 @@
|
||||||
834FD4EF27AF93680063BC83 /* ChunkList.m */,
|
834FD4EF27AF93680063BC83 /* ChunkList.m */,
|
||||||
8EC1225D0B993BD500C5B3AD /* ConverterNode.h */,
|
8EC1225D0B993BD500C5B3AD /* ConverterNode.h */,
|
||||||
8EC1225E0B993BD500C5B3AD /* ConverterNode.m */,
|
8EC1225E0B993BD500C5B3AD /* ConverterNode.m */,
|
||||||
|
83504163286447DA006B32CC /* Downmix.h */,
|
||||||
|
83504164286447DA006B32CC /* Downmix.m */,
|
||||||
17D21C7A0B8BE4BA00D1EBDE /* InputNode.h */,
|
17D21C7A0B8BE4BA00D1EBDE /* InputNode.h */,
|
||||||
17D21C7B0B8BE4BA00D1EBDE /* InputNode.m */,
|
17D21C7B0B8BE4BA00D1EBDE /* InputNode.m */,
|
||||||
17D21C7C0B8BE4BA00D1EBDE /* Node.h */,
|
17D21C7C0B8BE4BA00D1EBDE /* Node.h */,
|
||||||
17D21C7D0B8BE4BA00D1EBDE /* Node.m */,
|
17D21C7D0B8BE4BA00D1EBDE /* Node.m */,
|
||||||
17D21C7E0B8BE4BA00D1EBDE /* OutputNode.h */,
|
17D21C7E0B8BE4BA00D1EBDE /* OutputNode.h */,
|
||||||
17D21C7F0B8BE4BA00D1EBDE /* OutputNode.m */,
|
17D21C7F0B8BE4BA00D1EBDE /* OutputNode.m */,
|
||||||
83FFED502D5B08BC0044CCAF /* DSPNode.h */,
|
|
||||||
83FFED522D5B09320044CCAF /* DSPNode.m */,
|
|
||||||
839E899D2D5DB9D500A13526 /* VisualizationNode.h */,
|
|
||||||
839E899F2D5DBA1700A13526 /* VisualizationNode.m */,
|
|
||||||
);
|
);
|
||||||
path = Chain;
|
path = Chain;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -403,6 +366,10 @@
|
||||||
children = (
|
children = (
|
||||||
835DD2662ACAF1D90057E319 /* OutputCoreAudio.h */,
|
835DD2662ACAF1D90057E319 /* OutputCoreAudio.h */,
|
||||||
835DD2652ACAF1D90057E319 /* OutputCoreAudio.m */,
|
835DD2652ACAF1D90057E319 /* OutputCoreAudio.m */,
|
||||||
|
834A41AD287ABD6F00EB9D9B /* FSurroundFilter.h */,
|
||||||
|
834A41AE287ABD6F00EB9D9B /* FSurroundFilter.mm */,
|
||||||
|
839E56EB2879515D00DFB5F4 /* HeadphoneFilter.h */,
|
||||||
|
839E56EC2879515D00DFB5F4 /* HeadphoneFilter.mm */,
|
||||||
);
|
);
|
||||||
path = Output;
|
path = Output;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -410,7 +377,6 @@
|
||||||
17D21CD80B8BE5B400D1EBDE /* ThirdParty */ = {
|
17D21CD80B8BE5B400D1EBDE /* ThirdParty */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
83F9FFF52D6EC43900026576 /* soxr */,
|
|
||||||
835DD2692ACAF5AD0057E319 /* lvqcl */,
|
835DD2692ACAF5AD0057E319 /* lvqcl */,
|
||||||
834A41A4287A90AB00EB9D9B /* fsurround */,
|
834A41A4287A90AB00EB9D9B /* fsurround */,
|
||||||
839E56E02879450300DFB5F4 /* hrtf */,
|
839E56E02879450300DFB5F4 /* hrtf */,
|
||||||
|
@ -523,8 +489,7 @@
|
||||||
8377C64F27B8CAAB00E8BC0F /* Visualization */ = {
|
8377C64F27B8CAAB00E8BC0F /* Visualization */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
833442402D6EFA6700C51D38 /* VisualizationController.h */,
|
839B83F9286D91ED00F529EE /* VisualizationController.swift */,
|
||||||
833442412D6EFA6700C51D38 /* VisualizationController.m */,
|
|
||||||
);
|
);
|
||||||
path = Visualization;
|
path = Visualization;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -541,56 +506,6 @@
|
||||||
path = hrtf;
|
path = hrtf;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
83A349692D5C3F430096D530 /* DSP */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
833738ED2D5EA5B700278628 /* Downmix.h */,
|
|
||||||
833738EE2D5EA5B700278628 /* Downmix.m */,
|
|
||||||
83F8431E2D5C6272008C123B /* HeadphoneFilter.h */,
|
|
||||||
83F8431F2D5C6272008C123B /* HeadphoneFilter.mm */,
|
|
||||||
83A349702D5C41810096D530 /* FSurroundFilter.h */,
|
|
||||||
83A349712D5C41810096D530 /* FSurroundFilter.mm */,
|
|
||||||
83A349672D5C3F430096D530 /* DSPRubberbandNode.h */,
|
|
||||||
83A349682D5C3F430096D530 /* DSPRubberbandNode.m */,
|
|
||||||
83A3496C2D5C40490096D530 /* DSPFSurroundNode.h */,
|
|
||||||
83A3496E2D5C405E0096D530 /* DSPFSurroundNode.m */,
|
|
||||||
83A349742D5C50A10096D530 /* DSPHRTFNode.h */,
|
|
||||||
83A349762D5C50B20096D530 /* DSPHRTFNode.m */,
|
|
||||||
83F843222D5C66DA008C123B /* DSPEqualizerNode.h */,
|
|
||||||
83F843242D5C66E9008C123B /* DSPEqualizerNode.m */,
|
|
||||||
833738E92D5EA52500278628 /* DSPDownmixNode.h */,
|
|
||||||
833738EB2D5EA53500278628 /* DSPDownmixNode.m */,
|
|
||||||
);
|
|
||||||
path = DSP;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
83F9FFF12D6EC43900026576 /* include */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
83F9FFF02D6EC43900026576 /* soxr.h */,
|
|
||||||
);
|
|
||||||
path = include;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
83F9FFF32D6EC43900026576 /* lib */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
83F9FFF22D6EC43900026576 /* libsoxr.0.dylib */,
|
|
||||||
);
|
|
||||||
path = lib;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
83F9FFF52D6EC43900026576 /* soxr */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
83F9FFF12D6EC43900026576 /* include */,
|
|
||||||
83F9FFF32D6EC43900026576 /* lib */,
|
|
||||||
83F9FFF42D6EC43900026576 /* README.md */,
|
|
||||||
);
|
|
||||||
name = soxr;
|
|
||||||
path = ../ThirdParty/soxr;
|
|
||||||
sourceTree = SOURCE_ROOT;
|
|
||||||
};
|
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
/* Begin PBXHeadersBuildPhase section */
|
||||||
|
@ -598,47 +513,37 @@
|
||||||
isa = PBXHeadersBuildPhase;
|
isa = PBXHeadersBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
833442422D6EFA6700C51D38 /* VisualizationController.h in Headers */,
|
|
||||||
833738F02D5EA5B700278628 /* Downmix.h in Headers */,
|
|
||||||
834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */,
|
|
||||||
83F843202D5C6272008C123B /* HeadphoneFilter.h in Headers */,
|
|
||||||
83A349732D5C41810096D530 /* FSurroundFilter.h in Headers */,
|
|
||||||
839E56E82879450300DFB5F4 /* IHrtfData.h in Headers */,
|
839E56E82879450300DFB5F4 /* IHrtfData.h in Headers */,
|
||||||
17D21CA10B8BE4BA00D1EBDE /* BufferChain.h in Headers */,
|
17D21CA10B8BE4BA00D1EBDE /* BufferChain.h in Headers */,
|
||||||
831A50142865A7FD0049CFE4 /* rsstate.hpp in Headers */,
|
831A50142865A7FD0049CFE4 /* rsstate.hpp in Headers */,
|
||||||
835DD2682ACAF1D90057E319 /* OutputCoreAudio.h in Headers */,
|
|
||||||
834A41AC287A90AB00EB9D9B /* channelmaps.h in Headers */,
|
834A41AC287A90AB00EB9D9B /* channelmaps.h in Headers */,
|
||||||
83A3496D2D5C40490096D530 /* DSPFSurroundNode.h in Headers */,
|
|
||||||
83A3496B2D5C3F430096D530 /* DSPRubberbandNode.h in Headers */,
|
|
||||||
17D21CA50B8BE4BA00D1EBDE /* InputNode.h in Headers */,
|
17D21CA50B8BE4BA00D1EBDE /* InputNode.h in Headers */,
|
||||||
833738EA2D5EA52500278628 /* DSPDownmixNode.h in Headers */,
|
|
||||||
83F843232D5C66DA008C123B /* DSPEqualizerNode.h in Headers */,
|
|
||||||
834A41A9287A90AB00EB9D9B /* freesurround_decoder.h in Headers */,
|
834A41A9287A90AB00EB9D9B /* freesurround_decoder.h in Headers */,
|
||||||
834FD4F027AF93680063BC83 /* ChunkList.h in Headers */,
|
|
||||||
835DD2732ACAF5AD0057E319 /* util.h in Headers */,
|
835DD2732ACAF5AD0057E319 /* util.h in Headers */,
|
||||||
17D21CA70B8BE4BA00D1EBDE /* Node.h in Headers */,
|
17D21CA70B8BE4BA00D1EBDE /* Node.h in Headers */,
|
||||||
8399CF2C27B5D1D5008751F1 /* NSDictionary+Merge.h in Headers */,
|
8399CF2C27B5D1D5008751F1 /* NSDictionary+Merge.h in Headers */,
|
||||||
17D21CA90B8BE4BA00D1EBDE /* OutputNode.h in Headers */,
|
17D21CA90B8BE4BA00D1EBDE /* OutputNode.h in Headers */,
|
||||||
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */,
|
|
||||||
8328995427CB511000D7F028 /* RedundantPlaylistDataStore.h in Headers */,
|
8328995427CB511000D7F028 /* RedundantPlaylistDataStore.h in Headers */,
|
||||||
|
83504165286447DA006B32CC /* Downmix.h in Headers */,
|
||||||
839E56E52879450300DFB5F4 /* HrtfData.h in Headers */,
|
839E56E52879450300DFB5F4 /* HrtfData.h in Headers */,
|
||||||
83FFED512D5B08BC0044CCAF /* DSPNode.h in Headers */,
|
83B74281289E027F005AAC28 /* CogAudio-Bridging-Header.h in Headers */,
|
||||||
839E899E2D5DB9D500A13526 /* VisualizationNode.h in Headers */,
|
|
||||||
83A349752D5C50A10096D530 /* DSPHRTFNode.h in Headers */,
|
|
||||||
83F9FFF62D6EC43900026576 /* soxr.h in Headers */,
|
|
||||||
17D21CC70B8BE4BA00D1EBDE /* Status.h in Headers */,
|
17D21CC70B8BE4BA00D1EBDE /* Status.h in Headers */,
|
||||||
17D21CF30B8BE5EF00D1EBDE /* CogSemaphore.h in Headers */,
|
17D21CF30B8BE5EF00D1EBDE /* CogSemaphore.h in Headers */,
|
||||||
|
835DD2682ACAF1D90057E319 /* OutputCoreAudio.h in Headers */,
|
||||||
839E56E62879450300DFB5F4 /* Endianness.h in Headers */,
|
839E56E62879450300DFB5F4 /* Endianness.h in Headers */,
|
||||||
17D21DC70B8BE79700D1EBDE /* CoreAudioUtils.h in Headers */,
|
17D21DC70B8BE79700D1EBDE /* CoreAudioUtils.h in Headers */,
|
||||||
835DD2722ACAF5AD0057E319 /* lpc.h in Headers */,
|
835DD2722ACAF5AD0057E319 /* lpc.h in Headers */,
|
||||||
|
839E56ED2879515D00DFB5F4 /* HeadphoneFilter.h in Headers */,
|
||||||
17D21EBD0B8BF44000D1EBDE /* AudioPlayer.h in Headers */,
|
17D21EBD0B8BF44000D1EBDE /* AudioPlayer.h in Headers */,
|
||||||
831A50182865A8B30049CFE4 /* rsstate.h in Headers */,
|
831A50182865A8B30049CFE4 /* rsstate.h in Headers */,
|
||||||
|
834FD4F027AF93680063BC83 /* ChunkList.h in Headers */,
|
||||||
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */,
|
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */,
|
||||||
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */,
|
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */,
|
||||||
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */,
|
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */,
|
||||||
|
834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */,
|
||||||
|
834A41AF287ABD6F00EB9D9B /* FSurroundFilter.h in Headers */,
|
||||||
17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */,
|
17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */,
|
||||||
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */,
|
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */,
|
||||||
83B74281289E027F005AAC28 /* CogAudio-Bridging-Header.h in Headers */,
|
|
||||||
17C940230B900909008627D6 /* AudioMetadataReader.h in Headers */,
|
17C940230B900909008627D6 /* AudioMetadataReader.h in Headers */,
|
||||||
839E56F7287974A100DFB5F4 /* SandboxBroker.h in Headers */,
|
839E56F7287974A100DFB5F4 /* SandboxBroker.h in Headers */,
|
||||||
839065F32853338700636FBB /* dsd2float.h in Headers */,
|
839065F32853338700636FBB /* dsd2float.h in Headers */,
|
||||||
|
@ -646,6 +551,7 @@
|
||||||
839366671815923C006DD712 /* CogPluginMulti.h in Headers */,
|
839366671815923C006DD712 /* CogPluginMulti.h in Headers */,
|
||||||
17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */,
|
17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */,
|
||||||
835C88B1279811A500E28EAE /* hdcd_decode2.h in Headers */,
|
835C88B1279811A500E28EAE /* hdcd_decode2.h in Headers */,
|
||||||
|
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */,
|
||||||
8384912718080FF100E7332D /* Logging.h in Headers */,
|
8384912718080FF100E7332D /* Logging.h in Headers */,
|
||||||
8377C64E27B8C54400E8BC0F /* fft.h in Headers */,
|
8377C64E27B8C54400E8BC0F /* fft.h in Headers */,
|
||||||
835FAC5E27BCA14D00BA8562 /* BadSampleCleaner.h in Headers */,
|
835FAC5E27BCA14D00BA8562 /* BadSampleCleaner.h in Headers */,
|
||||||
|
@ -659,9 +565,9 @@
|
||||||
/* End PBXHeadersBuildPhase section */
|
/* End PBXHeadersBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
8DC2EF4F0486A6940098B216 /* CogAudio */ = {
|
8DC2EF4F0486A6940098B216 /* CogAudio Framework */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "CogAudio" */;
|
buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "CogAudio Framework" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
8DC2EF500486A6940098B216 /* Headers */,
|
8DC2EF500486A6940098B216 /* Headers */,
|
||||||
8DC2EF540486A6940098B216 /* Sources */,
|
8DC2EF540486A6940098B216 /* Sources */,
|
||||||
|
@ -673,7 +579,7 @@
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
name = CogAudio;
|
name = "CogAudio Framework";
|
||||||
productInstallPath = "$(HOME)/Library/Frameworks";
|
productInstallPath = "$(HOME)/Library/Frameworks";
|
||||||
productName = CogAudio;
|
productName = CogAudio;
|
||||||
productReference = 8DC2EF5B0486A6940098B216 /* CogAudio.framework */;
|
productReference = 8DC2EF5B0486A6940098B216 /* CogAudio.framework */;
|
||||||
|
@ -685,8 +591,7 @@
|
||||||
0867D690FE84028FC02AAC07 /* Project object */ = {
|
0867D690FE84028FC02AAC07 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8DC2EF4F0486A6940098B216 = {
|
8DC2EF4F0486A6940098B216 = {
|
||||||
LastSwiftMigration = 1330;
|
LastSwiftMigration = 1330;
|
||||||
|
@ -707,7 +612,7 @@
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
8DC2EF4F0486A6940098B216 /* CogAudio */,
|
8DC2EF4F0486A6940098B216 /* CogAudio Framework */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
@ -717,6 +622,8 @@
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
835DD2712ACAF5AD0057E319 /* License.txt in Resources */,
|
||||||
|
835DD2702ACAF5AD0057E319 /* LICENSE.LGPL in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -728,25 +635,20 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
17D21CA20B8BE4BA00D1EBDE /* BufferChain.m in Sources */,
|
17D21CA20B8BE4BA00D1EBDE /* BufferChain.m in Sources */,
|
||||||
83A349772D5C50B20096D530 /* DSPHRTFNode.m in Sources */,
|
|
||||||
17D21CA60B8BE4BA00D1EBDE /* InputNode.m in Sources */,
|
17D21CA60B8BE4BA00D1EBDE /* InputNode.m in Sources */,
|
||||||
83A3496A2D5C3F430096D530 /* DSPRubberbandNode.m in Sources */,
|
839E56EE2879515D00DFB5F4 /* HeadphoneFilter.mm in Sources */,
|
||||||
|
83504166286447DA006B32CC /* Downmix.m in Sources */,
|
||||||
8399CF2D27B5D1D5008751F1 /* NSDictionary+Merge.m in Sources */,
|
8399CF2D27B5D1D5008751F1 /* NSDictionary+Merge.m in Sources */,
|
||||||
83F843252D5C66E9008C123B /* DSPEqualizerNode.m in Sources */,
|
|
||||||
834A41AB287A90AB00EB9D9B /* channelmaps.cpp in Sources */,
|
834A41AB287A90AB00EB9D9B /* channelmaps.cpp in Sources */,
|
||||||
833738EC2D5EA53500278628 /* DSPDownmixNode.m in Sources */,
|
|
||||||
833442432D6EFA6700C51D38 /* VisualizationController.m in Sources */,
|
|
||||||
831A50162865A8800049CFE4 /* rsstate.cpp in Sources */,
|
831A50162865A8800049CFE4 /* rsstate.cpp in Sources */,
|
||||||
17D21CA80B8BE4BA00D1EBDE /* Node.m in Sources */,
|
17D21CA80B8BE4BA00D1EBDE /* Node.m in Sources */,
|
||||||
17D21CAA0B8BE4BA00D1EBDE /* OutputNode.m in Sources */,
|
17D21CAA0B8BE4BA00D1EBDE /* OutputNode.m in Sources */,
|
||||||
835C88B2279811A500E28EAE /* hdcd_decode2.c in Sources */,
|
835C88B2279811A500E28EAE /* hdcd_decode2.c in Sources */,
|
||||||
835FAC5F27BCA14D00BA8562 /* BadSampleCleaner.m in Sources */,
|
835FAC5F27BCA14D00BA8562 /* BadSampleCleaner.m in Sources */,
|
||||||
834FD4ED27AF91220063BC83 /* AudioChunk.m in Sources */,
|
834FD4ED27AF91220063BC83 /* AudioChunk.m in Sources */,
|
||||||
833738EF2D5EA5B700278628 /* Downmix.m in Sources */,
|
|
||||||
17D21CF40B8BE5EF00D1EBDE /* CogSemaphore.m in Sources */,
|
17D21CF40B8BE5EF00D1EBDE /* CogSemaphore.m in Sources */,
|
||||||
839E89A02D5DBA1700A13526 /* VisualizationNode.m in Sources */,
|
839B83FA286D91ED00F529EE /* VisualizationController.swift in Sources */,
|
||||||
8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */,
|
8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */,
|
||||||
83A3496F2D5C405E0096D530 /* DSPFSurroundNode.m in Sources */,
|
|
||||||
17D21DC80B8BE79700D1EBDE /* CoreAudioUtils.m in Sources */,
|
17D21DC80B8BE79700D1EBDE /* CoreAudioUtils.m in Sources */,
|
||||||
8328995327CB511000D7F028 /* RedundantPlaylistDataStore.m in Sources */,
|
8328995327CB511000D7F028 /* RedundantPlaylistDataStore.m in Sources */,
|
||||||
8377C64C27B8C51500E8BC0F /* fft_accelerate.c in Sources */,
|
8377C64C27B8C51500E8BC0F /* fft_accelerate.c in Sources */,
|
||||||
|
@ -758,13 +660,11 @@
|
||||||
8328995827CB51B700D7F028 /* SHA256Digest.m in Sources */,
|
8328995827CB51B700D7F028 /* SHA256Digest.m in Sources */,
|
||||||
17C940240B900909008627D6 /* AudioMetadataReader.m in Sources */,
|
17C940240B900909008627D6 /* AudioMetadataReader.m in Sources */,
|
||||||
17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */,
|
17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */,
|
||||||
83F843212D5C6272008C123B /* HeadphoneFilter.mm in Sources */,
|
|
||||||
17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */,
|
17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */,
|
||||||
834FD4F127AF93680063BC83 /* ChunkList.m in Sources */,
|
834FD4F127AF93680063BC83 /* ChunkList.m in Sources */,
|
||||||
83FFED532D5B09320044CCAF /* DSPNode.m in Sources */,
|
834A41B0287ABD6F00EB9D9B /* FSurroundFilter.mm in Sources */,
|
||||||
8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */,
|
8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */,
|
||||||
835DD2672ACAF1D90057E319 /* OutputCoreAudio.m in Sources */,
|
835DD2672ACAF1D90057E319 /* OutputCoreAudio.m in Sources */,
|
||||||
83A349722D5C41810096D530 /* FSurroundFilter.mm in Sources */,
|
|
||||||
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */,
|
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */,
|
||||||
B0575F300D687A4000411D77 /* Helper.m in Sources */,
|
B0575F300D687A4000411D77 /* Helper.m in Sources */,
|
||||||
835DD2742ACAF5AD0057E319 /* lpc.c in Sources */,
|
835DD2742ACAF5AD0057E319 /* lpc.c in Sources */,
|
||||||
|
@ -783,10 +683,9 @@
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEFINES_MODULE = YES;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
ENABLE_MODULE_VERIFIER = YES;
|
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
@ -794,22 +693,16 @@
|
||||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||||
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
||||||
HEADER_SEARCH_PATHS = (
|
HEADER_SEARCH_PATHS = ../ThirdParty/soxr/include;
|
||||||
../ThirdParty/soxr/include,
|
|
||||||
../ThirdParty/rubberband/include,
|
|
||||||
);
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks";
|
||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = ../ThirdParty/soxr/lib;
|
||||||
../ThirdParty/soxr/lib,
|
|
||||||
../ThirdParty/rubberband/lib,
|
|
||||||
);
|
|
||||||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 c++17";
|
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
||||||
PRODUCT_NAME = CogAudio;
|
PRODUCT_NAME = CogAudio;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "CogAudio-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
WARNING_LDFLAGS = "";
|
WARNING_LDFLAGS = "";
|
||||||
|
@ -823,31 +716,24 @@
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEFINES_MODULE = YES;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
ENABLE_MODULE_VERIFIER = YES;
|
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||||
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
GCC_PREFIX_HEADER = CogAudio_Prefix.pch;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = "";
|
GCC_PREPROCESSOR_DEFINITIONS = "";
|
||||||
HEADER_SEARCH_PATHS = (
|
HEADER_SEARCH_PATHS = ../ThirdParty/soxr/include;
|
||||||
../ThirdParty/soxr/include,
|
|
||||||
../ThirdParty/rubberband/include,
|
|
||||||
);
|
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks";
|
||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = ../ThirdParty/soxr/lib;
|
||||||
../ThirdParty/soxr/lib,
|
|
||||||
../ThirdParty/rubberband/lib,
|
|
||||||
);
|
|
||||||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 c++17";
|
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
PRODUCT_BUNDLE_IDENTIFIER = org.cogx.cogaudio;
|
||||||
PRODUCT_NAME = CogAudio;
|
PRODUCT_NAME = CogAudio;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "CogAudio-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
WARNING_LDFLAGS = "";
|
WARNING_LDFLAGS = "";
|
||||||
WRAPPER_EXTENSION = framework;
|
WRAPPER_EXTENSION = framework;
|
||||||
|
@ -880,11 +766,8 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"DEBUG=1",
|
"DEBUG=1",
|
||||||
|
@ -900,9 +783,7 @@
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
OTHER_CFLAGS = "-Wframe-larger-than=4000";
|
OTHER_CFLAGS = "-Wframe-larger-than=4000";
|
||||||
OTHER_CPLUSPLUSFLAGS = "-Wframe-larger-than=16000";
|
OTHER_CPLUSPLUSFLAGS = "-Wframe-larger-than=16000";
|
||||||
PRODUCT_MODULE_NAME = CogAudio;
|
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "CogAudio-Bridging-Header.h";
|
|
||||||
SYMROOT = ../build;
|
SYMROOT = ../build;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
|
@ -932,11 +813,8 @@
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DEFINES_MODULE = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = "HAVE_CONFIG_H=1";
|
GCC_PREPROCESSOR_DEFINITIONS = "HAVE_CONFIG_H=1";
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
@ -948,10 +826,7 @@
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
OTHER_CFLAGS = "-Wframe-larger-than=4000";
|
OTHER_CFLAGS = "-Wframe-larger-than=4000";
|
||||||
OTHER_CPLUSPLUSFLAGS = "-Wframe-larger-than=16000";
|
OTHER_CPLUSPLUSFLAGS = "-Wframe-larger-than=16000";
|
||||||
PRODUCT_MODULE_NAME = CogAudio;
|
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "CogAudio-Bridging-Header.h";
|
|
||||||
SYMROOT = ../build;
|
SYMROOT = ../build;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
@ -959,7 +834,7 @@
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "CogAudio" */ = {
|
1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "CogAudio Framework" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
1DEB91AE08733DA50010E9CD /* Debug */,
|
1DEB91AE08733DA50010E9CD /* Debug */,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "8DC2EF4F0486A6940098B216"
|
BlueprintIdentifier = "8DC2EF4F0486A6940098B216"
|
||||||
BuildableName = "CogAudio.framework"
|
BuildableName = "CogAudio.framework"
|
||||||
BlueprintName = "CogAudio"
|
BlueprintName = "CogAudio Framework"
|
||||||
ReferencedContainer = "container:CogAudio.xcodeproj">
|
ReferencedContainer = "container:CogAudio.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "8DC2EF4F0486A6940098B216"
|
BlueprintIdentifier = "8DC2EF4F0486A6940098B216"
|
||||||
BuildableName = "CogAudio.framework"
|
BuildableName = "CogAudio.framework"
|
||||||
BlueprintName = "CogAudio"
|
BlueprintName = "CogAudio Framework"
|
||||||
ReferencedContainer = "container:CogAudio.xcodeproj">
|
ReferencedContainer = "container:CogAudio.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "8DC2EF4F0486A6940098B216"
|
BlueprintIdentifier = "8DC2EF4F0486A6940098B216"
|
||||||
BuildableName = "CogAudio.framework"
|
BuildableName = "CogAudio.framework"
|
||||||
BlueprintName = "CogAudio"
|
BlueprintName = "CogAudio Framework"
|
||||||
ReferencedContainer = "container:CogAudio.xcodeproj">
|
ReferencedContainer = "container:CogAudio.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
int bufferSize;
|
int bufferSize;
|
||||||
int paddedBufferSize;
|
int paddedBufferSize;
|
||||||
double sampleRate;
|
|
||||||
int channelCount;
|
int channelCount;
|
||||||
uint32_t config;
|
uint32_t config;
|
||||||
|
|
||||||
|
@ -39,8 +38,6 @@
|
||||||
|
|
||||||
- (void)reset;
|
- (void)reset;
|
||||||
|
|
||||||
- (size_t)needPrefill;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif /* HeadphoneFilter_h */
|
#endif /* HeadphoneFilter_h */
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#import <fstream>
|
#import <fstream>
|
||||||
|
|
||||||
#import <soxr.h>
|
#import "rsstate.h"
|
||||||
|
|
||||||
#import "HrtfData.h"
|
#import "HrtfData.h"
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ static void transformPosition(float &elevation, float &azimuth, const simd_float
|
||||||
HrtfData *data;
|
HrtfData *data;
|
||||||
}
|
}
|
||||||
+ (impulseSetCache *)sharedController;
|
+ (impulseSetCache *)sharedController;
|
||||||
- (void)getImpulse:(NSURL *)url outImpulse:(float **)outImpulse outSampleCount:(int *)outSampleCount sampleRate:(double)sampleRate channelCount:(int)channelCount channelConfig:(uint32_t)channelConfig withMatrix:(simd_float4x4)matrix;
|
- (void)getImpulse:(NSURL *)url outImpulse:(float **)outImpulse outSampleCount:(int *)outSampleCount channelCount:(int)channelCount channelConfig:(uint32_t)channelConfig withMatrix:(simd_float4x4)matrix;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation impulseSetCache
|
@implementation impulseSetCache
|
||||||
|
@ -152,7 +152,7 @@ static impulseSetCache *_sharedController = nil;
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)getImpulse:(NSURL *)url outImpulse:(float **)outImpulse outSampleCount:(int *)outSampleCount sampleRate:(double)sampleRate channelCount:(int)channelCount channelConfig:(uint32_t)channelConfig withMatrix:(simd_float4x4)matrix {
|
- (void)getImpulse:(NSURL *)url outImpulse:(float **)outImpulse outSampleCount:(int *)outSampleCount channelCount:(int)channelCount channelConfig:(uint32_t)channelConfig withMatrix:(simd_float4x4)matrix {
|
||||||
double sampleRateOfSource = 0;
|
double sampleRateOfSource = 0;
|
||||||
int sampleCount = 0;
|
int sampleCount = 0;
|
||||||
|
|
||||||
|
@ -174,28 +174,13 @@ static impulseSetCache *_sharedController = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_HQ, 0);
|
|
||||||
soxr_io_spec_t io_spec = soxr_io_spec(SOXR_FLOAT32_I, SOXR_FLOAT32_I);
|
|
||||||
soxr_runtime_spec_t runtime_spec = soxr_runtime_spec(0);
|
|
||||||
|
|
||||||
bool resampling;
|
|
||||||
|
|
||||||
sampleRateOfSource = data->get_sample_rate();
|
sampleRateOfSource = data->get_sample_rate();
|
||||||
resampling = !!(fabs(sampleRateOfSource - sampleRate) > 1e-6);
|
|
||||||
|
|
||||||
uint32_t sampleCountResampled;
|
|
||||||
uint32_t sampleCountExact = data->get_response_length();
|
uint32_t sampleCountExact = data->get_response_length();
|
||||||
sampleCount = sampleCountExact + ((data->get_longest_delay() + 2) >> 2);
|
sampleCount = sampleCountExact + ((data->get_longest_delay() + 2) >> 2);
|
||||||
|
sampleCount = (sampleCount + 15) & ~15;
|
||||||
|
|
||||||
uint32_t actualSampleCount = sampleCount;
|
*outImpulse = (float *)calloc(sizeof(float), sampleCount * channelCount * 2);
|
||||||
if(resampling) {
|
|
||||||
sampleCountResampled = (uint32_t)(((double)sampleCountExact) * sampleRate / sampleRateOfSource);
|
|
||||||
actualSampleCount = (uint32_t)(((double)actualSampleCount) * sampleRate / sampleRateOfSource);
|
|
||||||
io_spec.scale = sampleRateOfSource / sampleRate;
|
|
||||||
}
|
|
||||||
actualSampleCount = (actualSampleCount + 15) & ~15;
|
|
||||||
|
|
||||||
*outImpulse = (float *)calloc(sizeof(float), actualSampleCount * channelCount * 2);
|
|
||||||
if(!*outImpulse) {
|
if(!*outImpulse) {
|
||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
@ -217,19 +202,12 @@ static impulseSetCache *_sharedController = nil;
|
||||||
|
|
||||||
data->get_direction_data(elevation, azimuth, speaker.distance, hrtfLeft, hrtfRight);
|
data->get_direction_data(elevation, azimuth, speaker.distance, hrtfLeft, hrtfRight);
|
||||||
|
|
||||||
if(resampling) {
|
cblas_scopy(sampleCountExact, &hrtfLeft.impulse_response[0], 1, &hrtfData[((hrtfLeft.delay + 2) >> 2) + sampleCount * i * 2], 1);
|
||||||
ssize_t leftDelay = (ssize_t)((double)(hrtfLeft.delay) * 0.25 * sampleRate / sampleRateOfSource);
|
cblas_scopy(sampleCountExact, &hrtfRight.impulse_response[0], 1, &hrtfData[((hrtfLeft.delay + 2) >> 2) + sampleCount * (i * 2 + 1)], 1);
|
||||||
ssize_t rightDelay = (ssize_t)((double)(hrtfRight.delay) * 0.25 * sampleRate / sampleRateOfSource);
|
|
||||||
soxr_oneshot(sampleRateOfSource, sampleRate, 1, &hrtfLeft.impulse_response[0], sampleCountExact, NULL, &hrtfData[leftDelay + actualSampleCount * i * 2], sampleCountResampled, NULL, &io_spec, &q_spec, &runtime_spec);
|
|
||||||
soxr_oneshot(sampleRateOfSource, sampleRate, 1, &hrtfRight.impulse_response[0], sampleCountExact, NULL, &hrtfData[rightDelay + actualSampleCount * (i * 2 + 1)], sampleCountResampled, NULL, &io_spec, &q_spec, &runtime_spec);
|
|
||||||
} else {
|
|
||||||
cblas_scopy(sampleCountExact, &hrtfLeft.impulse_response[0], 1, &hrtfData[((hrtfLeft.delay + 2) >> 2) + actualSampleCount * i * 2], 1);
|
|
||||||
cblas_scopy(sampleCountExact, &hrtfRight.impulse_response[0], 1, &hrtfData[((hrtfRight.delay + 2) >> 2) + actualSampleCount * (i * 2 + 1)], 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*outSampleCount = actualSampleCount;
|
*outSampleCount = sampleCount;
|
||||||
} catch(std::exception &e) {
|
} catch(std::exception &e) {
|
||||||
ALog(@"Exception caught: %s", e.what());
|
ALog(@"Exception caught: %s", e.what());
|
||||||
}
|
}
|
||||||
|
@ -264,13 +242,12 @@ static impulseSetCache *_sharedController = nil;
|
||||||
|
|
||||||
if(self) {
|
if(self) {
|
||||||
URL = url;
|
URL = url;
|
||||||
self->sampleRate = sampleRate;
|
|
||||||
channelCount = channels;
|
channelCount = channels;
|
||||||
self->config = config;
|
self->config = config;
|
||||||
|
|
||||||
float *impulseBuffer = NULL;
|
float *impulseBuffer = NULL;
|
||||||
int sampleCount = 0;
|
int sampleCount = 0;
|
||||||
[[impulseSetCache sharedController] getImpulse:url outImpulse:&impulseBuffer outSampleCount:&sampleCount sampleRate:sampleRate channelCount:channels channelConfig:config withMatrix:matrix];
|
[[impulseSetCache sharedController] getImpulse:url outImpulse:&impulseBuffer outSampleCount:&sampleCount channelCount:channels channelConfig:config withMatrix:matrix];
|
||||||
if(!impulseBuffer) {
|
if(!impulseBuffer) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -338,7 +315,7 @@ static impulseSetCache *_sharedController = nil;
|
||||||
|
|
||||||
float *impulseBuffer = NULL;
|
float *impulseBuffer = NULL;
|
||||||
int sampleCount = 0;
|
int sampleCount = 0;
|
||||||
[[impulseSetCache sharedController] getImpulse:URL outImpulse:&impulseBuffer outSampleCount:&sampleCount sampleRate:sampleRate channelCount:channelCount channelConfig:config withMatrix:matrix];
|
[[impulseSetCache sharedController] getImpulse:URL outImpulse:&impulseBuffer outSampleCount:&sampleCount channelCount:channelCount channelConfig:config withMatrix:matrix];
|
||||||
|
|
||||||
for(int i = 0; i < channelCount * 2; ++i) {
|
for(int i = 0; i < channelCount * 2; ++i) {
|
||||||
mirroredImpulseResponses[i] = &impulseBuffer[sampleCount * i];
|
mirroredImpulseResponses[i] = &impulseBuffer[sampleCount * i];
|
||||||
|
@ -379,8 +356,4 @@ static impulseSetCache *_sharedController = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (size_t)needPrefill {
|
|
||||||
return paddedBufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
|
@ -3,7 +3,7 @@
|
||||||
// Cog
|
// Cog
|
||||||
//
|
//
|
||||||
// Created by Christopher Snowhill on 7/25/23.
|
// Created by Christopher Snowhill on 7/25/23.
|
||||||
// Copyright 2023-2024 Christopher Snowhill. All rights reserved.
|
// Copyright 2023 Christopher Snowhill. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <AssertMacros.h>
|
#import <AssertMacros.h>
|
||||||
|
@ -22,15 +22,23 @@ using std::atomic_long;
|
||||||
#import <stdatomic.h>
|
#import <stdatomic.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#import "Downmix.h"
|
||||||
|
|
||||||
|
#import <CogAudio/CogAudio-Swift.h>
|
||||||
|
|
||||||
#import <simd/simd.h>
|
#import <simd/simd.h>
|
||||||
|
|
||||||
#import <CogAudio/ChunkList.h>
|
#import "HeadphoneFilter.h"
|
||||||
#import <CogAudio/HeadphoneFilter.h>
|
|
||||||
|
|
||||||
//#define OUTPUT_LOG
|
//#define OUTPUT_LOG
|
||||||
|
#ifdef OUTPUT_LOG
|
||||||
|
#import <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
@class OutputNode;
|
@class OutputNode;
|
||||||
|
|
||||||
|
@class FSurroundFilter;
|
||||||
|
|
||||||
@class AudioChunk;
|
@class AudioChunk;
|
||||||
|
|
||||||
@interface OutputCoreAudio : NSObject {
|
@interface OutputCoreAudio : NSObject {
|
||||||
|
@ -41,7 +49,13 @@ using std::atomic_long;
|
||||||
|
|
||||||
NSLock *outputLock;
|
NSLock *outputLock;
|
||||||
|
|
||||||
double streamTimestamp;
|
double secondsLatency;
|
||||||
|
double visPushed;
|
||||||
|
|
||||||
|
double lastClippedSampleRate;
|
||||||
|
|
||||||
|
void *rsvis;
|
||||||
|
double lastVisRate;
|
||||||
|
|
||||||
BOOL stopInvoked;
|
BOOL stopInvoked;
|
||||||
BOOL stopCompleted;
|
BOOL stopCompleted;
|
||||||
|
@ -52,13 +66,6 @@ using std::atomic_long;
|
||||||
BOOL paused;
|
BOOL paused;
|
||||||
BOOL restarted;
|
BOOL restarted;
|
||||||
BOOL commandStop;
|
BOOL commandStop;
|
||||||
BOOL resetting;
|
|
||||||
|
|
||||||
BOOL cutOffInput;
|
|
||||||
BOOL fading, faded;
|
|
||||||
float fadeLevel;
|
|
||||||
float fadeStep;
|
|
||||||
float fadeTarget;
|
|
||||||
|
|
||||||
BOOL eqEnabled;
|
BOOL eqEnabled;
|
||||||
BOOL eqInitialized;
|
BOOL eqInitialized;
|
||||||
|
@ -84,49 +91,87 @@ using std::atomic_long;
|
||||||
AudioStreamBasicDescription realStreamFormat; // stream format pre-hrtf
|
AudioStreamBasicDescription realStreamFormat; // stream format pre-hrtf
|
||||||
AudioStreamBasicDescription streamFormat; // stream format last seen in render callback
|
AudioStreamBasicDescription streamFormat; // stream format last seen in render callback
|
||||||
|
|
||||||
|
AudioStreamBasicDescription visFormat; // Mono format for vis
|
||||||
|
|
||||||
uint32_t deviceChannelConfig;
|
uint32_t deviceChannelConfig;
|
||||||
uint32_t realStreamChannelConfig;
|
uint32_t realStreamChannelConfig;
|
||||||
uint32_t streamChannelConfig;
|
uint32_t streamChannelConfig;
|
||||||
|
|
||||||
AUAudioUnit *_au;
|
AUAudioUnit *_au;
|
||||||
|
|
||||||
|
AudioTimeStamp timeStamp;
|
||||||
|
|
||||||
size_t _bufferSize;
|
size_t _bufferSize;
|
||||||
|
|
||||||
|
AudioUnit _eq;
|
||||||
|
|
||||||
|
DownmixProcessor *downmixer;
|
||||||
|
DownmixProcessor *downmixerForVis;
|
||||||
|
|
||||||
|
VisualizationController *visController;
|
||||||
|
|
||||||
|
BOOL enableHrtf;
|
||||||
|
HeadphoneFilter *hrtf;
|
||||||
|
|
||||||
|
BOOL enableFSurround;
|
||||||
|
BOOL FSurroundDelayRemoved;
|
||||||
|
int inputBufferLastTime;
|
||||||
|
FSurroundFilter *fsurround;
|
||||||
|
|
||||||
|
int inputRemain;
|
||||||
|
|
||||||
|
AudioChunk *chunkRemain;
|
||||||
|
|
||||||
|
int visResamplerRemain;
|
||||||
|
|
||||||
BOOL resetStreamFormat;
|
BOOL resetStreamFormat;
|
||||||
|
|
||||||
BOOL shouldPlayOutBuffer;
|
BOOL shouldPlayOutBuffer;
|
||||||
|
|
||||||
ChunkList *outputBuffer;
|
float *samplePtr;
|
||||||
|
float tempBuffer[512 * 32];
|
||||||
|
float rsInBuffer[8192 * 32];
|
||||||
|
float rsTempBuffer[4096 * 32];
|
||||||
|
float inputBuffer[4096 * 32]; // 4096 samples times maximum supported channel count
|
||||||
|
float fsurroundBuffer[8192 * 6];
|
||||||
|
float hrtfBuffer[4096 * 2];
|
||||||
|
float eqBuffer[4096 * 32];
|
||||||
|
float downmixBuffer[4096 * 8];
|
||||||
|
|
||||||
|
float visAudio[4096];
|
||||||
|
float visResamplerInput[8192];
|
||||||
|
float visTemp[8192];
|
||||||
|
|
||||||
|
BOOL referenceMatrixSet;
|
||||||
|
BOOL rotationMatrixUpdated;
|
||||||
|
simd_float4x4 rotationMatrix;
|
||||||
|
simd_float4x4 referenceMatrix;
|
||||||
|
|
||||||
#ifdef OUTPUT_LOG
|
#ifdef OUTPUT_LOG
|
||||||
NSFileHandle *_logFile;
|
FILE *_logFile;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithController:(OutputNode *)c;
|
- (id)initWithController:(OutputNode *)c;
|
||||||
|
|
||||||
- (BOOL)setup;
|
- (BOOL)setup;
|
||||||
- (OSStatus)setOutputDeviceByID:(int)deviceID;
|
- (OSStatus)setOutputDeviceByID:(AudioDeviceID)deviceID;
|
||||||
- (BOOL)setOutputDeviceWithDeviceDict:(NSDictionary *)deviceDict;
|
- (BOOL)setOutputDeviceWithDeviceDict:(NSDictionary *)deviceDict;
|
||||||
- (void)start;
|
- (void)start;
|
||||||
- (void)pause;
|
- (void)pause;
|
||||||
- (void)resume;
|
- (void)resume;
|
||||||
- (void)stop;
|
- (void)stop;
|
||||||
|
|
||||||
- (void)fadeOut;
|
|
||||||
- (void)fadeOutBackground;
|
|
||||||
- (void)fadeIn;
|
|
||||||
|
|
||||||
- (double)latency;
|
- (double)latency;
|
||||||
|
|
||||||
- (double)volume;
|
|
||||||
- (void)setVolume:(double)v;
|
- (void)setVolume:(double)v;
|
||||||
|
|
||||||
|
- (void)setEqualizerEnabled:(BOOL)enabled;
|
||||||
|
|
||||||
- (void)setShouldPlayOutBuffer:(BOOL)enabled;
|
- (void)setShouldPlayOutBuffer:(BOOL)enabled;
|
||||||
|
|
||||||
- (void)sustainHDCD;
|
- (void)sustainHDCD;
|
||||||
|
|
||||||
- (AudioStreamBasicDescription)deviceFormat;
|
- (void)reportMotion:(simd_float4x4)matrix;
|
||||||
- (uint32_t)deviceChannelConfig;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,6 @@
|
||||||
// Plugins! HOORAY!
|
// Plugins! HOORAY!
|
||||||
|
|
||||||
#if __has_include(<CogAudio/AudioChunk.h>)
|
#import "AudioChunk.h"
|
||||||
# import <CogAudio/AudioChunk.h>
|
|
||||||
#else
|
|
||||||
# import "AudioChunk.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@protocol CogSource <NSObject>
|
@protocol CogSource <NSObject>
|
||||||
+ (NSArray *)schemes; // http, file, etc
|
+ (NSArray *)schemes; // http, file, etc
|
||||||
|
@ -110,10 +106,9 @@
|
||||||
- (int)putMetadataInURL:(NSURL *)url;
|
- (int)putMetadataInURL:(NSURL *)url;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#ifdef __cplusplus
|
static NSString *guess_encoding_of_string(const char *input) {
|
||||||
extern "C" {
|
NSString *ret = @"";
|
||||||
#endif
|
NSData *stringData = [NSData dataWithBytes:input length:strlen(input)];
|
||||||
extern NSString *guess_encoding_of_string(const char *input);
|
[NSString stringEncodingForData:stringData encodingOptions:nil convertedString:&ret usedLossyConversion:nil];
|
||||||
#ifdef __cplusplus
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#import <CogAudio/Plugin.h>
|
#import "Plugin.h"
|
||||||
|
|
||||||
// Singletonish
|
// Singletonish
|
||||||
@interface PluginController : NSObject <CogPluginController> {
|
@interface PluginController : NSObject <CogPluginController> {
|
||||||
|
|
|
@ -389,6 +389,8 @@ static NSString *xmlEscapeString(NSString * string) {
|
||||||
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\
|
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\
|
||||||
<plist version=\"1.0\">\n\
|
<plist version=\"1.0\">\n\
|
||||||
<dict>\n\
|
<dict>\n\
|
||||||
|
\t<key>FirebaseCrashlyticsCollectionEnabled</key>\n\
|
||||||
|
\t<false/>\n\
|
||||||
\t<key>SUEnableInstallerLauncherService</key>\n\
|
\t<key>SUEnableInstallerLauncherService</key>\n\
|
||||||
\t<true/>\n\
|
\t<true/>\n\
|
||||||
\t<key>CFBundleDevelopmentRegion</key>\n\
|
\t<key>CFBundleDevelopmentRegion</key>\n\
|
||||||
|
@ -467,22 +469,12 @@ static NSString *xmlEscapeString(NSString * string) {
|
||||||
\t<string>MediaKeysApplication</string>\n\
|
\t<string>MediaKeysApplication</string>\n\
|
||||||
\t<key>NSRemindersUsageDescription</key>\n\
|
\t<key>NSRemindersUsageDescription</key>\n\
|
||||||
\t<string>Cog has no use for your reminders. Why are you trying to access them with an audio player?</string>\n\
|
\t<string>Cog has no use for your reminders. Why are you trying to access them with an audio player?</string>\n\
|
||||||
\t<key>NSDownloadsFolderUsageDescription</key>\n\
|
|
||||||
\t<string>We may request related audio files from this folder for playback purposes. We will only play back files you specifically add, unless you enable the option to add an entire folder. Granting permission either for individual files or for parent folders ensures their contents will remain playable in future sessions.</string>\n\
|
|
||||||
\t<key>NSDocumentsFolderUsageDescription</key>\n\
|
|
||||||
\t<string>We may request related audio files from this folder for playback purposes. We will only play back files you specifically add, unless you enable the option to add an entire folder. Granting permission either for individual files or for parent folders ensures their contents will remain playable in future sessions.</string>\n\
|
|
||||||
\t<key>NSDesktopFolderUsageDescription</key>\n\
|
|
||||||
\t<string>We may request related audio files from this folder for playback purposes. We will only play back files you specifically add, unless you enable the option to add an entire folder. Granting permission either for individual files or for parent folders ensures their contents will remain playable in future sessions.</string>\n\
|
|
||||||
\t<key>NSMotionUsageDescription</key>\n\
|
|
||||||
\t<string>Cog optionally supports motion tracking headphones for head tracked positional audio, using its own low latency positioning model.</string>\n\
|
|
||||||
\t<key>OSAScriptingDefinition</key>\n\
|
\t<key>OSAScriptingDefinition</key>\n\
|
||||||
\t<string>Cog.sdef</string>\n\
|
\t<string>Cog.sdef</string>\n\
|
||||||
\t<key>SUFeedURL</key>\n\
|
\t<key>SUFeedURL</key>\n\
|
||||||
\t<string>https://cogcdn.cog.losno.co/mercury.xml</string>\n\
|
\t<string>https://cogcdn.cog.losno.co/mercury.xml</string>\n\
|
||||||
\t<key>SUPublicEDKey</key>\n\
|
\t<key>SUPublicEDKey</key>\n\
|
||||||
\t<string>omxG7Rp0XK9/YEvKbVy7cd44eVAh1LJB6CmjQwjOJz4=</string>\n\
|
\t<string>omxG7Rp0XK9/YEvKbVy7cd44eVAh1LJB6CmjQwjOJz4=</string>\n\
|
||||||
\t<key>ITSAppUsesNonExemptEncryption</key>\n\
|
|
||||||
\t<false/>\n\
|
|
||||||
</dict>\n\
|
</dict>\n\
|
||||||
</plist>\n";
|
</plist>\n";
|
||||||
NSMutableArray * decodersRegistered = [[NSMutableArray alloc] init];
|
NSMutableArray * decodersRegistered = [[NSMutableArray alloc] init];
|
||||||
|
@ -830,24 +822,3 @@ static NSString *xmlEscapeString(NSString * string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NSString *guess_encoding_of_string(const char *input) {
|
|
||||||
NSString *ret = @"";
|
|
||||||
if(input && *input) {
|
|
||||||
@try {
|
|
||||||
ret = [NSString stringWithUTF8String:input];
|
|
||||||
}
|
|
||||||
@catch(NSException *e) {
|
|
||||||
ret = nil;
|
|
||||||
}
|
|
||||||
if(!ret) {
|
|
||||||
// This method is incredibly slow
|
|
||||||
NSData *stringData = [NSData dataWithBytes:input length:strlen(input)];
|
|
||||||
[NSString stringEncodingForData:stringData encodingOptions:nil convertedString:&ret usedLossyConversion:nil];
|
|
||||||
if(!ret) {
|
|
||||||
ret = @"";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
52
Audio/ThirdParty/lvqcl/lpc.c
vendored
52
Audio/ThirdParty/lvqcl/lpc.c
vendored
|
@ -139,10 +139,7 @@ static void vorbis_lpc_predict(float *coeff, float *prime, int m, float *data, l
|
||||||
}
|
}
|
||||||
|
|
||||||
void lpc_extrapolate2(float *const data, const size_t data_len, const int nch, const int lpc_order, const size_t extra_bkwd, const size_t extra_fwd, void **extrapolate_buffer, size_t *extrapolate_buffer_size) {
|
void lpc_extrapolate2(float *const data, const size_t data_len, const int nch, const int lpc_order, const size_t extra_bkwd, const size_t extra_fwd, void **extrapolate_buffer, size_t *extrapolate_buffer_size) {
|
||||||
const size_t max_to_prime = (data_len < lpc_order) ? data_len : lpc_order;
|
const size_t tdata_size = sizeof(float) * (extra_bkwd + data_len + extra_fwd);
|
||||||
const size_t min_data_len = (data_len < lpc_order) ? lpc_order : data_len;
|
|
||||||
|
|
||||||
const size_t tdata_size = sizeof(float) * (extra_bkwd + min_data_len + extra_fwd);
|
|
||||||
const size_t aut_size = sizeof(double) * (lpc_order + 1);
|
const size_t aut_size = sizeof(double) * (lpc_order + 1);
|
||||||
const size_t lpc_size = sizeof(double) * lpc_order;
|
const size_t lpc_size = sizeof(double) * lpc_order;
|
||||||
const size_t lpci_size = sizeof(float) * lpc_order;
|
const size_t lpci_size = sizeof(float) * lpc_order;
|
||||||
|
@ -155,65 +152,42 @@ void lpc_extrapolate2(float *const data, const size_t data_len, const int nch, c
|
||||||
*extrapolate_buffer_size = new_size;
|
*extrapolate_buffer_size = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
double *aut = (double *)(*extrapolate_buffer);
|
float *tdata = (float *)(*extrapolate_buffer); // for 1 channel only
|
||||||
double *lpc = (double *)(*extrapolate_buffer + aut_size);
|
|
||||||
|
|
||||||
float *tdata = (float *)(*extrapolate_buffer + aut_size + lpc_size); // for 1 channel only
|
double *aut = (double *)(*extrapolate_buffer + tdata_size);
|
||||||
|
double *lpc = (double *)(*extrapolate_buffer + tdata_size + aut_size);
|
||||||
float *lpci = (float *)(*extrapolate_buffer + aut_size + lpc_size + tdata_size);
|
float *lpci = (float *)(*extrapolate_buffer + tdata_size + aut_size + lpc_size);
|
||||||
float *work = (float *)(*extrapolate_buffer + aut_size + lpc_size + tdata_size + lpci_size);
|
float *work = (float *)(*extrapolate_buffer + tdata_size + aut_size + lpc_size + lpci_size);
|
||||||
|
|
||||||
for(int c = 0; c < nch; c++) {
|
for(int c = 0; c < nch; c++) {
|
||||||
if(extra_bkwd) {
|
if(extra_bkwd) {
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
tdata[min_data_len - 1 - i] = data[i * nch + c];
|
tdata[data_len - 1 - i] = data[i * nch + c];
|
||||||
if(data_len < min_data_len)
|
|
||||||
for(int i = (int)data_len; i < (int)min_data_len; i++)
|
|
||||||
tdata[min_data_len - 1 - i] = 0.0f;
|
|
||||||
} else {
|
} else {
|
||||||
const ssize_t len_diff = min_data_len - data_len;
|
|
||||||
if(len_diff <= 0) {
|
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
tdata[i] = data[i * nch + c];
|
tdata[i] = data[i * nch + c];
|
||||||
} else {
|
|
||||||
for(int i = 0; i < (int)len_diff; i++)
|
|
||||||
tdata[i] = 0.0f;
|
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
|
||||||
tdata[len_diff + i] = data[i * nch + c];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_window(tdata, min_data_len);
|
apply_window(tdata, data_len);
|
||||||
vorbis_lpc_from_data(tdata, lpci, (int)min_data_len, lpc_order, aut, lpc);
|
vorbis_lpc_from_data(tdata, lpci, (int)data_len, lpc_order, aut, lpc);
|
||||||
|
|
||||||
// restore after apply_window
|
// restore after apply_window
|
||||||
if(extra_bkwd) {
|
if(extra_bkwd) {
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
tdata[min_data_len - 1 - i] = data[i * nch + c];
|
tdata[data_len - 1 - i] = data[i * nch + c];
|
||||||
if(data_len < min_data_len)
|
|
||||||
for(int i = (int)data_len; i < (int)min_data_len; i++)
|
|
||||||
tdata[min_data_len - 1 - i] = 0.0f;
|
|
||||||
} else {
|
} else {
|
||||||
const ssize_t len_diff = min_data_len - data_len;
|
|
||||||
if(len_diff <= 0) {
|
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
for(int i = 0; i < (int)data_len; i++)
|
||||||
tdata[i] = data[i * nch + c];
|
tdata[i] = data[i * nch + c];
|
||||||
} else {
|
|
||||||
for(int i = 0; i < (int)len_diff; i++)
|
|
||||||
tdata[i] = 0.0f;
|
|
||||||
for(int i = 0; i < (int)data_len; i++)
|
|
||||||
tdata[len_diff + i] = data[i * nch + c];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vorbis_lpc_predict(lpci, tdata + min_data_len - lpc_order, lpc_order, tdata + min_data_len, extra_fwd + extra_bkwd, work);
|
vorbis_lpc_predict(lpci, tdata + data_len - lpc_order, lpc_order, tdata + data_len, extra_fwd + extra_bkwd, work);
|
||||||
|
|
||||||
if(extra_bkwd) {
|
if(extra_bkwd) {
|
||||||
for(int i = 0; i < extra_bkwd; i++)
|
for(int i = 0; i < extra_bkwd; i++)
|
||||||
data[(-i - 1) * nch + c] = tdata[min_data_len + i];
|
data[(-i - 1) * nch + c] = tdata[data_len + i];
|
||||||
} else {
|
} else {
|
||||||
for(int i = 0; i < extra_fwd; i++)
|
for(int i = 0; i < extra_fwd; i++)
|
||||||
data[(i + data_len) * nch + c] = tdata[min_data_len + i];
|
data[(i + data_len) * nch + c] = tdata[data_len + i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,20 +10,21 @@
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface VisualizationController : NSObject {
|
@interface VisualizationController : NSObject {
|
||||||
|
double sampleRate;
|
||||||
|
double latency;
|
||||||
|
float *visAudio;
|
||||||
|
int visAudioCursor, visAudioSize;
|
||||||
|
float *visAudioTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (VisualizationController *)sharedController;
|
+ (VisualizationController *)sharedController;
|
||||||
|
|
||||||
- (void)postLatency:(double)latency;
|
- (void)postLatency:(double)latency;
|
||||||
|
|
||||||
- (UInt64)samplesPosted;
|
|
||||||
|
|
||||||
- (void)postSampleRate:(double)sampleRate;
|
- (void)postSampleRate:(double)sampleRate;
|
||||||
- (void)postVisPCM:(const float *)inPCM amount:(int)amount;
|
- (void)postVisPCM:(const float *)inPCM amount:(int)amount;
|
||||||
- (double)readSampleRate;
|
- (double)readSampleRate;
|
||||||
- (void)copyVisPCM:(float *_Nullable)outPCM visFFT:(float *_Nullable)outFFT latencyOffset:(double)latency;
|
- (void)copyVisPCM:(float *)outPCM visFFT:(float *)outFFT latencyOffset:(double)latency;
|
||||||
|
|
||||||
- (void)reset;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,7 @@
|
||||||
|
|
||||||
#import "fft.h"
|
#import "fft.h"
|
||||||
|
|
||||||
@implementation VisualizationController {
|
@implementation VisualizationController
|
||||||
double sampleRate;
|
|
||||||
double latency;
|
|
||||||
float *visAudio;
|
|
||||||
int visAudioCursor, visAudioSize;
|
|
||||||
uint64_t visSamplesPosted;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VisualizationController *_sharedController = nil;
|
static VisualizationController *_sharedController = nil;
|
||||||
|
|
||||||
|
@ -33,8 +27,11 @@ static VisualizationController *_sharedController = nil;
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
visAudio = NULL;
|
visAudio = NULL;
|
||||||
visAudioSize = 0;
|
|
||||||
latency = 0;
|
latency = 0;
|
||||||
|
visAudioTemp = (float *) calloc(sizeof(float), 4096);
|
||||||
|
if(!visAudioTemp) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -43,17 +40,6 @@ static VisualizationController *_sharedController = nil;
|
||||||
fft_free();
|
fft_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reset {
|
|
||||||
@synchronized (self) {
|
|
||||||
latency = 0;
|
|
||||||
visAudioCursor = 0;
|
|
||||||
visSamplesPosted = 0;
|
|
||||||
if(visAudio && visAudioSize) {
|
|
||||||
bzero(visAudio, sizeof(float) * visAudioSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)postSampleRate:(double)sampleRate {
|
- (void)postSampleRate:(double)sampleRate {
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
if(self->sampleRate != sampleRate) {
|
if(self->sampleRate != sampleRate) {
|
||||||
|
@ -67,12 +53,6 @@ static VisualizationController *_sharedController = nil;
|
||||||
self->visAudio = visAudio;
|
self->visAudio = visAudio;
|
||||||
self->visAudioSize = visAudioSize;
|
self->visAudioSize = visAudioSize;
|
||||||
visAudioCursor %= visAudioSize;
|
visAudioCursor %= visAudioSize;
|
||||||
} else {
|
|
||||||
if(self->visAudio) {
|
|
||||||
free(self->visAudio);
|
|
||||||
self->visAudio = NULL;
|
|
||||||
}
|
|
||||||
self->visAudioSize = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,9 +60,6 @@ static VisualizationController *_sharedController = nil;
|
||||||
|
|
||||||
- (void)postVisPCM:(const float *)inPCM amount:(int)amount {
|
- (void)postVisPCM:(const float *)inPCM amount:(int)amount {
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
if(!visAudioSize) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int samplesRead = 0;
|
int samplesRead = 0;
|
||||||
while(amount > 0) {
|
while(amount > 0) {
|
||||||
int amountToCopy = (int)(visAudioSize - visAudioCursor);
|
int amountToCopy = (int)(visAudioSize - visAudioCursor);
|
||||||
|
@ -92,7 +69,6 @@ static VisualizationController *_sharedController = nil;
|
||||||
if(visAudioCursor >= visAudioSize) visAudioCursor -= visAudioSize;
|
if(visAudioCursor >= visAudioSize) visAudioCursor -= visAudioSize;
|
||||||
amount -= amountToCopy;
|
amount -= amountToCopy;
|
||||||
samplesRead += amountToCopy;
|
samplesRead += amountToCopy;
|
||||||
visSamplesPosted += amountToCopy;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,11 +84,7 @@ static VisualizationController *_sharedController = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UInt64)samplesPosted {
|
- (void)copyVisPCM:(float *)outPCM visFFT:(float *)outFFT latencyOffset:(double)latency {
|
||||||
return visSamplesPosted;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)copyVisPCM:(float *_Nullable)outPCM visFFT:(float *_Nullable)outFFT latencyOffset:(double)latency {
|
|
||||||
if(!outPCM && !outFFT) return;
|
if(!outPCM && !outFFT) return;
|
||||||
|
|
||||||
if(!visAudio || !visAudioSize) {
|
if(!visAudio || !visAudioSize) {
|
||||||
|
@ -121,12 +93,7 @@ static VisualizationController *_sharedController = nil;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *visAudioTemp = calloc(sizeof(float), 4096);
|
if(!outPCM) outPCM = &visAudioTemp[0];
|
||||||
if(!visAudioTemp) {
|
|
||||||
if(outPCM) bzero(outPCM, sizeof(float) * 4096);
|
|
||||||
if(outFFT) bzero(outFFT, sizeof(float) * 2048);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
if(!sampleRate) {
|
if(!sampleRate) {
|
||||||
|
@ -136,14 +103,11 @@ static VisualizationController *_sharedController = nil;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int latencySamples = (int)(sampleRate * (self->latency + latency)) + 2048;
|
int latencySamples = (int)(sampleRate * (self->latency + latency));
|
||||||
if(latencySamples < 4096) latencySamples = 4096;
|
if(latencySamples < 4096) latencySamples = 4096;
|
||||||
int readCursor = visAudioCursor - latencySamples;
|
int readCursor = visAudioCursor - latencySamples;
|
||||||
int samples = 4096;
|
int samples = 4096;
|
||||||
int samplesRead = 0;
|
int samplesRead = 0;
|
||||||
if(latencySamples + samples > visAudioSize) {
|
|
||||||
samples = (int)(visAudioSize - latencySamples);
|
|
||||||
}
|
|
||||||
while(readCursor < 0)
|
while(readCursor < 0)
|
||||||
readCursor += visAudioSize;
|
readCursor += visAudioSize;
|
||||||
while(readCursor >= visAudioSize)
|
while(readCursor >= visAudioSize)
|
||||||
|
@ -151,21 +115,16 @@ static VisualizationController *_sharedController = nil;
|
||||||
while(samples > 0) {
|
while(samples > 0) {
|
||||||
int samplesToRead = (int)(visAudioSize - readCursor);
|
int samplesToRead = (int)(visAudioSize - readCursor);
|
||||||
if(samplesToRead > samples) samplesToRead = samples;
|
if(samplesToRead > samples) samplesToRead = samples;
|
||||||
cblas_scopy(samplesToRead, visAudio + readCursor, 1, visAudioTemp + samplesRead, 1);
|
cblas_scopy(samplesToRead, visAudio + readCursor, 1, outPCM + samplesRead, 1);
|
||||||
samplesRead += samplesToRead;
|
samplesRead += samplesToRead;
|
||||||
readCursor += samplesToRead;
|
readCursor += samplesToRead;
|
||||||
samples -= samplesToRead;
|
samples -= samplesToRead;
|
||||||
if(readCursor >= visAudioSize) readCursor -= visAudioSize;
|
if(readCursor >= visAudioSize) readCursor -= visAudioSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(outPCM) {
|
|
||||||
cblas_scopy(4096, visAudioTemp, 1, outPCM, 1);
|
|
||||||
}
|
|
||||||
if(outFFT) {
|
if(outFFT) {
|
||||||
fft_calculate(visAudioTemp, outFFT, 2048);
|
fft_calculate(outPCM, outFFT, 2048);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(visAudioTemp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -15,7 +15,6 @@ class VisualizationController : NSObject {
|
||||||
var visAudio: [Float] = Array(repeating: 0.0, count: 44100 * 45)
|
var visAudio: [Float] = Array(repeating: 0.0, count: 44100 * 45)
|
||||||
var visAudioCursor = 0
|
var visAudioCursor = 0
|
||||||
var visAudioSize = 0
|
var visAudioSize = 0
|
||||||
var visSamplesPosted: UInt64 = 0
|
|
||||||
|
|
||||||
private static var sharedVisualizationController: VisualizationController = {
|
private static var sharedVisualizationController: VisualizationController = {
|
||||||
let visualizationController = VisualizationController()
|
let visualizationController = VisualizationController()
|
||||||
|
@ -35,7 +34,6 @@ class VisualizationController : NSObject {
|
||||||
for i in 0..<amount {
|
for i in 0..<amount {
|
||||||
self.visAudio[i] = 0
|
self.visAudio[i] = 0
|
||||||
}
|
}
|
||||||
self.visSamplesPosted = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,11 +42,6 @@ class VisualizationController : NSObject {
|
||||||
self.latency = latency
|
self.latency = latency
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
|
||||||
func samplesPosted() -> UInt64 {
|
|
||||||
return self.visSamplesPosted
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
func postSampleRate(_ sampleRate: Double) {
|
func postSampleRate(_ sampleRate: Double) {
|
||||||
serialQueue.sync {
|
serialQueue.sync {
|
||||||
|
@ -67,20 +60,13 @@ class VisualizationController : NSObject {
|
||||||
let bufferPointer = UnsafeBufferPointer<Float>(start: inPCM, count: amount)
|
let bufferPointer = UnsafeBufferPointer<Float>(start: inPCM, count: amount)
|
||||||
var j = self.visAudioCursor
|
var j = self.visAudioCursor
|
||||||
let k = self.visAudioSize
|
let k = self.visAudioSize
|
||||||
if(j + amount <= k) {
|
for i in 0..<amount {
|
||||||
let endIndex = j + amount;
|
let x = bufferPointer[i]
|
||||||
self.visAudio.replaceSubrange(j..<endIndex, with: bufferPointer)
|
self.visAudio[j] = x
|
||||||
j += amount
|
j += 1; if j >= k { j = 0 }
|
||||||
if(j >= k) { j = 0 }
|
|
||||||
} else {
|
|
||||||
let inEndIndex = k - j
|
|
||||||
let remainder = amount - inEndIndex
|
|
||||||
self.visAudio.replaceSubrange(j..<k, with: bufferPointer.prefix(inEndIndex))
|
|
||||||
self.visAudio.replaceSubrange(0..<remainder, with: bufferPointer.suffix(remainder))
|
|
||||||
j = remainder
|
|
||||||
}
|
}
|
||||||
self.visAudioCursor = j
|
self.visAudioCursor = j
|
||||||
self.visSamplesPosted += UInt64(amount);
|
self.latency += Double(amount) / self.sampleRate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +80,18 @@ class VisualizationController : NSObject {
|
||||||
@objc
|
@objc
|
||||||
func copyVisPCM(_ outPCM: UnsafeMutablePointer<Float>?, visFFT: UnsafeMutablePointer<Float>?, latencyOffset: Double) {
|
func copyVisPCM(_ outPCM: UnsafeMutablePointer<Float>?, visFFT: UnsafeMutablePointer<Float>?, latencyOffset: Double) {
|
||||||
if(self.visAudioSize == 0) {
|
if(self.visAudioSize == 0) {
|
||||||
outPCM?.update(repeating: 0.0, count: 4096)
|
if(outPCM != nil) {
|
||||||
visFFT?.update(repeating: 0.0, count: 2048)
|
let pcmPointer = UnsafeMutableBufferPointer<Float>(start: outPCM, count: 4096)
|
||||||
|
for i in 0...4095 {
|
||||||
|
pcmPointer[i] = 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(visFFT != nil) {
|
||||||
|
let fftPointer = UnsafeMutableBufferPointer<Float>(start: visFFT, count: 2048)
|
||||||
|
for i in 0...2047 {
|
||||||
|
fftPointer[i] = 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,9 +101,6 @@ class VisualizationController : NSObject {
|
||||||
// Offset latency so the target sample is in the center of the window
|
// Offset latency so the target sample is in the center of the window
|
||||||
let latencySamples = (Int)((self.latency + latencyOffset) * self.sampleRate) + 2048
|
let latencySamples = (Int)((self.latency + latencyOffset) * self.sampleRate) + 2048
|
||||||
var samplesToDo = 4096;
|
var samplesToDo = 4096;
|
||||||
if(latencySamples < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(latencySamples < 4096) {
|
if(latencySamples < 4096) {
|
||||||
// Latency can sometimes dip below this threshold
|
// Latency can sometimes dip below this threshold
|
||||||
samplesToDo = latencySamples;
|
samplesToDo = latencySamples;
|
||||||
|
@ -115,17 +108,25 @@ class VisualizationController : NSObject {
|
||||||
var j = self.visAudioCursor - latencySamples
|
var j = self.visAudioCursor - latencySamples
|
||||||
let k = self.visAudioSize
|
let k = self.visAudioSize
|
||||||
if j < 0 { j += k }
|
if j < 0 { j += k }
|
||||||
if(j + samplesToDo <= k) {
|
for i in 0..<samplesToDo {
|
||||||
outPCMCopy.replaceSubrange(0..<samplesToDo, with: self.visAudio.suffix(from: j).prefix(samplesToDo))
|
let x = self.visAudio[j]
|
||||||
} else {
|
outPCMCopy[i] = x
|
||||||
let outEndIndex = k - j
|
j += 1; if j >= k { j = 0 }
|
||||||
let remainder = samplesToDo - outEndIndex
|
}
|
||||||
outPCMCopy.replaceSubrange(0..<outEndIndex, with: self.visAudio.suffix(from: j))
|
if(samplesToDo < 4096) {
|
||||||
outPCMCopy.replaceSubrange(outEndIndex..<samplesToDo, with: self.visAudio.prefix(remainder))
|
for i in samplesToDo...4095 {
|
||||||
|
outPCMCopy[i] = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outPCM?.update(from: outPCMCopy, count: 4096)
|
if(outPCM != nil) {
|
||||||
|
let pcmPointer = UnsafeMutableBufferPointer<Float>(start: outPCM, count: 4096)
|
||||||
|
for i in 0...4095 {
|
||||||
|
let x = outPCMCopy[i]
|
||||||
|
pcmPointer[i] = x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(visFFT != nil) {
|
if(visFFT != nil) {
|
||||||
serialQueue.sync {
|
serialQueue.sync {
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22113.1" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22113.1"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<customObject id="-2" userLabel="File's Owner" customClass="FeedbackController">
|
<customObject id="-2" userLabel="File's Owner" customClass="FeedbackController">
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="emailView" destination="10" id="X4O-Qx-zUq"/>
|
<outlet property="fromView" destination="5" id="37"/>
|
||||||
<outlet property="messageView" destination="15" id="gwe-Bb-ZEz"/>
|
<outlet property="messageView" destination="15" id="38"/>
|
||||||
<outlet property="nameView" destination="5" id="9Uz-Hh-EVf"/>
|
<outlet property="sendingIndicator" destination="12" id="39"/>
|
||||||
|
<outlet property="subjectView" destination="10" id="36"/>
|
||||||
<outlet property="window" destination="1" id="42"/>
|
<outlet property="window" destination="1" id="42"/>
|
||||||
</connections>
|
</connections>
|
||||||
</customObject>
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<window title="Send Crash Feedback" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="1" userLabel="FeedbackWindow">
|
<window title="Send Feedback" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="1" userLabel="FeedbackWindow">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
<rect key="contentRect" x="168" y="357" width="480" height="376"/>
|
<rect key="contentRect" x="168" y="357" width="480" height="376"/>
|
||||||
|
@ -26,37 +27,7 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="480" height="376"/>
|
<rect key="frame" x="0.0" y="0.0" width="480" height="376"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8" userLabel="Name:">
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="10">
|
||||||
<rect key="frame" x="17" y="339" width="58" height="17"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Name:" id="18" userLabel="Name:">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5" userLabel="Name Field">
|
|
||||||
<rect key="frame" x="80" y="337" width="356" height="22"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="21">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
<connections>
|
|
||||||
<outlet property="nextKeyView" destination="10" id="CNG-sG-ab3"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4">
|
|
||||||
<rect key="frame" x="17" y="297" width="58" height="17"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Email:" id="22">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="10" userLabel="Email Field">
|
|
||||||
<rect key="frame" x="80" y="295" width="356" height="22"/>
|
<rect key="frame" x="80" y="295" width="356" height="22"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="left" drawsBackground="YES" id="16">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="left" drawsBackground="YES" id="16">
|
||||||
|
@ -65,13 +36,22 @@
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="nextKeyView" destination="15" id="Xi7-6Y-bG1"/>
|
<outlet property="nextKeyView" destination="15" id="30"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7">
|
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8">
|
||||||
<rect key="frame" x="17" y="262" width="272" height="17"/>
|
<rect key="frame" x="17" y="297" width="58" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Describe what you were doing:" id="19">
|
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Subject:" id="18">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7">
|
||||||
|
<rect key="frame" x="17" y="262" width="66" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Message:" id="19">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -81,15 +61,15 @@
|
||||||
<rect key="frame" x="20" y="55" width="440" height="199"/>
|
<rect key="frame" x="20" y="55" width="440" height="199"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<clipView key="contentView" drawsBackground="NO" id="tK9-bv-5OD">
|
<clipView key="contentView" drawsBackground="NO" id="tK9-bv-5OD">
|
||||||
<rect key="frame" x="1" y="1" width="423" height="197"/>
|
<rect key="frame" x="1" y="1" width="438" height="197"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView importsGraphics="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" usesRuler="YES" smartInsertDelete="YES" id="15">
|
<textView importsGraphics="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" usesRuler="YES" smartInsertDelete="YES" id="15">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="423" height="197"/>
|
<rect key="frame" x="0.0" y="0.0" width="438" height="197"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
<size key="minSize" width="423" height="197"/>
|
<size key="minSize" width="438" height="197"/>
|
||||||
<size key="maxSize" width="863" height="10000000"/>
|
<size key="maxSize" width="863" height="10000000"/>
|
||||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textView>
|
</textView>
|
||||||
|
@ -100,7 +80,7 @@
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="14">
|
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="14">
|
||||||
<rect key="frame" x="424" y="1" width="15" height="197"/>
|
<rect key="frame" x="423" y="1" width="16" height="197"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<connections>
|
<connections>
|
||||||
|
@ -131,6 +111,31 @@
|
||||||
<outlet property="nextKeyView" destination="5" id="28"/>
|
<outlet property="nextKeyView" destination="5" id="28"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<progressIndicator horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" maxValue="100" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="12">
|
||||||
|
<rect key="frame" x="444" y="340" width="16" height="16"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</progressIndicator>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
|
||||||
|
<rect key="frame" x="80" y="337" width="356" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="21">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<outlet property="nextKeyView" destination="10" id="33"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4">
|
||||||
|
<rect key="frame" x="17" y="339" width="71" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Email:" id="22">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
</subviews>
|
</subviews>
|
||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -167,7 +167,6 @@
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
<connections>
|
<connections>
|
||||||
<binding destination="-2" name="toolTip" keyPath="valueToDisplay.lengthInfo" id="26q-iJ-ecn"/>
|
|
||||||
<binding destination="-2" name="value" keyPath="valueToDisplay.lengthText" id="ji7-tL-8rb"/>
|
<binding destination="-2" name="value" keyPath="valueToDisplay.lengthText" id="ji7-tL-8rb"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -17,31 +17,31 @@
|
||||||
<window title="Cog" separatorStyle="none" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Cog" animationBehavior="default" tabbingMode="disallowed" toolbarStyle="unified" id="21" userLabel="Window" customClass="MainWindow">
|
<window title="Cog" separatorStyle="none" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Cog" animationBehavior="default" tabbingMode="disallowed" toolbarStyle="unified" id="21" userLabel="Window" customClass="MainWindow">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||||
<rect key="contentRect" x="331" y="367" width="1281" height="400"/>
|
<rect key="contentRect" x="331" y="367" width="1000" height="400"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1055"/>
|
||||||
<value key="minSize" type="size" width="750" height="200"/>
|
<value key="minSize" type="size" width="750" height="200"/>
|
||||||
<stackView key="contentView" distribution="equalSpacing" orientation="vertical" alignment="centerX" spacing="0.0" misplaced="YES" detachesHiddenViews="YES" id="2">
|
<stackView key="contentView" distribution="equalSpacing" orientation="vertical" alignment="centerX" spacing="0.0" misplaced="YES" detachesHiddenViews="YES" id="2">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1281" height="400"/>
|
<rect key="frame" x="0.0" y="0.0" width="1000" height="400"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<splitView dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2123">
|
<splitView dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2123">
|
||||||
<rect key="frame" x="0.0" y="349" width="1274" height="51"/>
|
<rect key="frame" x="0.0" y="362" width="1171" height="38"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="0.0" verticalLineScroll="24" verticalPageScroll="0.0" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="206" userLabel="Scroll View - Playlist View">
|
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="0.0" verticalLineScroll="24" verticalPageScroll="0.0" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" id="206" userLabel="Scroll View - Playlist View">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1274" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="1171" height="38"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="KWC-Ti-8KY">
|
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="KWC-Ti-8KY">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1274" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="1171" height="38"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" autosaveName="Playlist" rowHeight="18" headerView="1517" viewBased="YES" id="207" customClass="PlaylistView">
|
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" alternatingRowBackgroundColors="YES" autosaveName="Playlist" rowHeight="18" headerView="1517" viewBased="YES" id="207" customClass="PlaylistView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1274" height="34"/>
|
<rect key="frame" x="0.0" y="0.0" width="1171" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<size key="intercellSpacing" width="3" height="6"/>
|
<size key="intercellSpacing" width="3" height="6"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||||
<tableColumns>
|
<tableColumns>
|
||||||
<tableColumn identifier="index" editable="NO" width="62" minWidth="28" maxWidth="64" id="209">
|
<tableColumn identifier="index" editable="NO" width="63" minWidth="28" maxWidth="64" id="209">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="#">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="#">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
@ -54,11 +54,11 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="5N3-SP-Y8z">
|
<tableCellView id="5N3-SP-Y8z">
|
||||||
<rect key="frame" x="11" y="3" width="67" height="18"/>
|
<rect key="frame" x="11" y="3" width="68" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="w5u-JQ-3Hf">
|
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="w5u-JQ-3Hf">
|
||||||
<rect key="frame" x="0.0" y="1" width="67" height="16"/>
|
<rect key="frame" x="0.0" y="1" width="68" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="right" title="Table View Cell" id="FMU-QZ-NdQ">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="right" title="Table View Cell" id="FMU-QZ-NdQ">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="Vw5-xt-0vG">
|
<tableCellView id="Vw5-xt-0vG">
|
||||||
<rect key="frame" x="81" y="3" width="20" height="17"/>
|
<rect key="frame" x="82" y="3" width="20" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ERj-i9-caa">
|
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ERj-i9-caa">
|
||||||
|
@ -127,7 +127,7 @@
|
||||||
</tableCellView>
|
</tableCellView>
|
||||||
</prototypeCellViews>
|
</prototypeCellViews>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn identifier="rating" editable="NO" width="114" minWidth="48" maxWidth="128" id="208" userLabel="Rating">
|
<tableColumn identifier="rating" editable="NO" width="106.5" minWidth="48" maxWidth="128" id="208" userLabel="Rating">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Rating">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Rating">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
@ -141,11 +141,11 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="ZCP-Dx-UBV">
|
<tableCellView id="ZCP-Dx-UBV">
|
||||||
<rect key="frame" x="104" y="3" width="114" height="18"/>
|
<rect key="frame" x="105" y="3" width="107" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="exY-Bg-Mjm">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="exY-Bg-Mjm">
|
||||||
<rect key="frame" x="0.0" y="1" width="114" height="16"/>
|
<rect key="frame" x="0.0" y="1" width="107" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="sdo-Sm-KPH">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="sdo-Sm-KPH">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -171,7 +171,7 @@
|
||||||
</binding>
|
</binding>
|
||||||
</connections>
|
</connections>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn identifier="title" editable="NO" width="177" minWidth="96" maxWidth="1024" id="XBr-ec-D81">
|
<tableColumn identifier="title" editable="NO" width="168.5" minWidth="96" maxWidth="1024" id="XBr-ec-D81">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Title">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Title">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.33333299" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
@ -185,11 +185,11 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="ZHl-H1-IIC">
|
<tableCellView id="ZHl-H1-IIC">
|
||||||
<rect key="frame" x="221" y="3" width="177" height="18"/>
|
<rect key="frame" x="215" y="3" width="168" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="dQP-wC-mba">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="dQP-wC-mba">
|
||||||
<rect key="frame" x="0.0" y="1" width="177" height="16"/>
|
<rect key="frame" x="0.0" y="1" width="168" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="VVx-99-roJ">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="VVx-99-roJ">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -259,7 +259,7 @@
|
||||||
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="dJs-UO-m5r"/>
|
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="dJs-UO-m5r"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn identifier="artist" editable="NO" width="200" minWidth="96" maxWidth="1024" id="391">
|
<tableColumn identifier="artist" editable="NO" width="193" minWidth="96" maxWidth="1024" id="391">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Artist">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Artist">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -273,11 +273,11 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="gpC-Oe-Rog">
|
<tableCellView id="gpC-Oe-Rog">
|
||||||
<rect key="frame" x="401" y="3" width="200" height="18"/>
|
<rect key="frame" x="386" y="3" width="193" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="1WK-qN-Mgj">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="1WK-qN-Mgj">
|
||||||
<rect key="frame" x="0.0" y="1" width="200" height="16"/>
|
<rect key="frame" x="0.0" y="1" width="193" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="71l-3L-S3g">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="71l-3L-S3g">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -347,7 +347,7 @@
|
||||||
</binding>
|
</binding>
|
||||||
</connections>
|
</connections>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn identifier="album" editable="NO" width="200.5" minWidth="96" maxWidth="1024" id="806">
|
<tableColumn identifier="album" editable="NO" width="193.5" minWidth="96" maxWidth="1024" id="806">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Album">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Album">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -361,11 +361,11 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="1ed-gX-bct">
|
<tableCellView id="1ed-gX-bct">
|
||||||
<rect key="frame" x="604" y="3" width="201" height="18"/>
|
<rect key="frame" x="582" y="3" width="194" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="nEt-s5-vRX">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="nEt-s5-vRX">
|
||||||
<rect key="frame" x="0.0" y="1" width="201" height="16"/>
|
<rect key="frame" x="0.0" y="1" width="194" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="moV-3G-GpB">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="moV-3G-GpB">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -391,7 +391,7 @@
|
||||||
</binding>
|
</binding>
|
||||||
</connections>
|
</connections>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn identifier="length" editable="NO" width="93.5" minWidth="43.62012" maxWidth="96" id="807">
|
<tableColumn identifier="length" editable="NO" width="95" minWidth="43.62012" maxWidth="96" id="807">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Length">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Length">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -404,11 +404,11 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="hhB-nv-e78">
|
<tableCellView id="hhB-nv-e78">
|
||||||
<rect key="frame" x="808" y="3" width="93" height="18"/>
|
<rect key="frame" x="779" y="3" width="95" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="tHy-sM-HDB">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="tHy-sM-HDB">
|
||||||
<rect key="frame" x="0.0" y="1" width="94" height="16"/>
|
<rect key="frame" x="0.0" y="1" width="95" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="Igo-5f-yim">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="Igo-5f-yim">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -435,7 +435,7 @@
|
||||||
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1919"/>
|
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1919"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn identifier="year" editable="NO" width="93.5" minWidth="42" maxWidth="96" id="848">
|
<tableColumn identifier="year" editable="NO" width="95" minWidth="42" maxWidth="96" id="848">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Year">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Year">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -448,11 +448,11 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="q93-oh-i5T">
|
<tableCellView id="q93-oh-i5T">
|
||||||
<rect key="frame" x="904" y="3" width="94" height="18"/>
|
<rect key="frame" x="877" y="3" width="95" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="bOi-LI-TDx">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="bOi-LI-TDx">
|
||||||
<rect key="frame" x="0.0" y="1" width="94" height="16"/>
|
<rect key="frame" x="0.0" y="1" width="95" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="C2Q-qG-dwX">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="C2Q-qG-dwX">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -475,7 +475,7 @@
|
||||||
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1921"/>
|
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1921"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn identifier="genre" editable="NO" width="112.5" minWidth="32" maxWidth="512" id="849">
|
<tableColumn identifier="genre" editable="NO" width="106.5" minWidth="32" maxWidth="512" id="849">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Genre">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Genre">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -489,11 +489,11 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="rRl-p9-Awr">
|
<tableCellView id="rRl-p9-Awr">
|
||||||
<rect key="frame" x="1001" y="3" width="112" height="18"/>
|
<rect key="frame" x="975" y="3" width="106" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="yW6-2w-6mN">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="yW6-2w-6mN">
|
||||||
<rect key="frame" x="0.0" y="1" width="113" height="16"/>
|
<rect key="frame" x="0.0" y="1" width="106" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="js2-sT-U4M">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="js2-sT-U4M">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -516,7 +516,7 @@
|
||||||
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1922"/>
|
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1922"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn identifier="track" editable="NO" width="69.5" minWidth="24" maxWidth="72" id="850">
|
<tableColumn identifier="track" editable="NO" width="71" minWidth="24" maxWidth="72" id="850">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="№">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="№">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -529,11 +529,11 @@
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
<prototypeCellViews>
|
<prototypeCellViews>
|
||||||
<tableCellView id="hgh-VE-5kl">
|
<tableCellView id="hgh-VE-5kl">
|
||||||
<rect key="frame" x="1116" y="3" width="70" height="18"/>
|
<rect key="frame" x="1084" y="3" width="75" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="yEY-MI-d3o">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="yEY-MI-d3o">
|
||||||
<rect key="frame" x="0.0" y="1" width="70" height="16"/>
|
<rect key="frame" x="0.0" y="1" width="75" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="tus-lr-RhS">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="tus-lr-RhS">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -556,50 +556,6 @@
|
||||||
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1923"/>
|
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="1923"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn identifier="playcount" editable="NO" width="69.5" minWidth="24" maxWidth="72" id="1g1-Th-emL" userLabel="Play Count">
|
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="right" title="Play Count">
|
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</tableHeaderCell>
|
|
||||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="right" title="Text Cell" id="Bhh-hp-xx3">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
|
||||||
<prototypeCellViews>
|
|
||||||
<tableCellView id="aED-2V-LLM">
|
|
||||||
<rect key="frame" x="1189" y="3" width="73" height="18"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="tYz-2J-JRx">
|
|
||||||
<rect key="frame" x="0.0" y="1" width="74" height="16"/>
|
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="HJL-T1-ufx">
|
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="tYz-2J-JRx" firstAttribute="centerX" secondItem="aED-2V-LLM" secondAttribute="centerX" id="37Y-n2-p29"/>
|
|
||||||
<constraint firstItem="tYz-2J-JRx" firstAttribute="leading" secondItem="aED-2V-LLM" secondAttribute="leading" constant="2" id="4gs-nP-xUS"/>
|
|
||||||
<constraint firstItem="tYz-2J-JRx" firstAttribute="centerY" secondItem="aED-2V-LLM" secondAttribute="centerY" id="SjU-Ta-4Sc"/>
|
|
||||||
</constraints>
|
|
||||||
<connections>
|
|
||||||
<outlet property="textField" destination="tYz-2J-JRx" id="bNh-Jc-1yQ"/>
|
|
||||||
</connections>
|
|
||||||
</tableCellView>
|
|
||||||
</prototypeCellViews>
|
|
||||||
<connections>
|
|
||||||
<binding destination="218" name="value" keyPath="arrangedObjects.playCount" id="6s9-cV-iYx">
|
|
||||||
<dictionary key="options">
|
|
||||||
<bool key="NSConditionallySetsEditable" value="YES"/>
|
|
||||||
</dictionary>
|
|
||||||
</binding>
|
|
||||||
<binding destination="1689" name="fontSize" keyPath="values.fontSize" id="iAQ-bR-gvW"/>
|
|
||||||
</connections>
|
|
||||||
</tableColumn>
|
|
||||||
<tableColumn identifier="path" editable="NO" width="64" minWidth="32" maxWidth="2048" hidden="YES" id="1712">
|
<tableColumn identifier="path" editable="NO" width="64" minWidth="32" maxWidth="2048" hidden="YES" id="1712">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Path">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Path">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -888,11 +844,11 @@
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="1515">
|
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="1515">
|
||||||
<rect key="frame" x="1209" y="17" width="15" height="11"/>
|
<rect key="frame" x="85" y="17" width="15" height="68"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<tableHeaderView key="headerView" wantsLayer="YES" id="1517">
|
<tableHeaderView key="headerView" wantsLayer="YES" id="1517">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1274" height="17"/>
|
<rect key="frame" x="0.0" y="0.0" width="1171" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</tableHeaderView>
|
</tableHeaderView>
|
||||||
</scrollView>
|
</scrollView>
|
||||||
|
@ -905,7 +861,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</splitView>
|
</splitView>
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="778">
|
<textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="778">
|
||||||
<rect key="frame" x="507" y="4" width="261" height="14"/>
|
<rect key="frame" x="455" y="4" width="261" height="14"/>
|
||||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="center" title="Total Duration: 00 hours 00 minutes 00 seconds" bezelStyle="round" id="1473">
|
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="center" title="Total Duration: 00 hours 00 minutes 00 seconds" bezelStyle="round" id="1473">
|
||||||
<font key="font" metaFont="controlContent" size="11"/>
|
<font key="font" metaFont="controlContent" size="11"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -940,7 +896,7 @@
|
||||||
<real value="3.4028234663852886e+38"/>
|
<real value="3.4028234663852886e+38"/>
|
||||||
</customSpacing>
|
</customSpacing>
|
||||||
</stackView>
|
</stackView>
|
||||||
<toolbar key="toolbar" implicitIdentifier="B4998081-90DD-45DD-8243-0F7039C7DEA2" showsBaselineSeparator="NO" displayMode="iconOnly" sizeMode="regular" id="1523">
|
<toolbar key="toolbar" implicitIdentifier="B4998081-90DD-45DD-8243-0F7039C7DEA2" displayMode="iconOnly" sizeMode="regular" id="1523">
|
||||||
<allowedToolbarItems>
|
<allowedToolbarItems>
|
||||||
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="1552"/>
|
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="1552"/>
|
||||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="1529"/>
|
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="1529"/>
|
||||||
|
@ -1042,7 +998,7 @@
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
</toolbarItem>
|
</toolbarItem>
|
||||||
<toolbarItem implicitItemIdentifier="3B680DEB-106E-4549-A478-FFB8A6738053" label="Volume" paletteLabel="Volume" image="volume3Template" bordered="YES" visibilityPriority="10" sizingBehavior="auto" id="1610">
|
<toolbarItem implicitItemIdentifier="3B680DEB-106E-4549-A478-FFB8A6738053" label="Volume" paletteLabel="Volume" image="volume3Template" visibilityPriority="10" sizingBehavior="auto" id="1610">
|
||||||
<nil key="toolTip"/>
|
<nil key="toolTip"/>
|
||||||
<button key="view" verticalHuggingPriority="750" id="1608" customClass="VolumeButton">
|
<button key="view" verticalHuggingPriority="750" id="1608" customClass="VolumeButton">
|
||||||
<rect key="frame" x="9" y="14" width="29" height="23"/>
|
<rect key="frame" x="9" y="14" width="29" height="23"/>
|
||||||
|
@ -1056,24 +1012,6 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</toolbarItem>
|
</toolbarItem>
|
||||||
<toolbarItem implicitItemIdentifier="7BC995AD-3F93-40E1-AE76-94574D34BCB0" label="Speed" paletteLabel="Speed" image="deskclock" catalog="system" bordered="YES" visibilityPriority="10" sizingBehavior="auto" id="ufn-od-xJF" userLabel="Speed">
|
|
||||||
<nil key="toolTip"/>
|
|
||||||
<button key="view" verticalHuggingPriority="750" id="Ta5-Ik-jh9" userLabel="Speed Button" customClass="SpeedButton">
|
|
||||||
<rect key="frame" x="7" y="14" width="27" height="23"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="deskclock" catalog="system" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="2Al-Cl-n36">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<outlet property="_LockButton" destination="OQS-2p-1yP" id="F1I-fb-SDQ"/>
|
|
||||||
<outlet property="_PitchSlider" destination="6P4-yi-9TK" id="Ni0-G0-USM"/>
|
|
||||||
<outlet property="_ResetButton" destination="3Zc-Xv-g24" id="C7x-EU-QpA"/>
|
|
||||||
<outlet property="_TempoSlider" destination="stI-oD-51s" id="Mt0-7i-R4f"/>
|
|
||||||
<outlet property="_popView" destination="90w-7t-RYP" id="qfi-e0-UZc"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</toolbarItem>
|
|
||||||
<toolbarItem implicitItemIdentifier="2F487D99-16E9-4BF8-9A98-637FABEB2716" label="Info Inspector" paletteLabel="Info Inspector" image="infoTemplate" navigational="YES" id="1629">
|
<toolbarItem implicitItemIdentifier="2F487D99-16E9-4BF8-9A98-637FABEB2716" label="Info Inspector" paletteLabel="Info Inspector" image="infoTemplate" navigational="YES" id="1629">
|
||||||
<nil key="toolTip"/>
|
<nil key="toolTip"/>
|
||||||
<size key="minSize" width="28" height="23"/>
|
<size key="minSize" width="28" height="23"/>
|
||||||
|
@ -1237,7 +1175,6 @@
|
||||||
<toolbarItem reference="ZH9-ZU-skw"/>
|
<toolbarItem reference="ZH9-ZU-skw"/>
|
||||||
<toolbarItem reference="1539"/>
|
<toolbarItem reference="1539"/>
|
||||||
<toolbarItem reference="1610"/>
|
<toolbarItem reference="1610"/>
|
||||||
<toolbarItem reference="ufn-od-xJF"/>
|
|
||||||
<toolbarItem reference="1552"/>
|
<toolbarItem reference="1552"/>
|
||||||
<toolbarItem reference="1568"/>
|
<toolbarItem reference="1568"/>
|
||||||
<toolbarItem reference="1551"/>
|
<toolbarItem reference="1551"/>
|
||||||
|
@ -1267,7 +1204,7 @@
|
||||||
<outlet property="mainToolbar" destination="1523" id="J2X-YK-xV0"/>
|
<outlet property="mainToolbar" destination="1523" id="J2X-YK-xV0"/>
|
||||||
<outlet property="playlistView" destination="206" id="mah-wo-1nd"/>
|
<outlet property="playlistView" destination="206" id="mah-wo-1nd"/>
|
||||||
</connections>
|
</connections>
|
||||||
<point key="canvasLocation" x="270.5" y="131"/>
|
<point key="canvasLocation" x="130" y="131"/>
|
||||||
</window>
|
</window>
|
||||||
<window title="Cog" separatorStyle="none" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Mini Window" animationBehavior="default" toolbarStyle="unified" id="2234" userLabel="Mini Window (Window)" customClass="MiniWindow">
|
<window title="Cog" separatorStyle="none" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="Mini Window" animationBehavior="default" toolbarStyle="unified" id="2234" userLabel="Mini Window (Window)" customClass="MiniWindow">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
|
@ -1277,7 +1214,7 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="581" height="0.0"/>
|
<rect key="frame" x="0.0" y="0.0" width="581" height="0.0"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
</view>
|
</view>
|
||||||
<toolbar key="toolbar" implicitIdentifier="35998ECE-5AD8-429E-8479-657249B22C9C" showsBaselineSeparator="NO" displayMode="iconOnly" sizeMode="regular" id="2222" userLabel="Mini Toolbar">
|
<toolbar key="toolbar" implicitIdentifier="35998ECE-5AD8-429E-8479-657249B22C9C" displayMode="iconOnly" sizeMode="regular" id="2222" userLabel="Mini Toolbar">
|
||||||
<allowedToolbarItems>
|
<allowedToolbarItems>
|
||||||
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="2227"/>
|
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="2227"/>
|
||||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="2228"/>
|
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="2228"/>
|
||||||
|
@ -1671,12 +1608,6 @@
|
||||||
<action selector="scrollToCurrentEntry:" target="207" id="1888"/>
|
<action selector="scrollToCurrentEntry:" target="207" id="1888"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Selection Follows Playback" id="Q7K-Eu-1Vf">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<binding destination="1689" name="value" keyPath="values.selectionFollowsPlayback" id="pml-0X-qIh"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
@ -1888,12 +1819,6 @@
|
||||||
<action selector="stopAfterCurrent:" target="218" id="1896"/>
|
<action selector="stopAfterCurrent:" target="218" id="1896"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Always Stop After Current" keyEquivalent="." id="y8c-n8-5Uh">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
|
||||||
<connections>
|
|
||||||
<binding destination="1689" name="value" keyPath="values.alwaysStopAfterCurrent" id="rwr-s6-PnE"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
@ -2253,7 +2178,6 @@ Gw
|
||||||
<string>path</string>
|
<string>path</string>
|
||||||
<string>status</string>
|
<string>status</string>
|
||||||
<mutableString>queued</mutableString>
|
<mutableString>queued</mutableString>
|
||||||
<string>playCount</string>
|
|
||||||
</declaredKeys>
|
</declaredKeys>
|
||||||
<classReference key="objectClass" className="PlaylistEntry"/>
|
<classReference key="objectClass" className="PlaylistEntry"/>
|
||||||
<connections>
|
<connections>
|
||||||
|
@ -2416,12 +2340,9 @@ Gw
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="appController" destination="226" id="TnP-DA-nJl"/>
|
<outlet property="appController" destination="226" id="TnP-DA-nJl"/>
|
||||||
<outlet property="equalizerWindowController" destination="dJ9-b3-BFu" id="gB5-Bu-vqC"/>
|
<outlet property="equalizerWindowController" destination="dJ9-b3-BFu" id="gB5-Bu-vqC"/>
|
||||||
<outlet property="lockButton" destination="OQS-2p-1yP" id="RfR-WH-ZPY"/>
|
|
||||||
<outlet property="pitchSlider" destination="6P4-yi-9TK" id="Lnu-kw-iYW"/>
|
|
||||||
<outlet property="playlistController" destination="218" id="706"/>
|
<outlet property="playlistController" destination="218" id="706"/>
|
||||||
<outlet property="playlistLoader" destination="1319" id="ghZ-65-60L"/>
|
<outlet property="playlistLoader" destination="1319" id="ghZ-65-60L"/>
|
||||||
<outlet property="playlistView" destination="207" id="717"/>
|
<outlet property="playlistView" destination="207" id="717"/>
|
||||||
<outlet property="tempoSlider" destination="stI-oD-51s" id="dDc-lb-crL"/>
|
|
||||||
<outlet property="volumeSlider" destination="1612" id="1615"/>
|
<outlet property="volumeSlider" destination="1612" id="1615"/>
|
||||||
</connections>
|
</connections>
|
||||||
</customObject>
|
</customObject>
|
||||||
|
@ -2601,107 +2522,6 @@ Gw
|
||||||
</subviews>
|
</subviews>
|
||||||
<point key="canvasLocation" x="615" y="-25"/>
|
<point key="canvasLocation" x="615" y="-25"/>
|
||||||
</customView>
|
</customView>
|
||||||
<customView id="90w-7t-RYP" userLabel="Speed View">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="69" height="216"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uVG-0w-rW4">
|
|
||||||
<rect key="frame" x="4" y="199" width="24" height="14"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="🎵" id="bQV-ZD-SDv">
|
|
||||||
<font key="font" metaFont="smallSystem"/>
|
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VUX-JL-rjr">
|
|
||||||
<rect key="frame" x="41" y="199" width="24" height="14"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="⏰" id="4R4-ba-Ndx">
|
|
||||||
<font key="font" metaFont="smallSystem"/>
|
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
<slider horizontalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6P4-yi-9TK" userLabel="Pitch Slider" customClass="PitchSlider">
|
|
||||||
<rect key="frame" x="6" y="34" width="20" height="164"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<sliderCell key="cell" controlSize="small" continuous="YES" state="on" alignment="left" maxValue="100" doubleValue="40.824829049999998" tickMarkPosition="left" sliderType="linear" id="vTw-tV-W5R"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="changePitch:" target="705" id="bZt-zY-tjg"/>
|
|
||||||
<binding destination="1689" name="enabled" keyPath="values.rubberbandEngine" id="3Kk-ix-XCv">
|
|
||||||
<dictionary key="options">
|
|
||||||
<string key="NSValueTransformerName">RubberbandEngineEnabledTransformer</string>
|
|
||||||
</dictionary>
|
|
||||||
</binding>
|
|
||||||
<outlet property="_TempoSlider" destination="stI-oD-51s" id="HMq-pE-Ssc"/>
|
|
||||||
</connections>
|
|
||||||
</slider>
|
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OQS-2p-1yP" userLabel="Lock Button">
|
|
||||||
<rect key="frame" x="17" y="101" width="36" height="27"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<buttonCell key="cell" type="push" title="🔒" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="M0v-A9-meu">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
|
||||||
<font key="font" metaFont="smallSystem"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="pressLock:" target="Ta5-Ik-jh9" id="HnF-AC-arz"/>
|
|
||||||
<binding destination="1689" name="enabled" keyPath="values.rubberbandEngine" id="BUK-i6-qzt">
|
|
||||||
<dictionary key="options">
|
|
||||||
<string key="NSValueTransformerName">RubberbandEngineEnabledTransformer</string>
|
|
||||||
</dictionary>
|
|
||||||
</binding>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<slider horizontalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="stI-oD-51s" userLabel="Tempo Slider" customClass="TempoSlider">
|
|
||||||
<rect key="frame" x="42" y="34" width="20" height="164"/>
|
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
|
||||||
<sliderCell key="cell" controlSize="small" continuous="YES" alignment="left" maxValue="100" doubleValue="40.824829049999998" tickMarkPosition="left" sliderType="linear" id="94j-7B-a8j"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="changeTempo:" target="705" id="8xu-Dm-ceG"/>
|
|
||||||
<binding destination="1689" name="enabled" keyPath="values.rubberbandEngine" id="eRW-kg-FQc">
|
|
||||||
<dictionary key="options">
|
|
||||||
<string key="NSValueTransformerName">RubberbandEngineEnabledTransformer</string>
|
|
||||||
</dictionary>
|
|
||||||
</binding>
|
|
||||||
<outlet property="_PitchSlider" destination="6P4-yi-9TK" id="QaV-cx-2wf"/>
|
|
||||||
</connections>
|
|
||||||
</slider>
|
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3Zc-Xv-g24" userLabel="Reset Button">
|
|
||||||
<rect key="frame" x="2" y="2" width="64" height="27"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<buttonCell key="cell" type="push" title="1.0×" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ijs-k0-EIP">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
|
||||||
<font key="font" metaFont="smallSystem"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="pressReset:" target="Ta5-Ik-jh9" id="zoi-N3-teA"/>
|
|
||||||
<binding destination="1689" name="enabled" keyPath="values.rubberbandEngine" id="GU1-d5-uWi">
|
|
||||||
<dictionary key="options">
|
|
||||||
<string key="NSValueTransformerName">RubberbandEngineEnabledTransformer</string>
|
|
||||||
</dictionary>
|
|
||||||
</binding>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yQh-Rt-nJL" userLabel="Notice">
|
|
||||||
<rect key="frame" x="0.0" y="57" width="66" height="27"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<buttonCell key="cell" type="push" title="⚠️" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="XV7-Re-I9u">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
|
||||||
<font key="font" metaFont="smallSystem"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="showRubberbandSettings:" target="226" id="zqd-7k-1f0"/>
|
|
||||||
<binding destination="1689" name="hidden" keyPath="values.rubberbandEngine" id="BoK-zT-W4T">
|
|
||||||
<dictionary key="options">
|
|
||||||
<string key="NSValueTransformerName">RubberbandEngineHiddenTransformer</string>
|
|
||||||
</dictionary>
|
|
||||||
</binding>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
|
||||||
<point key="canvasLocation" x="964.5" y="12"/>
|
|
||||||
</customView>
|
|
||||||
<customObject id="1675" customClass="SpotlightWindowController">
|
<customObject id="1675" customClass="SpotlightWindowController">
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="playlistLoader" destination="1319" id="1694"/>
|
<outlet property="playlistLoader" destination="1319" id="1694"/>
|
||||||
|
@ -2767,7 +2587,6 @@ Gw
|
||||||
</objects>
|
</objects>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="deadItemsTemplate" width="20" height="20"/>
|
<image name="deadItemsTemplate" width="20" height="20"/>
|
||||||
<image name="deskclock" catalog="system" width="15" height="16"/>
|
|
||||||
<image name="duplicateItemsTemplate" width="20" height="20"/>
|
<image name="duplicateItemsTemplate" width="20" height="20"/>
|
||||||
<image name="equalizerTemplate" width="20" height="20"/>
|
<image name="equalizerTemplate" width="20" height="20"/>
|
||||||
<image name="hdcdLogoTemplate" width="656" height="225"/>
|
<image name="hdcdLogoTemplate" width="656" height="225"/>
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.security.app-sandbox</key>
|
<key>com.apple.security.app-sandbox</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.cs.disable-library-validation</key>
|
|
||||||
<true/>
|
|
||||||
<key>com.apple.security.cs.allow-jit</key>
|
<key>com.apple.security.cs.allow-jit</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.files.user-selected.read-write</key>
|
<key>com.apple.security.files.user-selected.read-write</key>
|
||||||
|
|
|
@ -98,11 +98,13 @@
|
||||||
830C37A527B95EB300E02BB0 /* EqualizerWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 830C37A427B95EB300E02BB0 /* EqualizerWindowController.m */; };
|
830C37A527B95EB300E02BB0 /* EqualizerWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 830C37A427B95EB300E02BB0 /* EqualizerWindowController.m */; };
|
||||||
830C37FC27B9956C00E02BB0 /* analyzer.c in Sources */ = {isa = PBXBuildFile; fileRef = 830C37F227B9956C00E02BB0 /* analyzer.c */; };
|
830C37FC27B9956C00E02BB0 /* analyzer.c in Sources */ = {isa = PBXBuildFile; fileRef = 830C37F227B9956C00E02BB0 /* analyzer.c */; };
|
||||||
831B99BF27C23E88005A969B /* Cog.sdef in Resources */ = {isa = PBXBuildFile; fileRef = 831B99BE27C23E88005A969B /* Cog.sdef */; };
|
831B99BF27C23E88005A969B /* Cog.sdef in Resources */ = {isa = PBXBuildFile; fileRef = 831B99BE27C23E88005A969B /* Cog.sdef */; };
|
||||||
|
83229C9F283B0095004626A8 /* SpectrumWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83229C9D283B0095004626A8 /* SpectrumWindowController.m */; };
|
||||||
83256B68286661FC0036D9C0 /* libmpg123.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83256B672866617F0036D9C0 /* libmpg123.0.dylib */; };
|
83256B68286661FC0036D9C0 /* libmpg123.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83256B672866617F0036D9C0 /* libmpg123.0.dylib */; };
|
||||||
83256B69286661FC0036D9C0 /* libmpg123.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83256B672866617F0036D9C0 /* libmpg123.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
83256B69286661FC0036D9C0 /* libmpg123.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83256B672866617F0036D9C0 /* libmpg123.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
8327DBA9293CAD2400CD0580 /* Organya.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8327DB94293C923500CD0580 /* Organya.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
8327DBA9293CAD2400CD0580 /* Organya.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8327DB94293C923500CD0580 /* Organya.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
832923AF279FAC400048201E /* Cog.q1.json in Resources */ = {isa = PBXBuildFile; fileRef = 832923AE279FAC400048201E /* Cog.q1.json */; };
|
832923AF279FAC400048201E /* Cog.q1.json in Resources */ = {isa = PBXBuildFile; fileRef = 832923AE279FAC400048201E /* Cog.q1.json */; };
|
||||||
832CFC4F2851AA1A002AC26F /* NSView+Visibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 832CFC4E2851AA1A002AC26F /* NSView+Visibility.m */; };
|
832CFC4F2851AA1A002AC26F /* NSView+Visibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 832CFC4E2851AA1A002AC26F /* NSView+Visibility.m */; };
|
||||||
|
832CFC562851AA8B002AC26F /* SpectrumViewCG.m in Sources */ = {isa = PBXBuildFile; fileRef = 832CFC552851AA8B002AC26F /* SpectrumViewCG.m */; };
|
||||||
833D0C2527C4ABB80060E16A /* ScriptAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 833D0C2427C4ABB80060E16A /* ScriptAdditions.m */; };
|
833D0C2527C4ABB80060E16A /* ScriptAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 833D0C2427C4ABB80060E16A /* ScriptAdditions.m */; };
|
||||||
83489C6B2782F78700BDCEA2 /* libvgmPlayer.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83489C542782F2DF00BDCEA2 /* libvgmPlayer.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
83489C6B2782F78700BDCEA2 /* libvgmPlayer.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83489C542782F2DF00BDCEA2 /* libvgmPlayer.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
834B05EA2859C006000B7DC0 /* TotalTimeTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 834B05E92859C006000B7DC0 /* TotalTimeTransformer.m */; };
|
834B05EA2859C006000B7DC0 /* TotalTimeTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 834B05E92859C006000B7DC0 /* TotalTimeTransformer.m */; };
|
||||||
|
@ -136,40 +138,34 @@
|
||||||
836FB5A718206F2500B3AD2D /* Hively.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 836FB5471820538800B3AD2D /* Hively.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
836FB5A718206F2500B3AD2D /* Hively.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 836FB5471820538800B3AD2D /* Hively.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
8370D73D277419F700245CE0 /* SQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8370D73C277419F700245CE0 /* SQLiteStore.m */; };
|
8370D73D277419F700245CE0 /* SQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8370D73C277419F700245CE0 /* SQLiteStore.m */; };
|
||||||
8370D73F2775AE1300245CE0 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8370D73E2775AE1300245CE0 /* libsqlite3.tbd */; };
|
8370D73F2775AE1300245CE0 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8370D73E2775AE1300245CE0 /* libsqlite3.tbd */; };
|
||||||
|
8372C93D27C7895300E250C9 /* MAD.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8372C93027C785BE00E250C9 /* MAD.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
8377C66327B8CF6300E8BC0F /* SpectrumViewSK.m in Sources */ = {isa = PBXBuildFile; fileRef = 8377C66127B8CF6300E8BC0F /* SpectrumViewSK.m */; };
|
8377C66327B8CF6300E8BC0F /* SpectrumViewSK.m in Sources */ = {isa = PBXBuildFile; fileRef = 8377C66127B8CF6300E8BC0F /* SpectrumViewSK.m */; };
|
||||||
8377C6B927B900F000E8BC0F /* SpectrumItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 8377C6B827B900F000E8BC0F /* SpectrumItem.m */; };
|
8377C6B927B900F000E8BC0F /* SpectrumItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 8377C6B827B900F000E8BC0F /* SpectrumItem.m */; };
|
||||||
837DC92B285B05710005C58A /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 837DC92A285B05710005C58A /* CoreData.framework */; };
|
837DC92B285B05710005C58A /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 837DC92A285B05710005C58A /* CoreData.framework */; };
|
||||||
837DC931285B3F790005C58A /* DataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 837DC92F285B3F790005C58A /* DataModel.xcdatamodeld */; };
|
837DC931285B3F790005C58A /* DataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 837DC92F285B3F790005C58A /* DataModel.xcdatamodeld */; };
|
||||||
8381A09227C5F72F00A1C530 /* SHA256Digest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8381A09127C5F72F00A1C530 /* SHA256Digest.m */; };
|
8381A09227C5F72F00A1C530 /* SHA256Digest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8381A09127C5F72F00A1C530 /* SHA256Digest.m */; };
|
||||||
8384914018083E4E00E7332D /* filetype.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8384913D18083E4E00E7332D /* filetype.icns */; };
|
8384914018083E4E00E7332D /* filetype.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8384913D18083E4E00E7332D /* filetype.icns */; };
|
||||||
838770FA2D6F0996001455A0 /* FeedbackController.m in Sources */ = {isa = PBXBuildFile; fileRef = 838770F42D6F0996001455A0 /* FeedbackController.m */; };
|
|
||||||
838A33742D06A9B100D0D770 /* librubberband.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 838A33732D06A9B100D0D770 /* librubberband.3.dylib */; };
|
|
||||||
838A33752D06A9CE00D0D770 /* librubberband.3.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 838A33732D06A9B100D0D770 /* librubberband.3.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
|
||||||
838A337D2D06C14200D0D770 /* TempoSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 838A337C2D06C14200D0D770 /* TempoSlider.m */; };
|
|
||||||
838A337E2D06C14200D0D770 /* PitchSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 838A337A2D06C14200D0D770 /* PitchSlider.m */; };
|
|
||||||
838A33832D06CF4100D0D770 /* SpectrumViewCG.m in Sources */ = {isa = PBXBuildFile; fileRef = 838A33802D06CF4100D0D770 /* SpectrumViewCG.m */; };
|
|
||||||
838A33842D06CF4100D0D770 /* SpectrumWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 838A33822D06CF4100D0D770 /* SpectrumWindowController.m */; };
|
|
||||||
838A33872D06CFCA00D0D770 /* SpeedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 838A33862D06CFCA00D0D770 /* SpeedButton.m */; };
|
|
||||||
83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83922FB6286B1AA900A0B039 /* WebKit.framework */; };
|
83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83922FB6286B1AA900A0B039 /* WebKit.framework */; };
|
||||||
839614A2286ED97200D3EEDB /* AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614A0286ED97200D3EEDB /* AboutWindowController.xib */; };
|
839614A2286ED97200D3EEDB /* AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614A0286ED97200D3EEDB /* AboutWindowController.xib */; };
|
||||||
839614AD286EDA5C00D3EEDB /* SpectrumWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614AB286EDA5C00D3EEDB /* SpectrumWindow.xib */; };
|
839614AD286EDA5C00D3EEDB /* SpectrumWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614AB286EDA5C00D3EEDB /* SpectrumWindow.xib */; };
|
||||||
|
83978E16285C58190076ED21 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 83978E15285C58190076ED21 /* FirebaseCrashlytics */; };
|
||||||
|
83978E26285C596F0076ED21 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 83978E25285C596F0076ED21 /* FirebaseAnalytics */; };
|
||||||
|
83978E29285C5C0A0076ED21 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 83978E28285C5C0A0076ED21 /* GoogleService-Info.plist */; };
|
||||||
83988F0E27BE0A5900A0E89A /* RedundantPlaylistDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 83988F0D27BE0A5900A0E89A /* RedundantPlaylistDataStore.m */; };
|
83988F0E27BE0A5900A0E89A /* RedundantPlaylistDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 83988F0D27BE0A5900A0E89A /* RedundantPlaylistDataStore.m */; };
|
||||||
8399D4E21805A55000B503B1 /* XmlContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8399D4E01805A55000B503B1 /* XmlContainer.m */; };
|
8399D4E21805A55000B503B1 /* XmlContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8399D4E01805A55000B503B1 /* XmlContainer.m */; };
|
||||||
839B837F286D7F8D00F529EE /* NumberHertzToStringTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839B837E286D7F8D00F529EE /* NumberHertzToStringTransformer.swift */; };
|
839B837F286D7F8D00F529EE /* NumberHertzToStringTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839B837E286D7F8D00F529EE /* NumberHertzToStringTransformer.swift */; };
|
||||||
839DA7CF274A2D4C001B18E5 /* NSDictionary+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = 839DA7CE274A2D4C001B18E5 /* NSDictionary+Merge.m */; };
|
839DA7CF274A2D4C001B18E5 /* NSDictionary+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = 839DA7CE274A2D4C001B18E5 /* NSDictionary+Merge.m */; };
|
||||||
839E56F52879625100DFB5F4 /* SADIE_D02-96000.mhr in Resources */ = {isa = PBXBuildFile; fileRef = 839E56F12879625100DFB5F4 /* SADIE_D02-96000.mhr */; };
|
839E56F52879625100DFB5F4 /* SADIE_D02-96000.mhr in Resources */ = {isa = PBXBuildFile; fileRef = 839E56F12879625100DFB5F4 /* SADIE_D02-96000.mhr */; };
|
||||||
839E876E2D5DA0AC00A13526 /* RubberbandEngineTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E876D2D5DA0AC00A13526 /* RubberbandEngineTransformer.m */; };
|
|
||||||
83A360B220E4E81D00192DAB /* Flac.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8303A30C20E4E3D000951EF8 /* Flac.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
83A360B220E4E81D00192DAB /* Flac.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8303A30C20E4E3D000951EF8 /* Flac.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
83A3B734283AE89000CC6593 /* ColorToValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A3B72F283AE6AA00CC6593 /* ColorToValueTransformer.m */; };
|
83A3B734283AE89000CC6593 /* ColorToValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A3B72F283AE6AA00CC6593 /* ColorToValueTransformer.m */; };
|
||||||
83AA7D04279EBCA900087AA4 /* libavcodec.61.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D00279EBC8200087AA4 /* libavcodec.61.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
83AA7D04279EBCA900087AA4 /* libavcodec.59.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D00279EBC8200087AA4 /* libavcodec.59.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
83AA7D05279EBCAB00087AA4 /* libavformat.61.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D03279EBC8300087AA4 /* libavformat.61.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
83AA7D05279EBCAB00087AA4 /* libavformat.59.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D03279EBC8300087AA4 /* libavformat.59.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
83AA7D06279EBCAD00087AA4 /* libavutil.59.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D02279EBC8200087AA4 /* libavutil.59.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
83AA7D06279EBCAD00087AA4 /* libavutil.57.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D02279EBC8200087AA4 /* libavutil.57.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
83AA7D07279EBCAF00087AA4 /* libswresample.5.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D01279EBC8200087AA4 /* libswresample.5.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
83AA7D07279EBCAF00087AA4 /* libswresample.4.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA7D01279EBC8200087AA4 /* libswresample.4.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
83B06704180D579E008E3612 /* MIDI.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B066A1180D5669008E3612 /* MIDI.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
83B06704180D579E008E3612 /* MIDI.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B066A1180D5669008E3612 /* MIDI.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
83B61E2429A8296500CD0580 /* LyricsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 83B61E2229A8296500CD0580 /* LyricsWindow.xib */; };
|
83B61E2429A8296500CD0580 /* LyricsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 83B61E2229A8296500CD0580 /* LyricsWindow.xib */; };
|
||||||
83B61E2829A82A0200CD0580 /* LyricsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83B61E2729A82A0200CD0580 /* LyricsWindowController.m */; };
|
83B61E2829A82A0200CD0580 /* LyricsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83B61E2729A82A0200CD0580 /* LyricsWindowController.m */; };
|
||||||
83B72E3B279045B7006007A3 /* libfdk-aac.2.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B72E2A279044F6006007A3 /* libfdk-aac.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
83B72E3B279045B7006007A3 /* libfdk-aac.2.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B72E2A279044F6006007A3 /* libfdk-aac.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
83B73B652D8FD75A00A57F08 /* minimp3.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83B73B602D8FC05A00A57F08 /* minimp3.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
|
||||||
83BC5AB220E4C87100631CD4 /* DualWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BC5AB020E4C87100631CD4 /* DualWindow.m */; };
|
83BC5AB220E4C87100631CD4 /* DualWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BC5AB020E4C87100631CD4 /* DualWindow.m */; };
|
||||||
83BC5ABF20E4CE7A00631CD4 /* InfoInspector.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B0D00F6320EA00694C57 /* InfoInspector.xib */; };
|
83BC5ABF20E4CE7A00631CD4 /* InfoInspector.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B0D00F6320EA00694C57 /* InfoInspector.xib */; };
|
||||||
83BC5AC020E4CE7D00631CD4 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17342A980D5FD20B00E8D854 /* MainMenu.xib */; };
|
83BC5AC020E4CE7D00631CD4 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17342A980D5FD20B00E8D854 /* MainMenu.xib */; };
|
||||||
|
@ -180,7 +176,6 @@
|
||||||
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; };
|
83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; };
|
||||||
83F9D8071A884C54007ABEC2 /* SilenceDecoder.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83F9D7F61A884B46007ABEC2 /* SilenceDecoder.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
83F9D8071A884C54007ABEC2 /* SilenceDecoder.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83F9D7F61A884B46007ABEC2 /* SilenceDecoder.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
83F9FFEF2D6EB75B00026576 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 83F9FFEE2D6EB75B00026576 /* Sentry */; };
|
|
||||||
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
|
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
|
||||||
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
|
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
|
||||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
||||||
|
@ -195,7 +190,7 @@
|
||||||
8E8D41C80CBB0DA900135C1B /* Pls.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E8D41C70CBB0DA000135C1B /* Pls.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
8E8D41C80CBB0DA900135C1B /* Pls.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E8D41C70CBB0DA000135C1B /* Pls.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A30140BA792DC0091081B /* NSFileHandle+CreateFile.m */; };
|
8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A30140BA792DC0091081B /* NSFileHandle+CreateFile.m */; };
|
||||||
99EAACA80DD1BB7A00423C38 /* APL.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 566D321B0D538550004466A5 /* APL.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
99EAACA80DD1BB7A00423C38 /* APL.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 566D321B0D538550004466A5 /* APL.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in Copy Files */ = {isa = PBXBuildFile; fileRef = 17F5622E0C3BD8FB0019975C /* Preferences.preferencePane */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17F5622E0C3BD8FB0019975C /* Preferences.preferencePane */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
ED69CBC725BE32C00090B90D /* MASShortcut.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED69CBBF25BE328C0090B90D /* MASShortcut.framework */; };
|
ED69CBC725BE32C00090B90D /* MASShortcut.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED69CBBF25BE328C0090B90D /* MASShortcut.framework */; };
|
||||||
ED69CBCA25BE32E80090B90D /* MASShortcut.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = ED69CBBF25BE328C0090B90D /* MASShortcut.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
ED69CBCA25BE32E80090B90D /* MASShortcut.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = ED69CBBF25BE328C0090B90D /* MASShortcut.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
EDAAA41F25A665C000731773 /* PositionSliderToolbarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDAAA41E25A665C000731773 /* PositionSliderToolbarItem.swift */; };
|
EDAAA41F25A665C000731773 /* PositionSliderToolbarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDAAA41E25A665C000731773 /* PositionSliderToolbarItem.swift */; };
|
||||||
|
@ -511,6 +506,20 @@
|
||||||
remoteGlobalIDString = 836FB52C1820538700B3AD2D;
|
remoteGlobalIDString = 836FB52C1820538700B3AD2D;
|
||||||
remoteInfo = Hively;
|
remoteInfo = Hively;
|
||||||
};
|
};
|
||||||
|
8372C92F27C785BE00E250C9 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 8372C92A27C785BD00E250C9 /* MAD.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 8372C92327C785BD00E250C9;
|
||||||
|
remoteInfo = MAD;
|
||||||
|
};
|
||||||
|
8372C93B27C7893100E250C9 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 8372C92A27C785BD00E250C9 /* MAD.xcodeproj */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 8372C92227C785BD00E250C9;
|
||||||
|
remoteInfo = MAD;
|
||||||
|
};
|
||||||
8375B36117FFEF010092A79F /* PBXContainerItemProxy */ = {
|
8375B36117FFEF010092A79F /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 8359FF2C17FEF35C0060F3ED /* ArchiveSource.xcodeproj */;
|
containerPortal = 8359FF2C17FEF35C0060F3ED /* ArchiveSource.xcodeproj */;
|
||||||
|
@ -532,20 +541,6 @@
|
||||||
remoteGlobalIDString = 83B06686180D5668008E3612;
|
remoteGlobalIDString = 83B06686180D5668008E3612;
|
||||||
remoteInfo = MIDI;
|
remoteInfo = MIDI;
|
||||||
};
|
};
|
||||||
83B73B5F2D8FC05A00A57F08 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 8372C92A27C785BD00E250C9 /* minimp3.xcodeproj */;
|
|
||||||
proxyType = 2;
|
|
||||||
remoteGlobalIDString = 8372C92327C785BD00E250C9;
|
|
||||||
remoteInfo = minimp3;
|
|
||||||
};
|
|
||||||
83B73B632D8FD74000A57F08 /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 8372C92A27C785BD00E250C9 /* minimp3.xcodeproj */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = 8372C92227C785BD00E250C9;
|
|
||||||
remoteInfo = minimp3;
|
|
||||||
};
|
|
||||||
83BB13C120E4E38E00723731 /* PBXContainerItemProxy */ = {
|
83BB13C120E4E38E00723731 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 836F6B2518BDB80D0095E648 /* vgmstream.xcodeproj */;
|
containerPortal = 836F6B2518BDB80D0095E648 /* vgmstream.xcodeproj */;
|
||||||
|
@ -661,15 +656,14 @@
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
07DFC3930ECDF80100DA400D /* Copy Files */ = {
|
07DFC3930ECDF80100DA400D /* CopyFiles */ = {
|
||||||
isa = PBXCopyFilesBuildPhase;
|
isa = PBXCopyFilesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 7;
|
dstSubfolderSpec = 7;
|
||||||
files = (
|
files = (
|
||||||
ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in Copy Files */,
|
ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in CopyFiles */,
|
||||||
);
|
);
|
||||||
name = "Copy Files";
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
177FD1000B90CB570011C3B5 /* CopyFiles */ = {
|
177FD1000B90CB570011C3B5 /* CopyFiles */ = {
|
||||||
|
@ -678,8 +672,8 @@
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 13;
|
dstSubfolderSpec = 13;
|
||||||
files = (
|
files = (
|
||||||
83B73B652D8FD75A00A57F08 /* minimp3.bundle in CopyFiles */,
|
|
||||||
8327DBA9293CAD2400CD0580 /* Organya.bundle in CopyFiles */,
|
8327DBA9293CAD2400CD0580 /* Organya.bundle in CopyFiles */,
|
||||||
|
8372C93D27C7895300E250C9 /* MAD.bundle in CopyFiles */,
|
||||||
83489C6B2782F78700BDCEA2 /* libvgmPlayer.bundle in CopyFiles */,
|
83489C6B2782F78700BDCEA2 /* libvgmPlayer.bundle in CopyFiles */,
|
||||||
834D794020E4EFEF00C4A5CC /* VorbisPlugin.bundle in CopyFiles */,
|
834D794020E4EFEF00C4A5CC /* VorbisPlugin.bundle in CopyFiles */,
|
||||||
834D793F20E4EFEA00C4A5CC /* OpusPlugin.bundle in CopyFiles */,
|
834D793F20E4EFEA00C4A5CC /* OpusPlugin.bundle in CopyFiles */,
|
||||||
|
@ -723,11 +717,10 @@
|
||||||
83256B69286661FC0036D9C0 /* libmpg123.0.dylib in CopyFiles */,
|
83256B69286661FC0036D9C0 /* libmpg123.0.dylib in CopyFiles */,
|
||||||
836EF0C927BB91E900BF35B2 /* libvorbisfile.3.dylib in CopyFiles */,
|
836EF0C927BB91E900BF35B2 /* libvorbisfile.3.dylib in CopyFiles */,
|
||||||
836EF0C827BB91E600BF35B2 /* libogg.0.dylib in CopyFiles */,
|
836EF0C827BB91E600BF35B2 /* libogg.0.dylib in CopyFiles */,
|
||||||
83AA7D07279EBCAF00087AA4 /* libswresample.5.dylib in CopyFiles */,
|
83AA7D07279EBCAF00087AA4 /* libswresample.4.dylib in CopyFiles */,
|
||||||
83AA7D06279EBCAD00087AA4 /* libavutil.59.dylib in CopyFiles */,
|
83AA7D06279EBCAD00087AA4 /* libavutil.57.dylib in CopyFiles */,
|
||||||
838A33752D06A9CE00D0D770 /* librubberband.3.dylib in CopyFiles */,
|
83AA7D05279EBCAB00087AA4 /* libavformat.59.dylib in CopyFiles */,
|
||||||
83AA7D05279EBCAB00087AA4 /* libavformat.61.dylib in CopyFiles */,
|
83AA7D04279EBCA900087AA4 /* libavcodec.59.dylib in CopyFiles */,
|
||||||
83AA7D04279EBCA900087AA4 /* libavcodec.61.dylib in CopyFiles */,
|
|
||||||
83B72E3B279045B7006007A3 /* libfdk-aac.2.dylib in CopyFiles */,
|
83B72E3B279045B7006007A3 /* libfdk-aac.2.dylib in CopyFiles */,
|
||||||
8305963C277F013200EBFAAE /* File_Extractor.framework in CopyFiles */,
|
8305963C277F013200EBFAAE /* File_Extractor.framework in CopyFiles */,
|
||||||
ED69CBCA25BE32E80090B90D /* MASShortcut.framework in CopyFiles */,
|
ED69CBCA25BE32E80090B90D /* MASShortcut.framework in CopyFiles */,
|
||||||
|
@ -775,7 +768,7 @@
|
||||||
177042970B8BC53600B86321 /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = "<group>"; };
|
177042970B8BC53600B86321 /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = "<group>"; };
|
||||||
177042980B8BC53600B86321 /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AppController.m; sourceTree = "<group>"; };
|
177042980B8BC53600B86321 /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AppController.m; sourceTree = "<group>"; };
|
||||||
177042990B8BC53600B86321 /* PlaybackController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PlaybackController.h; sourceTree = "<group>"; };
|
177042990B8BC53600B86321 /* PlaybackController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PlaybackController.h; sourceTree = "<group>"; };
|
||||||
1770429A0B8BC53600B86321 /* PlaybackController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlaybackController.m; sourceTree = "<group>"; };
|
1770429A0B8BC53600B86321 /* PlaybackController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PlaybackController.m; sourceTree = "<group>"; };
|
||||||
1778D3C80F645BF00037E7A0 /* MissingAlbumArtTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MissingAlbumArtTransformer.h; path = InfoInspector/MissingAlbumArtTransformer.h; sourceTree = "<group>"; };
|
1778D3C80F645BF00037E7A0 /* MissingAlbumArtTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MissingAlbumArtTransformer.h; path = InfoInspector/MissingAlbumArtTransformer.h; sourceTree = "<group>"; };
|
||||||
1778D3C90F645BF00037E7A0 /* MissingAlbumArtTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MissingAlbumArtTransformer.m; path = InfoInspector/MissingAlbumArtTransformer.m; sourceTree = "<group>"; };
|
1778D3C90F645BF00037E7A0 /* MissingAlbumArtTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MissingAlbumArtTransformer.m; path = InfoInspector/MissingAlbumArtTransformer.m; sourceTree = "<group>"; };
|
||||||
177EBF860B8BC2A70000BC8C /* ImageTextCell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageTextCell.h; sourceTree = "<group>"; };
|
177EBF860B8BC2A70000BC8C /* ImageTextCell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageTextCell.h; sourceTree = "<group>"; };
|
||||||
|
@ -874,6 +867,19 @@
|
||||||
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||||
32CA4F630368D1EE00C91783 /* Cog_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cog_Prefix.pch; sourceTree = "<group>"; };
|
32CA4F630368D1EE00C91783 /* Cog_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cog_Prefix.pch; sourceTree = "<group>"; };
|
||||||
3DDFC2472344EC6B000F1453 /* Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
|
3DDFC2472344EC6B000F1453 /* Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
|
||||||
|
491C55B6287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/AboutWindowController.strings; sourceTree = "<group>"; };
|
||||||
|
491C55B7287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Equalizer.strings; sourceTree = "<group>"; };
|
||||||
|
491C55B8287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoInspector.strings; sourceTree = "<group>"; };
|
||||||
|
491C55B9287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/MainMenu.strings; sourceTree = "<group>"; };
|
||||||
|
491C55BA287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/OpenURLPanel.strings; sourceTree = "<group>"; };
|
||||||
|
491C55BB287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/FileTree.strings; sourceTree = "<group>"; };
|
||||||
|
491C55BC287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/SpectrumWindow.strings; sourceTree = "<group>"; };
|
||||||
|
491C55BD287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/SpotlightPanel.strings; sourceTree = "<group>"; };
|
||||||
|
491C55BE287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Feedback.strings; sourceTree = "<group>"; };
|
||||||
|
491C55BF287AA4B6007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
|
491C55C2287AA4B7007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
|
491C55C3287AA4B7007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
491C55C4287AA4B7007D96F5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = ru; path = ru.lproj/Credits.html; sourceTree = "<group>"; };
|
||||||
5604D4590D60349B004F5C5D /* SpotlightWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpotlightWindowController.m; path = Spotlight/SpotlightWindowController.m; sourceTree = "<group>"; };
|
5604D4590D60349B004F5C5D /* SpotlightWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpotlightWindowController.m; path = Spotlight/SpotlightWindowController.m; sourceTree = "<group>"; };
|
||||||
5604D45A0D60349B004F5C5D /* SpotlightWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpotlightWindowController.h; path = Spotlight/SpotlightWindowController.h; sourceTree = "<group>"; };
|
5604D45A0D60349B004F5C5D /* SpotlightWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpotlightWindowController.h; path = Spotlight/SpotlightWindowController.h; sourceTree = "<group>"; };
|
||||||
5604D4F40D60726E004F5C5D /* SpotlightPlaylistEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpotlightPlaylistEntry.h; path = Spotlight/SpotlightPlaylistEntry.h; sourceTree = "<group>"; };
|
5604D4F40D60726E004F5C5D /* SpotlightPlaylistEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpotlightPlaylistEntry.h; path = Spotlight/SpotlightPlaylistEntry.h; sourceTree = "<group>"; };
|
||||||
|
@ -899,11 +905,15 @@
|
||||||
830C37F227B9956C00E02BB0 /* analyzer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = analyzer.c; sourceTree = "<group>"; };
|
830C37F227B9956C00E02BB0 /* analyzer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = analyzer.c; sourceTree = "<group>"; };
|
||||||
8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = sidplay.xcodeproj; path = Plugins/sidplay/sidplay.xcodeproj; sourceTree = "<group>"; };
|
8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = sidplay.xcodeproj; path = Plugins/sidplay/sidplay.xcodeproj; sourceTree = "<group>"; };
|
||||||
831B99BE27C23E88005A969B /* Cog.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Cog.sdef; sourceTree = "<group>"; };
|
831B99BE27C23E88005A969B /* Cog.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Cog.sdef; sourceTree = "<group>"; };
|
||||||
|
83229C9C283B0095004626A8 /* SpectrumWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SpectrumWindowController.h; sourceTree = "<group>"; };
|
||||||
|
83229C9D283B0095004626A8 /* SpectrumWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SpectrumWindowController.m; sourceTree = "<group>"; };
|
||||||
83256B672866617F0036D9C0 /* libmpg123.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libmpg123.0.dylib; path = ThirdParty/mpg123/lib/libmpg123.0.dylib; sourceTree = "<group>"; };
|
83256B672866617F0036D9C0 /* libmpg123.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libmpg123.0.dylib; path = ThirdParty/mpg123/lib/libmpg123.0.dylib; sourceTree = "<group>"; };
|
||||||
8327DB8F293C923500CD0580 /* Organya.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Organya.xcodeproj; path = Plugins/Organya/Organya.xcodeproj; sourceTree = "<group>"; };
|
8327DB8F293C923500CD0580 /* Organya.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Organya.xcodeproj; path = Plugins/Organya/Organya.xcodeproj; sourceTree = "<group>"; };
|
||||||
832923AE279FAC400048201E /* Cog.q1.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Cog.q1.json; sourceTree = "<group>"; };
|
832923AE279FAC400048201E /* Cog.q1.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Cog.q1.json; sourceTree = "<group>"; };
|
||||||
832CFC4E2851AA1A002AC26F /* NSView+Visibility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSView+Visibility.m"; sourceTree = "<group>"; };
|
832CFC4E2851AA1A002AC26F /* NSView+Visibility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSView+Visibility.m"; sourceTree = "<group>"; };
|
||||||
832CFC532851AA37002AC26F /* NSView+Visibility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSView+Visibility.h"; sourceTree = "<group>"; };
|
832CFC532851AA37002AC26F /* NSView+Visibility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSView+Visibility.h"; sourceTree = "<group>"; };
|
||||||
|
832CFC542851AA8B002AC26F /* SpectrumViewCG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpectrumViewCG.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
832CFC552851AA8B002AC26F /* SpectrumViewCG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpectrumViewCG.m; sourceTree = SOURCE_ROOT; };
|
||||||
833D0C2027C4ABA00060E16A /* ScriptAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScriptAdditions.h; sourceTree = "<group>"; };
|
833D0C2027C4ABA00060E16A /* ScriptAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScriptAdditions.h; sourceTree = "<group>"; };
|
||||||
833D0C2427C4ABB80060E16A /* ScriptAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScriptAdditions.m; sourceTree = "<group>"; };
|
833D0C2427C4ABB80060E16A /* ScriptAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScriptAdditions.m; sourceTree = "<group>"; };
|
||||||
833F681E1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
833F681E1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
|
@ -955,7 +965,7 @@
|
||||||
8370D739277419D200245CE0 /* SQLiteStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLiteStore.h; sourceTree = "<group>"; };
|
8370D739277419D200245CE0 /* SQLiteStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLiteStore.h; sourceTree = "<group>"; };
|
||||||
8370D73C277419F700245CE0 /* SQLiteStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SQLiteStore.m; sourceTree = "<group>"; };
|
8370D73C277419F700245CE0 /* SQLiteStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SQLiteStore.m; sourceTree = "<group>"; };
|
||||||
8370D73E2775AE1300245CE0 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
|
8370D73E2775AE1300245CE0 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
|
||||||
8372C92A27C785BD00E250C9 /* minimp3.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = minimp3.xcodeproj; path = Plugins/minimp3/minimp3.xcodeproj; sourceTree = "<group>"; };
|
8372C92A27C785BD00E250C9 /* MAD.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MAD.xcodeproj; path = Plugins/MAD/MAD.xcodeproj; sourceTree = "<group>"; };
|
||||||
8375B05117FFEA400092A79F /* OpusPlugin.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpusPlugin.xcodeproj; path = Plugins/Opus/OpusPlugin.xcodeproj; sourceTree = "<group>"; };
|
8375B05117FFEA400092A79F /* OpusPlugin.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpusPlugin.xcodeproj; path = Plugins/Opus/OpusPlugin.xcodeproj; sourceTree = "<group>"; };
|
||||||
8377C66127B8CF6300E8BC0F /* SpectrumViewSK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectrumViewSK.m; path = Visualization/SpectrumViewSK.m; sourceTree = "<group>"; };
|
8377C66127B8CF6300E8BC0F /* SpectrumViewSK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpectrumViewSK.m; path = Visualization/SpectrumViewSK.m; sourceTree = "<group>"; };
|
||||||
8377C66227B8CF6300E8BC0F /* SpectrumViewSK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectrumViewSK.h; path = Visualization/SpectrumViewSK.h; sourceTree = "<group>"; };
|
8377C66227B8CF6300E8BC0F /* SpectrumViewSK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpectrumViewSK.h; path = Visualization/SpectrumViewSK.h; sourceTree = "<group>"; };
|
||||||
|
@ -969,21 +979,24 @@
|
||||||
8384912518080F2D00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
|
8384912518080F2D00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
|
||||||
8384913D18083E4E00E7332D /* filetype.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = filetype.icns; sourceTree = "<group>"; };
|
8384913D18083E4E00E7332D /* filetype.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = filetype.icns; sourceTree = "<group>"; };
|
||||||
83859520234FEB35004E9946 /* Cog.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Cog.entitlements; sourceTree = "<group>"; };
|
83859520234FEB35004E9946 /* Cog.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Cog.entitlements; sourceTree = "<group>"; };
|
||||||
838770F32D6F0996001455A0 /* FeedbackController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FeedbackController.h; sourceTree = "<group>"; };
|
|
||||||
838770F42D6F0996001455A0 /* FeedbackController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FeedbackController.m; sourceTree = "<group>"; };
|
|
||||||
838A33732D06A9B100D0D770 /* librubberband.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = librubberband.3.dylib; path = ThirdParty/rubberband/lib/librubberband.3.dylib; sourceTree = "<group>"; };
|
|
||||||
838A33792D06C14200D0D770 /* PitchSlider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PitchSlider.h; path = Window/PitchSlider.h; sourceTree = "<group>"; };
|
|
||||||
838A337A2D06C14200D0D770 /* PitchSlider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = PitchSlider.m; path = Window/PitchSlider.m; sourceTree = "<group>"; };
|
|
||||||
838A337B2D06C14200D0D770 /* TempoSlider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TempoSlider.h; path = Window/TempoSlider.h; sourceTree = "<group>"; };
|
|
||||||
838A337C2D06C14200D0D770 /* TempoSlider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TempoSlider.m; path = Window/TempoSlider.m; sourceTree = "<group>"; };
|
|
||||||
838A337F2D06CF4100D0D770 /* SpectrumViewCG.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpectrumViewCG.h; path = Visualization/SpectrumViewCG.h; sourceTree = "<group>"; };
|
|
||||||
838A33802D06CF4100D0D770 /* SpectrumViewCG.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SpectrumViewCG.m; path = Visualization/SpectrumViewCG.m; sourceTree = "<group>"; };
|
|
||||||
838A33812D06CF4100D0D770 /* SpectrumWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpectrumWindowController.h; path = Visualization/SpectrumWindowController.h; sourceTree = "<group>"; };
|
|
||||||
838A33822D06CF4100D0D770 /* SpectrumWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SpectrumWindowController.m; path = Visualization/SpectrumWindowController.m; sourceTree = "<group>"; };
|
|
||||||
838A33852D06CFCA00D0D770 /* SpeedButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpeedButton.h; path = Window/SpeedButton.h; sourceTree = "<group>"; };
|
|
||||||
838A33862D06CFCA00D0D770 /* SpeedButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SpeedButton.m; path = Window/SpeedButton.m; sourceTree = "<group>"; };
|
|
||||||
838EE79E29A8556000CD0580 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/LyricsWindow.strings; sourceTree = "<group>"; };
|
838EE79E29A8556000CD0580 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/LyricsWindow.strings; sourceTree = "<group>"; };
|
||||||
838EE7A029A8556500CD0580 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/LyricsWindow.strings; sourceTree = "<group>"; };
|
838EE7A029A8556500CD0580 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/LyricsWindow.strings; sourceTree = "<group>"; };
|
||||||
|
838EE7A229A8557000CD0580 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/LyricsWindow.strings; sourceTree = "<group>"; };
|
||||||
|
838EE7A429A8557200CD0580 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/LyricsWindow.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8A729A8600600CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/AboutWindowController.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8A829A8600700CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Equalizer.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8A929A8600700CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoInspector.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8AA29A8600700CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/MainMenu.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8AB29A8600700CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/OpenURLPanel.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8AC29A8600700CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/FileTree.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8AD29A8600700CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/SpectrumWindow.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8AE29A8600800CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/SpotlightPanel.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8AF29A8600800CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Feedback.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8B029A8600800CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/LyricsWindow.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8B129A8600800CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
|
838EE8B629A8600900CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8B729A8600900CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
838EE8B829A8600900CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = tr; path = tr.lproj/Credits.html; sourceTree = "<group>"; };
|
||||||
838F84FF25687C5C00C3E614 /* Cog-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Cog-Bridging-Header.h"; sourceTree = "<group>"; };
|
838F84FF25687C5C00C3E614 /* Cog-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Cog-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
83922FB6286B1AA900A0B039 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
|
83922FB6286B1AA900A0B039 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
|
||||||
839614A1286ED97200D3EEDB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutWindowController.xib; sourceTree = "<group>"; };
|
839614A1286ED97200D3EEDB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutWindowController.xib; sourceTree = "<group>"; };
|
||||||
|
@ -994,6 +1007,7 @@
|
||||||
839614AC286EDA5C00D3EEDB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SpectrumWindow.xib; sourceTree = "<group>"; };
|
839614AC286EDA5C00D3EEDB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SpectrumWindow.xib; sourceTree = "<group>"; };
|
||||||
839614AF286EDA6800D3EEDB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/SpectrumWindow.strings; sourceTree = "<group>"; };
|
839614AF286EDA6800D3EEDB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/SpectrumWindow.strings; sourceTree = "<group>"; };
|
||||||
839614B1286EDA6E00D3EEDB /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/SpectrumWindow.strings; sourceTree = "<group>"; };
|
839614B1286EDA6E00D3EEDB /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/SpectrumWindow.strings; sourceTree = "<group>"; };
|
||||||
|
83978E28285C5C0A0076ED21 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
83988F0C27BE0A5900A0E89A /* RedundantPlaylistDataStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RedundantPlaylistDataStore.h; sourceTree = "<group>"; };
|
83988F0C27BE0A5900A0E89A /* RedundantPlaylistDataStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RedundantPlaylistDataStore.h; sourceTree = "<group>"; };
|
||||||
83988F0D27BE0A5900A0E89A /* RedundantPlaylistDataStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RedundantPlaylistDataStore.m; sourceTree = "<group>"; };
|
83988F0D27BE0A5900A0E89A /* RedundantPlaylistDataStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RedundantPlaylistDataStore.m; sourceTree = "<group>"; };
|
||||||
8399D4E01805A55000B503B1 /* XmlContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XmlContainer.m; sourceTree = "<group>"; };
|
8399D4E01805A55000B503B1 /* XmlContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XmlContainer.m; sourceTree = "<group>"; };
|
||||||
|
@ -1003,14 +1017,12 @@
|
||||||
839DA7CE274A2D4C001B18E5 /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Merge.m"; sourceTree = "<group>"; };
|
839DA7CE274A2D4C001B18E5 /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Merge.m"; sourceTree = "<group>"; };
|
||||||
839E3B53286595D700880EA2 /* GeneralPane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GeneralPane.h; path = Preferences/Preferences/GeneralPane.h; sourceTree = "<group>"; };
|
839E3B53286595D700880EA2 /* GeneralPane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GeneralPane.h; path = Preferences/Preferences/GeneralPane.h; sourceTree = "<group>"; };
|
||||||
839E56F12879625100DFB5F4 /* SADIE_D02-96000.mhr */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SADIE_D02-96000.mhr"; sourceTree = "<group>"; };
|
839E56F12879625100DFB5F4 /* SADIE_D02-96000.mhr */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SADIE_D02-96000.mhr"; sourceTree = "<group>"; };
|
||||||
839E876C2D5DA0AC00A13526 /* RubberbandEngineTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RubberbandEngineTransformer.h; path = Preferences/Preferences/RubberbandEngineTransformer.h; sourceTree = "<group>"; };
|
|
||||||
839E876D2D5DA0AC00A13526 /* RubberbandEngineTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RubberbandEngineTransformer.m; path = Preferences/Preferences/RubberbandEngineTransformer.m; sourceTree = "<group>"; };
|
|
||||||
83A3B72F283AE6AA00CC6593 /* ColorToValueTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ColorToValueTransformer.m; path = Preferences/Preferences/ColorToValueTransformer.m; sourceTree = "<group>"; };
|
83A3B72F283AE6AA00CC6593 /* ColorToValueTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ColorToValueTransformer.m; path = Preferences/Preferences/ColorToValueTransformer.m; sourceTree = "<group>"; };
|
||||||
83A3B733283AE6AA00CC6593 /* ColorToValueTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ColorToValueTransformer.h; path = Preferences/Preferences/ColorToValueTransformer.h; sourceTree = "<group>"; };
|
83A3B733283AE6AA00CC6593 /* ColorToValueTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ColorToValueTransformer.h; path = Preferences/Preferences/ColorToValueTransformer.h; sourceTree = "<group>"; };
|
||||||
83AA7D00279EBC8200087AA4 /* libavcodec.61.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavcodec.61.dylib; path = ThirdParty/ffmpeg/lib/libavcodec.61.dylib; sourceTree = "<group>"; };
|
83AA7D00279EBC8200087AA4 /* libavcodec.59.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavcodec.59.dylib; path = ThirdParty/ffmpeg/lib/libavcodec.59.dylib; sourceTree = "<group>"; };
|
||||||
83AA7D01279EBC8200087AA4 /* libswresample.5.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libswresample.5.dylib; path = ThirdParty/ffmpeg/lib/libswresample.5.dylib; sourceTree = "<group>"; };
|
83AA7D01279EBC8200087AA4 /* libswresample.4.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libswresample.4.dylib; path = ThirdParty/ffmpeg/lib/libswresample.4.dylib; sourceTree = "<group>"; };
|
||||||
83AA7D02279EBC8200087AA4 /* libavutil.59.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavutil.59.dylib; path = ThirdParty/ffmpeg/lib/libavutil.59.dylib; sourceTree = "<group>"; };
|
83AA7D02279EBC8200087AA4 /* libavutil.57.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavutil.57.dylib; path = ThirdParty/ffmpeg/lib/libavutil.57.dylib; sourceTree = "<group>"; };
|
||||||
83AA7D03279EBC8300087AA4 /* libavformat.61.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavformat.61.dylib; path = ThirdParty/ffmpeg/lib/libavformat.61.dylib; sourceTree = "<group>"; };
|
83AA7D03279EBC8300087AA4 /* libavformat.59.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libavformat.59.dylib; path = ThirdParty/ffmpeg/lib/libavformat.59.dylib; sourceTree = "<group>"; };
|
||||||
83AB9031237CEFD300A433D5 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
|
83AB9031237CEFD300A433D5 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
|
||||||
83B0669C180D5668008E3612 /* MIDI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MIDI.xcodeproj; path = Plugins/MIDI/MIDI.xcodeproj; sourceTree = "<group>"; };
|
83B0669C180D5668008E3612 /* MIDI.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MIDI.xcodeproj; path = Plugins/MIDI/MIDI.xcodeproj; sourceTree = "<group>"; };
|
||||||
83B61E2329A8296500CD0580 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LyricsWindow.xib; sourceTree = "<group>"; };
|
83B61E2329A8296500CD0580 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LyricsWindow.xib; sourceTree = "<group>"; };
|
||||||
|
@ -1038,8 +1050,21 @@
|
||||||
83BC5ADA20E4D0E900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Feedback.strings; sourceTree = "<group>"; };
|
83BC5ADA20E4D0E900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Feedback.strings; sourceTree = "<group>"; };
|
||||||
83BC5ADC20E4D0EC00631CD4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Feedback.strings; sourceTree = "<group>"; };
|
83BC5ADC20E4D0EC00631CD4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Feedback.strings; sourceTree = "<group>"; };
|
||||||
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CogAssets.xcassets; sourceTree = "<group>"; };
|
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CogAssets.xcassets; sourceTree = "<group>"; };
|
||||||
|
83D2E23D287ED5ED00DD441F /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = pl; path = pl.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
83D3C5FC201C674D005564CB /* AdPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AdPlug.xcodeproj; path = Plugins/AdPlug/AdPlug.xcodeproj; sourceTree = "<group>"; };
|
83D3C5FC201C674D005564CB /* AdPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AdPlug.xcodeproj; path = Plugins/AdPlug/AdPlug.xcodeproj; sourceTree = "<group>"; };
|
||||||
83E5EFAC1FFEF78100659F0F /* OpenMPT.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpenMPT.xcodeproj; path = Plugins/OpenMPT/OpenMPT.xcodeproj; sourceTree = "<group>"; };
|
83E5EFAC1FFEF78100659F0F /* OpenMPT.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpenMPT.xcodeproj; path = Plugins/OpenMPT/OpenMPT.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
83F0E6A3287CAB3800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/AboutWindowController.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E6A4287CAB3800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Equalizer.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E6A5287CAB3800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoInspector.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E6A6287CAB3800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/MainMenu.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E6A7287CAB3800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/OpenURLPanel.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E6A8287CAB3800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/FileTree.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E6A9287CAB3800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/SpectrumWindow.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E6AA287CAB3800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/SpotlightPanel.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E6AB287CAB3800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Feedback.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E8AD287CD48800D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E8B1287CD50700D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
83F0E8B2287CD52500D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = pl; path = pl.lproj/Credits.html; sourceTree = "<group>"; };
|
||||||
83F9D7F11A884B44007ABEC2 /* SilenceDecoder.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SilenceDecoder.xcodeproj; path = Plugins/SilenceDecoder/SilenceDecoder.xcodeproj; sourceTree = "<group>"; };
|
83F9D7F11A884B44007ABEC2 /* SilenceDecoder.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SilenceDecoder.xcodeproj; path = Plugins/SilenceDecoder/SilenceDecoder.xcodeproj; sourceTree = "<group>"; };
|
||||||
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
8E07AB760AAC930B00A4B32F /* PreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PreferencesController.h; path = Preferences/PreferencesController.h; sourceTree = "<group>"; };
|
8E07AB760AAC930B00A4B32F /* PreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PreferencesController.h; path = Preferences/PreferencesController.h; sourceTree = "<group>"; };
|
||||||
|
@ -1081,11 +1106,11 @@
|
||||||
83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */,
|
83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */,
|
||||||
835FAC7E27BCDF5B00BA8562 /* libaom.a in Frameworks */,
|
835FAC7E27BCDF5B00BA8562 /* libaom.a in Frameworks */,
|
||||||
837DC92B285B05710005C58A /* CoreData.framework in Frameworks */,
|
837DC92B285B05710005C58A /* CoreData.framework in Frameworks */,
|
||||||
838A33742D06A9B100D0D770 /* librubberband.3.dylib in Frameworks */,
|
83978E26285C596F0076ED21 /* FirebaseAnalytics in Frameworks */,
|
||||||
17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */,
|
17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */,
|
||||||
17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */,
|
17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */,
|
||||||
83F9FFEF2D6EB75B00026576 /* Sentry in Frameworks */,
|
|
||||||
17BB5CFB0B8A86350009ACB1 /* CoreAudioKit.framework in Frameworks */,
|
17BB5CFB0B8A86350009ACB1 /* CoreAudioKit.framework in Frameworks */,
|
||||||
|
83978E16285C58190076ED21 /* FirebaseCrashlytics in Frameworks */,
|
||||||
17BB5EA60B8A87850009ACB1 /* IOKit.framework in Frameworks */,
|
17BB5EA60B8A87850009ACB1 /* IOKit.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -1105,7 +1130,6 @@
|
||||||
080E96DDFE201D6D7F000001 /* Classes */ = {
|
080E96DDFE201D6D7F000001 /* Classes */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
838770F72D6F0996001455A0 /* Feedback */,
|
|
||||||
835F00B3279BD1CD00055FCF /* Formatters */,
|
835F00B3279BD1CD00055FCF /* Formatters */,
|
||||||
177042960B8BC53600B86321 /* Application */,
|
177042960B8BC53600B86321 /* Application */,
|
||||||
17E0D5D20F520E75005B6FED /* Window */,
|
17E0D5D20F520E75005B6FED /* Window */,
|
||||||
|
@ -1138,7 +1162,6 @@
|
||||||
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
|
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
838A33732D06A9B100D0D770 /* librubberband.3.dylib */,
|
|
||||||
836DF616298F6EC400CD0580 /* libsoxr.0.dylib */,
|
836DF616298F6EC400CD0580 /* libsoxr.0.dylib */,
|
||||||
83256B672866617F0036D9C0 /* libmpg123.0.dylib */,
|
83256B672866617F0036D9C0 /* libmpg123.0.dylib */,
|
||||||
835FAC7C27BCDF5B00BA8562 /* libaom.a */,
|
835FAC7C27BCDF5B00BA8562 /* libaom.a */,
|
||||||
|
@ -1150,10 +1173,10 @@
|
||||||
836EF0C627BB91AB00BF35B2 /* libvorbisfile.3.dylib */,
|
836EF0C627BB91AB00BF35B2 /* libvorbisfile.3.dylib */,
|
||||||
836EF0C427BB919300BF35B2 /* libogg.0.dylib */,
|
836EF0C427BB919300BF35B2 /* libogg.0.dylib */,
|
||||||
83B72E2A279044F6006007A3 /* libfdk-aac.2.dylib */,
|
83B72E2A279044F6006007A3 /* libfdk-aac.2.dylib */,
|
||||||
83AA7D00279EBC8200087AA4 /* libavcodec.61.dylib */,
|
83AA7D00279EBC8200087AA4 /* libavcodec.59.dylib */,
|
||||||
83AA7D03279EBC8300087AA4 /* libavformat.61.dylib */,
|
83AA7D03279EBC8300087AA4 /* libavformat.59.dylib */,
|
||||||
83AA7D02279EBC8200087AA4 /* libavutil.59.dylib */,
|
83AA7D02279EBC8200087AA4 /* libavutil.57.dylib */,
|
||||||
83AA7D01279EBC8200087AA4 /* libswresample.5.dylib */,
|
83AA7D01279EBC8200087AA4 /* libswresample.4.dylib */,
|
||||||
83059634277F011100EBFAAE /* File_Extractor.xcodeproj */,
|
83059634277F011100EBFAAE /* File_Extractor.xcodeproj */,
|
||||||
17BB5EA50B8A87850009ACB1 /* IOKit.framework */,
|
17BB5EA50B8A87850009ACB1 /* IOKit.framework */,
|
||||||
17BB5CF60B8A86350009ACB1 /* AudioUnit.framework */,
|
17BB5CF60B8A86350009ACB1 /* AudioUnit.framework */,
|
||||||
|
@ -1270,7 +1293,7 @@
|
||||||
17C808830C3BD181005707C4 /* HTTPSource.xcodeproj */,
|
17C808830C3BD181005707C4 /* HTTPSource.xcodeproj */,
|
||||||
83489C4E2782F2DF00BDCEA2 /* libvgmPlayer.xcodeproj */,
|
83489C4E2782F2DF00BDCEA2 /* libvgmPlayer.xcodeproj */,
|
||||||
8E8D40820CBB036600135C1B /* M3u.xcodeproj */,
|
8E8D40820CBB036600135C1B /* M3u.xcodeproj */,
|
||||||
8372C92A27C785BD00E250C9 /* minimp3.xcodeproj */,
|
8372C92A27C785BD00E250C9 /* MAD.xcodeproj */,
|
||||||
83B0669C180D5668008E3612 /* MIDI.xcodeproj */,
|
83B0669C180D5668008E3612 /* MIDI.xcodeproj */,
|
||||||
17C8089E0C3BD1AB005707C4 /* Musepack.xcodeproj */,
|
17C8089E0C3BD1AB005707C4 /* Musepack.xcodeproj */,
|
||||||
83E5EFAC1FFEF78100659F0F /* OpenMPT.xcodeproj */,
|
83E5EFAC1FFEF78100659F0F /* OpenMPT.xcodeproj */,
|
||||||
|
@ -1373,8 +1396,6 @@
|
||||||
17E0D5D20F520E75005B6FED /* Window */ = {
|
17E0D5D20F520E75005B6FED /* Window */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0A9CEA012861501700E47168 /* AboutWindowController.swift */,
|
|
||||||
0A9CEA0A286152DF00E47168 /* DraggableView.swift */,
|
|
||||||
83BC5AB120E4C87100631CD4 /* DualWindow.h */,
|
83BC5AB120E4C87100631CD4 /* DualWindow.h */,
|
||||||
83BC5AB020E4C87100631CD4 /* DualWindow.m */,
|
83BC5AB020E4C87100631CD4 /* DualWindow.m */,
|
||||||
17E0D5E10F520F02005B6FED /* MainWindow.h */,
|
17E0D5E10F520F02005B6FED /* MainWindow.h */,
|
||||||
|
@ -1383,8 +1404,6 @@
|
||||||
836D28A718086386005B7299 /* MiniModeMenuTitleTransformer.m */,
|
836D28A718086386005B7299 /* MiniModeMenuTitleTransformer.m */,
|
||||||
17E0D5E30F520F02005B6FED /* MiniWindow.h */,
|
17E0D5E30F520F02005B6FED /* MiniWindow.h */,
|
||||||
17E0D5E40F520F02005B6FED /* MiniWindow.m */,
|
17E0D5E40F520F02005B6FED /* MiniWindow.m */,
|
||||||
838A33792D06C14200D0D770 /* PitchSlider.h */,
|
|
||||||
838A337A2D06C14200D0D770 /* PitchSlider.m */,
|
|
||||||
1752C36A0F59E00100F85F28 /* PlaybackButtons.h */,
|
1752C36A0F59E00100F85F28 /* PlaybackButtons.h */,
|
||||||
1752C36B0F59E00100F85F28 /* PlaybackButtons.m */,
|
1752C36B0F59E00100F85F28 /* PlaybackButtons.m */,
|
||||||
17E0D5E50F520F02005B6FED /* PositionSlider.h */,
|
17E0D5E50F520F02005B6FED /* PositionSlider.h */,
|
||||||
|
@ -1394,16 +1413,14 @@
|
||||||
172A12320F5911D20078EF0C /* RepeatTransformers.m */,
|
172A12320F5911D20078EF0C /* RepeatTransformers.m */,
|
||||||
172A123A0F5912AE0078EF0C /* ShuffleTransformers.h */,
|
172A123A0F5912AE0078EF0C /* ShuffleTransformers.h */,
|
||||||
172A123B0F5912AE0078EF0C /* ShuffleTransformers.m */,
|
172A123B0F5912AE0078EF0C /* ShuffleTransformers.m */,
|
||||||
838A33852D06CFCA00D0D770 /* SpeedButton.h */,
|
|
||||||
838A33862D06CFCA00D0D770 /* SpeedButton.m */,
|
|
||||||
838A337B2D06C14200D0D770 /* TempoSlider.h */,
|
|
||||||
838A337C2D06C14200D0D770 /* TempoSlider.m */,
|
|
||||||
17E0D5E70F520F02005B6FED /* TimeField.h */,
|
17E0D5E70F520F02005B6FED /* TimeField.h */,
|
||||||
17E0D5E80F520F02005B6FED /* TimeField.m */,
|
17E0D5E80F520F02005B6FED /* TimeField.m */,
|
||||||
17E0D6180F520F9F005B6FED /* VolumeButton.h */,
|
17E0D6180F520F9F005B6FED /* VolumeButton.h */,
|
||||||
17E0D6190F520F9F005B6FED /* VolumeButton.m */,
|
17E0D6190F520F9F005B6FED /* VolumeButton.m */,
|
||||||
17E0D61A0F520F9F005B6FED /* VolumeSlider.h */,
|
17E0D61A0F520F9F005B6FED /* VolumeSlider.h */,
|
||||||
17E0D61B0F520F9F005B6FED /* VolumeSlider.m */,
|
17E0D61B0F520F9F005B6FED /* VolumeSlider.m */,
|
||||||
|
0A9CEA012861501700E47168 /* AboutWindowController.swift */,
|
||||||
|
0A9CEA0A286152DF00E47168 /* DraggableView.swift */,
|
||||||
);
|
);
|
||||||
name = Window;
|
name = Window;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1411,8 +1428,6 @@
|
||||||
17E0D5F60F520F42005B6FED /* Transformers */ = {
|
17E0D5F60F520F42005B6FED /* Transformers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
839E876C2D5DA0AC00A13526 /* RubberbandEngineTransformer.h */,
|
|
||||||
839E876D2D5DA0AC00A13526 /* RubberbandEngineTransformer.m */,
|
|
||||||
83A3B733283AE6AA00CC6593 /* ColorToValueTransformer.h */,
|
83A3B733283AE6AA00CC6593 /* ColorToValueTransformer.h */,
|
||||||
83A3B72F283AE6AA00CC6593 /* ColorToValueTransformer.m */,
|
83A3B72F283AE6AA00CC6593 /* ColorToValueTransformer.m */,
|
||||||
17E0D6120F520F87005B6FED /* FontSizetoLineHeightTransformer.h */,
|
17E0D6120F520F87005B6FED /* FontSizetoLineHeightTransformer.h */,
|
||||||
|
@ -1463,6 +1478,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0A1B412E286F6301008A6A44 /* Localizable.stringsdict */,
|
0A1B412E286F6301008A6A44 /* Localizable.stringsdict */,
|
||||||
|
83978E28285C5C0A0076ED21 /* GoogleService-Info.plist */,
|
||||||
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */,
|
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */,
|
||||||
83859520234FEB35004E9946 /* Cog.entitlements */,
|
83859520234FEB35004E9946 /* Cog.entitlements */,
|
||||||
080E96DDFE201D6D7F000001 /* Classes */,
|
080E96DDFE201D6D7F000001 /* Classes */,
|
||||||
|
@ -1773,32 +1789,31 @@
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
8372C92B27C785BD00E250C9 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8372C93027C785BE00E250C9 /* MAD.bundle */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
8377C66027B8CF2300E8BC0F /* Visualization */ = {
|
8377C66027B8CF2300E8BC0F /* Visualization */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
830C37EF27B9956C00E02BB0 /* ThirdParty */,
|
830C37EF27B9956C00E02BB0 /* ThirdParty */,
|
||||||
8377C6B727B900F000E8BC0F /* SpectrumItem.h */,
|
8377C66427B8CF7A00E8BC0F /* VisualizationController.h */,
|
||||||
8377C6B827B900F000E8BC0F /* SpectrumItem.m */,
|
|
||||||
838A337F2D06CF4100D0D770 /* SpectrumViewCG.h */,
|
|
||||||
838A33802D06CF4100D0D770 /* SpectrumViewCG.m */,
|
|
||||||
8377C66227B8CF6300E8BC0F /* SpectrumViewSK.h */,
|
8377C66227B8CF6300E8BC0F /* SpectrumViewSK.h */,
|
||||||
8377C66127B8CF6300E8BC0F /* SpectrumViewSK.m */,
|
8377C66127B8CF6300E8BC0F /* SpectrumViewSK.m */,
|
||||||
838A33812D06CF4100D0D770 /* SpectrumWindowController.h */,
|
832CFC542851AA8B002AC26F /* SpectrumViewCG.h */,
|
||||||
838A33822D06CF4100D0D770 /* SpectrumWindowController.m */,
|
832CFC552851AA8B002AC26F /* SpectrumViewCG.m */,
|
||||||
8377C66427B8CF7A00E8BC0F /* VisualizationController.h */,
|
8377C6B727B900F000E8BC0F /* SpectrumItem.h */,
|
||||||
|
8377C6B827B900F000E8BC0F /* SpectrumItem.m */,
|
||||||
|
83229C9C283B0095004626A8 /* SpectrumWindowController.h */,
|
||||||
|
83229C9D283B0095004626A8 /* SpectrumWindowController.m */,
|
||||||
);
|
);
|
||||||
name = Visualization;
|
name = Visualization;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
838770F72D6F0996001455A0 /* Feedback */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
838770F32D6F0996001455A0 /* FeedbackController.h */,
|
|
||||||
838770F42D6F0996001455A0 /* FeedbackController.m */,
|
|
||||||
);
|
|
||||||
path = Feedback;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
83B0669D180D5668008E3612 /* Products */ = {
|
83B0669D180D5668008E3612 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1816,14 +1831,6 @@
|
||||||
path = LyricsWindow;
|
path = LyricsWindow;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
83B73B5C2D8FC05A00A57F08 /* Products */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
83B73B602D8FC05A00A57F08 /* minimp3.bundle */,
|
|
||||||
);
|
|
||||||
name = Products;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
83BB13AE20E4E38E00723731 /* Products */ = {
|
83BB13AE20E4E38E00723731 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1978,14 +1985,14 @@
|
||||||
8D1107290486CEB800E47090 /* Resources */,
|
8D1107290486CEB800E47090 /* Resources */,
|
||||||
8E757AEC09F3265E0080F1EE /* CopyFiles */,
|
8E757AEC09F3265E0080F1EE /* CopyFiles */,
|
||||||
177FD1000B90CB570011C3B5 /* CopyFiles */,
|
177FD1000B90CB570011C3B5 /* CopyFiles */,
|
||||||
07DFC3930ECDF80100DA400D /* Copy Files */,
|
07DFC3930ECDF80100DA400D /* CopyFiles */,
|
||||||
83978E27285C5A4C0076ED21 /* Run Sentry symbol upload */,
|
83978E27285C5A4C0076ED21 /* Run Crashlytics symbol upload */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
83B73B642D8FD74000A57F08 /* PBXTargetDependency */,
|
|
||||||
8327DBA8293CAD0A00CD0580 /* PBXTargetDependency */,
|
8327DBA8293CAD0A00CD0580 /* PBXTargetDependency */,
|
||||||
|
8372C93C27C7893100E250C9 /* PBXTargetDependency */,
|
||||||
83489C6A2782F76900BDCEA2 /* PBXTargetDependency */,
|
83489C6A2782F76900BDCEA2 /* PBXTargetDependency */,
|
||||||
ED69CBC625BE32B40090B90D /* PBXTargetDependency */,
|
ED69CBC625BE32B40090B90D /* PBXTargetDependency */,
|
||||||
834D793E20E4EFD200C4A5CC /* PBXTargetDependency */,
|
834D793E20E4EFD200C4A5CC /* PBXTargetDependency */,
|
||||||
|
@ -2018,7 +2025,8 @@
|
||||||
);
|
);
|
||||||
name = Cog;
|
name = Cog;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
83F9FFEE2D6EB75B00026576 /* Sentry */,
|
83978E15285C58190076ED21 /* FirebaseCrashlytics */,
|
||||||
|
83978E25285C596F0076ED21 /* FirebaseAnalytics */,
|
||||||
);
|
);
|
||||||
productInstallPath = /Applications;
|
productInstallPath = /Applications;
|
||||||
productName = Cog;
|
productName = Cog;
|
||||||
|
@ -2062,7 +2070,7 @@
|
||||||
);
|
);
|
||||||
mainGroup = 29B97314FDCFA39411CA2CEA /* Cog */;
|
mainGroup = 29B97314FDCFA39411CA2CEA /* Cog */;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
83F9FFED2D6EB75B00026576 /* XCRemoteSwiftPackageReference "sentry-cocoa" */,
|
83978E14285C58190076ED21 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
|
||||||
);
|
);
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectReferences = (
|
projectReferences = (
|
||||||
|
@ -2130,6 +2138,10 @@
|
||||||
ProductGroup = 8E8D40830CBB036600135C1B /* Products */;
|
ProductGroup = 8E8D40830CBB036600135C1B /* Products */;
|
||||||
ProjectRef = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */;
|
ProjectRef = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */;
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 8372C92B27C785BD00E250C9 /* Products */;
|
||||||
|
ProjectRef = 8372C92A27C785BD00E250C9 /* MAD.xcodeproj */;
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ProductGroup = ED69CBB925BE328C0090B90D /* Products */;
|
ProductGroup = ED69CBB925BE328C0090B90D /* Products */;
|
||||||
ProjectRef = ED69CBB825BE328C0090B90D /* MASShortcut.xcodeproj */;
|
ProjectRef = ED69CBB825BE328C0090B90D /* MASShortcut.xcodeproj */;
|
||||||
|
@ -2138,10 +2150,6 @@
|
||||||
ProductGroup = 83B0669D180D5668008E3612 /* Products */;
|
ProductGroup = 83B0669D180D5668008E3612 /* Products */;
|
||||||
ProjectRef = 83B0669C180D5668008E3612 /* MIDI.xcodeproj */;
|
ProjectRef = 83B0669C180D5668008E3612 /* MIDI.xcodeproj */;
|
||||||
},
|
},
|
||||||
{
|
|
||||||
ProductGroup = 83B73B5C2D8FC05A00A57F08 /* Products */;
|
|
||||||
ProjectRef = 8372C92A27C785BD00E250C9 /* minimp3.xcodeproj */;
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
ProductGroup = 17C8089F0C3BD1AB005707C4 /* Products */;
|
ProductGroup = 17C8089F0C3BD1AB005707C4 /* Products */;
|
||||||
ProjectRef = 17C8089E0C3BD1AB005707C4 /* Musepack.xcodeproj */;
|
ProjectRef = 17C8089E0C3BD1AB005707C4 /* Musepack.xcodeproj */;
|
||||||
|
@ -2357,6 +2365,13 @@
|
||||||
remoteRef = 836FB5461820538800B3AD2D /* PBXContainerItemProxy */;
|
remoteRef = 836FB5461820538800B3AD2D /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
|
8372C93027C785BE00E250C9 /* MAD.bundle */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = wrapper.cfbundle;
|
||||||
|
path = MAD.bundle;
|
||||||
|
remoteRef = 8372C92F27C785BE00E250C9 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
83B066A1180D5669008E3612 /* MIDI.bundle */ = {
|
83B066A1180D5669008E3612 /* MIDI.bundle */ = {
|
||||||
isa = PBXReferenceProxy;
|
isa = PBXReferenceProxy;
|
||||||
fileType = wrapper.cfbundle;
|
fileType = wrapper.cfbundle;
|
||||||
|
@ -2364,13 +2379,6 @@
|
||||||
remoteRef = 83B066A0180D5669008E3612 /* PBXContainerItemProxy */;
|
remoteRef = 83B066A0180D5669008E3612 /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
83B73B602D8FC05A00A57F08 /* minimp3.bundle */ = {
|
|
||||||
isa = PBXReferenceProxy;
|
|
||||||
fileType = wrapper.cfbundle;
|
|
||||||
path = minimp3.bundle;
|
|
||||||
remoteRef = 83B73B5F2D8FC05A00A57F08 /* PBXContainerItemProxy */;
|
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
|
||||||
};
|
|
||||||
83BB13C220E4E38E00723731 /* vgmstream.bundle */ = {
|
83BB13C220E4E38E00723731 /* vgmstream.bundle */ = {
|
||||||
isa = PBXReferenceProxy;
|
isa = PBXReferenceProxy;
|
||||||
fileType = wrapper.cfbundle;
|
fileType = wrapper.cfbundle;
|
||||||
|
@ -2485,6 +2493,7 @@
|
||||||
832923AF279FAC400048201E /* Cog.q1.json in Resources */,
|
832923AF279FAC400048201E /* Cog.q1.json in Resources */,
|
||||||
17D1B2820CF8B2830028F5B5 /* vg.icns in Resources */,
|
17D1B2820CF8B2830028F5B5 /* vg.icns in Resources */,
|
||||||
17D1B2830CF8B2830028F5B5 /* xm.icns in Resources */,
|
17D1B2830CF8B2830028F5B5 /* xm.icns in Resources */,
|
||||||
|
83978E29285C5C0A0076ED21 /* GoogleService-Info.plist in Resources */,
|
||||||
836DF61E298F7F6E00CD0580 /* Scenes.scnassets in Resources */,
|
836DF61E298F7F6E00CD0580 /* Scenes.scnassets in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -2511,7 +2520,7 @@
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "$SCRIPT_INPUT_FILE_0 $SCRIPT_INPUT_FILE_1 $SCRIPT_OUTPUT_FILE_0\n";
|
shellScript = "$SCRIPT_INPUT_FILE_0 $SCRIPT_INPUT_FILE_1 $SCRIPT_OUTPUT_FILE_0\n";
|
||||||
};
|
};
|
||||||
83978E27285C5A4C0076ED21 /* Run Sentry symbol upload */ = {
|
83978E27285C5A4C0076ED21 /* Run Crashlytics symbol upload */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
alwaysOutOfDate = 1;
|
alwaysOutOfDate = 1;
|
||||||
buildActionMask = 12;
|
buildActionMask = 12;
|
||||||
|
@ -2523,14 +2532,14 @@
|
||||||
"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}",
|
"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}",
|
||||||
"$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)",
|
"$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)",
|
||||||
);
|
);
|
||||||
name = "Run Sentry symbol upload";
|
name = "Run Crashlytics symbol upload";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
);
|
);
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "if [[ \"x${SENTRY_URL}\" != \"x\" ]] && [[ \"x${SENTRY_PROJECT}\" != \"x\" ]] && [[ \"x${SENTRY_AUTH_TOKEN}\" != \"x\" ]]; then\n if [[ \"${CONFIGURATION}\" = \"Release\" ]] || [[ \"${CONFIGURATION}\" = \"Adhoc\" ]]; then\n echo \"Uploading dSYMs...\"\n export PATH=$PATH:/usr/local/bin:/opt/homebrew/bin\n sentry-cli --url \"${SENTRY_URL}\" debug-files upload -p \"${SENTRY_PROJECT}\" --auth-token \"${SENTRY_AUTH_TOKEN}\" --include-sources \"${DWARF_DSYM_FOLDER_PATH}\"\n else\n echo \"Skip dSYMs upload\"\n fi\nelse\n echo \"Sentry settings not configured\"\nfi\n\nexit 0\n";
|
shellScript = "if [[ \"${CONFIGURATION}\" = \"Release\" ]] || [[ \"${CONFIGURATION}\" = \"Adhoc\" ]]; then\n echo \"Uploading dSYMs...\"\n find \"${DWARF_DSYM_FOLDER_PATH}\" -name \"*.dSYM\" -print0 | xargs -0 -I \\{\\} \"${BUILD_DIR%/Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols\" -gsp \"${SRCROOT}/GoogleService-Info.plist\" -p mac \\{\\}\nelse\n echo \"Skip dSYMs upload\"\nfi\n\nexit 0\n";
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
@ -2551,7 +2560,6 @@
|
||||||
177EBFA70B8BC2A70000BC8C /* ImageTextCell.m in Sources */,
|
177EBFA70B8BC2A70000BC8C /* ImageTextCell.m in Sources */,
|
||||||
177EC0270B8BC2CF0000BC8C /* TrackingCell.m in Sources */,
|
177EC0270B8BC2CF0000BC8C /* TrackingCell.m in Sources */,
|
||||||
177EC0290B8BC2CF0000BC8C /* TrackingSlider.m in Sources */,
|
177EC0290B8BC2CF0000BC8C /* TrackingSlider.m in Sources */,
|
||||||
838A33872D06CFCA00D0D770 /* SpeedButton.m in Sources */,
|
|
||||||
1770429C0B8BC53600B86321 /* AppController.m in Sources */,
|
1770429C0B8BC53600B86321 /* AppController.m in Sources */,
|
||||||
1770429E0B8BC53600B86321 /* PlaybackController.m in Sources */,
|
1770429E0B8BC53600B86321 /* PlaybackController.m in Sources */,
|
||||||
8355D6B6180612F300D05687 /* NSData+MD5.m in Sources */,
|
8355D6B6180612F300D05687 /* NSData+MD5.m in Sources */,
|
||||||
|
@ -2559,7 +2567,6 @@
|
||||||
1755E1F90BA0D2B600CA3560 /* PlaylistLoader.m in Sources */,
|
1755E1F90BA0D2B600CA3560 /* PlaylistLoader.m in Sources */,
|
||||||
8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */,
|
8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */,
|
||||||
179790E10C087AB7001D6996 /* OpenURLPanel.m in Sources */,
|
179790E10C087AB7001D6996 /* OpenURLPanel.m in Sources */,
|
||||||
838770FA2D6F0996001455A0 /* FeedbackController.m in Sources */,
|
|
||||||
837DC931285B3F790005C58A /* DataModel.xcdatamodeld in Sources */,
|
837DC931285B3F790005C58A /* DataModel.xcdatamodeld in Sources */,
|
||||||
835FAC7927BCDF2A00BA8562 /* AVIFDecoder.m in Sources */,
|
835FAC7927BCDF2A00BA8562 /* AVIFDecoder.m in Sources */,
|
||||||
EDAAA41F25A665C000731773 /* PositionSliderToolbarItem.swift in Sources */,
|
EDAAA41F25A665C000731773 /* PositionSliderToolbarItem.swift in Sources */,
|
||||||
|
@ -2569,11 +2576,7 @@
|
||||||
5604D4F60D60726E004F5C5D /* SpotlightPlaylistEntry.m in Sources */,
|
5604D4F60D60726E004F5C5D /* SpotlightPlaylistEntry.m in Sources */,
|
||||||
56462EAF0D6341F6000AB68C /* SpotlightTransformers.m in Sources */,
|
56462EAF0D6341F6000AB68C /* SpotlightTransformers.m in Sources */,
|
||||||
830C37A527B95EB300E02BB0 /* EqualizerWindowController.m in Sources */,
|
830C37A527B95EB300E02BB0 /* EqualizerWindowController.m in Sources */,
|
||||||
838A337D2D06C14200D0D770 /* TempoSlider.m in Sources */,
|
832CFC562851AA8B002AC26F /* SpectrumViewCG.m in Sources */,
|
||||||
838A337E2D06C14200D0D770 /* PitchSlider.m in Sources */,
|
|
||||||
838A33832D06CF4100D0D770 /* SpectrumViewCG.m in Sources */,
|
|
||||||
839E876E2D5DA0AC00A13526 /* RubberbandEngineTransformer.m in Sources */,
|
|
||||||
838A33842D06CF4100D0D770 /* SpectrumWindowController.m in Sources */,
|
|
||||||
83B61E2829A82A0200CD0580 /* LyricsWindowController.m in Sources */,
|
83B61E2829A82A0200CD0580 /* LyricsWindowController.m in Sources */,
|
||||||
56462EB20D634206000AB68C /* SpotlightPlaylistController.m in Sources */,
|
56462EB20D634206000AB68C /* SpotlightPlaylistController.m in Sources */,
|
||||||
07E18DF30D62B38400BB0E11 /* NSArray+ShuffleUtils.m in Sources */,
|
07E18DF30D62B38400BB0E11 /* NSArray+ShuffleUtils.m in Sources */,
|
||||||
|
@ -2620,6 +2623,7 @@
|
||||||
17F6C8070F603701000D9DA9 /* PlaybackEventController.m in Sources */,
|
17F6C8070F603701000D9DA9 /* PlaybackEventController.m in Sources */,
|
||||||
83BC5AB220E4C87100631CD4 /* DualWindow.m in Sources */,
|
83BC5AB220E4C87100631CD4 /* DualWindow.m in Sources */,
|
||||||
8307D30E28606148000FF8EB /* SandboxBroker.m in Sources */,
|
8307D30E28606148000FF8EB /* SandboxBroker.m in Sources */,
|
||||||
|
83229C9F283B0095004626A8 /* SpectrumWindowController.m in Sources */,
|
||||||
835F00BB279BD1CD00055FCF /* SecondsFormatter.m in Sources */,
|
835F00BB279BD1CD00055FCF /* SecondsFormatter.m in Sources */,
|
||||||
1784560F0F631E24007E8021 /* FileTreeViewController.m in Sources */,
|
1784560F0F631E24007E8021 /* FileTreeViewController.m in Sources */,
|
||||||
178456120F631E31007E8021 /* SideViewController.m in Sources */,
|
178456120F631E31007E8021 /* SideViewController.m in Sources */,
|
||||||
|
@ -2748,6 +2752,11 @@
|
||||||
name = Hively;
|
name = Hively;
|
||||||
targetProxy = 836FB5A518206F1500B3AD2D /* PBXContainerItemProxy */;
|
targetProxy = 836FB5A518206F1500B3AD2D /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
|
8372C93C27C7893100E250C9 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
name = MAD;
|
||||||
|
targetProxy = 8372C93B27C7893100E250C9 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
8375B36217FFEF010092A79F /* PBXTargetDependency */ = {
|
8375B36217FFEF010092A79F /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
name = ArchiveSource;
|
name = ArchiveSource;
|
||||||
|
@ -2758,11 +2767,6 @@
|
||||||
name = MIDI;
|
name = MIDI;
|
||||||
targetProxy = 83B06702180D5776008E3612 /* PBXContainerItemProxy */;
|
targetProxy = 83B06702180D5776008E3612 /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
83B73B642D8FD74000A57F08 /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
name = minimp3;
|
|
||||||
targetProxy = 83B73B632D8FD74000A57F08 /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
83BCB8D917FC96F800760340 /* PBXTargetDependency */ = {
|
83BCB8D917FC96F800760340 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
name = HighlyComplete;
|
name = HighlyComplete;
|
||||||
|
@ -2801,6 +2805,9 @@
|
||||||
children = (
|
children = (
|
||||||
833F681E1CDBCAA700AFB9F0 /* es */,
|
833F681E1CDBCAA700AFB9F0 /* es */,
|
||||||
835C888C22CC1882001B4B3F /* en */,
|
835C888C22CC1882001B4B3F /* en */,
|
||||||
|
83F0E8AD287CD48800D84594 /* pl */,
|
||||||
|
491C55C2287AA4B7007D96F5 /* ru */,
|
||||||
|
838EE8B629A8600900CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = InfoPlist.strings;
|
name = InfoPlist.strings;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2810,6 +2817,9 @@
|
||||||
children = (
|
children = (
|
||||||
0A1B412D286F6301008A6A44 /* es */,
|
0A1B412D286F6301008A6A44 /* es */,
|
||||||
0A1B412F286F6307008A6A44 /* en */,
|
0A1B412F286F6307008A6A44 /* en */,
|
||||||
|
491C55BF287AA4B6007D96F5 /* ru */,
|
||||||
|
83D2E23D287ED5ED00DD441F /* pl */,
|
||||||
|
838EE8B129A8600800CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = Localizable.stringsdict;
|
name = Localizable.stringsdict;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2820,6 +2830,9 @@
|
||||||
83BC5AB720E4C91400631CD4 /* Base */,
|
83BC5AB720E4C91400631CD4 /* Base */,
|
||||||
83BC5AD220E4D0B400631CD4 /* es */,
|
83BC5AD220E4D0B400631CD4 /* es */,
|
||||||
83BC5AD420E4D0B600631CD4 /* en */,
|
83BC5AD420E4D0B600631CD4 /* en */,
|
||||||
|
83F0E6A8287CAB3800D84594 /* pl */,
|
||||||
|
491C55BB287AA4B6007D96F5 /* ru */,
|
||||||
|
838EE8AC29A8600700CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = FileTree.xib;
|
name = FileTree.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2830,6 +2843,9 @@
|
||||||
83BC5AB520E4C91200631CD4 /* Base */,
|
83BC5AB520E4C91200631CD4 /* Base */,
|
||||||
83BC5AC620E4D04600631CD4 /* en */,
|
83BC5AC620E4D04600631CD4 /* en */,
|
||||||
83BC5AC820E4D05A00631CD4 /* es */,
|
83BC5AC820E4D05A00631CD4 /* es */,
|
||||||
|
83F0E6A6287CAB3800D84594 /* pl */,
|
||||||
|
491C55B9287AA4B6007D96F5 /* ru */,
|
||||||
|
838EE8AA29A8600700CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = MainMenu.xib;
|
name = MainMenu.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2840,6 +2856,9 @@
|
||||||
83BC5AB620E4C91300631CD4 /* Base */,
|
83BC5AB620E4C91300631CD4 /* Base */,
|
||||||
83BC5ACE20E4D09700631CD4 /* es */,
|
83BC5ACE20E4D09700631CD4 /* es */,
|
||||||
83BC5AD020E4D09800631CD4 /* en */,
|
83BC5AD020E4D09800631CD4 /* en */,
|
||||||
|
83F0E6A7287CAB3800D84594 /* pl */,
|
||||||
|
491C55BA287AA4B6007D96F5 /* ru */,
|
||||||
|
838EE8AB29A8600700CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = OpenURLPanel.xib;
|
name = OpenURLPanel.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2850,6 +2869,9 @@
|
||||||
83BC5AB820E4C91400631CD4 /* Base */,
|
83BC5AB820E4C91400631CD4 /* Base */,
|
||||||
83BC5AD620E4D0D800631CD4 /* es */,
|
83BC5AD620E4D0D800631CD4 /* es */,
|
||||||
83BC5AD820E4D0D900631CD4 /* en */,
|
83BC5AD820E4D0D900631CD4 /* en */,
|
||||||
|
83F0E6AA287CAB3800D84594 /* pl */,
|
||||||
|
491C55BD287AA4B6007D96F5 /* ru */,
|
||||||
|
838EE8AE29A8600800CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = SpotlightPanel.xib;
|
name = SpotlightPanel.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2860,6 +2882,9 @@
|
||||||
83BC5AB420E4C91100631CD4 /* Base */,
|
83BC5AB420E4C91100631CD4 /* Base */,
|
||||||
83BC5ACA20E4D07200631CD4 /* es */,
|
83BC5ACA20E4D07200631CD4 /* es */,
|
||||||
83BC5ACC20E4D07700631CD4 /* en */,
|
83BC5ACC20E4D07700631CD4 /* en */,
|
||||||
|
83F0E6A5287CAB3800D84594 /* pl */,
|
||||||
|
491C55B8287AA4B6007D96F5 /* ru */,
|
||||||
|
838EE8A929A8600700CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = InfoInspector.xib;
|
name = InfoInspector.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2870,6 +2895,9 @@
|
||||||
83BC5AB920E4C91500631CD4 /* Base */,
|
83BC5AB920E4C91500631CD4 /* Base */,
|
||||||
83BC5ADA20E4D0E900631CD4 /* en */,
|
83BC5ADA20E4D0E900631CD4 /* en */,
|
||||||
83BC5ADC20E4D0EC00631CD4 /* es */,
|
83BC5ADC20E4D0EC00631CD4 /* es */,
|
||||||
|
83F0E6AB287CAB3800D84594 /* pl */,
|
||||||
|
491C55BE287AA4B6007D96F5 /* ru */,
|
||||||
|
838EE8AF29A8600800CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = Feedback.xib;
|
name = Feedback.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2879,6 +2907,9 @@
|
||||||
children = (
|
children = (
|
||||||
833F68251CDBCAA800AFB9F0 /* es */,
|
833F68251CDBCAA800AFB9F0 /* es */,
|
||||||
835C888B22CC1881001B4B3F /* en */,
|
835C888B22CC1881001B4B3F /* en */,
|
||||||
|
83F0E8B2287CD52500D84594 /* pl */,
|
||||||
|
491C55C4287AA4B7007D96F5 /* ru */,
|
||||||
|
838EE8B829A8600900CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = Credits.html;
|
name = Credits.html;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2889,6 +2920,9 @@
|
||||||
830C37A027B95E3000E02BB0 /* Base */,
|
830C37A027B95E3000E02BB0 /* Base */,
|
||||||
839614A8286EDA0400D3EEDB /* en */,
|
839614A8286EDA0400D3EEDB /* en */,
|
||||||
839614AA286EDA0600D3EEDB /* es */,
|
839614AA286EDA0600D3EEDB /* es */,
|
||||||
|
83F0E6A4287CAB3800D84594 /* pl */,
|
||||||
|
491C55B7287AA4B6007D96F5 /* ru */,
|
||||||
|
838EE8A829A8600700CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = Equalizer.xib;
|
name = Equalizer.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2899,6 +2933,9 @@
|
||||||
839614A1286ED97200D3EEDB /* Base */,
|
839614A1286ED97200D3EEDB /* Base */,
|
||||||
839614A4286ED98600D3EEDB /* en */,
|
839614A4286ED98600D3EEDB /* en */,
|
||||||
839614A6286ED98800D3EEDB /* es */,
|
839614A6286ED98800D3EEDB /* es */,
|
||||||
|
83F0E6A3287CAB3800D84594 /* pl */,
|
||||||
|
491C55B6287AA4B6007D96F5 /* ru */,
|
||||||
|
838EE8A729A8600600CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = AboutWindowController.xib;
|
name = AboutWindowController.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2909,6 +2946,9 @@
|
||||||
839614AC286EDA5C00D3EEDB /* Base */,
|
839614AC286EDA5C00D3EEDB /* Base */,
|
||||||
839614AF286EDA6800D3EEDB /* en */,
|
839614AF286EDA6800D3EEDB /* en */,
|
||||||
839614B1286EDA6E00D3EEDB /* es */,
|
839614B1286EDA6E00D3EEDB /* es */,
|
||||||
|
83F0E6A9287CAB3800D84594 /* pl */,
|
||||||
|
491C55BC287AA4B6007D96F5 /* ru */,
|
||||||
|
838EE8AD29A8600700CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = SpectrumWindow.xib;
|
name = SpectrumWindow.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2919,6 +2959,9 @@
|
||||||
83B61E2329A8296500CD0580 /* Base */,
|
83B61E2329A8296500CD0580 /* Base */,
|
||||||
838EE79E29A8556000CD0580 /* en */,
|
838EE79E29A8556000CD0580 /* en */,
|
||||||
838EE7A029A8556500CD0580 /* es */,
|
838EE7A029A8556500CD0580 /* es */,
|
||||||
|
838EE7A229A8557000CD0580 /* ru */,
|
||||||
|
838EE7A429A8557200CD0580 /* pl */,
|
||||||
|
838EE8B029A8600800CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = LyricsWindow.xib;
|
name = LyricsWindow.xib;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2928,6 +2971,9 @@
|
||||||
children = (
|
children = (
|
||||||
833F681F1CDBCAA800AFB9F0 /* es */,
|
833F681F1CDBCAA800AFB9F0 /* es */,
|
||||||
835C888D22CC1882001B4B3F /* en */,
|
835C888D22CC1882001B4B3F /* en */,
|
||||||
|
83F0E8B1287CD50700D84594 /* pl */,
|
||||||
|
491C55C3287AA4B7007D96F5 /* ru */,
|
||||||
|
838EE8B729A8600900CD0580 /* tr */,
|
||||||
);
|
);
|
||||||
name = Localizable.strings;
|
name = Localizable.strings;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2967,8 +3013,6 @@
|
||||||
"$(PROJECT_DIR)/ThirdParty/avif/lib",
|
"$(PROJECT_DIR)/ThirdParty/avif/lib",
|
||||||
"$(PROJECT_DIR)/ThirdParty/mpg123/lib",
|
"$(PROJECT_DIR)/ThirdParty/mpg123/lib",
|
||||||
"$(PROJECT_DIR)/ThirdParty/soxr/lib",
|
"$(PROJECT_DIR)/ThirdParty/soxr/lib",
|
||||||
"$(PROJECT_DIR)",
|
|
||||||
"$(PROJECT_DIR)/ThirdParty/rubberband/lib",
|
|
||||||
);
|
);
|
||||||
OTHER_CFLAGS = (
|
OTHER_CFLAGS = (
|
||||||
"-D__MACOSX__",
|
"-D__MACOSX__",
|
||||||
|
@ -3026,8 +3070,6 @@
|
||||||
"$(PROJECT_DIR)/ThirdParty/avif/lib",
|
"$(PROJECT_DIR)/ThirdParty/avif/lib",
|
||||||
"$(PROJECT_DIR)/ThirdParty/mpg123/lib",
|
"$(PROJECT_DIR)/ThirdParty/mpg123/lib",
|
||||||
"$(PROJECT_DIR)/ThirdParty/soxr/lib",
|
"$(PROJECT_DIR)/ThirdParty/soxr/lib",
|
||||||
"$(PROJECT_DIR)",
|
|
||||||
"$(PROJECT_DIR)/ThirdParty/rubberband/lib",
|
|
||||||
);
|
);
|
||||||
OTHER_CFLAGS = (
|
OTHER_CFLAGS = (
|
||||||
"-D__MACOSX__",
|
"-D__MACOSX__",
|
||||||
|
@ -3165,21 +3207,26 @@
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCRemoteSwiftPackageReference section */
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
83F9FFED2D6EB75B00026576 /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {
|
83978E14285C58190076ED21 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/getsentry/sentry-cocoa.git";
|
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = upToNextMajorVersion;
|
kind = upToNextMajorVersion;
|
||||||
minimumVersion = 8.47.0;
|
minimumVersion = 9.0.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
83F9FFEE2D6EB75B00026576 /* Sentry */ = {
|
83978E15285C58190076ED21 /* FirebaseCrashlytics */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 83F9FFED2D6EB75B00026576 /* XCRemoteSwiftPackageReference "sentry-cocoa" */;
|
package = 83978E14285C58190076ED21 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
|
||||||
productName = Sentry;
|
productName = FirebaseCrashlytics;
|
||||||
|
};
|
||||||
|
83978E25285C596F0076ED21 /* FirebaseAnalytics */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 83978E14285C58190076ED21 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
|
||||||
|
productName = FirebaseAnalytics;
|
||||||
};
|
};
|
||||||
/* End XCSwiftPackageProductDependency section */
|
/* End XCSwiftPackageProductDependency section */
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,113 @@
|
||||||
{
|
{
|
||||||
"originHash" : "7b5e54f81ac1ebaa640945691cb38c371b637198701f04fba811702fc8e7067e",
|
|
||||||
"pins" : [
|
"pins" : [
|
||||||
{
|
{
|
||||||
"identity" : "sentry-cocoa",
|
"identity" : "abseil-cpp-swiftpm",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/getsentry/sentry-cocoa.git",
|
"location" : "https://github.com/firebase/abseil-cpp-SwiftPM.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "6c81e671154e63464dd6749b7ba3279dd390a146",
|
"revision" : "d302de612e3d57c6f4afaf087da18fba8eac72a7",
|
||||||
"version" : "8.50.1"
|
"version" : "0.20220203.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "boringssl-swiftpm",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/firebase/boringssl-SwiftPM.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "79db6516894a932d0ddaff3b05b9da1e4f6c4069",
|
||||||
|
"version" : "0.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "firebase-ios-sdk",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/firebase/firebase-ios-sdk",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "2eb177effe7baf1f13ad0c5f4eb8c71a98429fb5",
|
||||||
|
"version" : "9.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "googleappmeasurement",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/google/GoogleAppMeasurement.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "192cce3e0486aecfdb61102a9c694c78dc89dc48",
|
||||||
|
"version" : "9.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "googledatatransport",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/google/GoogleDataTransport.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "b905c49326b72211531ed9d7baa02d724828a8dc",
|
||||||
|
"version" : "9.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "googleutilities",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/google/GoogleUtilities.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "f4abe56ce62a779e64b525eb133c8fc2a84bbc1f",
|
||||||
|
"version" : "7.7.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "grpc-ios",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/grpc/grpc-ios.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "2af4f6e9c2b18beae228f50b1198c641be859d2b",
|
||||||
|
"version" : "1.44.2-grpc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "gtm-session-fetcher",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/google/gtm-session-fetcher.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "19605024d59eaefdb1f6a2cb11ebe75df4421126",
|
||||||
|
"version" : "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "leveldb",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/firebase/leveldb.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "0706abcc6b0bd9cedfbb015ba840e4a780b5159b",
|
||||||
|
"version" : "1.22.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "nanopb",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/firebase/nanopb.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692",
|
||||||
|
"version" : "2.30909.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "promises",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/google/promises.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "46c1e6b5ac09d8f82c991061c659f67e573d425d",
|
||||||
|
"version" : "2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-protobuf",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/apple/swift-protobuf.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "e1499bc69b9040b29184f7f2996f7bab467c1639",
|
||||||
|
"version" : "1.19.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version" : 3
|
"version" : 2
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.7">
|
version = "1.7">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -281,17 +281,15 @@ void equalizerLoadPreset(AudioUnit au) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void equalizerApplyPreset(AudioUnit au, const NSDictionary *preset) {
|
void equalizerApplyPreset(AudioUnit au, const NSDictionary *preset) {
|
||||||
if(preset) {
|
if(au && preset) {
|
||||||
@synchronized(cog_equalizer_band_settings) {
|
@synchronized(cog_equalizer_band_settings) {
|
||||||
if(!cog_equalizer_band_settings)
|
if(!cog_equalizer_band_settings)
|
||||||
cog_equalizer_band_settings = _cog_equalizer_band_settings();
|
cog_equalizer_band_settings = _cog_equalizer_band_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(au) {
|
|
||||||
AudioUnitParameterValue paramValue = 0;
|
AudioUnitParameterValue paramValue = 0;
|
||||||
if(AudioUnitGetParameter(au, kGraphicEQParam_NumberOfBands, kAudioUnitScope_Global, 0, ¶mValue))
|
if(AudioUnitGetParameter(au, kGraphicEQParam_NumberOfBands, kAudioUnitScope_Global, 0, ¶mValue))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
float presetValues[31];
|
float presetValues[31];
|
||||||
interpolateBands(presetValues, preset);
|
interpolateBands(presetValues, preset);
|
||||||
|
@ -299,16 +297,12 @@ void equalizerApplyPreset(AudioUnit au, const NSDictionary *preset) {
|
||||||
float preamp = getPreamp(preset);
|
float preamp = getPreamp(preset);
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setFloat:preamp forKey:[cog_equalizer_band_settings objectAtIndex:0]];
|
[[NSUserDefaults standardUserDefaults] setFloat:preamp forKey:[cog_equalizer_band_settings objectAtIndex:0]];
|
||||||
if(au) {
|
|
||||||
AudioUnitSetParameter(au, kGraphicEQParam_NumberOfBands, kAudioUnitScope_Global, 0, 1, 0);
|
AudioUnitSetParameter(au, kGraphicEQParam_NumberOfBands, kAudioUnitScope_Global, 0, 1, 0);
|
||||||
}
|
|
||||||
for(unsigned int i = 0; i < 31; ++i) {
|
for(unsigned int i = 0; i < 31; ++i) {
|
||||||
[[NSUserDefaults standardUserDefaults] setFloat:presetValues[i] forKey:[cog_equalizer_band_settings objectAtIndex:i + 1]];
|
[[NSUserDefaults standardUserDefaults] setFloat:presetValues[i] forKey:[cog_equalizer_band_settings objectAtIndex:i + 1]];
|
||||||
if(au) {
|
|
||||||
AudioUnitSetParameter(au, i, kAudioUnitScope_Global, 0, presetValues[i], 0);
|
AudioUnitSetParameter(au, i, kAudioUnitScope_Global, 0, presetValues[i], 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@implementation EqPresetBehaviorArrayController
|
@implementation EqPresetBehaviorArrayController
|
||||||
|
|
|
@ -10,18 +10,15 @@
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
@interface FeedbackController : NSWindowController <FeedbackSocketDelegate> {
|
@interface FeedbackController : NSWindowController <FeedbackSocketDelegate> {
|
||||||
IBOutlet NSTextField* nameView;
|
IBOutlet NSTextField* fromView;
|
||||||
IBOutlet NSTextField* emailView;
|
IBOutlet NSTextField* subjectView;
|
||||||
IBOutlet NSTextView* messageView;
|
IBOutlet NSTextView* messageView;
|
||||||
|
IBOutlet NSProgressIndicator* sendingIndicator;
|
||||||
|
|
||||||
|
FeedbackSocket* feedbackSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)sendFeedback:(id)sender;
|
- (IBAction)sendFeedback:(id)sender;
|
||||||
- (IBAction)cancel:(id)sender;
|
- (IBAction)cancel:(id)sender;
|
||||||
|
|
||||||
- (BOOL)waitForCompletion;
|
|
||||||
|
|
||||||
- (NSString *)name;
|
|
||||||
- (NSString *)email;
|
|
||||||
- (NSString *)comments;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -10,67 +10,62 @@
|
||||||
|
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
|
|
||||||
@implementation FeedbackController {
|
@implementation FeedbackController
|
||||||
BOOL showing;
|
|
||||||
BOOL sent;
|
|
||||||
|
|
||||||
NSString *name;
|
|
||||||
NSString *email;
|
|
||||||
NSString *comments;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)init {
|
- (id)init {
|
||||||
self = [super initWithWindowNibName:@"Feedback"];
|
return [super initWithWindowNibName:@"Feedback"];
|
||||||
if(self) {
|
|
||||||
showing = NO;
|
|
||||||
sent = NO;
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)showWindow:(id)sender {
|
- (IBAction)showWindow:(id)sender {
|
||||||
[nameView setStringValue:@""];
|
[fromView setStringValue:@""];
|
||||||
[emailView setStringValue:@""];
|
[subjectView setStringValue:@""];
|
||||||
[messageView setString:@""];
|
[messageView setString:@""];
|
||||||
|
|
||||||
[super showWindow:sender];
|
[super showWindow:sender];
|
||||||
|
}
|
||||||
|
|
||||||
showing = YES;
|
- (void)alertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo {
|
||||||
|
if([(NSNumber *)CFBridgingRelease(contextInfo) boolValue] == YES) {
|
||||||
|
[[self window] close];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)feedbackDidNotSend:(FeedbackSocket *)feedback {
|
||||||
|
ALog(@"Error sending feedback");
|
||||||
|
|
||||||
|
[sendingIndicator stopAnimation:self];
|
||||||
|
|
||||||
|
NSAlert *alert = [[NSAlert alloc] init];
|
||||||
|
[alert setMessageText:NSLocalizedString(@"FeedbackFailedMessageText", @"")];
|
||||||
|
[alert setInformativeText:NSLocalizedString(@"FeedbackFailedInformativeText", @"")];
|
||||||
|
|
||||||
|
[alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:(void *)CFBridgingRetain([NSNumber numberWithBool:NO])];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)feedbackDidSend:(FeedbackSocket *)feedback {
|
||||||
|
[sendingIndicator stopAnimation:self];
|
||||||
|
|
||||||
|
NSAlert *alert = [[NSAlert alloc] init];
|
||||||
|
[alert setMessageText:NSLocalizedString(@"FeedbackSuccessMessageText", @"")];
|
||||||
|
[alert setInformativeText:NSLocalizedString(@"FeedbackSuccessInformativeText", @"")];
|
||||||
|
|
||||||
|
[alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:(void *)CFBridgingRetain([NSNumber numberWithBool:YES])];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)sendFeedback:(id)sender {
|
- (IBAction)sendFeedback:(id)sender {
|
||||||
name = [nameView stringValue];
|
[sendingIndicator startAnimation:self];
|
||||||
email = [emailView stringValue];
|
|
||||||
comments = [messageView string];
|
|
||||||
|
|
||||||
[[self window] close];
|
// Using this so that if its a bad connection, it doesnt sit there looking stupid..or should it
|
||||||
sent = YES;
|
feedbackSocket = [[FeedbackSocket alloc] init];
|
||||||
showing = NO;
|
[feedbackSocket setDelegate:self];
|
||||||
|
|
||||||
|
NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
|
||||||
|
|
||||||
|
[feedbackSocket sendFeedback:[fromView stringValue] subject:[subjectView stringValue] message:[messageView string] version:version];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)cancel:(id)sender {
|
- (IBAction)cancel:(id)sender {
|
||||||
[[self window] close];
|
[[self window] close];
|
||||||
sent = NO;
|
|
||||||
showing = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)waitForCompletion {
|
|
||||||
while(showing) {
|
|
||||||
usleep(2000);
|
|
||||||
}
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)name {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)email {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)comments {
|
|
||||||
return comments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -23,28 +23,8 @@
|
||||||
NSString *title = nil;
|
NSString *title = nil;
|
||||||
NSString *artist = nil;
|
NSString *artist = nil;
|
||||||
if(metadata) {
|
if(metadata) {
|
||||||
id _title = [metadata valueForKey:@"title"];
|
title = [metadata valueForKey:@"title"];
|
||||||
id _artist = [metadata valueForKey:@"artist"];
|
artist = [metadata valueForKey:@"artist"];
|
||||||
|
|
||||||
if([_title isKindOfClass:[NSArray class]]) {
|
|
||||||
NSArray *titlearray = _title;
|
|
||||||
title = [titlearray componentsJoinedByString:@", "];
|
|
||||||
} else if([_title isKindOfClass:[NSString class]]) {
|
|
||||||
title = _title;
|
|
||||||
} else if([_title isKindOfClass:[NSNumber class]]) {
|
|
||||||
NSNumber *titlenumber = _title;
|
|
||||||
title = [NSString stringWithFormat:@"%@", titlenumber];
|
|
||||||
}
|
|
||||||
|
|
||||||
if([_artist isKindOfClass:[NSArray class]]) {
|
|
||||||
NSArray *artistarray = _artist;
|
|
||||||
artist = [artistarray componentsJoinedByString:@", "];
|
|
||||||
} else if([_artist isKindOfClass:[NSString class]]) {
|
|
||||||
artist = _artist;
|
|
||||||
} else if([_artist isKindOfClass:[NSNumber class]]) {
|
|
||||||
NSNumber *artistnumber = _artist;
|
|
||||||
artist = [NSString stringWithFormat:@"%@", artistnumber];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(title && [title length]) {
|
if(title && [title length]) {
|
||||||
|
|
|
@ -24,8 +24,3 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface SecondsFractionFormatter : NSFormatter {
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
|
@ -99,83 +99,3 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation SecondsFractionFormatter
|
|
||||||
|
|
||||||
- (NSString *)stringForObjectValue:(id)object {
|
|
||||||
NSString *result = nil;
|
|
||||||
double value;
|
|
||||||
unsigned days = 0;
|
|
||||||
unsigned hours = 0;
|
|
||||||
unsigned minutes = 0;
|
|
||||||
float seconds = 0.0;
|
|
||||||
|
|
||||||
if(nil == object || NO == [object isKindOfClass:[NSNumber class]] || isnan([object doubleValue])) {
|
|
||||||
return @"";
|
|
||||||
}
|
|
||||||
|
|
||||||
value = [object doubleValue];
|
|
||||||
|
|
||||||
seconds = fmod(value, 60.0);
|
|
||||||
minutes = (unsigned)floor(value / 60.0);
|
|
||||||
|
|
||||||
while(60 <= minutes) {
|
|
||||||
minutes -= 60;
|
|
||||||
++hours;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(24 <= hours) {
|
|
||||||
hours -= 24;
|
|
||||||
++days;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(0 < days) {
|
|
||||||
result = [NSString stringWithFormat:@"%u:%.2u:%.2u:%06.3f", days, hours, minutes, seconds];
|
|
||||||
} else if(0 < hours) {
|
|
||||||
result = [NSString stringWithFormat:@"%u:%.2u:%06.3f", hours, minutes, seconds];
|
|
||||||
} else if(0 < minutes) {
|
|
||||||
result = [NSString stringWithFormat:@"%u:%06.3f", minutes, seconds];
|
|
||||||
} else {
|
|
||||||
result = [NSString stringWithFormat:@"0:%06.3f", seconds];
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)getObjectValue:(id *)object forString:(NSString *)string errorDescription:(NSString **)error {
|
|
||||||
NSScanner *scanner = nil;
|
|
||||||
BOOL result = NO;
|
|
||||||
double value = 0.0;
|
|
||||||
double seconds = 0.0;
|
|
||||||
|
|
||||||
scanner = [NSScanner scannerWithString:string];
|
|
||||||
|
|
||||||
while(NO == [scanner isAtEnd]) {
|
|
||||||
// Grab a value
|
|
||||||
if([scanner scanDouble:&value]) {
|
|
||||||
seconds *= 60.0;
|
|
||||||
seconds += value;
|
|
||||||
result = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab the separator, if present
|
|
||||||
[scanner scanString:@":" intoString:NULL];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result && NULL != object) {
|
|
||||||
*object = @(seconds);
|
|
||||||
} else if(NULL != error) {
|
|
||||||
*error = @"Couldn't convert value to seconds";
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSAttributedString *)attributedStringForObjectValue:(id)object withDefaultAttributes:(NSDictionary *)attributes {
|
|
||||||
NSAttributedString *result = nil;
|
|
||||||
|
|
||||||
result = [[NSAttributedString alloc] initWithString:[self stringForObjectValue:object] attributes:attributes];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2021-2025 Christopher Snowhill. All rights reserved.</string>
|
<string>Copyright © 2021-2023 Christopher Snowhill. All rights reserved.</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 48;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -557,8 +557,7 @@
|
||||||
83D3C4CB201C654F005564CB /* Project object */ = {
|
83D3C4CB201C654F005564CB /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
ORGANIZATIONNAME = "Christopher Snowhill";
|
ORGANIZATIONNAME = "Christopher Snowhill";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
83D3C4D3201C654F005564CB = {
|
83D3C4D3201C654F005564CB = {
|
||||||
|
@ -722,11 +721,9 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
@ -788,11 +785,9 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
@ -815,9 +810,7 @@
|
||||||
83D3C4DD201C6550005564CB /* Debug */ = {
|
83D3C4DD201C6550005564CB /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -832,11 +825,7 @@
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = AdPlug/Info.plist;
|
INFOPLIST_FILE = AdPlug/Info.plist;
|
||||||
INSTALL_PATH = "@loader_path/../Frameworks";
|
INSTALL_PATH = "@loader_path/../Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/../Frameworks",
|
|
||||||
"@loader_path/Frameworks",
|
|
||||||
);
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libAdPlug;
|
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libAdPlug;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
@ -846,9 +835,7 @@
|
||||||
83D3C4DE201C6550005564CB /* Release */ = {
|
83D3C4DE201C6550005564CB /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -859,11 +846,7 @@
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = AdPlug/Info.plist;
|
INFOPLIST_FILE = AdPlug/Info.plist;
|
||||||
INSTALL_PATH = "@loader_path/../Frameworks";
|
INSTALL_PATH = "@loader_path/../Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||||
"$(inherited)",
|
|
||||||
"@executable_path/../Frameworks",
|
|
||||||
"@loader_path/Frameworks",
|
|
||||||
);
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libAdPlug;
|
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libAdPlug;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -631,8 +631,7 @@
|
||||||
8359FF3317FEF39F0060F3ED /* Project object */ = {
|
8359FF3317FEF39F0060F3ED /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
ORGANIZATIONNAME = "Christopher Snowhill";
|
ORGANIZATIONNAME = "Christopher Snowhill";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8359FF3B17FEF39F0060F3ED = {
|
8359FF3B17FEF39F0060F3ED = {
|
||||||
|
@ -791,10 +790,8 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
@ -850,11 +847,9 @@
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
@ -875,9 +870,7 @@
|
||||||
8359FF6517FEF39F0060F3ED /* Debug */ = {
|
8359FF6517FEF39F0060F3ED /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -900,9 +893,7 @@
|
||||||
8359FF6617FEF39F0060F3ED /* Release */ = {
|
8359FF6617FEF39F0060F3ED /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2021-2025 Christopher Snowhill. All rights reserved.</string>
|
<string>Copyright © 2021-2023 Christopher Snowhill. All rights reserved.</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -627,8 +627,7 @@
|
||||||
0867D690FE84028FC02AAC07 /* Project object */ = {
|
0867D690FE84028FC02AAC07 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8DC2EF4F0486A6940098B216 = {
|
8DC2EF4F0486A6940098B216 = {
|
||||||
DevelopmentTeam = "";
|
DevelopmentTeam = "";
|
||||||
|
@ -746,10 +745,8 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -782,9 +779,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -836,10 +831,8 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
@ -885,10 +878,8 @@
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include "Bml_Parser.h"
|
#include "Bml_Parser.h"
|
||||||
|
|
||||||
/* Copyright (C) 2013-2025 Christopher Snowhill. This module is free
|
/* Copyright (C) 2013-2023 Christopher Snowhill. This module is free
|
||||||
software; you can redistribute it and/or modify it under the terms of
|
software; you can redistribute it and/or modify it under the terms of
|
||||||
the GNU Lesser General Public License as published by the Free Software
|
the GNU Lesser General Public License as published by the Free Software
|
||||||
Foundation; either version 2.1 of the License, or (at your option) any
|
Foundation; either version 2.1 of the License, or (at your option) any
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/* Copyright (C) 2013-2025 Christopher Snowhill. This module is free
|
/* Copyright (C) 2013-2023 Christopher Snowhill. This module is free
|
||||||
software; you can redistribute it and/or modify it under the terms of
|
software; you can redistribute it and/or modify it under the terms of
|
||||||
the GNU Lesser General Public License as published by the Free Software
|
the GNU Lesser General Public License as published by the Free Software
|
||||||
Foundation; either version 2.1 of the License, or (at your option) any
|
Foundation; either version 2.1 of the License, or (at your option) any
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -248,8 +248,7 @@
|
||||||
8343792C17F97BDB00584396 /* Project object */ = {
|
8343792C17F97BDB00584396 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
ORGANIZATIONNAME = "Christopher Snowhill";
|
ORGANIZATIONNAME = "Christopher Snowhill";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8343793417F97BDB00584396 = {
|
8343793417F97BDB00584396 = {
|
||||||
|
@ -356,10 +355,8 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
@ -414,11 +411,9 @@
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
@ -438,9 +433,7 @@
|
||||||
8343795E17F97BDB00584396 /* Debug */ = {
|
8343795E17F97BDB00584396 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -462,9 +455,7 @@
|
||||||
8343795F17F97BDB00584396 /* Release */ = {
|
8343795F17F97BDB00584396 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2021-2025 Christopher Snowhill. All rights reserved.</string>
|
<string>Copyright © 2021-2023 Christopher Snowhill. All rights reserved.</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -187,8 +187,7 @@
|
||||||
8360EF0717F92C91005208A4 /* Project object */ = {
|
8360EF0717F92C91005208A4 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
ORGANIZATIONNAME = "Christopher Snowhill";
|
ORGANIZATIONNAME = "Christopher Snowhill";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8360EF0F17F92C91005208A4 = {
|
8360EF0F17F92C91005208A4 = {
|
||||||
|
@ -293,10 +292,8 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
@ -351,11 +348,9 @@
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
@ -375,9 +370,7 @@
|
||||||
8360EF3917F92C91005208A4 /* Debug */ = {
|
8360EF3917F92C91005208A4 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -401,9 +394,7 @@
|
||||||
8360EF3A17F92C91005208A4 /* Release */ = {
|
8360EF3A17F92C91005208A4 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2021-2025 Christopher Snowhill. All rights reserved.</string>
|
<string>Copyright © 2021-2023 Christopher Snowhill. All rights reserved.</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -159,8 +159,7 @@
|
||||||
834378D517F96E2600584396 /* Project object */ = {
|
834378D517F96E2600584396 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
ORGANIZATIONNAME = "Christopher Snowhill";
|
ORGANIZATIONNAME = "Christopher Snowhill";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
834378DD17F96E2600584396 = {
|
834378DD17F96E2600584396 = {
|
||||||
|
@ -261,10 +260,8 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
@ -323,11 +320,9 @@
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
@ -354,9 +349,7 @@
|
||||||
8343790717F96E2600584396 /* Debug */ = {
|
8343790717F96E2600584396 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -373,9 +366,7 @@
|
||||||
8343790817F96E2600584396 /* Release */ = {
|
8343790817F96E2600584396 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2021-2025 Christopher Snowhill. All rights reserved.</string>
|
<string>Copyright © 2021-2023 Christopher Snowhill. All rights reserved.</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -201,8 +201,7 @@
|
||||||
8343786517F9658E00584396 /* Project object */ = {
|
8343786517F9658E00584396 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
ORGANIZATIONNAME = "Christopher Snowhill";
|
ORGANIZATIONNAME = "Christopher Snowhill";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8343786D17F9658E00584396 = {
|
8343786D17F9658E00584396 = {
|
||||||
|
@ -306,10 +305,8 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
@ -370,11 +367,9 @@
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
@ -403,9 +398,7 @@
|
||||||
8343789717F9658E00584396 /* Debug */ = {
|
8343789717F9658E00584396 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -423,9 +416,7 @@
|
||||||
8343789817F9658E00584396 /* Release */ = {
|
8343789817F9658E00584396 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2021-2025 Christopher Snowhill. All rights reserved.</string>
|
<string>Copyright © 2021-2023 Christopher Snowhill. All rights reserved.</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -141,8 +141,7 @@
|
||||||
836FB54D182053D700B3AD2D /* Project object */ = {
|
836FB54D182053D700B3AD2D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
ORGANIZATIONNAME = "Christopher Snowhill";
|
ORGANIZATIONNAME = "Christopher Snowhill";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
836FB555182053D700B3AD2D = {
|
836FB555182053D700B3AD2D = {
|
||||||
|
@ -241,10 +240,8 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
@ -301,11 +298,9 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
@ -326,9 +321,7 @@
|
||||||
836FB57F182053D700B3AD2D /* Debug */ = {
|
836FB57F182053D700B3AD2D /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -344,9 +337,7 @@
|
||||||
836FB580182053D700B3AD2D /* Release */ = {
|
836FB580182053D700B3AD2D /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2021-2025 Christopher Snowhill. All rights reserved.</string>
|
<string>Copyright © 2021-2023 Christopher Snowhill. All rights reserved.</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 54;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -242,8 +242,7 @@
|
||||||
0867D690FE84028FC02AAC07 /* Project object */ = {
|
0867D690FE84028FC02AAC07 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
LastUpgradeCheck = 1400;
|
||||||
LastUpgradeCheck = 1620;
|
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8DC2EF4F0486A6940098B216 = {
|
8DC2EF4F0486A6940098B216 = {
|
||||||
DevelopmentTeam = "";
|
DevelopmentTeam = "";
|
||||||
|
@ -324,10 +323,8 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -352,9 +349,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
FRAMEWORK_VERSION = A;
|
FRAMEWORK_VERSION = A;
|
||||||
|
@ -398,10 +393,8 @@
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
@ -445,10 +438,8 @@
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1620"
|
LastUpgradeVersion = "1500"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2021-2025 Christopher Snowhill. All rights reserved.</string>
|
<string>Copyright © 2021-2023 Christopher Snowhill. All rights reserved.</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2004-2025, OpenMPT Project Developers and Contributors
|
Copyright (c) 2004-2023, OpenMPT Project Developers and Contributors
|
||||||
Copyright (c) 1997-2003, Olivier Lapicque
|
Copyright (c) 1997-2003, Olivier Lapicque
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,6 @@
|
||||||
# ONLY_TEST=0 Only build the test suite.
|
# ONLY_TEST=0 Only build the test suite.
|
||||||
# STRICT=0 Treat warnings as errors.
|
# STRICT=0 Treat warnings as errors.
|
||||||
# MODERN=0 Pass more modern compiler options.
|
# MODERN=0 Pass more modern compiler options.
|
||||||
# ANCIENT=0 Pass compiler options compatible with older versions.
|
|
||||||
# NATIVE=0 Optimize for system CPU.
|
# NATIVE=0 Optimize for system CPU.
|
||||||
# STDCXX=c++17 C++ standard version (default depends on compiler)
|
# STDCXX=c++17 C++ standard version (default depends on compiler)
|
||||||
# STDC=c17 C standard version (default depends on compiler)
|
# STDC=c17 C standard version (default depends on compiler)
|
||||||
|
@ -256,27 +255,6 @@ NUMTHREADS:=$(shell nproc)
|
||||||
|
|
||||||
else ifeq ($(OS),Windows_NT)
|
else ifeq ($(OS),Windows_NT)
|
||||||
|
|
||||||
ifeq ($(shell uname -o),Cygwin)
|
|
||||||
|
|
||||||
HOST=unix
|
|
||||||
HOST_FLAVOUR=CYGWIN
|
|
||||||
|
|
||||||
TOOLCHAIN_SUFFIX=
|
|
||||||
|
|
||||||
CPPCHECK = cppcheck
|
|
||||||
|
|
||||||
MKDIR_P = mkdir -p
|
|
||||||
RM = rm -f
|
|
||||||
RMTREE = rm -rf
|
|
||||||
INSTALL = install
|
|
||||||
INSTALL_MAKE_DIR = install -d
|
|
||||||
INSTALL_DIR = cp -r -v
|
|
||||||
FIXPATH = $1
|
|
||||||
|
|
||||||
NUMTHREADS:=$(NUMBER_OF_PROCESSORS)
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
HOST=windows
|
HOST=windows
|
||||||
HOST_FLAVOUR=
|
HOST_FLAVOUR=
|
||||||
|
|
||||||
|
@ -294,8 +272,6 @@ FIXPATH = $(subst /,\,$1)
|
||||||
|
|
||||||
NUMTHREADS:=$(NUMBER_OF_PROCESSORS)
|
NUMTHREADS:=$(NUMBER_OF_PROCESSORS)
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
HOST=unix
|
HOST=unix
|
||||||
|
@ -609,10 +585,32 @@ endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(MPT_COMPILER_NOIPARA),1)
|
ifeq ($(OPTIMIZE_FASTMATH),2)
|
||||||
# See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115049>.
|
CPPFLAGS += -DMPT_CHECK_CXX_IGNORE_WARNING_FASTMATH -DMPT_CHECK_CXX_IGNORE_WARNING_FINITEMATH
|
||||||
CXXFLAGS += -fno-ipa-ra
|
CXXFLAGS += -ffast-math
|
||||||
CFLAGS += -fno-ipa-ra
|
CFLAGS += -ffast-math
|
||||||
|
else ifeq ($(OPTIMIZE_FASTMATH),1)
|
||||||
|
CPPFLAGS += -DMPT_CHECK_CXX_IGNORE_WARNING_FINITEMATH
|
||||||
|
CXXFLAGS += -fassociative-math
|
||||||
|
CXXFLAGS += -fcx-limited-range
|
||||||
|
CXXFLAGS += -fexcess-precision=fast
|
||||||
|
CXXFLAGS += -ffinite-math-only
|
||||||
|
CXXFLAGS += -freciprocal-math
|
||||||
|
CXXFLAGS += -fno-math-errno
|
||||||
|
CXXFLAGS += -fno-rounding-math
|
||||||
|
CXXFLAGS += -fno-signaling-nans
|
||||||
|
CXXFLAGS += -fno-signed-zeros
|
||||||
|
CXXFLAGS += -fno-trapping-math
|
||||||
|
CFLAGS += -fassociative-math
|
||||||
|
CFLAGS += -fcx-limited-range
|
||||||
|
CFLAGS += -fexcess-precision=fast
|
||||||
|
CFLAGS += -ffinite-math-only
|
||||||
|
CFLAGS += -freciprocal-math
|
||||||
|
CFLAGS += -fno-math-errno
|
||||||
|
CFLAGS += -fno-rounding-math
|
||||||
|
CFLAGS += -fno-signaling-nans
|
||||||
|
CFLAGS += -fno-signed-zeros
|
||||||
|
CFLAGS += -fno-trapping-math
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CHECKED),1)
|
ifeq ($(CHECKED),1)
|
||||||
|
@ -709,10 +707,10 @@ endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(LOCAL_MPG123),1)
|
ifeq ($(LOCAL_MPG123),1)
|
||||||
CPPFLAGS_MPG123 := -DMPT_WITH_MPG123 -DMPG123_NO_LARGENAME
|
CPPFLAGS_MPG123 := -DMPT_WITH_MPG123
|
||||||
LDFLAGS_MPG123 :=
|
LDFLAGS_MPG123 :=
|
||||||
LDLIBS_MPG123 :=
|
LDLIBS_MPG123 :=
|
||||||
CPPFLAGS_MPG123 += -Iinclude/mpg123/src/include/ -Iinclude/mpg123/ports/generic/
|
CPPFLAGS_MPG123 += -Iinclude/mpg123/src/libmpg123/ -Iinclude/mpg123/src/compat/ -Iinclude/mpg123/src/ -Iinclude/mpg123/ports/makefile/
|
||||||
LOCAL_MPG123_SOURCES :=
|
LOCAL_MPG123_SOURCES :=
|
||||||
LOCAL_MPG123_SOURCES += include/mpg123/src/compat/compat.c
|
LOCAL_MPG123_SOURCES += include/mpg123/src/compat/compat.c
|
||||||
LOCAL_MPG123_SOURCES += include/mpg123/src/compat/compat_str.c
|
LOCAL_MPG123_SOURCES += include/mpg123/src/compat/compat_str.c
|
||||||
|
@ -728,7 +726,6 @@ LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/index.c
|
||||||
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/layer1.c
|
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/layer1.c
|
||||||
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/layer2.c
|
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/layer2.c
|
||||||
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/layer3.c
|
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/layer3.c
|
||||||
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/lfs_wrap.c
|
|
||||||
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/libmpg123.c
|
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/libmpg123.c
|
||||||
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/ntom.c
|
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/ntom.c
|
||||||
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/optimize.c
|
LOCAL_MPG123_SOURCES += include/mpg123/src/libmpg123/optimize.c
|
||||||
|
@ -744,10 +741,6 @@ include/mpg123/src/compat/%$(FLAVOUR_O).o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENER
|
||||||
include/mpg123/src/compat/%.test$(FLAVOUR_O).o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
|
include/mpg123/src/compat/%.test$(FLAVOUR_O).o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
|
||||||
include/mpg123/src/libmpg123/%$(FLAVOUR_O).o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
|
include/mpg123/src/libmpg123/%$(FLAVOUR_O).o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
|
||||||
include/mpg123/src/libmpg123/%.test$(FLAVOUR_O).o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
|
include/mpg123/src/libmpg123/%.test$(FLAVOUR_O).o : CFLAGS+=$(CFLAGS_SILENT) -DOPT_GENERIC
|
||||||
include/mpg123/src/compat/%$(FLAVOUR_O).o : CPPFLAGS:= -Iinclude/mpg123/src/include/ -Iinclude/mpg123/ports/generic/ $(CPPFLAGS)
|
|
||||||
include/mpg123/src/compat/%.test$(FLAVOUR_O).o : CPPFLAGS:= -Iinclude/mpg123/src/include/ -Iinclude/mpg123/ports/generic/ $(CPPFLAGS)
|
|
||||||
include/mpg123/src/libmpg123/%$(FLAVOUR_O).o : CPPFLAGS:= -Iinclude/mpg123/src/include/ -Iinclude/mpg123/ports/generic/ $(CPPFLAGS)
|
|
||||||
include/mpg123/src/libmpg123/%.test$(FLAVOUR_O).o : CPPFLAGS:= -Iinclude/mpg123/src/include/ -Iinclude/mpg123/ports/generic/ $(CPPFLAGS)
|
|
||||||
else
|
else
|
||||||
ifeq ($(NO_MPG123),1)
|
ifeq ($(NO_MPG123),1)
|
||||||
else
|
else
|
||||||
|
@ -802,10 +795,7 @@ ifeq ($(LOCAL_VORBIS),1)
|
||||||
CPPFLAGS_VORBIS := -DMPT_WITH_VORBIS
|
CPPFLAGS_VORBIS := -DMPT_WITH_VORBIS
|
||||||
LDFLAGS_VORBIS :=
|
LDFLAGS_VORBIS :=
|
||||||
LDLIBS_VORBIS :=
|
LDLIBS_VORBIS :=
|
||||||
CPPFLAGS_VORBIS += -Iinclude/vorbis/include/ -Iinclude/vorbis/lib/
|
CPPFLAGS_VORBIS += -Iinclude/vorbis/include/ -Iinclude/vorbis/lib/ -DHAVE_ALLOCA_H
|
||||||
ifneq ($(MPT_COMPILER_NOALLOCAH),1)
|
|
||||||
CPPFLAGS_VORBIS += -DHAVE_ALLOCA_H
|
|
||||||
endif
|
|
||||||
LOCAL_VORBIS_SOURCES :=
|
LOCAL_VORBIS_SOURCES :=
|
||||||
LOCAL_VORBIS_SOURCES += include/vorbis/lib/analysis.c
|
LOCAL_VORBIS_SOURCES += include/vorbis/lib/analysis.c
|
||||||
LOCAL_VORBIS_SOURCES += include/vorbis/lib/bitrate.c
|
LOCAL_VORBIS_SOURCES += include/vorbis/lib/bitrate.c
|
||||||
|
@ -999,10 +989,8 @@ endif
|
||||||
|
|
||||||
CPPCHECK_FLAGS += -j $(NUMTHREADS)
|
CPPCHECK_FLAGS += -j $(NUMTHREADS)
|
||||||
CPPCHECK_FLAGS += --std=c11 --std=c++17
|
CPPCHECK_FLAGS += --std=c11 --std=c++17
|
||||||
CPPCHECK_FLAGS += --library=build/cppcheck/glibc-workarounds.cfg
|
|
||||||
CPPCHECK_FLAGS += --quiet
|
CPPCHECK_FLAGS += --quiet
|
||||||
CPPCHECK_FLAGS += --enable=warning --inline-suppr --template='{file}:{line}: warning: {severity}: {message} [{id}]'
|
CPPCHECK_FLAGS += --enable=warning --inline-suppr --template='{file}:{line}: warning: {severity}: {message} [{id}]'
|
||||||
CPPCHECK_FLAGS += --check-level=exhaustive
|
|
||||||
CPPCHECK_FLAGS += --suppress=missingIncludeSystem
|
CPPCHECK_FLAGS += --suppress=missingIncludeSystem
|
||||||
CPPCHECK_FLAGS += --suppress=uninitMemberVar
|
CPPCHECK_FLAGS += --suppress=uninitMemberVar
|
||||||
|
|
||||||
|
@ -1108,15 +1096,11 @@ CPPFLAGS += -DLIBOPENMPT_BUILD
|
||||||
|
|
||||||
|
|
||||||
COMMON_CXX_SOURCES += \
|
COMMON_CXX_SOURCES += \
|
||||||
$(sort $(wildcard src/openmpt/all/*.cpp)) \
|
|
||||||
$(sort $(wildcard src/openmpt/base/*.cpp)) \
|
|
||||||
$(sort $(wildcard src/openmpt/logging/*.cpp)) \
|
|
||||||
$(sort $(wildcard src/openmpt/random/*.cpp)) \
|
|
||||||
$(sort $(wildcard common/*.cpp)) \
|
$(sort $(wildcard common/*.cpp)) \
|
||||||
|
$(sort $(wildcard src/mpt/src/*.cpp)) \
|
||||||
|
|
||||||
SOUNDLIB_CXX_SOURCES += \
|
SOUNDLIB_CXX_SOURCES += \
|
||||||
$(COMMON_CXX_SOURCES) \
|
$(COMMON_CXX_SOURCES) \
|
||||||
$(sort $(wildcard src/openmpt/soundbase/*.cpp)) \
|
|
||||||
$(sort $(wildcard soundlib/*.cpp)) \
|
$(sort $(wildcard soundlib/*.cpp)) \
|
||||||
$(sort $(wildcard soundlib/plugins/*.cpp)) \
|
$(sort $(wildcard soundlib/plugins/*.cpp)) \
|
||||||
$(sort $(wildcard soundlib/plugins/dmo/*.cpp)) \
|
$(sort $(wildcard soundlib/plugins/dmo/*.cpp)) \
|
||||||
|
@ -1760,7 +1744,6 @@ bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION).msvc.zip: bin/$
|
||||||
svn export ./build/scriptlib bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/scriptlib --native-eol CRLF
|
svn export ./build/scriptlib bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/scriptlib --native-eol CRLF
|
||||||
svn export ./build/svn_version bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/svn_version --native-eol CRLF
|
svn export ./build/svn_version bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/svn_version --native-eol CRLF
|
||||||
svn export ./build/vs bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs --native-eol CRLF
|
svn export ./build/vs bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs --native-eol CRLF
|
||||||
svn export ./build/vs2017winxpansi bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017winxpansi --native-eol CRLF
|
|
||||||
svn export ./build/vs2017winxp bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017winxp --native-eol CRLF
|
svn export ./build/vs2017winxp bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2017winxp --native-eol CRLF
|
||||||
svn export ./build/vs2019win7 bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2019win7 --native-eol CRLF
|
svn export ./build/vs2019win7 bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2019win7 --native-eol CRLF
|
||||||
svn export ./build/vs2019win81 bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2019win81 --native-eol CRLF
|
svn export ./build/vs2019win81 bin/$(FLAVOUR_DIR)dist-zip/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/build/vs2019win81 --native-eol CRLF
|
||||||
|
@ -1866,6 +1849,7 @@ bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION).dev.js.tar:
|
||||||
mkdir -p bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin
|
mkdir -p bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin
|
||||||
mkdir -p bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)all
|
mkdir -p bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)all
|
||||||
cp bin/$(FLAVOUR_DIR)stage/all/libopenmpt.js bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)all/libopenmpt.js
|
cp bin/$(FLAVOUR_DIR)stage/all/libopenmpt.js bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)all/libopenmpt.js
|
||||||
|
cp bin/$(FLAVOUR_DIR)stage/all/libopenmpt.js.mem bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)all/libopenmpt.js.mem
|
||||||
cp bin/$(FLAVOUR_DIR)stage/all/libopenmpt.wasm bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)all/libopenmpt.wasm
|
cp bin/$(FLAVOUR_DIR)stage/all/libopenmpt.wasm bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)all/libopenmpt.wasm
|
||||||
cp bin/$(FLAVOUR_DIR)stage/all/libopenmpt.wasm.js bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)all/libopenmpt.wasm.js
|
cp bin/$(FLAVOUR_DIR)stage/all/libopenmpt.wasm.js bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)all/libopenmpt.wasm.js
|
||||||
mkdir -p bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)wasm
|
mkdir -p bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)wasm
|
||||||
|
@ -1873,6 +1857,7 @@ bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION).dev.js.tar:
|
||||||
cp bin/$(FLAVOUR_DIR)stage/wasm/libopenmpt.wasm bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)wasm/libopenmpt.wasm
|
cp bin/$(FLAVOUR_DIR)stage/wasm/libopenmpt.wasm bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)wasm/libopenmpt.wasm
|
||||||
mkdir -p bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)js
|
mkdir -p bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)js
|
||||||
cp bin/$(FLAVOUR_DIR)stage/js/libopenmpt.js bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)js/libopenmpt.js
|
cp bin/$(FLAVOUR_DIR)stage/js/libopenmpt.js bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)js/libopenmpt.js
|
||||||
|
cp bin/$(FLAVOUR_DIR)stage/js/libopenmpt.js.mem bin/$(FLAVOUR_DIR)dist-js/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/bin/$(FLAVOUR_DIR)js/libopenmpt.js.mem
|
||||||
cd bin/$(FLAVOUR_DIR)dist-js/ && tar cv --numeric-owner --owner=0 --group=0 libopenmpt-$(DIST_LIBOPENMPT_VERSION) > libopenmpt-$(DIST_LIBOPENMPT_VERSION).dev.js.tar
|
cd bin/$(FLAVOUR_DIR)dist-js/ && tar cv --numeric-owner --owner=0 --group=0 libopenmpt-$(DIST_LIBOPENMPT_VERSION) > libopenmpt-$(DIST_LIBOPENMPT_VERSION).dev.js.tar
|
||||||
|
|
||||||
.PHONY: bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION).bin.dos.zip
|
.PHONY: bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION).bin.dos.zip
|
||||||
|
@ -1896,11 +1881,6 @@ else
|
||||||
svn export ./include/miniz/miniz.c bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSES/MINIZ.TXT --native-eol CRLF
|
svn export ./include/miniz/miniz.c bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSES/MINIZ.TXT --native-eol CRLF
|
||||||
svn export ./include/stb_vorbis/stb_vorbis.c bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSES/STBVORB.TXT --native-eol CRLF
|
svn export ./include/stb_vorbis/stb_vorbis.c bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSES/STBVORB.TXT --native-eol CRLF
|
||||||
endif
|
endif
|
||||||
mkdir -p bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSES/DJGPP
|
|
||||||
cp $(shell dirname $(shell which i386-pc-msdosdjgpp-gcc))/../license/copying bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSES/DJGPP/COPYING
|
|
||||||
cp $(shell dirname $(shell which i386-pc-msdosdjgpp-gcc))/../license/copying.dj bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSES/DJGPP/COPYING.DJ
|
|
||||||
cp $(shell dirname $(shell which i386-pc-msdosdjgpp-gcc))/../license/copying.lib bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSES/DJGPP/COPYING.LIB
|
|
||||||
cp $(shell dirname $(shell which i386-pc-msdosdjgpp-gcc))/../license/source.txt bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/LICENSES/DJGPP/SOURCE.TXT
|
|
||||||
mkdir -p bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/SRC
|
mkdir -p bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/SRC
|
||||||
cp build/externals/csdpmi7s.zip bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/SRC/CSDPMI7S.ZIP
|
cp build/externals/csdpmi7s.zip bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/SRC/CSDPMI7S.ZIP
|
||||||
mkdir -p bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/BIN
|
mkdir -p bin/$(FLAVOUR_DIR)dist-dos/libopenmpt-$(DIST_LIBOPENMPT_VERSION)/BIN
|
||||||
|
@ -2025,10 +2005,10 @@ ifeq ($(SHARED_LIB),1)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
contrib/fuzzing/fuzz$(FLAVOUR_O).o: contrib/fuzzing/fuzz.cpp
|
contrib/fuzzing/fuzz$(FLAVOUR_O).o: contrib/fuzzing/fuzz.c
|
||||||
$(INFO) [CXX] $<
|
$(INFO) [CC] $<
|
||||||
$(VERYSILENT)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -M -MT$@ $< > $*$(FLAVOUR_O).d
|
$(VERYSILENT)$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -M -MT$@ $< > $*$(FLAVOUR_O).d
|
||||||
$(SILENT)$(COMPILE.cc) $(OUTPUT_OPTION) $<
|
$(SILENT)$(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||||
bin/$(FLAVOUR_DIR)fuzz$(EXESUFFIX): contrib/fuzzing/fuzz$(FLAVOUR_O).o $(OBJECTS_LIBOPENMPT) $(OUTPUT_LIBOPENMPT)
|
bin/$(FLAVOUR_DIR)fuzz$(EXESUFFIX): contrib/fuzzing/fuzz$(FLAVOUR_O).o $(OBJECTS_LIBOPENMPT) $(OUTPUT_LIBOPENMPT)
|
||||||
$(INFO) [LD] $@
|
$(INFO) [LD] $@
|
||||||
$(SILENT)$(LINK.cc) $(LDFLAGS_LIBOPENMPT) contrib/fuzzing/fuzz$(FLAVOUR_O).o $(OBJECTS_LIBOPENMPT) $(LOADLIBES) $(LDLIBS) $(LDLIBS_LIBOPENMPT) -o $@
|
$(SILENT)$(LINK.cc) $(LDFLAGS_LIBOPENMPT) contrib/fuzzing/fuzz$(FLAVOUR_O).o $(OBJECTS_LIBOPENMPT) $(LOADLIBES) $(LDLIBS) $(LDLIBS_LIBOPENMPT) -o $@
|
||||||
|
|
|
@ -56,9 +56,8 @@ How to compile
|
||||||
|
|
||||||
- Visual Studio 2017 XP targeting toolset
|
- Visual Studio 2017 XP targeting toolset
|
||||||
|
|
||||||
- OpenMPT requires the compile host system to be Windows 8.1 (or later) on
|
- OpenMPT requires the compile host system to be Windows 8.1 (or later) amd64,
|
||||||
amd64 for VS2019 and VS2017, Windows 10 (or later) on amd64 for VS2022, or
|
or Windows 11 (or later) ARM64.
|
||||||
Windows 11 (or later) ARM64.
|
|
||||||
|
|
||||||
- In order to build OpenMPT for Windows XP, the Visual Studio 2017 XP
|
- In order to build OpenMPT for Windows XP, the Visual Studio 2017 XP
|
||||||
targeting toolset as well as the Windows 8.1 SDK need to be installed. The
|
targeting toolset as well as the Windows 8.1 SDK need to be installed. The
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue