cog/Plugins/GME/GameDecoder.m

191 lines
3.6 KiB
Matlab
Raw Normal View History

2007-10-11 23:11:58 +00:00
//
// GameFile.m
// Cog
//
// Created by Vincent Spader on 5/29/06.
// Copyright 2006 Vincent Spader. All rights reserved.
//
#import "GameDecoder.h"
#import "Logging.h"
2007-10-11 23:11:58 +00:00
@implementation GameDecoder
gme_err_t readCallback( void* data, void* out, long count )
{
id source = (id)data;
DLog(@"Amount: %li", count);
int n = [source read:out amount:count];
DLog(@"Read: %i", n);
2007-10-11 23:11:58 +00:00
if (n <= 0) {
DLog(@"ERROR!");
2007-10-11 23:11:58 +00:00
return (gme_err_t)1; //Return non-zero for error
}
return 0; //Return 0 for no error
}
- (BOOL)open:(id<CogSource>)s
{
[self setSource:s];
//We need file-size to use GME
if (![source seekable]) {
return NO;
}
gme_err_t error;
NSString *ext = [[[[source url] path] pathExtension] lowercaseString];
gme_type_t type = gme_identify_extension([ext UTF8String]);
if (!type)
{
ALog(@"GME: No type!");
2007-10-11 23:11:58 +00:00
return NO;
}
emu = gme_new_emu(type, 44100);
if (!emu)
{
ALog(@"GME: No new emu!");
2007-10-11 23:11:58 +00:00
return NO;
}
[source seek:0 whence:SEEK_END];
long size = [source tell];
[source seek:0 whence:SEEK_SET];
DLog(@"Size: %li", size);
2007-10-11 23:11:58 +00:00
error = gme_load_custom(emu, readCallback, size, s);
2007-10-11 23:11:58 +00:00
if (error)
{
ALog(@"GME: ERROR Loding custom!");
2007-10-11 23:11:58 +00:00
return NO;
}
int track_num = [[[source url] fragment] intValue]; //What if theres no fragment? Assuming we get 0.
2013-09-28 03:24:23 +00:00
gme_info_t * info;
2007-10-11 23:11:58 +00:00
error = gme_track_info( emu, &info, track_num );
if (error)
{
ALog(@"Unable to get track info");
return NO;
2007-10-11 23:11:58 +00:00
}
//As recommended
2013-09-28 03:24:23 +00:00
if (info->length > 0) {
DLog(@"Using length: %i", info->length);
2013-09-28 03:24:23 +00:00
length = info->length;
2007-10-11 23:11:58 +00:00
}
2013-09-28 03:24:23 +00:00
else if (info->loop_length > 0) {
DLog(@"Using loop length: %i", info->loop_length);
2013-09-28 03:24:23 +00:00
length = info->intro_length + 2*info->loop_length;
2007-10-11 23:11:58 +00:00
}
else {
length = 150000;
DLog(@"Setting default: %li", length);
2007-10-11 23:11:58 +00:00
}
2013-09-28 03:24:23 +00:00
gme_free_info( info );
2007-10-11 23:11:58 +00:00
DLog(@"Length: %li", length);
2007-10-11 23:11:58 +00:00
DLog(@"Track num: %i", track_num);
2007-10-11 23:11:58 +00:00
error = gme_start_track(emu, track_num);
if (error)
{
ALog(@"GME: Error starting track");
2007-10-11 23:11:58 +00:00
return NO;
}
gme_set_fade( emu, length, 8000 );
length += 8000;
[self willChangeValueForKey:@"properties"];
[self didChangeValueForKey:@"properties"];
2007-10-11 23:11:58 +00:00
return YES;
}
- (NSDictionary *)properties
{
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:0], @"bitrate",
[NSNumber numberWithFloat:44100], @"sampleRate",
[NSNumber numberWithLong:length*44.1], @"totalFrames",
2007-10-11 23:11:58 +00:00
[NSNumber numberWithInt:sizeof(short)*8], @"bitsPerSample", //Samples are short
[NSNumber numberWithInt:2], @"channels", //output from gme_play is in stereo
[NSNumber numberWithBool:[source seekable]], @"seekable",
@"host", @"endian",
nil];
}
- (int)readAudio:(void *)buf frames:(UInt32)frames
2007-10-11 23:11:58 +00:00
{
int numSamples = frames * 2; //channels = 2
2007-10-11 23:11:58 +00:00
if (gme_track_ended(emu)) {
2007-10-11 23:11:58 +00:00
return 0;
}
gme_play(emu, numSamples, (short int *)buf);
//Some formats support length, but we'll add that in the future.
//(From gme.txt) If track length, then use it. If loop length, play for intro + loop * 2. Otherwise, default to 2.5 minutes
return frames; //GME will always generate samples. There's no real EOS.
2007-10-11 23:11:58 +00:00
}
- (long)seek:(long)frame
2007-10-11 23:11:58 +00:00
{
gme_err_t error;
error = gme_seek(emu, frame/44.1);
2007-10-11 23:11:58 +00:00
if (error) {
return -1;
}
return frame;
2007-10-11 23:11:58 +00:00
}
- (void)close
{
if (emu) {
gme_delete(emu);
emu = NULL;
}
if (source) {
[source close];
[self setSource:nil];
}
}
+ (NSArray *)fileTypes
{
2013-10-04 16:00:32 +00:00
return [NSArray arrayWithObjects:@"ay", @"gbs", @"hes", @"kss", @"nsf", @"nsfe", @"sap", @"sgc", @"spc", @"vgm", @"vgz", nil];
2007-10-11 23:11:58 +00:00
}
2007-10-14 18:39:58 +00:00
+ (NSArray *)mimeTypes
{
return nil;
2007-10-14 18:39:58 +00:00
}
2007-10-11 23:11:58 +00:00
- (void)setSource:(id<CogSource>)s
{
[s retain];
[source release];
source = s;
}
- (id<CogSource>)source
{
return source;
}
@end