Synth settings #293

Merged
kode54 merged 2 commits from synthSettings into main 2022-07-02 04:25:24 -04:00
28 changed files with 562 additions and 103 deletions

View file

@ -558,6 +558,11 @@ static AppController *kAppController = nil;
[userDefaultsValuesDict setObject:barColor forKey:@"spectrumBarColor"]; [userDefaultsValuesDict setObject:barColor forKey:@"spectrumBarColor"];
[userDefaultsValuesDict setObject:dotColor forKey:@"spectrumDotColor"]; [userDefaultsValuesDict setObject:dotColor forKey:@"spectrumDotColor"];
[userDefaultsValuesDict setObject:@(150.0) forKey:@"synthDefaultSeconds"];
[userDefaultsValuesDict setObject:@(8.0) forKey:@"synthDefaultFadeSeconds"];
[userDefaultsValuesDict setObject:@(2) forKey:@"synthDefaultLoopCount"];
[userDefaultsValuesDict setObject:@(44100) forKey:@"synthSampleRate"];
// Register and sync defaults // Register and sync defaults
[[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict]; [[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
[[NSUserDefaults standardUserDefaults] synchronize]; [[NSUserDefaults standardUserDefaults] synchronize];

View file

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
833A899A286FF2FD0022E036 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 833A8999286FF2FD0022E036 /* Cocoa.framework */; };
833AFD3620E4ED9D00F0C21E /* libAdPlug.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83AA434020E4EC8C00E861B2 /* libAdPlug.framework */; }; 833AFD3620E4ED9D00F0C21E /* libAdPlug.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83AA434020E4EC8C00E861B2 /* libAdPlug.framework */; };
83747C6F2862DDDB0021245F /* Shared.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 83747C6D2862DDDB0021245F /* Shared.xcconfig */; }; 83747C6F2862DDDB0021245F /* Shared.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 83747C6D2862DDDB0021245F /* Shared.xcconfig */; };
83C2806320E4ECAD00823BF9 /* libAdPlug.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA434020E4EC8C00E861B2 /* libAdPlug.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 83C2806320E4ECAD00823BF9 /* libAdPlug.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83AA434020E4EC8C00E861B2 /* libAdPlug.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@ -51,6 +52,7 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
833A8999286FF2FD0022E036 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
83747C6D2862DDDB0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C6D2862DDDB0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
83D3C5F3201C674D005564CB /* AdPlug.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AdPlug.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 83D3C5F3201C674D005564CB /* AdPlug.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AdPlug.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
83D3C5F6201C674D005564CB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 83D3C5F6201C674D005564CB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -77,6 +79,7 @@
files = ( files = (
83D3C6A6201D3951005564CB /* libbinio.framework in Frameworks */, 83D3C6A6201D3951005564CB /* libbinio.framework in Frameworks */,
833AFD3620E4ED9D00F0C21E /* libAdPlug.framework in Frameworks */, 833AFD3620E4ED9D00F0C21E /* libAdPlug.framework in Frameworks */,
833A899A286FF2FD0022E036 /* Cocoa.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -141,6 +144,7 @@
83D3C602201C675D005564CB /* Frameworks */ = { 83D3C602201C675D005564CB /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
833A8999286FF2FD0022E036 /* Cocoa.framework */,
83D3C6A7201D3951005564CB /* libbinio.framework */, 83D3C6A7201D3951005564CB /* libbinio.framework */,
83D3C603201C6775005564CB /* libAdPlug.xcodeproj */, 83D3C603201C6775005564CB /* libAdPlug.xcodeproj */,
); );

View file

@ -17,6 +17,8 @@
CPlayer* m_player; CPlayer* m_player;
Copl* m_emu; Copl* m_emu;
double sampleRate;
unsigned int subsong, samples_todo; unsigned int subsong, samples_todo;
id<CogSource> source; id<CogSource> source;

View file

@ -47,7 +47,14 @@ static CAdPlugDatabase *g_database = NULL;
- (BOOL)open:(id<CogSource>)s { - (BOOL)open:(id<CogSource>)s {
[self setSource:s]; [self setSource:s];
m_emu = new CNemuopl(44100); sampleRate = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthSampleRate"] doubleValue];
if(sampleRate < 8000.0) {
sampleRate = 44100.0;
} else if(sampleRate > 192000.0) {
sampleRate = 192000.0;
}
m_emu = new CNemuopl(sampleRate);
NSString *path = [[s url] absoluteString]; NSString *path = [[s url] absoluteString];
NSRange fragmentRange = [path rangeOfString:@"#" options:NSBackwardsSearch]; NSRange fragmentRange = [path rangeOfString:@"#" options:NSBackwardsSearch];
@ -68,7 +75,7 @@ static CAdPlugDatabase *g_database = NULL;
samples_todo = 0; samples_todo = 0;
length = m_player->songlength(subsong) * 441 / 10; length = m_player->songlength(subsong) * sampleRate / 1000.0;
current_pos = 0; current_pos = 0;
m_player->rewind(subsong); m_player->rewind(subsong);
@ -81,7 +88,7 @@ static CAdPlugDatabase *g_database = NULL;
- (NSDictionary *)properties { - (NSDictionary *)properties {
return @{ @"bitrate": @(0), return @{ @"bitrate": @(0),
@"sampleRate": @(44100.0), @"sampleRate": @(sampleRate),
@"totalFrames": @(length), @"totalFrames": @(length),
@"bitsPerSample": @(16), // Samples are short @"bitsPerSample": @(16), // Samples are short
@"floatingPoint": @(NO), @"floatingPoint": @(NO),
@ -106,7 +113,7 @@ static CAdPlugDatabase *g_database = NULL;
if(!samples_todo) { if(!samples_todo) {
running = m_player->update() && running; running = m_player->update() && running;
if(!dont_loop || running) { if(!dont_loop || running) {
samples_todo = 44100 / m_player->getrefresh(); samples_todo = (int)ceil(sampleRate / m_player->getrefresh());
current_pos += samples_todo; current_pos += samples_todo;
} }
} }
@ -132,7 +139,7 @@ static CAdPlugDatabase *g_database = NULL;
while(current_pos < frame) { while(current_pos < frame) {
m_player->update(); m_player->update();
current_pos += 44100 / m_player->getrefresh(); current_pos += (long)ceil(sampleRate / m_player->getrefresh());
} }
samples_todo = (UInt32)(frame - current_pos); samples_todo = (UInt32)(frame - current_pos);

View file

@ -17,7 +17,7 @@ extern gme_err_t readCallback(void* data, void* out, int count);
@interface GameDecoder : NSObject <CogDecoder> { @interface GameDecoder : NSObject <CogDecoder> {
Music_Emu* emu; Music_Emu* emu;
id<CogSource> source; id<CogSource> source;
long sampleRate; double sampleRate;
long length; long length;
long fade; long fade;
NSString* codec; NSString* codec;

View file

@ -53,10 +53,15 @@ gme_err_t readCallback(void *data, void *out, int count) {
return NO; return NO;
} }
sampleRate = 44100; sampleRate = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthSampleRate"] doubleValue];
if(sampleRate < 8000.0) {
sampleRate = 44100.0;
} else if(sampleRate > 192000.0) {
sampleRate = 192000.0;
}
if(type == gme_spc_type || type == gme_sfm_type) if(type == gme_spc_type || type == gme_sfm_type)
sampleRate = 32000; sampleRate = 32000.0;
emu = gme_new_emu(type, (int)sampleRate); emu = gme_new_emu(type, (int)sampleRate);
if(!emu) { if(!emu) {
@ -109,16 +114,30 @@ gme_err_t readCallback(void *data, void *out, int count) {
length = info->length; length = info->length;
} else if(info->loop_length > 0) { } else if(info->loop_length > 0) {
DLog(@"Using loop length: %i", info->loop_length); DLog(@"Using loop length: %i", info->loop_length);
length = info->intro_length + 2 * info->loop_length; int loopCount = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultLoopCount"] intValue];
if(loopCount < 0) {
loopCount = 1;
} else if(loopCount > 10) {
loopCount = 10;
}
length = info->intro_length + loopCount * info->loop_length;
} else { } else {
length = 150000; double defaultLength = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultSeconds"] doubleValue];
if(defaultLength < 0) {
defaultLength = 150.0;
}
length = (int)ceil(defaultLength * 1000.0);
DLog(@"Setting default: %li", length); DLog(@"Setting default: %li", length);
} }
if(info->fade_length >= 0) { if(info->fade_length >= 0) {
fade = info->fade_length; fade = info->fade_length;
} else { } else {
fade = 8000; double defaultFade = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultFadeSeconds"] doubleValue];
if(defaultFade < 0) {
defaultFade = 0;
}
fade = (int)ceil(defaultFade * 1000.0);
} }
gme_free_info(info); gme_free_info(info);
@ -143,7 +162,7 @@ gme_err_t readCallback(void *data, void *out, int count) {
- (NSDictionary *)properties { - (NSDictionary *)properties {
return @{ @"bitrate": @(0), return @{ @"bitrate": @(0),
@"sampleRate": @(sampleRate), @"sampleRate": @(sampleRate),
@"totalFrames": @((long)(length * ((float)sampleRate * 0.001))), @"totalFrames": @((long)(length * (sampleRate * 0.001))),
@"bitsPerSample": @(sizeof(short) * 8), // Samples are short @"bitsPerSample": @(sizeof(short) * 8), // Samples are short
@"channels": @(2), // output from gme_play is in stereo @"channels": @(2), // output from gme_play is in stereo
@"seekable": @(YES), @"seekable": @(YES),
@ -176,7 +195,7 @@ gme_err_t readCallback(void *data, void *out, int count) {
- (long)seek:(long)frame { - (long)seek:(long)frame {
gme_err_t error; gme_err_t error;
error = gme_seek(emu, frame / 44.1); error = gme_seek(emu, frame * sampleRate * 0.001);
if(error) { if(error) {
return -1; return -1;
} }

View file

@ -1205,8 +1205,17 @@ static int usf_info(void *context, const char *name, const char *value) {
tagFadeMs = info.tag_fade_ms; tagFadeMs = info.tag_fade_ms;
if(!tagLengthMs) { if(!tagLengthMs) {
tagLengthMs = (2 * 60 + 30) * 1000; double defaultLength = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultSeconds"] doubleValue];
tagFadeMs = 8000; double defaultFade = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultFadeSeconds"] doubleValue];
if(defaultLength < 0) {
defaultLength = 150.0;
}
if(defaultFade < 0) {
defaultFade = 0;
}
tagLengthMs = (int)ceil(defaultLength * 1000.0);
tagFadeMs = (int)ceil(defaultFade * 1000.0);
} }
replayGainAlbumGain = info.albumGain; replayGainAlbumGain = info.albumGain;

View file

@ -17,6 +17,8 @@
int32_t *buffer; int32_t *buffer;
int trackNumber; int trackNumber;
double sampleRate;
long totalFrames; long totalFrames;
long framesLength; long framesLength;
long framesFade; long framesFade;

View file

@ -33,10 +33,17 @@ static void oneTimeInit(void) {
if(size > UINT_MAX) if(size > UINT_MAX)
return NO; return NO;
sampleRate = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthSampleRate"] doubleValue];
if(sampleRate < 8000.0) {
sampleRate = 44100.0;
} else if(sampleRate > 192000.0) {
sampleRate = 192000.0;
}
void *data = malloc(size); void *data = malloc(size);
[s read:data amount:size]; [s read:data amount:size];
tune = hvl_LoadTune(data, (uint32_t)size, 44100, 2); tune = hvl_LoadTune(data, (uint32_t)size, (int)sampleRate, 2);
free(data); free(data);
if(!tune) if(!tune)
return NO; return NO;
@ -62,14 +69,19 @@ static void oneTimeInit(void) {
++loops; ++loops;
} }
framesLength = tune->ht_PlayingTime * 44100 / (tune->ht_SpeedMultiplier * 50); double defaultFade = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultFadeSeconds"] doubleValue];
framesFade = 44100 * 8; if(defaultFade < 0.0) {
defaultFade = 0.0;
}
framesLength = tune->ht_PlayingTime * sampleRate / (tune->ht_SpeedMultiplier * 50);
framesFade = (int)ceil(sampleRate * defaultFade);
totalFrames = framesLength + framesFade; totalFrames = framesLength + framesFade;
framesRead = 0; framesRead = 0;
framesInBuffer = 0; framesInBuffer = 0;
buffer = malloc(sizeof(int32_t) * (44100 / 50) * 2); buffer = malloc(sizeof(int32_t) * ((int)ceil(sampleRate) / 50) * 2);
hvl_InitSubsong(tune, trackNumber); hvl_InitSubsong(tune, trackNumber);
@ -81,7 +93,7 @@ static void oneTimeInit(void) {
- (NSDictionary *)properties { - (NSDictionary *)properties {
return @{ @"bitrate": @(0), return @{ @"bitrate": @(0),
@"sampleRate": @(44100), @"sampleRate": @(sampleRate),
@"totalFrames": @(totalFrames), @"totalFrames": @(totalFrames),
@"bitsPerSample": @(32), @"bitsPerSample": @(32),
@"floatingPoint": @(YES), @"floatingPoint": @(YES),
@ -121,7 +133,7 @@ static void oneTimeInit(void) {
} }
} }
hvl_DecodeFrame(tune, (int8_t *)buffer, ((int8_t *)buffer) + 4, 8); hvl_DecodeFrame(tune, (int8_t *)buffer, ((int8_t *)buffer) + 4, 8);
framesInBuffer = 44100 / 50; framesInBuffer = (int)ceil(sampleRate / 50);
} }
if(!repeatone && framesRead + total > framesLength) { if(!repeatone && framesRead + total > framesLength) {
@ -156,7 +168,7 @@ static void oneTimeInit(void) {
while(framesRead < frame) { while(framesRead < frame) {
hvl_play_irq(tune); hvl_play_irq(tune);
framesRead += 44100 / 50; framesRead += (int)ceil(sampleRate / 50);
} }
return framesRead; return framesRead;

View file

@ -30,6 +30,8 @@ class BMPlayer;
BOOL soundFontsAssigned; BOOL soundFontsAssigned;
BOOL isLooped; BOOL isLooped;
double sampleRate;
long totalFrames; long totalFrames;
long framesLength; long framesLength;
long framesFade; long framesFade;

View file

@ -46,6 +46,13 @@ static OSType getOSType(const char *in_) {
return NO; return NO;
} }
sampleRate = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthSampleRate"] doubleValue];
if(sampleRate < 8000.0) {
sampleRate = 44100.0;
} else if(sampleRate > 192000.0) {
sampleRate = 192000.0;
}
source = s; source = s;
std::vector<uint8_t> file_data; std::vector<uint8_t> file_data;
@ -76,8 +83,12 @@ static OSType getOSType(const char *in_) {
if(loopStart != 0 || loopEnd != framesLength) { if(loopStart != 0 || loopEnd != framesLength) {
// two loops and a fade // two loops and a fade
double defaultFade = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultFadeSeconds"] doubleValue];
if(defaultFade < 0.0) {
defaultFade = 0.0;
}
framesLength = loopStart + (loopEnd - loopStart) * 2; framesLength = loopStart + (loopEnd - loopStart) * 2;
framesFade = 8000; framesFade = (int)ceil(defaultFade * 1000.0);
isLooped = YES; isLooped = YES;
} else { } else {
framesLength += 1000; framesLength += 1000;
@ -85,8 +96,8 @@ static OSType getOSType(const char *in_) {
isLooped = NO; isLooped = NO;
} }
framesLength = framesLength * 441 / 10; framesLength = (int)ceil(framesLength * sampleRate * 0.001);
framesFade = framesFade * 441 / 10; framesFade = (int)ceil(framesFade * sampleRate * 0.001);
totalFrames = framesLength + framesFade; totalFrames = framesLength + framesFade;
@ -100,7 +111,7 @@ static OSType getOSType(const char *in_) {
- (NSDictionary *)properties { - (NSDictionary *)properties {
return @{ @"bitrate": @(0), return @{ @"bitrate": @(0),
@"sampleRate": @(44100), @"sampleRate": @(sampleRate),
@"totalFrames": @(totalFrames), @"totalFrames": @(totalFrames),
@"bitsPerSample": @(32), @"bitsPerSample": @(32),
@"floatingPoint": @(YES), @"floatingPoint": @(YES),
@ -203,7 +214,7 @@ static OSType getOSType(const char *in_) {
resamplingSinc = true; resamplingSinc = true;
bmplayer->setSincInterpolation(resamplingSinc); bmplayer->setSincInterpolation(resamplingSinc);
bmplayer->setSampleRate(44100); bmplayer->setSampleRate(sampleRate);
if([soundFontPath length]) if([soundFontPath length])
bmplayer->setFileSoundFont([soundFontPath UTF8String]); bmplayer->setFileSoundFont([soundFontPath UTF8String]);
@ -219,7 +230,7 @@ static OSType getOSType(const char *in_) {
msplayer->set_extp(1); msplayer->set_extp(1);
msplayer->setSampleRate(44100); msplayer->setSampleRate(sampleRate);
} else if([[plugin substringToIndex:5] isEqualToString:@"OPL3W"]) { } else if([[plugin substringToIndex:5] isEqualToString:@"OPL3W"]) {
MSPlayer *msplayer = new MSPlayer; MSPlayer *msplayer = new MSPlayer;
player = msplayer; player = msplayer;
@ -230,7 +241,7 @@ static OSType getOSType(const char *in_) {
msplayer->set_extp(1); msplayer->set_extp(1);
msplayer->setSampleRate(44100); msplayer->setSampleRate(sampleRate);
} else { } else {
const char *cplugin = [plugin UTF8String]; const char *cplugin = [plugin UTF8String];
OSType componentSubType; OSType componentSubType;
@ -243,7 +254,7 @@ static OSType getOSType(const char *in_) {
auplayer = new AUPlayer; auplayer = new AUPlayer;
auplayer->setComponent(componentSubType, componentManufacturer); auplayer->setComponent(componentSubType, componentManufacturer);
auplayer->setSampleRate(44100); auplayer->setSampleRate(sampleRate);
if([soundFontPath length]) { if([soundFontPath length]) {
auplayer->setSoundFont([soundFontPath UTF8String]); auplayer->setSoundFont([soundFontPath UTF8String]);

View file

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
833A899C286FF3150022E036 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 833A899B286FF3150022E036 /* Cocoa.framework */; };
83747C1A2862DB2F0021245F /* Shared.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 83747C182862DB2F0021245F /* Shared.xcconfig */; }; 83747C1A2862DB2F0021245F /* Shared.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 83747C182862DB2F0021245F /* Shared.xcconfig */; };
83E5FE731FFF010C00659F0F /* OMPTDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83E5FE6D1FFF010B00659F0F /* OMPTDecoder.mm */; }; 83E5FE731FFF010C00659F0F /* OMPTDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83E5FE6D1FFF010B00659F0F /* OMPTDecoder.mm */; };
83E5FE741FFF010C00659F0F /* OMPTContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83E5FE6F1FFF010B00659F0F /* OMPTContainer.mm */; }; 83E5FE741FFF010C00659F0F /* OMPTContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83E5FE6F1FFF010B00659F0F /* OMPTContainer.mm */; };
@ -47,6 +48,7 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
833A899B286FF3150022E036 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
83747C182862DB2F0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C182862DB2F0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
83E5EFA31FFEF78100659F0F /* OpenMPT.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OpenMPT.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 83E5EFA31FFEF78100659F0F /* OpenMPT.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OpenMPT.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
83E5EFA61FFEF78100659F0F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 83E5EFA61FFEF78100659F0F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -67,6 +69,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
833A899C286FF3150022E036 /* Cocoa.framework in Frameworks */,
83F30AE8286EBD2A0005EF06 /* libOpenMPT.framework in Frameworks */, 83F30AE8286EBD2A0005EF06 /* libOpenMPT.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -113,6 +116,7 @@
83E5EFB21FFEF79000659F0F /* Frameworks */ = { 83E5EFB21FFEF79000659F0F /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
833A899B286FF3150022E036 /* Cocoa.framework */,
83F30A81286EBB420005EF06 /* libOpenMPT.xcodeproj */, 83F30A81286EBB420005EF06 /* libOpenMPT.xcodeproj */,
); );
name = Frameworks; name = Frameworks;

View file

@ -19,6 +19,8 @@
id<CogSource> source; id<CogSource> source;
long length; long length;
double sampleRate;
} }
- (void)setSource:(id<CogSource>)s; - (void)setSource:(id<CogSource>)s;

View file

@ -39,6 +39,13 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
long size = [source tell]; long size = [source tell];
[source seek:0 whence:SEEK_SET]; [source seek:0 whence:SEEK_SET];
sampleRate = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthSampleRate"] doubleValue];
if(sampleRate < 8000.0) {
sampleRate = 44100.0;
} else if(sampleRate > 192000.0) {
sampleRate = 192000.0;
}
std::vector<char> data(static_cast<std::size_t>(size)); std::vector<char> data(static_cast<std::size_t>(size));
[source read:data.data() amount:size]; [source read:data.data() amount:size];
@ -71,7 +78,7 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
mod->select_subsong(track_num); mod->select_subsong(track_num);
length = mod->get_duration_seconds() * 44100.0; length = mod->get_duration_seconds() * sampleRate;
mod->set_repeat_count(IsRepeatOneSet() ? -1 : 0); mod->set_repeat_count(IsRepeatOneSet() ? -1 : 0);
mod->set_render_param(openmpt::module::RENDER_MASTERGAIN_MILLIBEL, 0); mod->set_render_param(openmpt::module::RENDER_MASTERGAIN_MILLIBEL, 0);
@ -91,7 +98,7 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
- (NSDictionary *)properties { - (NSDictionary *)properties {
return @{ @"bitrate": @(0), return @{ @"bitrate": @(0),
@"sampleRate": @(44100), @"sampleRate": @(sampleRate),
@"totalFrames": @(length), @"totalFrames": @(length),
@"bitsPerSample": @(32), @"bitsPerSample": @(32),
@"floatingPoint": @(YES), @"floatingPoint": @(YES),
@ -114,7 +121,7 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
if(framesToRender > frames) if(framesToRender > frames)
framesToRender = frames; framesToRender = frames;
std::size_t count = mod->read_interleaved_stereo(44100, framesToRender, ((float *)buf) + total * 2); std::size_t count = mod->read_interleaved_stereo(sampleRate, framesToRender, ((float *)buf) + total * 2);
if(count == 0) if(count == 0)
break; break;
@ -128,7 +135,7 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {
mod->set_position_seconds(frame * (1.0 / 44100.0)); mod->set_position_seconds(frame / sampleRate);
return frame; return frame;
} }

View file

@ -19,6 +19,9 @@
DATA_LOADER* dLoad; DATA_LOADER* dLoad;
PlayerA* mainPlr; PlayerA* mainPlr;
id<CogSource> source; id<CogSource> source;
double sampleRate;
long loopCount;
double fadeTime;
long length; long length;
BOOL trackEnded; BOOL trackEnded;
} }

View file

@ -88,7 +88,6 @@ static void PlayerLogCallback(void* userParam, PlayerBase* player, UINT8 level,
return; return;
} }
const int sampleRate = 44100;
const int numChannels = 2; const int numChannels = 2;
const int numBitsPerSample = 24; const int numBitsPerSample = 24;
const int smplAlloc = 2048; const int smplAlloc = 2048;
@ -112,8 +111,24 @@ const int masterVol = 0x10000; // Fixed point 16.16
return NO; return NO;
} }
sampleRate = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthSampleRate"] doubleValue];
if(sampleRate < 8000.0) {
sampleRate = 44100.0;
} else if(sampleRate > 192000.0) {
sampleRate = 192000.0;
}
loopCount = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultLoopCount"] longValue];
if(loopCount < 1) {
loopCount = 1;
} else if(loopCount > 10) {
loopCount = 10;
}
fadeTime = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultFadeSeconds"] doubleValue];
BOOL repeatOne = IsRepeatOneSet(); BOOL repeatOne = IsRepeatOneSet();
uint32_t maxLoops = repeatOne ? 0 : 2; uint32_t maxLoops = repeatOne ? 0 : (uint32_t)loopCount;
mainPlr = new PlayerA; mainPlr = new PlayerA;
mainPlr->RegisterPlayerEngine(new VGMPlayer); mainPlr->RegisterPlayerEngine(new VGMPlayer);
@ -127,12 +142,12 @@ const int masterVol = 0x10000; // Fixed point 16.16
PlayerA::Config pCfg = mainPlr->GetConfiguration(); PlayerA::Config pCfg = mainPlr->GetConfiguration();
pCfg.masterVol = masterVol; pCfg.masterVol = masterVol;
pCfg.loopCount = maxLoops; pCfg.loopCount = maxLoops;
pCfg.fadeSmpls = sampleRate * 4; // fade over 4 seconds pCfg.fadeSmpls = (int)ceil(sampleRate * fadeTime); // fade over configured duration
pCfg.endSilenceSmpls = sampleRate / 2; // 0.5 seconds of silence at the end pCfg.endSilenceSmpls = sampleRate / 2; // 0.5 seconds of silence at the end
pCfg.pbSpeed = 1.0; pCfg.pbSpeed = 1.0;
mainPlr->SetConfiguration(pCfg); mainPlr->SetConfiguration(pCfg);
} }
mainPlr->SetOutputSettings(sampleRate, numChannels, numBitsPerSample, smplAlloc); mainPlr->SetOutputSettings((int)ceil(sampleRate), numChannels, numBitsPerSample, smplAlloc);
[source seek:0 whence:SEEK_END]; [source seek:0 whence:SEEK_END];
size_t size = [source tell]; size_t size = [source tell];
@ -198,7 +213,7 @@ const int masterVol = 0x10000; // Fixed point 16.16
return 0; return 0;
BOOL repeatOne = IsRepeatOneSet(); BOOL repeatOne = IsRepeatOneSet();
uint32_t maxLoops = repeatOne ? 0 : 2; uint32_t maxLoops = repeatOne ? 0 : (uint32_t)loopCount;
PlayerBase* player = mainPlr->GetPlayer(); PlayerBase* player = mainPlr->GetPlayer();
mainPlr->SetLoopCount(maxLoops); mainPlr->SetLoopCount(maxLoops);

View file

@ -29,6 +29,8 @@
NSString *currentUrl; NSString *currentUrl;
BOOL hintAdded; BOOL hintAdded;
double sampleRate;
int n_channels; int n_channels;
long renderedTotal; long renderedTotal;

View file

@ -166,6 +166,13 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
[self setSource:s]; [self setSource:s];
sampleRate = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthSampleRate"] doubleValue];
if(sampleRate < 8000.0) {
sampleRate = 44100.0;
} else if(sampleRate > 192000.0) {
sampleRate = 192000.0;
}
NSString *path = [[s url] absoluteString]; NSString *path = [[s url] absoluteString];
NSRange fragmentRange = [path rangeOfString:@"#" options:NSBackwardsSearch]; NSRange fragmentRange = [path rangeOfString:@"#" options:NSBackwardsSearch];
if(fragmentRange.location != NSNotFound) { if(fragmentRange.location != NSNotFound) {
@ -195,7 +202,9 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
n_channels = 1; n_channels = 1;
length = 3 * 60 * 44100; double defaultLength = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultSeconds"] doubleValue];
length = (int)ceil(sampleRate * defaultLength);
tune->selectSong(track_num); tune->selectSong(track_num);
@ -224,7 +233,7 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
const SidTuneInfo *tuneInfo = tune->getInfo(); const SidTuneInfo *tuneInfo = tune->getInfo();
SidConfig conf = engine->config(); SidConfig conf = engine->config();
conf.frequency = 44100; conf.frequency = (int)ceil(sampleRate);
conf.sidEmulation = builder; conf.sidEmulation = builder;
conf.playback = SidConfig::MONO; conf.playback = SidConfig::MONO;
if(tuneInfo && (tuneInfo->sidChips() > 1)) if(tuneInfo && (tuneInfo->sidChips() > 1))
@ -236,8 +245,13 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
n_channels = 2; n_channels = 2;
} }
double defaultFade = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultFadeSeconds"] doubleValue];
if(defaultFade < 0.0) {
defaultFade = 0.0;
}
renderedTotal = 0; renderedTotal = 0;
fadeTotal = fadeRemain = 44100 * 8; fadeTotal = fadeRemain = (int)ceil(sampleRate * defaultFade);
[self willChangeValueForKey:@"properties"]; [self willChangeValueForKey:@"properties"];
[self didChangeValueForKey:@"properties"]; [self didChangeValueForKey:@"properties"];
@ -247,7 +261,7 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
- (NSDictionary *)properties { - (NSDictionary *)properties {
return @{ @"bitrate": @(0), return @{ @"bitrate": @(0),
@"sampleRate": @(44100), @"sampleRate": @(sampleRate),
@"totalFrames": @(length), @"totalFrames": @(length),
@"bitsPerSample": @(16), @"bitsPerSample": @(16),
@"floatingPoint": @(NO), @"floatingPoint": @(NO),

View file

@ -10,6 +10,7 @@
8314D8091A35654900EEE8E6 /* SidDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8314D8041A35654900EEE8E6 /* SidDecoder.mm */; }; 8314D8091A35654900EEE8E6 /* SidDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8314D8041A35654900EEE8E6 /* SidDecoder.mm */; };
8314D80A1A35654900EEE8E6 /* SidMetadataReader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8314D8061A35654900EEE8E6 /* SidMetadataReader.mm */; }; 8314D80A1A35654900EEE8E6 /* SidMetadataReader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8314D8061A35654900EEE8E6 /* SidMetadataReader.mm */; };
8314D80B1A35654900EEE8E6 /* SidContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8314D8081A35654900EEE8E6 /* SidContainer.mm */; }; 8314D80B1A35654900EEE8E6 /* SidContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8314D8081A35654900EEE8E6 /* SidContainer.mm */; };
833A8998286FF2E30022E036 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 833A8996286FF2E30022E036 /* Cocoa.framework */; };
836F5BEC1A357915002730CC /* roms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 836F5BEA1A357915002730CC /* roms.cpp */; }; 836F5BEC1A357915002730CC /* roms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 836F5BEA1A357915002730CC /* roms.cpp */; };
83747C012862DA420021245F /* Shared.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 83747BFF2862DA420021245F /* Shared.xcconfig */; }; 83747C012862DA420021245F /* Shared.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 83747BFF2862DA420021245F /* Shared.xcconfig */; };
EDBE911825E7EA01001EB4A4 /* sidplayfp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDBE8F0F25E7E74D001EB4A4 /* sidplayfp.framework */; }; EDBE911825E7EA01001EB4A4 /* sidplayfp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDBE8F0F25E7E74D001EB4A4 /* sidplayfp.framework */; };
@ -51,6 +52,7 @@
8314D80C1A35657700EEE8E6 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../../Audio/Plugin.h; sourceTree = "<group>"; }; 8314D80C1A35657700EEE8E6 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../../Audio/Plugin.h; sourceTree = "<group>"; };
8314D80D1A35658C00EEE8E6 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../../Utils/Logging.h; sourceTree = "<group>"; }; 8314D80D1A35658C00EEE8E6 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../../Utils/Logging.h; sourceTree = "<group>"; };
8314D80E1A3565AC00EEE8E6 /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../../Playlist/PlaylistController.h; sourceTree = "<group>"; }; 8314D80E1A3565AC00EEE8E6 /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../../Playlist/PlaylistController.h; sourceTree = "<group>"; };
833A8996286FF2E30022E036 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
836F5BEA1A357915002730CC /* roms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = roms.cpp; sourceTree = SOURCE_ROOT; }; 836F5BEA1A357915002730CC /* roms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = roms.cpp; sourceTree = SOURCE_ROOT; };
836F5BEB1A357915002730CC /* roms.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = roms.hpp; sourceTree = SOURCE_ROOT; }; 836F5BEB1A357915002730CC /* roms.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = roms.hpp; sourceTree = SOURCE_ROOT; };
83747BFF2862DA420021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747BFF2862DA420021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
@ -62,6 +64,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
833A8998286FF2E30022E036 /* Cocoa.framework in Frameworks */,
EDBE911825E7EA01001EB4A4 /* sidplayfp.framework in Frameworks */, EDBE911825E7EA01001EB4A4 /* sidplayfp.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -117,6 +120,7 @@
8314D64A1A354E4400EEE8E6 /* Frameworks */ = { 8314D64A1A354E4400EEE8E6 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
833A8996286FF2E30022E036 /* Cocoa.framework */,
EDBE8F0A25E7E74D001EB4A4 /* sidplayfp.xcodeproj */, EDBE8F0A25E7E74D001EB4A4 /* sidplayfp.xcodeproj */,
); );
name = Frameworks; name = Frameworks;

View file

@ -30,6 +30,8 @@
BOOL playForever; BOOL playForever;
BOOL canPlayForever; BOOL canPlayForever;
int loopCount;
double fadeTime;
int sampleRate; int sampleRate;
int channels; int channels;
int bitrate; int bitrate;

View file

@ -234,6 +234,18 @@ static NSString *get_description_tag(const char *description, const char *tag, c
- (BOOL)open:(id<CogSource>)s { - (BOOL)open:(id<CogSource>)s {
int track_num = [[[s url] fragment] intValue]; int track_num = [[[s url] fragment] intValue];
loopCount = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultLoopCount"] intValue];
if(loopCount < 1) {
loopCount = 1;
} else if(loopCount > 10) {
loopCount = 10;
}
fadeTime = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] valueForKey:@"synthDefaultFadeTime"] doubleValue];
if(fadeTime < 0.0) {
fadeTime = 0.0;
}
NSString *path = [[s url] absoluteString]; NSString *path = [[s url] absoluteString];
NSRange fragmentRange = [path rangeOfString:@"#" options:NSBackwardsSearch]; NSRange fragmentRange = [path rangeOfString:@"#" options:NSBackwardsSearch];
if(fragmentRange.location != NSNotFound) { if(fragmentRange.location != NSNotFound) {
@ -262,8 +274,8 @@ static NSString *get_description_tag(const char *description, const char *tag, c
vcfg.allow_play_forever = 1; vcfg.allow_play_forever = 1;
vcfg.play_forever = playForever; vcfg.play_forever = playForever;
vcfg.loop_count = 2; vcfg.loop_count = loopCount;
vcfg.fade_time = 10; vcfg.fade_time = fadeTime;
vcfg.fade_delay = 0; vcfg.fade_delay = 0;
vcfg.ignore_loop = 0; vcfg.ignore_loop = 0;

View file

@ -53,29 +53,8 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="253">
<rect key="frame" x="158" y="96" width="257" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" inset="2" id="254">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="255">
<items>
<menuItem title="Item 1" id="256"/>
<menuItem title="Item 2" id="257"/>
<menuItem title="Item 3" id="258"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<binding destination="246" name="content" keyPath="arrangedObjects" id="264"/>
<binding destination="246" name="contentValues" keyPath="arrangedObjects.name" previousBinding="307" id="308"/>
<binding destination="246" name="contentObjects" keyPath="arrangedObjects.preference" previousBinding="264" id="307"/>
<binding destination="52" name="selectedObject" keyPath="values.openingFilesAlteredBehavior" previousBinding="308" id="309"/>
</connections>
</popUpButton>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="247"> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="247">
<rect key="frame" x="158" y="134" width="257" height="26"/> <rect key="frame" x="158" y="133" width="356" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" selectedItem="250" id="248"> <popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" selectedItem="250" id="248">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -117,6 +96,27 @@
<binding destination="52" name="value" keyPath="values.quitOnNaturalStop" id="T4y-d6-qSk"/> <binding destination="52" name="value" keyPath="values.quitOnNaturalStop" id="T4y-d6-qSk"/>
</connections> </connections>
</button> </button>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="253">
<rect key="frame" x="158" y="95" width="356" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" inset="2" id="254">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="255">
<items>
<menuItem title="Item 1" id="256"/>
<menuItem title="Item 2" id="257"/>
<menuItem title="Item 3" id="258"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<binding destination="246" name="content" keyPath="arrangedObjects" id="264"/>
<binding destination="246" name="contentValues" keyPath="arrangedObjects.name" previousBinding="307" id="308"/>
<binding destination="246" name="contentObjects" keyPath="arrangedObjects.preference" previousBinding="264" id="307"/>
<binding destination="52" name="selectedObject" keyPath="values.openingFilesAlteredBehavior" previousBinding="308" id="309"/>
</connections>
</popUpButton>
</subviews> </subviews>
<point key="canvasLocation" x="-151" y="-283.5"/> <point key="canvasLocation" x="-151" y="-283.5"/>
</customView> </customView>
@ -211,7 +211,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="60"> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="60">
<rect key="frame" x="144" y="35" width="251" height="26"/> <rect key="frame" x="144" y="35" width="370" height="26"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<popUpButtonCell key="cell" type="push" title="Item1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="62" id="210"> <popUpButtonCell key="cell" type="push" title="Item1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" inset="2" arrowPosition="arrowAtCenter" preferredEdge="maxY" selectedItem="62" id="210">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -241,7 +241,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2v7-Ef-ekr"> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2v7-Ef-ekr">
<rect key="frame" x="144" y="6" width="251" height="26"/> <rect key="frame" x="144" y="6" width="370" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="vmS-eb-zen"> <popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="vmS-eb-zen">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -592,11 +592,11 @@
<point key="canvasLocation" x="450" y="183"/> <point key="canvasLocation" x="450" y="183"/>
</customView> </customView>
<customView wantsLayer="YES" id="JXu-ar-J3Y" userLabel="MIDIView"> <customView wantsLayer="YES" id="JXu-ar-J3Y" userLabel="MIDIView">
<rect key="frame" x="0.0" y="0.0" width="530" height="140"/> <rect key="frame" x="0.0" y="0.0" width="530" height="244"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews> <subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SBO-WF-DVS" userLabel="Push Button - Select a SoundFont"> <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SBO-WF-DVS" userLabel="Push Button - Select a SoundFont">
<rect key="frame" x="15" y="98" width="160" height="32"/> <rect key="frame" x="15" y="202" width="160" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Select a SoundFont" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="yeL-9c-lFq" userLabel="Button Cell - Select a SoundFont"> <buttonCell key="cell" type="push" title="Select a SoundFont" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="yeL-9c-lFq" userLabel="Button Cell - Select a SoundFont">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -607,7 +607,7 @@
</connections> </connections>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="FRC-Dh-BS2" userLabel="Text Field - Selected:"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="FRC-Dh-BS2" userLabel="Text Field - Selected:">
<rect key="frame" x="174" y="107" width="95" height="17"/> <rect key="frame" x="174" y="211" width="95" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Selected:" id="KJz-qS-IcO" userLabel="Text Field Cell - Selected"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Selected:" id="KJz-qS-IcO" userLabel="Text Field Cell - Selected">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@ -616,7 +616,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cZr-2d-6cv"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cZr-2d-6cv">
<rect key="frame" x="273" y="107" width="239" height="17"/> <rect key="frame" x="273" y="211" width="239" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="ECB-P0-pve"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="ECB-P0-pve">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@ -633,7 +633,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G86-18-hiK"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G86-18-hiK">
<rect key="frame" x="20" y="47" width="150" height="17"/> <rect key="frame" x="18" y="151" width="152" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Resampling Quality:" id="eX0-PC-iVo"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Resampling Quality:" id="eX0-PC-iVo">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@ -642,7 +642,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4uG-vW-B64"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4uG-vW-B64">
<rect key="frame" x="18" y="78" width="152" height="17"/> <rect key="frame" x="18" y="182" width="152" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="MIDI Plugin:" id="n5F-dq-NZh"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="MIDI Plugin:" id="n5F-dq-NZh">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@ -651,7 +651,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8Nj-G4-5ag"> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8Nj-G4-5ag">
<rect key="frame" x="173" y="72" width="341" height="26"/> <rect key="frame" x="173" y="176" width="341" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="vaQ-pZ-jXy" id="xcv-1b-kTI"> <popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="vaQ-pZ-jXy" id="xcv-1b-kTI">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -672,7 +672,7 @@
</connections> </connections>
</popUpButton> </popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="K5c-km-7Qa"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="K5c-km-7Qa">
<rect key="frame" x="20" y="16" width="150" height="17"/> <rect key="frame" x="20" y="120" width="150" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="MIDI Flavor:" id="FQF-vJ-hBx"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="MIDI Flavor:" id="FQF-vJ-hBx">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@ -681,7 +681,7 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1Yw-25-Gbs"> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1Yw-25-Gbs">
<rect key="frame" x="173" y="10" width="341" height="26"/> <rect key="frame" x="173" y="114" width="341" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" autoenablesItems="NO" altersStateOfSelectedItem="NO" selectedItem="XzK-h2-vIT" id="qzt-Ox-taI"> <popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" autoenablesItems="NO" altersStateOfSelectedItem="NO" selectedItem="XzK-h2-vIT" id="qzt-Ox-taI">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -702,7 +702,7 @@
</connections> </connections>
</popUpButton> </popUpButton>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E1D-Bo-ZVf"> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E1D-Bo-ZVf">
<rect key="frame" x="173" y="41" width="341" height="26"/> <rect key="frame" x="173" y="145" width="341" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="3Gx-cs-3B0" id="5q7-83-7V6"> <popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="3Gx-cs-3B0" id="5q7-83-7V6">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
@ -722,8 +722,138 @@
<binding destination="52" name="selectedObject" keyPath="values.resampling" previousBinding="KxI-52-0UK" id="wsy-tb-NFy"/> <binding destination="52" name="selectedObject" keyPath="values.resampling" previousBinding="KxI-52-0UK" id="wsy-tb-NFy"/>
</connections> </connections>
</popUpButton> </popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ygc-nv-ZkO">
<rect key="frame" x="18" y="94" width="152" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Default play time:" id="AQZ-ku-F8u">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="l3L-N5-gU1">
<rect key="frame" x="176" y="91" width="96" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" alignment="center" drawsBackground="YES" id="Isi-54-78h">
<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>
<binding destination="52" name="value" keyPath="values.synthDefaultSeconds" id="6aS-7t-Otv">
<dictionary key="options">
<string key="NSValueTransformerName">TimeIntervalToStringTransformer</string>
</dictionary>
</binding>
</connections>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HDu-ff-N3s">
<rect key="frame" x="176" y="65" width="96" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" alignment="center" drawsBackground="YES" id="9Hu-FG-spW">
<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>
<binding destination="52" name="value" keyPath="values.synthDefaultFadeSeconds" id="4mn-az-iz7">
<dictionary key="options">
<string key="NSValueTransformerName">TimeIntervalToStringTransformer</string>
</dictionary>
</binding>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JmH-HM-zwz">
<rect key="frame" x="276" y="94" width="91" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="hh:mm:ss.ms" id="klv-Wh-0ur">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qhe-ea-0bx">
<rect key="frame" x="18" y="68" width="152" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Default fade time:" id="UdW-qd-A0x">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eyL-LI-NzO">
<rect key="frame" x="276" y="68" width="91" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="hh:mm:ss.ms" id="zaI-0m-tQf">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4PD-ys-Cfu">
<rect key="frame" x="18" y="42" width="152" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Default loop count:" id="Fgm-Vs-tgU">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="FX5-Lt-csQ">
<rect key="frame" x="176" y="39" width="96" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="center" drawsBackground="YES" id="v5P-kg-a0v">
<numberFormatter key="formatter" formatterBehavior="default10_4" numberStyle="decimal" formatWidth="-1" minimumIntegerDigits="1" maximumIntegerDigits="2000000000" maximumFractionDigits="3" id="Bii-6P-aHq"/>
<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>
<binding destination="52" name="value" keyPath="values.synthDefaultLoopCount" id="h30-gW-yrc"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8jM-zP-FSb">
<rect key="frame" x="276" y="42" width="228" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="(will be preferred if possible)" id="POG-ai-6D2">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Rrf-kn-YnS">
<rect key="frame" x="18" y="15" width="152" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Sample rate:" id="A9I-fr-vHp">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CiQ-nY-YXA">
<rect key="frame" x="176" y="12" width="96" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="right" drawsBackground="YES" id="h3A-Br-Gyc">
<numberFormatter key="formatter" formatterBehavior="default10_4" numberStyle="decimal" formatWidth="-1" minimumIntegerDigits="1" maximumIntegerDigits="2000000000" maximumFractionDigits="3" id="btb-qT-AIL"/>
<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>
<binding destination="52" name="value" keyPath="values.synthSampleRate" id="C52-5h-iFA"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="esA-Kb-zTw">
<rect key="frame" x="276" y="15" width="70" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Hz" id="0Am-5Y-EKq">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews> </subviews>
<point key="canvasLocation" x="450" y="339"/> <point key="canvasLocation" x="450" y="391"/>
</customView> </customView>
<arrayController objectClassName="NSDictionary" editable="NO" id="JB6-r9-XpG" userLabel="ResamplerBehavior" customClass="ResamplerBehaviorArrayController"> <arrayController objectClassName="NSDictionary" editable="NO" id="JB6-r9-XpG" userLabel="ResamplerBehavior" customClass="ResamplerBehaviorArrayController">
<declaredKeys> <declaredKeys>

View file

@ -9,6 +9,7 @@
#import "GeneralPreferencesPlugin.h" #import "GeneralPreferencesPlugin.h"
#import "ColorToValueTransformer.h" #import "ColorToValueTransformer.h"
#import "PathToFileTransformer.h" #import "PathToFileTransformer.h"
#import "TimeIntervalToStringTransformer.h"
@implementation GeneralPreferencesPlugin @implementation GeneralPreferencesPlugin
@ -20,6 +21,10 @@
NSValueTransformer *colorToValueTransformer = [[ColorToValueTransformer alloc] init]; NSValueTransformer *colorToValueTransformer = [[ColorToValueTransformer alloc] init];
[NSValueTransformer setValueTransformer:colorToValueTransformer [NSValueTransformer setValueTransformer:colorToValueTransformer
forName:@"ColorToValueTransformer"]; forName:@"ColorToValueTransformer"];
NSValueTransformer *timeIntervalToStringTransformer = [[TimeIntervalToStringTransformer alloc] init];
[NSValueTransformer setValueTransformer:timeIntervalToStringTransformer
forName:@"TimeIntervalToStringTransformer"];
} }
+ (NSArray *)preferencePanes { + (NSArray *)preferencePanes {

View file

@ -22,6 +22,7 @@
8307D31728606EAF000FF8EB /* growl@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8307D31328606EAF000FF8EB /* growl@2x.png */; }; 8307D31728606EAF000FF8EB /* growl@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8307D31328606EAF000FF8EB /* growl@2x.png */; };
8307D31828606EAF000FF8EB /* general.png in Resources */ = {isa = PBXBuildFile; fileRef = 8307D31428606EAF000FF8EB /* general.png */; }; 8307D31828606EAF000FF8EB /* general.png in Resources */ = {isa = PBXBuildFile; fileRef = 8307D31428606EAF000FF8EB /* general.png */; };
8307D31928606EAF000FF8EB /* growl.png in Resources */ = {isa = PBXBuildFile; fileRef = 8307D31528606EAF000FF8EB /* growl.png */; }; 8307D31928606EAF000FF8EB /* growl.png in Resources */ = {isa = PBXBuildFile; fileRef = 8307D31528606EAF000FF8EB /* growl.png */; };
833A899F286FF3850022E036 /* TimeIntervalToStringTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 833A899E286FF3850022E036 /* TimeIntervalToStringTransformer.m */; };
83651DA527322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83651DA327322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m */; }; 83651DA527322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83651DA327322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m */; };
8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */; }; 8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8372053618E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m */; };
837C0D401C50954000CAE18F /* MIDIPluginBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */; }; 837C0D401C50954000CAE18F /* MIDIPluginBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 837C0D3F1C50954000CAE18F /* MIDIPluginBehaviorArrayController.m */; };
@ -102,6 +103,8 @@
8307D31328606EAF000FF8EB /* growl@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "growl@2x.png"; path = "Icons/growl@2x.png"; sourceTree = "<group>"; }; 8307D31328606EAF000FF8EB /* growl@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "growl@2x.png"; path = "Icons/growl@2x.png"; sourceTree = "<group>"; };
8307D31428606EAF000FF8EB /* general.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = general.png; path = Icons/general.png; sourceTree = "<group>"; }; 8307D31428606EAF000FF8EB /* general.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = general.png; path = Icons/general.png; sourceTree = "<group>"; };
8307D31528606EAF000FF8EB /* growl.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = growl.png; path = Icons/growl.png; sourceTree = "<group>"; }; 8307D31528606EAF000FF8EB /* growl.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = growl.png; path = Icons/growl.png; sourceTree = "<group>"; };
833A899D286FF3850022E036 /* TimeIntervalToStringTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TimeIntervalToStringTransformer.h; sourceTree = "<group>"; };
833A899E286FF3850022E036 /* TimeIntervalToStringTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TimeIntervalToStringTransformer.m; sourceTree = "<group>"; };
833F681B1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F681B1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
833F681C1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; }; 833F681C1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
8347435D20E6D58800063D45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Preferences.strings; sourceTree = "<group>"; }; 8347435D20E6D58800063D45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Preferences.strings; sourceTree = "<group>"; };
@ -313,6 +316,8 @@
83F27E731810E45D00CEF538 /* PathToFileTransformer.m */, 83F27E731810E45D00CEF538 /* PathToFileTransformer.m */,
83A3B72A283AE04800CC6593 /* ColorToValueTransformer.h */, 83A3B72A283AE04800CC6593 /* ColorToValueTransformer.h */,
83A3B72B283AE04800CC6593 /* ColorToValueTransformer.m */, 83A3B72B283AE04800CC6593 /* ColorToValueTransformer.m */,
833A899D286FF3850022E036 /* TimeIntervalToStringTransformer.h */,
833A899E286FF3850022E036 /* TimeIntervalToStringTransformer.m */,
); );
name = Transformers; name = Transformers;
sourceTree = "<group>"; sourceTree = "<group>";
@ -487,6 +492,7 @@
83A3B72C283AE04800CC6593 /* ColorToValueTransformer.m in Sources */, 83A3B72C283AE04800CC6593 /* ColorToValueTransformer.m in Sources */,
837C0D401C50954000CAE18F /* MIDIPluginBehaviorArrayController.m in Sources */, 837C0D401C50954000CAE18F /* MIDIPluginBehaviorArrayController.m in Sources */,
17C6433F0B8A783F00C53518 /* OutputPane.m in Sources */, 17C6433F0B8A783F00C53518 /* OutputPane.m in Sources */,
833A899F286FF3850022E036 /* TimeIntervalToStringTransformer.m in Sources */,
99F1813F0DE01D7A00FD5FFB /* PlaylistBehaviorArrayController.m in Sources */, 99F1813F0DE01D7A00FD5FFB /* PlaylistBehaviorArrayController.m in Sources */,
8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */, 8372053718E3DEAF007EFAD4 /* ResamplerBehaviorArrayController.m in Sources */,
); );

View file

@ -0,0 +1,16 @@
//
// TimeIntervalToStringTransformer.h
// Preferences
//
// Created by Christopher Snowhill on 7/1/22.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface TimeIntervalToStringTransformer : NSValueTransformer
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,63 @@
//
// TimeIntervalToStringTransformer.m
// Preferences
//
// Created by Christopher Snowhill on 7/1/22.
//
#import "TimeIntervalToStringTransformer.h"
#import <math.h>
@implementation TimeIntervalToStringTransformer
+ (Class)transformedValueClass {
return [NSString class];
}
+ (BOOL)allowsReverseTransformation {
return YES;
}
// Convert from string to NSURL
- (id)reverseTransformedValue:(id)value {
if(value == nil) return nil;
if([value isKindOfClass:[NSString class]]) {
NSString *theString = (NSString *)value;
NSArray *components = [theString componentsSeparatedByString:@":"];
double interval = 0.0;
for(size_t i = 0, j = [components count]; i < j; ++i) {
interval += ([components[j - i - 1] doubleValue]) * pow(60.0, i);
}
return @(interval);
}
return nil;
}
- (id)transformedValue:(id)value {
if(value == nil) return @"";
if([value isKindOfClass:[NSNumber class]]) {
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
[formatter setAllowedUnits:NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond];
double secondsValue = [value doubleValue];
double fractionValue = fmod(secondsValue, 1.0);
secondsValue = (double)(int)secondsValue;
NSString *wholePart = [formatter stringFromTimeInterval:(NSTimeInterval)secondsValue];
NSUInteger fractionMillis = (int)(fractionValue * 1000.0);
if(fractionMillis >= 1) {
NSString *fractionPart = [NSString stringWithFormat:@".%03lu", fractionMillis];
fractionPart = [fractionPart stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithRange:NSMakeRange('0', 1)]];
return [wholePart stringByAppendingString:fractionPart];
}
return wholePart;
}
return @"";
}
@end

View file

@ -11,18 +11,6 @@
/* Class = "NSMenuItem"; title = "Item3"; ObjectID = "64"; */ /* Class = "NSMenuItem"; title = "Item3"; ObjectID = "64"; */
"64.title" = "Item3"; "64.title" = "Item3";
/* Class = "NSMenu"; title = "OtherViews"; ObjectID = "107"; */
"107.title" = "OtherViews";
/* Class = "NSMenuItem"; title = "Stable"; ObjectID = "108"; */
"108.title" = "Stable";
/* Class = "NSMenuItem"; title = "Unstable"; ObjectID = "109"; */
"109.title" = "Unstable";
/* Class = "NSMenuItem"; title = "Nightly"; ObjectID = "110"; */
"110.title" = "Nightly";
/* Class = "NSTextFieldCell"; title = "Play:"; ObjectID = "198"; */ /* Class = "NSTextFieldCell"; title = "Play:"; ObjectID = "198"; */
"198.title" = "Play:"; "198.title" = "Play:";
@ -35,9 +23,6 @@
/* Class = "NSButtonCell"; title = "Automatically check for updates on startup"; ObjectID = "207"; */ /* Class = "NSButtonCell"; title = "Automatically check for updates on startup"; ObjectID = "207"; */
"207.title" = "Automatically check for updates on startup"; "207.title" = "Automatically check for updates on startup";
/* Class = "NSTextFieldCell"; title = "Update Feed:"; ObjectID = "209"; */
"209.title" = "Update Feed:";
/* Class = "NSTextFieldCell"; title = "Output Device: "; ObjectID = "211"; */ /* Class = "NSTextFieldCell"; title = "Output Device: "; ObjectID = "211"; */
"211.title" = "Output Device: "; "211.title" = "Output Device: ";
@ -80,15 +65,9 @@
/* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "1Yq-6f-Uho"; */ /* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "1Yq-6f-Uho"; */
"1Yq-6f-Uho.title" = "Item 2"; "1Yq-6f-Uho.title" = "Item 2";
/* Class = "NSButtonCell"; title = "Enable Last.fm support (Last.fm client must be installed)"; ObjectID = "2N5-DH-IO6"; */
"2N5-DH-IO6.title" = "Enable Last.fm support (Last.fm client must be installed)";
/* Class = "NSMenuItem"; title = "Item 1"; ObjectID = "3Gx-cs-3B0"; */ /* Class = "NSMenuItem"; title = "Item 1"; ObjectID = "3Gx-cs-3B0"; */
"3Gx-cs-3B0.title" = "Item 1"; "3Gx-cs-3B0.title" = "Item 1";
/* Class = "NSButtonCell"; title = "Allow Last.fm client to control media keys"; ObjectID = "4Yi-67-ivc"; */
"4Yi-67-ivc.title" = "Allow Last.fm client to control media keys";
/* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "99B-Tx-dPH"; */ /* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "99B-Tx-dPH"; */
"99B-Tx-dPH.title" = "Item 2"; "99B-Tx-dPH.title" = "Item 2";
@ -164,5 +143,86 @@
/* Class = "NSButtonCell"; title = "Select a SoundFont"; ObjectID = "yeL-9c-lFq"; */ /* Class = "NSButtonCell"; title = "Select a SoundFont"; ObjectID = "yeL-9c-lFq"; */
"yeL-9c-lFq.title" = "Select a SoundFont"; "yeL-9c-lFq.title" = "Select a SoundFont";
/* Class = "NSButtonCell"; title = "Automatically launch Last.fm client"; ObjectID = "ze8-9p-SeX"; */ /* Class = "NSTextFieldCell"; title = "Hz"; ObjectID = "0Am-5Y-EKq"; */
"ze8-9p-SeX.title" = "Automatically launch Last.fm client"; "0Am-5Y-EKq.title" = "Hz";
/* Class = "NSButtonCell"; title = "Reset to defaults"; ObjectID = "1y7-iZ-BhE"; */
"1y7-iZ-BhE.title" = "Reset to defaults";
/* Class = "NSTextFieldCell"; title = "Table View Cell"; ObjectID = "7un-em-D8r"; */
"7un-em-D8r.title" = "Table View Cell";
/* Class = "NSTextFieldCell"; title = "Sample rate:"; ObjectID = "A9I-fr-vHp"; */
"A9I-fr-vHp.title" = "Sample rate:";
/* Class = "NSTextFieldCell"; title = "Default play time:"; ObjectID = "AQZ-ku-F8u"; */
"AQZ-ku-F8u.title" = "Default play time:";
/* Class = "NSTextFieldCell"; title = "Spectrum bars"; ObjectID = "Bll-IJ-lje"; */
"Bll-IJ-lje.title" = "Spectrum bars";
/* Class = "NSTextFieldCell"; title = "Spectrum peaks"; ObjectID = "CQI-YZ-B3V"; */
"CQI-YZ-B3V.title" = "Spectrum peaks";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "Dhd-k8-ZXq"; */
"Dhd-k8-ZXq.title" = "Text Cell";
/* Class = "NSTextFieldCell"; title = "Default loop count:"; ObjectID = "Fgm-Vs-tgU"; */
"Fgm-Vs-tgU.title" = "Default loop count:";
/* Class = "NSMenuItem"; title = "Delete Invalid Paths"; ObjectID = "JU5-o7-jid"; */
"JU5-o7-jid.title" = "Delete Invalid Paths";
/* Class = "NSMenuItem"; title = "Add Path"; ObjectID = "JxP-0t-mTB"; */
"JxP-0t-mTB.title" = "Add Path";
/* Class = "NSTextFieldCell"; title = "Table View Cell"; ObjectID = "LwT-Qb-47r"; */
"LwT-Qb-47r.title" = "Table View Cell";
/* Class = "NSTextFieldCell"; title = "(will be preferred if possible)"; ObjectID = "POG-ai-6D2"; */
"POG-ai-6D2.title" = "(will be preferred if possible)";
/* Class = "NSButtonCell"; title = "Quit when playback completes"; ObjectID = "SBA-J5-rEd"; */
"SBA-J5-rEd.title" = "Quit when playback completes";
/* Class = "NSTextFieldCell"; title = "Default fade time:"; ObjectID = "UdW-qd-A0x"; */
"UdW-qd-A0x.title" = "Default fade time:";
/* Class = "NSTableColumn"; headerCell.title = "Path"; ObjectID = "Yz2-Ee-bZ0"; */
"Yz2-Ee-bZ0.headerCell.title" = "Path";
/* Class = "NSTextFieldCell"; title = "Text Cell"; ObjectID = "bWQ-dT-X3w"; */
"bWQ-dT-X3w.title" = "Text Cell";
/* Class = "NSButtonCell"; title = "Limit volume control to 100%"; ObjectID = "ds2-aw-ebU"; */
"ds2-aw-ebU.title" = "Limit volume control to 100%";
/* Class = "NSButtonCell"; title = "Spectrum 2D view"; ObjectID = "gXL-j6-df0"; */
"gXL-j6-df0.title" = "Spectrum 2D view";
/* Class = "NSTextFieldCell"; title = "hh:mm:ss.ms"; ObjectID = "klv-Wh-0ur"; */
"klv-Wh-0ur.title" = "hh:mm:ss.ms";
/* Class = "NSTextFieldCell"; title = "hh:mm:ss.ms"; ObjectID = "zaI-0m-tQf"; */
"zaI-0m-tQf.title" = "hh:mm:ss.ms";
/* Class = "NSTableColumn"; headerCell.title = "Valid"; ObjectID = "lEg-E3-TBs"; */
"lEg-E3-TBs.headerCell.title" = "Valid";
/* Class = "NSMenuItem"; title = "Delete Path"; ObjectID = "nva-pz-xSS"; */
"nva-pz-xSS.title" = "Delete Path";
/* Class = "NSMenuItem"; title = "Suggest Paths"; ObjectID = "qjI-dK-nfG"; */
"qjI-dK-nfG.title" = "Suggest Paths";
/* Class = "NSButtonCell"; title = "Allow insecure SSL connections"; ObjectID = "sva-DV-ina"; */
"sva-DV-ina.title" = "Allow insecure SSL connections";
/* Class = "NSButtonCell"; title = "Show stop button"; ObjectID = "vMI-lj-Lrz"; */
"vMI-lj-Lrz.title" = "Show stop button";
/* Class = "NSTextFieldCell"; title = "Folder access paths:"; ObjectID = "wWm-AD-cD4"; */
"wWm-AD-cD4.title" = "Folder access paths:";
/* Class = "NSButtonCell"; title = "Send crash reports and usage data"; ObjectID = "zQ2-6O-3Og"; */
"zQ2-6O-3Og.title" = "Send crash reports and usage data";

View file

@ -199,3 +199,44 @@
/* Class = "NSButtonCell"; title = "Send crash reports and usage data"; ObjectID = "zQ2-6O-3Og"; */ /* Class = "NSButtonCell"; title = "Send crash reports and usage data"; ObjectID = "zQ2-6O-3Og"; */
"zQ2-6O-3Og.title" = "Enviar informes de fallas y datos de uso"; "zQ2-6O-3Og.title" = "Enviar informes de fallas y datos de uso";
/* Class = "NSTextFieldCell"; title = "Default loop count:"; ObjectID = "Fgm-Vs-tgU"; */
"Fgm-Vs-tgU.title" = "Bucles por defecto:";
/* Class = "NSTextFieldCell"; title = "Hz"; ObjectID = "0Am-5Y-EKq"; */
"0Am-5Y-EKq.title" = "Hz";
/* Class = "NSMenuItem"; title = "Item 3"; ObjectID = "1Cb-TU-E0q"; */
"1Cb-TU-E0q.title" = "Item 3";
/* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "1Yq-6f-Uho"; */
"1Yq-6f-Uho.title" = "Item 2";
/* Class = "NSButtonCell"; title = "Reset to defaults"; ObjectID = "1y7-iZ-BhE"; */
"1y7-iZ-BhE.title" = "Volver a valores por defecto";
/* Class = "NSMenuItem"; title = "Item 1"; ObjectID = "3Gx-cs-3B0"; */
"3Gx-cs-3B0.title" = "Item 1";
/* Class = "NSTextFieldCell"; title = "Table View Cell"; ObjectID = "7un-em-D8r"; */
"7un-em-D8r.title" = "Celda de vista de tabla";
/* Class = "NSMenuItem"; title = "Item 2"; ObjectID = "99B-Tx-dPH"; */
"99B-Tx-dPH.title" = "Item 2";
/* Class = "NSTextFieldCell"; title = "Sample rate:"; ObjectID = "A9I-fr-vHp"; */
"A9I-fr-vHp.title" = "Tasa de muestreo:";
/* Class = "NSTextFieldCell"; title = "Default play time:"; ObjectID = "AQZ-ku-F8u"; */
"AQZ-ku-F8u.title" = "Tiempo de reproducción:";
/* Class = "NSTextFieldCell"; title = "(will be preferred if possible)"; ObjectID = "POG-ai-6D2"; */
"POG-ai-6D2.title" = "(se usará si es posible)";
/* Class = "NSTextFieldCell"; title = "Default fade time:"; ObjectID = "UdW-qd-A0x"; */
"UdW-qd-A0x.title" = "Tiempo de fundido:";
/* Class = "NSTextFieldCell"; title = "hh:mm:ss.ms"; ObjectID = "klv-Wh-0ur"; */
"klv-Wh-0ur.title" = "hh:mm:ss.ms";
/* Class = "NSTextFieldCell"; title = "hh:mm:ss.ms"; ObjectID = "zaI-0m-tQf"; */
"zaI-0m-tQf.title" = "hh:mm:ss.ms";