nsf_extractor.c (5179B)
1 /* 2 * This file is part of libextractor. 3 * Copyright (C) 2006, 2009, 2012 Toni Ruottu and Christian Grothoff 4 * 5 * libextractor is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published 7 * by the Free Software Foundation; either version 3, or (at your 8 * option) any later version. 9 * 10 * libextractor is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with libextractor; see the file COPYING. If not, write to the 17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 /** 22 * @file plugins/nsf_extractor.c 23 * @brief plugin to support Nes Sound Format files 24 * @author Toni Ruottu 25 * @author Christian Grothoff 26 */ 27 #include "platform.h" 28 #include "extractor.h" 29 30 31 /* television system flags */ 32 #define PAL_FLAG 0x01 33 #define DUAL_FLAG 0x02 34 35 /* sound chip flags */ 36 #define VRCVI_FLAG 0x01 37 #define VRCVII_FLAG 0x02 38 #define FDS_FLAG 0x04 39 #define MMC5_FLAG 0x08 40 #define NAMCO_FLAG 0x10 41 #define SUNSOFT_FLAG 0x20 42 43 44 /** 45 * Header of an NSF file. 46 */ 47 struct header 48 { 49 /** 50 * Magic code. 51 */ 52 char magicid[5]; 53 54 /** 55 * NSF version number. 56 */ 57 char nsfversion; 58 59 /** 60 * Number of songs. 61 */ 62 unsigned char songs; 63 64 /** 65 * Starting song. 66 */ 67 unsigned char firstsong; 68 69 /** 70 * Unknown. 71 */ 72 uint16_t loadaddr; 73 74 /** 75 * Unknown. 76 */ 77 uint16_t initaddr; 78 79 /** 80 * Unknown. 81 */ 82 uint16_t playaddr; 83 84 /** 85 * Album title. 86 */ 87 char title[32]; 88 89 /** 90 * Artist name. 91 */ 92 char artist[32]; 93 94 /** 95 * Copyright information. 96 */ 97 char copyright[32]; 98 99 /** 100 * Unknown. 101 */ 102 uint16_t ntscspeed; 103 104 /** 105 * Unknown. 106 */ 107 char bankswitch[8]; 108 109 /** 110 * Unknown. 111 */ 112 uint16_t palspeed; 113 114 /** 115 * Flags for TV encoding. 116 */ 117 char tvflags; 118 119 /** 120 * Flags about the decoder chip. 121 */ 122 char chipflags; 123 }; 124 125 126 /** 127 * Give metadata to LE; return if 'proc' returns non-zero. 128 * 129 * @param s metadata value as UTF8 130 * @param t metadata type to use 131 */ 132 #define ADD(s,t) do { if (0 != ec->proc (ec->cls, "nsf", t, \ 133 EXTRACTOR_METAFORMAT_UTF8, \ 134 "text/plain", s, strlen (s) \ 135 + 1)) return; \ 136 } while (0) 137 138 139 /** 140 * "extract" meta data from a Nes Sound Format file 141 * 142 * NSF specification version 1.61 was used, while this piece of 143 * software was originally written. 144 * 145 * @param ec extraction context 146 */ 147 void 148 EXTRACTOR_nsf_extract_method (struct EXTRACTOR_ExtractContext *ec) 149 { 150 char album[33]; 151 char artist[33]; 152 char copyright[33]; 153 char songs[32]; 154 char startingsong[32]; 155 char nsfversion[32]; 156 const struct header *head; 157 void *data; 158 ssize_t ds; 159 160 ds = ec->read (ec->cls, 161 &data, 162 sizeof (struct header)); 163 if ( (-1 == ds) || 164 (sizeof (struct header) > ds) ) 165 return; 166 head = data; 167 168 /* Check "magic" id bytes */ 169 if (memcmp (head->magicid, "NESM\x1a", 5)) 170 return; 171 ADD ("audio/x-nsf", EXTRACTOR_METATYPE_MIMETYPE); 172 snprintf (nsfversion, 173 sizeof(nsfversion), 174 "%d", 175 head->nsfversion); 176 ADD (nsfversion, EXTRACTOR_METATYPE_FORMAT_VERSION); 177 snprintf (songs, 178 sizeof(songs), 179 "%d", 180 (int) head->songs); 181 ADD (songs, EXTRACTOR_METATYPE_SONG_COUNT); 182 snprintf (startingsong, 183 sizeof(startingsong), 184 "%d", 185 (int) head->firstsong); 186 ADD (startingsong, EXTRACTOR_METATYPE_STARTING_SONG); 187 memcpy (&album, head->title, 32); 188 album[32] = '\0'; 189 ADD (album, EXTRACTOR_METATYPE_ALBUM); 190 memcpy (&artist, head->artist, 32); 191 artist[32] = '\0'; 192 ADD (artist, EXTRACTOR_METATYPE_ARTIST); 193 memcpy (©right, head->copyright, 32); 194 copyright[32] = '\0'; 195 ADD (copyright, EXTRACTOR_METATYPE_COPYRIGHT); 196 197 if (0 != (head->tvflags & DUAL_FLAG)) 198 { 199 ADD ("PAL/NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 200 } 201 else 202 { 203 if (0 != (head->tvflags & PAL_FLAG)) 204 ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 205 else 206 ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 207 } 208 209 /* Detect Extra Sound Chips needed to play the files */ 210 if (0 != (head->chipflags & VRCVI_FLAG)) 211 ADD ("VRCVI", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 212 if (0 != (head->chipflags & VRCVII_FLAG)) 213 ADD ("VRCVII", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 214 if (0 != (head->chipflags & FDS_FLAG)) 215 ADD ("FDS Sound", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 216 if (0 != (head->chipflags & MMC5_FLAG)) 217 ADD ("MMC5 audio", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 218 if (0 != (head->chipflags & NAMCO_FLAG)) 219 ADD ("Namco 106", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 220 if (0 != (head->chipflags & SUNSOFT_FLAG)) 221 ADD ("Sunsoft FME-07", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 222 } 223 224 225 /* end of nsf_extractor.c */