/* * This file is part of libextractor. * Copyright (C) 2006, 2009, 2012 Toni Ruottu and Christian Grothoff * * libextractor is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 3, or (at your * option) any later version. * * libextractor is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with libextractor; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /** * @file plugins/nsf_extractor.c * @brief plugin to support Nes Sound Format files * @author Toni Ruottu * @author Christian Grothoff */ #include "platform.h" #include "extractor.h" /* television system flags */ #define PAL_FLAG 0x01 #define DUAL_FLAG 0x02 /* sound chip flags */ #define VRCVI_FLAG 0x01 #define VRCVII_FLAG 0x02 #define FDS_FLAG 0x04 #define MMC5_FLAG 0x08 #define NAMCO_FLAG 0x10 #define SUNSOFT_FLAG 0x20 /** * Header of an NSF file. */ struct header { /** * Magic code. */ char magicid[5]; /** * NSF version number. */ char nsfversion; /** * Number of songs. */ unsigned char songs; /** * Starting song. */ unsigned char firstsong; /** * Unknown. */ uint16_t loadaddr; /** * Unknown. */ uint16_t initaddr; /** * Unknown. */ uint16_t playaddr; /** * Album title. */ char title[32]; /** * Artist name. */ char artist[32]; /** * Copyright information. */ char copyright[32]; /** * Unknown. */ uint16_t ntscspeed; /** * Unknown. */ char bankswitch[8]; /** * Unknown. */ uint16_t palspeed; /** * Flags for TV encoding. */ char tvflags; /** * Flags about the decoder chip. */ char chipflags; }; /** * Give metadata to LE; return if 'proc' returns non-zero. * * @param s metadata value as UTF8 * @param t metadata type to use */ #define ADD(s,t) do { if (0 != ec->proc (ec->cls, "nsf", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen (s) + 1)) return; } while (0) /** * "extract" meta data from a Nes Sound Format file * * NSF specification version 1.61 was used, while this piece of * software was originally written. * * @param ec extraction context */ void EXTRACTOR_nsf_extract_method (struct EXTRACTOR_ExtractContext *ec) { char album[33]; char artist[33]; char copyright[33]; char songs[32]; char startingsong[32]; char nsfversion[32]; const struct header *head; void *data; ssize_t ds; ds = ec->read (ec->cls, &data, sizeof (struct header)); if ( (-1 == ds) || (sizeof (struct header) > ds) ) return; head = data; /* Check "magic" id bytes */ if (memcmp (head->magicid, "NESM\x1a", 5)) return; ADD ("audio/x-nsf", EXTRACTOR_METATYPE_MIMETYPE); snprintf (nsfversion, sizeof(nsfversion), "%d", head->nsfversion); ADD (nsfversion, EXTRACTOR_METATYPE_FORMAT_VERSION); snprintf (songs, sizeof(songs), "%d", (int) head->songs); ADD (songs, EXTRACTOR_METATYPE_SONG_COUNT); snprintf (startingsong, sizeof(startingsong), "%d", (int) head->firstsong); ADD (startingsong, EXTRACTOR_METATYPE_STARTING_SONG); memcpy (&album, head->title, 32); album[32] = '\0'; ADD (album, EXTRACTOR_METATYPE_ALBUM); memcpy (&artist, head->artist, 32); artist[32] = '\0'; ADD (artist, EXTRACTOR_METATYPE_ARTIST); memcpy (©right, head->copyright, 32); copyright[32] = '\0'; ADD (copyright, EXTRACTOR_METATYPE_COPYRIGHT); if (0 != (head->tvflags & DUAL_FLAG)) { ADD ("PAL/NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); } else { if (0 != (head->tvflags & PAL_FLAG)) ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); else ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); } /* Detect Extra Sound Chips needed to play the files */ if (0 != (head->chipflags & VRCVI_FLAG)) ADD ("VRCVI", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); if (0 != (head->chipflags & VRCVII_FLAG)) ADD ("VRCVII", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); if (0 != (head->chipflags & FDS_FLAG)) ADD ("FDS Sound", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); if (0 != (head->chipflags & MMC5_FLAG)) ADD ("MMC5 audio", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); if (0 != (head->chipflags & NAMCO_FLAG)) ADD ("Namco 106", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); if (0 != (head->chipflags & SUNSOFT_FLAG)) ADD ("Sunsoft FME-07", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); } /* end of nsf_extractor.c */