cog/Plugins/libvgmPlayer/libvgmMetadataReader.mm

193 lines
4.3 KiB
Plaintext

//
// libvgmMetadataReader.mm
// libvgmPlayer
//
// Created by Christopher Snowhill on 1/03/22.
// Copyright 2022 __LoSnoCo__. All rights reserved.
//
#import "libvgmMetadataReader.h"
#import "libvgmDecoder.h"
#import "Logging.h"
#import <libvgm/utils/MemoryLoader.h>
#import <libvgm/player/s98player.hpp>
#import <libvgm/player/droplayer.hpp>
#import <libvgm/player/vgmplayer.hpp>
#import <libvgm/player/gymplayer.hpp>
@implementation libvgmMetadataReader
#ifdef _DEBUG
const int logLevel = DEVLOG_DEBUG;
#else
const int logLevel = DEVLOG_INFO;
#endif
static UINT8 FilePlayCallback(PlayerBase* player, void* userParam, UINT8 evtType, void* evtParam)
{
return 0x00;
}
static DATA_LOADER* RequestFileCallback(void* userParam, PlayerBase* player, const char* fileName)
{
return NULL;
}
static const char* LogLevel2Str(UINT8 level)
{
static const char* LVL_NAMES[6] = {" ??? ", "Error", "Warn ", "Info ", "Debug", "Trace"};
if (level >= (sizeof(LVL_NAMES) / sizeof(LVL_NAMES[0])))
level = 0;
return LVL_NAMES[level];
}
static void PlayerLogCallback(void* userParam, PlayerBase* player, UINT8 level, UINT8 srcType,
const char* srcTag, const char* message)
{
if (level > logLevel)
return; // don't print messages with higher verbosity than current log level
if (srcType == PLRLOGSRC_PLR)
{
ALog(@"[%s] %s: %s", LogLevel2Str(level), player->GetPlayerName(), message);
}
else
{
ALog(@"[%s] %s %s: %s", LogLevel2Str(level), player->GetPlayerName(), srcTag, message);
}
return;
}
static std::string FCC2Str(UINT32 fcc)
{
std::string result(4, '\0');
result[0] = (char)((fcc >> 24) & 0xFF);
result[1] = (char)((fcc >> 16) & 0xFF);
result[2] = (char)((fcc >> 8) & 0xFF);
result[3] = (char)((fcc >> 0) & 0xFF);
return result;
}
+ (NSArray *)fileTypes
{
return [libvgmDecoder fileTypes];
}
+ (NSArray *)mimeTypes
{
return [libvgmDecoder mimeTypes];
}
+ (float)priority
{
return [libvgmDecoder priority];
}
+ (NSDictionary *)metadataForURL:(NSURL *)url
{
id audioSourceClass = NSClassFromString(@"AudioSource");
id<CogSource> source = [audioSourceClass audioSourceForURL:url];
if (![source open:url])
return 0;
if (![source seekable])
return 0;
PlayerA mainPlr;
mainPlr.RegisterPlayerEngine(new VGMPlayer);
mainPlr.RegisterPlayerEngine(new S98Player);
mainPlr.RegisterPlayerEngine(new DROPlayer);
mainPlr.RegisterPlayerEngine(new GYMPlayer);
mainPlr.SetEventCallback(FilePlayCallback, NULL);
mainPlr.SetFileReqCallback(RequestFileCallback, NULL);
mainPlr.SetLogCallback(PlayerLogCallback, NULL);
mainPlr.SetOutputSettings(44100, 2, 24, 2048);
[source seek:0 whence:SEEK_END];
size_t size = [source tell];
[source seek:0 whence:SEEK_SET];
UINT8* fileData = (UINT8*) malloc(size);
if (!fileData)
return 0;
size_t bytesRead = [source read:fileData amount:size];
if (bytesRead != size)
{
free(fileData);
return 0;
}
DATA_LOADER *dLoad = MemoryLoader_Init(fileData, (unsigned int)size);
if (!dLoad)
{
free(fileData);
return 0;
}
DataLoader_SetPreloadBytes(dLoad,0x100);
if (DataLoader_Load(dLoad))
{
DataLoader_Deinit(dLoad);
free(fileData);
return 0;
}
if (mainPlr.LoadFile(dLoad))
{
DataLoader_Deinit(dLoad);
free(fileData);
return 0;
}
NSString *system = @"";
NSString *title = @"";
NSString *artist = @"";
NSString *album = @"";
NSNumber *year = [NSNumber numberWithInt:0];
PlayerBase* player = mainPlr.GetPlayer();
const char* const* tagList = player->GetTags();
for (const char* const* t = tagList; *t; t += 2)
{
if (!strcmp(t[0], "TITLE"))
title = [NSString stringWithUTF8String:t[1]];
else if (!strcmp(t[0], "ARTIST"))
artist = [NSString stringWithUTF8String:t[1]];
else if (!strcmp(t[0], "GAME"))
album = [NSString stringWithUTF8String:t[1]];
else if (!strcmp(t[0], "DATE"))
{
char * end;
unsigned long theYear = strtoul(t[1], &end, 10);
year = [NSNumber numberWithLong:theYear];
}
}
PLR_SONG_INFO sInf;
player->GetSongInfo(sInf);
system = [NSString stringWithFormat:@"%s v%X.%02X", FCC2Str(sInf.format).c_str(), sInf.fileVerMaj, sInf.fileVerMin];
mainPlr.UnloadFile();
DataLoader_Deinit(dLoad);
free(fileData);
NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:
system, @"codec",
album, @"album",
title, @"title",
artist, @"artist",
year, @"year",
nil];
return dict;
}
@end