libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

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 (&copyright, 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 */