source: extensions/charlies_content/getid3/getid3/module.tag.id3v1.php @ 3318

Last change on this file since 3318 was 3318, checked in by vdigital, 15 years ago

+ Add Charlies' content to depository

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 KB
Line 
1<?php
2// +----------------------------------------------------------------------+
3// | PHP version 5                                                        |
4// +----------------------------------------------------------------------+
5// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 |
6// +----------------------------------------------------------------------+
7// | This source file is subject to version 2 of the GPL license,         |
8// | that is bundled with this package in the file license.txt and is     |
9// | available through the world-wide-web at the following url:           |
10// | http://www.gnu.org/copyleft/gpl.html                                 |
11// +----------------------------------------------------------------------+
12// | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    |
13// +----------------------------------------------------------------------+
14// | Authors: James Heinrich <infoØgetid3*org>                            |
15// |          Allan Hansen <ahØartemis*dk>                                |
16// +----------------------------------------------------------------------+
17// | module.tag.id3v1.php                                                 |
18// | module for analyzing ID3v1 tags                                      |
19// | dependencies: NONE                                                   |
20// +----------------------------------------------------------------------+
21//
22// $Id: module.tag.id3v1.php 3318 2009-05-20 21:54:10Z vdigital $
23
24       
25       
26class getid3_id3v1 extends getid3_handler
27{
28
29    public function Analyze() {
30
31        $getid3 = $this->getid3;
32               
33        fseek($getid3->fp, -256, SEEK_END);
34        $pre_id3v1 = fread($getid3->fp, 128);
35        $id3v1_tag = fread($getid3->fp, 128);
36
37        if (substr($id3v1_tag, 0, 3) == 'TAG') {
38       
39            $getid3->info['avdataend'] -= 128;
40       
41            // Shortcut
42            $getid3->info['id3v1'] = array ();
43            $info_id3v1 = &$getid3->info['id3v1'];
44
45            $info_id3v1['title']   = getid3_id3v1::cutfield(substr($id3v1_tag,  3, 30));
46            $info_id3v1['artist']  = getid3_id3v1::cutfield(substr($id3v1_tag, 33, 30));
47            $info_id3v1['album']   = getid3_id3v1::cutfield(substr($id3v1_tag, 63, 30));
48            $info_id3v1['year']    = getid3_id3v1::cutfield(substr($id3v1_tag, 93,  4));
49            $info_id3v1['comment'] = substr($id3v1_tag,  97, 30);  // can't remove nulls yet, track detection depends on them
50            $info_id3v1['genreid'] = ord(substr($id3v1_tag, 127, 1));
51
52            // If second-last byte of comment field is null and last byte of comment field is non-null then this is ID3v1.1 and the comment field is 28 bytes long and the 30th byte is the track number
53            if (($id3v1_tag{125} === "\x00") && ($id3v1_tag{126} !== "\x00")) {
54                $info_id3v1['track']   = ord(substr($info_id3v1['comment'], 29,  1));
55                $info_id3v1['comment'] =     substr($info_id3v1['comment'],  0, 28);
56            }
57            $info_id3v1['comment'] = getid3_id3v1::cutfield($info_id3v1['comment']);
58
59            $info_id3v1['genre'] = getid3_id3v1::LookupGenreName($info_id3v1['genreid']);
60            if (!empty($info_id3v1['genre'])) {
61                unset($info_id3v1['genreid']);
62            }
63            if (empty($info_id3v1['genre']) || (@$info_id3v1['genre'] == 'Unknown')) {
64                unset($info_id3v1['genre']);
65            }
66
67            foreach ($info_id3v1 as $key => $value) {
68                $key != 'comments' and $info_id3v1['comments'][$key][0] = $value;
69            }
70
71            $info_id3v1['tag_offset_end']   = filesize($getid3->filename);
72            $info_id3v1['tag_offset_start'] = $info_id3v1['tag_offset_end'] - 128;
73        }   
74           
75        if (substr($pre_id3v1, 0, 3) == 'TAG') {
76            // The way iTunes handles tags is, well, brain-damaged.
77            // It completely ignores v1 if ID3v2 is present.
78            // This goes as far as adding a new v1 tag *even if there already is one*
79
80            // A suspected double-ID3v1 tag has been detected, but it could be that the "TAG" identifier is a legitimate part of an APE or Lyrics3 tag
81            if (substr($pre_id3v1, 96, 8) == 'APETAGEX') {
82                // an APE tag footer was found before the last ID3v1, assume false "TAG" synch
83            } elseif (substr($pre_id3v1, 119, 6) == 'LYRICS') {
84                // a Lyrics3 tag footer was found before the last ID3v1, assume false "TAG" synch
85            } else {
86                // APE and Lyrics3 footers not found - assume double ID3v1
87                $getid3->warning('Duplicate ID3v1 tag detected - this has been known to happen with iTunes.');
88                $getid3->info['avdataend'] -= 128;
89            }
90        }
91
92        return true;
93    }
94   
95   
96
97    public static function cutfield($str) {
98       
99        return trim(substr($str, 0, strcspn($str, "\x00")));
100    }
101
102
103
104    public static function ArrayOfGenres($allow_SCMPX_extended=false) {
105       
106        static $lookup = array (
107            0    => 'Blues',
108            1    => 'Classic Rock',
109            2    => 'Country',
110            3    => 'Dance',
111            4    => 'Disco',
112            5    => 'Funk',
113            6    => 'Grunge',
114            7    => 'Hip-Hop',
115            8    => 'Jazz',
116            9    => 'Metal',
117            10   => 'New Age',
118            11   => 'Oldies',
119            12   => 'Other',
120            13   => 'Pop',
121            14   => 'R&B',
122            15   => 'Rap',
123            16   => 'Reggae',
124            17   => 'Rock',
125            18   => 'Techno',
126            19   => 'Industrial',
127            20   => 'Alternative',
128            21   => 'Ska',
129            22   => 'Death Metal',
130            23   => 'Pranks',
131            24   => 'Soundtrack',
132            25   => 'Euro-Techno',
133            26   => 'Ambient',
134            27   => 'Trip-Hop',
135            28   => 'Vocal',
136            29   => 'Jazz+Funk',
137            30   => 'Fusion',
138            31   => 'Trance',
139            32   => 'Classical',
140            33   => 'Instrumental',
141            34   => 'Acid',
142            35   => 'House',
143            36   => 'Game',
144            37   => 'Sound Clip',
145            38   => 'Gospel',
146            39   => 'Noise',
147            40   => 'Alt. Rock',
148            41   => 'Bass',
149            42   => 'Soul',
150            43   => 'Punk',
151            44   => 'Space',
152            45   => 'Meditative',
153            46   => 'Instrumental Pop',
154            47   => 'Instrumental Rock',
155            48   => 'Ethnic',
156            49   => 'Gothic',
157            50   => 'Darkwave',
158            51   => 'Techno-Industrial',
159            52   => 'Electronic',
160            53   => 'Pop-Folk',
161            54   => 'Eurodance',
162            55   => 'Dream',
163            56   => 'Southern Rock',
164            57   => 'Comedy',
165            58   => 'Cult',
166            59   => 'Gangsta Rap',
167            60   => 'Top 40',
168            61   => 'Christian Rap',
169            62   => 'Pop/Funk',
170            63   => 'Jungle',
171            64   => 'Native American',
172            65   => 'Cabaret',
173            66   => 'New Wave',
174            67   => 'Psychedelic',
175            68   => 'Rave',
176            69   => 'Showtunes',
177            70   => 'Trailer',
178            71   => 'Lo-Fi',
179            72   => 'Tribal',
180            73   => 'Acid Punk',
181            74   => 'Acid Jazz',
182            75   => 'Polka',
183            76   => 'Retro',
184            77   => 'Musical',
185            78   => 'Rock & Roll',
186            79   => 'Hard Rock',
187            80   => 'Folk',
188            81   => 'Folk/Rock',
189            82   => 'National Folk',
190            83   => 'Swing',
191            84   => 'Fast-Fusion',
192            85   => 'Bebob',
193            86   => 'Latin',
194            87   => 'Revival',
195            88   => 'Celtic',
196            89   => 'Bluegrass',
197            90   => 'Avantgarde',
198            91   => 'Gothic Rock',
199            92   => 'Progressive Rock',
200            93   => 'Psychedelic Rock',
201            94   => 'Symphonic Rock',
202            95   => 'Slow Rock',
203            96   => 'Big Band',
204            97   => 'Chorus',
205            98   => 'Easy Listening',
206            99   => 'Acoustic',
207            100  => 'Humour',
208            101  => 'Speech',
209            102  => 'Chanson',
210            103  => 'Opera',
211            104  => 'Chamber Music',
212            105  => 'Sonata',
213            106  => 'Symphony',
214            107  => 'Booty Bass',
215            108  => 'Primus',
216            109  => 'Porn Groove',
217            110  => 'Satire',
218            111  => 'Slow Jam',
219            112  => 'Club',
220            113  => 'Tango',
221            114  => 'Samba',
222            115  => 'Folklore',
223            116  => 'Ballad',
224            117  => 'Power Ballad',
225            118  => 'Rhythmic Soul',
226            119  => 'Freestyle',
227            120  => 'Duet',
228            121  => 'Punk Rock',
229            122  => 'Drum Solo',
230            123  => 'A Cappella',
231            124  => 'Euro-House',
232            125  => 'Dance Hall',
233            126  => 'Goa',
234            127  => 'Drum & Bass',
235            128  => 'Club-House',
236            129  => 'Hardcore',
237            130  => 'Terror',
238            131  => 'Indie',
239            132  => 'BritPop',
240            133  => 'Negerpunk',
241            134  => 'Polsk Punk',
242            135  => 'Beat',
243            136  => 'Christian Gangsta Rap',
244            137  => 'Heavy Metal',
245            138  => 'Black Metal',
246            139  => 'Crossover',
247            140  => 'Contemporary Christian',
248            141  => 'Christian Rock',
249            142  => 'Merengue',
250            143  => 'Salsa',
251            144  => 'Trash Metal',
252            145  => 'Anime',
253            146  => 'JPop',
254            147  => 'Synthpop',
255
256            255  => 'Unknown',
257
258            'CR' => 'Cover',
259            'RX' => 'Remix'
260        );
261
262        static $lookupSCMPX = array ();
263        if ($allow_SCMPX_extended && empty($lookupSCMPX)) {
264            $lookupSCMPX = $lookup;
265            // http://www.geocities.co.jp/SiliconValley-Oakland/3664/alittle.html#GenreExtended
266            // Extended ID3v1 genres invented by SCMPX
267            // Note that 255 "Japanese Anime" conflicts with standard "Unknown"
268            $lookupSCMPX[240] = 'Sacred';
269            $lookupSCMPX[241] = 'Northern Europe';
270            $lookupSCMPX[242] = 'Irish & Scottish';
271            $lookupSCMPX[243] = 'Scotland';
272            $lookupSCMPX[244] = 'Ethnic Europe';
273            $lookupSCMPX[245] = 'Enka';
274            $lookupSCMPX[246] = 'Children\'s Song';
275            $lookupSCMPX[247] = 'Japanese Sky';
276            $lookupSCMPX[248] = 'Japanese Heavy Rock';
277            $lookupSCMPX[249] = 'Japanese Doom Rock';
278            $lookupSCMPX[250] = 'Japanese J-POP';
279            $lookupSCMPX[251] = 'Japanese Seiyu';
280            $lookupSCMPX[252] = 'Japanese Ambient Techno';
281            $lookupSCMPX[253] = 'Japanese Moemoe';
282            $lookupSCMPX[254] = 'Japanese Tokusatsu';
283            //$lookupSCMPX[255] = 'Japanese Anime';
284        }
285
286        return ($allow_SCMPX_extended ? $lookupSCMPX : $lookup);
287    }
288
289
290
291    public static function LookupGenreName($genre_id, $allow_SCMPX_extended=true) {
292   
293        switch ($genre_id) {
294            case 'RX':
295            case 'CR':
296                break;
297            default:
298                $genre_id = intval($genre_id); // to handle 3 or '3' or '03'
299                break;
300        }
301        $lookup = getid3_id3v1::ArrayOfGenres($allow_SCMPX_extended);
302        return (isset($lookup[$genre_id]) ? $lookup[$genre_id] : false);
303    }
304   
305
306    public static function LookupGenreID($genre, $allow_SCMPX_extended=false) {
307       
308        $lookup = getid3_id3v1::ArrayOfGenres($allow_SCMPX_extended);
309        $lower_case_no_space_search_term = strtolower(str_replace(' ', '', $genre));
310        foreach ($lookup as $key => $value) {
311            foreach ($lookup as $key => $value) {
312                if (strtolower(str_replace(' ', '', $value)) == $lower_case_no_space_search_term) {
313                    return $key;
314                }
315            }
316            return false;
317        }
318        return (isset($lookup[$genre_id]) ? $lookup[$genre_id] : false);
319    }
320
321}
322
323
324?>
Note: See TracBrowser for help on using the repository browser.