Implemented new VGMStream properties and metadata caching, which keeps file smashing under control, which stops Hardened Runtime from crashing on us
parent
9be094328c
commit
389a701553
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
8340888E1F6F604C00DCD404 /* VGMMetadataReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8340888B1F6F604A00DCD404 /* VGMMetadataReader.m */; };
|
8340888E1F6F604C00DCD404 /* VGMMetadataReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8340888B1F6F604A00DCD404 /* VGMMetadataReader.m */; };
|
||||||
|
835D2420235AB319009A1251 /* VGMPropertiesReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 835D241E235AB318009A1251 /* VGMPropertiesReader.m */; };
|
||||||
836F6B1418BDB80D0095E648 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 836F6B1318BDB80D0095E648 /* Cocoa.framework */; };
|
836F6B1418BDB80D0095E648 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 836F6B1318BDB80D0095E648 /* Cocoa.framework */; };
|
||||||
836F6B1E18BDB80D0095E648 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 836F6B1C18BDB80D0095E648 /* InfoPlist.strings */; };
|
836F6B1E18BDB80D0095E648 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 836F6B1C18BDB80D0095E648 /* InfoPlist.strings */; };
|
||||||
836F705C18BDC40E0095E648 /* VGMDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 836F705B18BDC40E0095E648 /* VGMDecoder.m */; };
|
836F705C18BDC40E0095E648 /* VGMDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 836F705B18BDC40E0095E648 /* VGMDecoder.m */; };
|
||||||
|
@ -51,6 +52,8 @@
|
||||||
833F68491CDBCAC000AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
833F68491CDBCAC000AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
8340888B1F6F604A00DCD404 /* VGMMetadataReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VGMMetadataReader.m; sourceTree = "<group>"; };
|
8340888B1F6F604A00DCD404 /* VGMMetadataReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VGMMetadataReader.m; sourceTree = "<group>"; };
|
||||||
8340888D1F6F604B00DCD404 /* VGMMetadataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VGMMetadataReader.h; sourceTree = "<group>"; };
|
8340888D1F6F604B00DCD404 /* VGMMetadataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VGMMetadataReader.h; sourceTree = "<group>"; };
|
||||||
|
835D241E235AB318009A1251 /* VGMPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VGMPropertiesReader.m; sourceTree = "<group>"; };
|
||||||
|
835D241F235AB319009A1251 /* VGMPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VGMPropertiesReader.h; sourceTree = "<group>"; };
|
||||||
836F6B1018BDB80D0095E648 /* vgmstream.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = vgmstream.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
836F6B1018BDB80D0095E648 /* vgmstream.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = vgmstream.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
836F6B1318BDB80D0095E648 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
836F6B1318BDB80D0095E648 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||||
836F6B1618BDB80D0095E648 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
836F6B1618BDB80D0095E648 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||||
|
@ -124,6 +127,8 @@
|
||||||
836F6B1918BDB80D0095E648 /* vgmstream */ = {
|
836F6B1918BDB80D0095E648 /* vgmstream */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
835D241F235AB319009A1251 /* VGMPropertiesReader.h */,
|
||||||
|
835D241E235AB318009A1251 /* VGMPropertiesReader.m */,
|
||||||
8340888D1F6F604B00DCD404 /* VGMMetadataReader.h */,
|
8340888D1F6F604B00DCD404 /* VGMMetadataReader.h */,
|
||||||
8340888B1F6F604A00DCD404 /* VGMMetadataReader.m */,
|
8340888B1F6F604A00DCD404 /* VGMMetadataReader.m */,
|
||||||
83AA5D2C1F6E30080020821C /* VGMContainer.h */,
|
83AA5D2C1F6E30080020821C /* VGMContainer.h */,
|
||||||
|
@ -248,6 +253,7 @@
|
||||||
8340888E1F6F604C00DCD404 /* VGMMetadataReader.m in Sources */,
|
8340888E1F6F604C00DCD404 /* VGMMetadataReader.m in Sources */,
|
||||||
83AA5D2D1F6E30080020821C /* VGMInterface.m in Sources */,
|
83AA5D2D1F6E30080020821C /* VGMInterface.m in Sources */,
|
||||||
83AA5D2E1F6E30080020821C /* VGMContainer.m in Sources */,
|
83AA5D2E1F6E30080020821C /* VGMContainer.m in Sources */,
|
||||||
|
835D2420235AB319009A1251 /* VGMPropertiesReader.m in Sources */,
|
||||||
836F705C18BDC40E0095E648 /* VGMDecoder.m in Sources */,
|
836F705C18BDC40E0095E648 /* VGMDecoder.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
|
@ -13,6 +13,18 @@
|
||||||
|
|
||||||
#import "Plugin.h"
|
#import "Plugin.h"
|
||||||
|
|
||||||
|
@interface VGMInfoCache : NSObject {
|
||||||
|
NSMutableDictionary *storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
+(id)sharedCache;
|
||||||
|
|
||||||
|
-(void)stuffURL:(NSURL *)url stream:(VGMSTREAM *)stream;
|
||||||
|
-(NSDictionary*)getPropertiesForURL:(NSURL *)url;
|
||||||
|
-(NSDictionary*)getMetadataForURL:(NSURL *)url;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@interface VGMDecoder : NSObject <CogDecoder> {
|
@interface VGMDecoder : NSObject <CogDecoder> {
|
||||||
VGMSTREAM *stream;
|
VGMSTREAM *stream;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,101 @@
|
||||||
|
|
||||||
#import "PlaylistController.h"
|
#import "PlaylistController.h"
|
||||||
|
|
||||||
|
@implementation VGMInfoCache
|
||||||
|
|
||||||
|
+(id)sharedCache {
|
||||||
|
static VGMInfoCache *sharedMyCache = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
sharedMyCache = [[self alloc] init];
|
||||||
|
});
|
||||||
|
return sharedMyCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(id)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
storage = [[NSMutableDictionary alloc] init];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)stuffURL:(NSURL *)url stream:(VGMSTREAM *)stream {
|
||||||
|
int track_num = [[url fragment] intValue];
|
||||||
|
|
||||||
|
int sampleRate = stream->sample_rate;
|
||||||
|
int channels = stream->channels;
|
||||||
|
long totalFrames = get_vgmstream_play_samples( 2.0, 10.0, 10.0, stream );
|
||||||
|
long framesFade = stream->loop_flag ? sampleRate * 10 : 0;
|
||||||
|
long framesLength = totalFrames - framesFade;
|
||||||
|
|
||||||
|
int bitrate = get_vgmstream_average_bitrate(stream);
|
||||||
|
|
||||||
|
NSDictionary * properties =
|
||||||
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
[NSNumber numberWithInt:bitrate / 1000], @"bitrate",
|
||||||
|
[NSNumber numberWithInt:sampleRate], @"sampleRate",
|
||||||
|
[NSNumber numberWithDouble:totalFrames], @"totalFrames",
|
||||||
|
[NSNumber numberWithInt:16], @"bitsPerSample",
|
||||||
|
[NSNumber numberWithBool:NO], @"floatingPoint",
|
||||||
|
[NSNumber numberWithInt:channels], @"channels",
|
||||||
|
[NSNumber numberWithBool:YES], @"seekable",
|
||||||
|
@"host", @"endian",
|
||||||
|
nil];
|
||||||
|
|
||||||
|
NSString * title;
|
||||||
|
|
||||||
|
if ( stream->num_streams > 1 ) {
|
||||||
|
title = [NSString stringWithFormat:@"%@ - %s", [[url URLByDeletingPathExtension] lastPathComponent], stream->stream_name];
|
||||||
|
} else {
|
||||||
|
title = [[url URLByDeletingPathExtension] lastPathComponent];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDictionary * metadata =
|
||||||
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
title, @"title",
|
||||||
|
[NSNumber numberWithInt:track_num], @"track",
|
||||||
|
nil];
|
||||||
|
|
||||||
|
NSDictionary * package =
|
||||||
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
properties, @"properties",
|
||||||
|
metadata, @"metadata",
|
||||||
|
nil];
|
||||||
|
|
||||||
|
@synchronized (self) {
|
||||||
|
[storage setValue:package forKey:[url absoluteString]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSDictionary*)getPropertiesForURL:(NSURL *)url {
|
||||||
|
NSDictionary *properties = nil;
|
||||||
|
|
||||||
|
@synchronized (self) {
|
||||||
|
NSDictionary * package = [storage objectForKey:[url absoluteString]];
|
||||||
|
if (package) {
|
||||||
|
properties = [package objectForKey:@"properties"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSDictionary*)getMetadataForURL:(NSURL *)url {
|
||||||
|
NSDictionary *metadata = nil;
|
||||||
|
|
||||||
|
@synchronized (self) {
|
||||||
|
NSDictionary * package = [storage objectForKey:[url absoluteString]];
|
||||||
|
if (package) {
|
||||||
|
metadata = [package objectForKey:@"metadata"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
@implementation VGMDecoder
|
@implementation VGMDecoder
|
||||||
|
|
||||||
- (BOOL)open:(id<CogSource>)s
|
- (BOOL)open:(id<CogSource>)s
|
||||||
|
@ -23,6 +118,8 @@
|
||||||
path = [path substringToIndex:fragmentRange.location];
|
path = [path substringToIndex:fragmentRange.location];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSLog(@"Opening %@ subsong %d", path, track_num);
|
||||||
|
|
||||||
stream = init_vgmstream_from_cogfile([[path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String], track_num);
|
stream = init_vgmstream_from_cogfile([[path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String], track_num);
|
||||||
if ( !stream )
|
if ( !stream )
|
||||||
return NO;
|
return NO;
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
|
|
||||||
+ (NSDictionary *)metadataForURL:(NSURL *)url
|
+ (NSDictionary *)metadataForURL:(NSURL *)url
|
||||||
{
|
{
|
||||||
|
VGMInfoCache * sharedMyCache = [VGMInfoCache sharedCache];
|
||||||
|
|
||||||
|
NSDictionary * metadata = [sharedMyCache getMetadataForURL:url];
|
||||||
|
|
||||||
|
if (!metadata) {
|
||||||
int track_num = [[url fragment] intValue];
|
int track_num = [[url fragment] intValue];
|
||||||
|
|
||||||
NSString * path = [url absoluteString];
|
NSString * path = [url absoluteString];
|
||||||
|
@ -41,18 +46,14 @@
|
||||||
if ( !stream )
|
if ( !stream )
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
NSString * title;
|
[sharedMyCache stuffURL:url stream:stream];
|
||||||
|
|
||||||
if ( stream->num_streams > 1 ) {
|
close_vgmstream(stream);
|
||||||
title = [NSString stringWithFormat:@"%@ - %s", [[url URLByDeletingPathExtension] lastPathComponent], stream->stream_name];
|
|
||||||
} else {
|
metadata = [sharedMyCache getMetadataForURL:url];
|
||||||
title = [[url URLByDeletingPathExtension] lastPathComponent];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
return metadata;
|
||||||
title, @"title",
|
|
||||||
[NSNumber numberWithInt:track_num], @"track",
|
|
||||||
nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
//
|
||||||
|
// VGMPropertiesReader.h
|
||||||
|
// VGMStream
|
||||||
|
//
|
||||||
|
// Created by Christopher Snowhill on 10/18/19.
|
||||||
|
// Copyright 2019 __LoSnoCo__. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#import "Plugin.h"
|
||||||
|
|
||||||
|
@interface VGMPropertiesReader : NSObject <CogPropertiesReader> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,61 @@
|
||||||
|
//
|
||||||
|
// VGMPropertiesReader.m
|
||||||
|
// VGMStream
|
||||||
|
//
|
||||||
|
// Created by Christopher Snowhill on 10/18/19.
|
||||||
|
// Copyright 2019 __LoSnoCo__. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "VGMPropertiesReader.h"
|
||||||
|
#import "VGMDecoder.h"
|
||||||
|
#import "VGMInterface.h"
|
||||||
|
|
||||||
|
@implementation VGMPropertiesReader
|
||||||
|
|
||||||
|
+ (NSArray *)fileTypes
|
||||||
|
{
|
||||||
|
return [VGMDecoder fileTypes];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSArray *)mimeTypes
|
||||||
|
{
|
||||||
|
return [VGMDecoder mimeTypes];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (float)priority
|
||||||
|
{
|
||||||
|
return [VGMDecoder priority];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSDictionary *)propertiesForSource:(id<CogSource>)source
|
||||||
|
{
|
||||||
|
VGMInfoCache * sharedMyCache = [VGMInfoCache sharedCache];
|
||||||
|
|
||||||
|
NSURL * url = [source url];
|
||||||
|
|
||||||
|
NSDictionary * properties = [sharedMyCache getPropertiesForURL:url];
|
||||||
|
|
||||||
|
if (!properties) {
|
||||||
|
int track_num = [[url fragment] intValue];
|
||||||
|
|
||||||
|
NSString * path = [url absoluteString];
|
||||||
|
NSRange fragmentRange = [path rangeOfString:@"#" options:NSBackwardsSearch];
|
||||||
|
if (fragmentRange.location != NSNotFound) {
|
||||||
|
path = [path substringToIndex:fragmentRange.location];
|
||||||
|
}
|
||||||
|
|
||||||
|
VGMSTREAM * stream = init_vgmstream_from_cogfile([[path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] UTF8String], track_num);
|
||||||
|
if ( !stream )
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
[sharedMyCache stuffURL:url stream:stream];
|
||||||
|
|
||||||
|
close_vgmstream(stream);
|
||||||
|
|
||||||
|
properties = [sharedMyCache getPropertiesForURL:url];
|
||||||
|
}
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue