ILIAS  release_4-4 Revision
All Data Structures Namespaces Files Functions Variables Modules Pages
getid3_id3v1 Class Reference

getID3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g // More...

+ Collaboration diagram for getid3_id3v1:

Public Member Functions

 getid3_id3v1 (&$fd, &$ThisFileInfo)
 
 cutfield ($str)
 
 ArrayOfGenres ($allowSCMPXextended=false)
 
 LookupGenreName ($genreid, $allowSCMPXextended=true)
 
 LookupGenreID ($genre, $allowSCMPXextended=false)
 
 StandardiseID3v1GenreName ($OriginalGenre)
 
 GenerateID3v1Tag ($title, $artist, $album, $year, $genreid, $comment, $track='')
 

Detailed Description

getID3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g //

Definition at line 17 of file module.tag.id3v1.php.

Member Function Documentation

◆ ArrayOfGenres()

getid3_id3v1::ArrayOfGenres (   $allowSCMPXextended = false)

Definition at line 103 of file module.tag.id3v1.php.

Referenced by LookupGenreID(), and LookupGenreName().

103  {
104  static $GenreLookup = array(
105  0 => 'Blues',
106  1 => 'Classic Rock',
107  2 => 'Country',
108  3 => 'Dance',
109  4 => 'Disco',
110  5 => 'Funk',
111  6 => 'Grunge',
112  7 => 'Hip-Hop',
113  8 => 'Jazz',
114  9 => 'Metal',
115  10 => 'New Age',
116  11 => 'Oldies',
117  12 => 'Other',
118  13 => 'Pop',
119  14 => 'R&B',
120  15 => 'Rap',
121  16 => 'Reggae',
122  17 => 'Rock',
123  18 => 'Techno',
124  19 => 'Industrial',
125  20 => 'Alternative',
126  21 => 'Ska',
127  22 => 'Death Metal',
128  23 => 'Pranks',
129  24 => 'Soundtrack',
130  25 => 'Euro-Techno',
131  26 => 'Ambient',
132  27 => 'Trip-Hop',
133  28 => 'Vocal',
134  29 => 'Jazz+Funk',
135  30 => 'Fusion',
136  31 => 'Trance',
137  32 => 'Classical',
138  33 => 'Instrumental',
139  34 => 'Acid',
140  35 => 'House',
141  36 => 'Game',
142  37 => 'Sound Clip',
143  38 => 'Gospel',
144  39 => 'Noise',
145  40 => 'Alt. Rock',
146  41 => 'Bass',
147  42 => 'Soul',
148  43 => 'Punk',
149  44 => 'Space',
150  45 => 'Meditative',
151  46 => 'Instrumental Pop',
152  47 => 'Instrumental Rock',
153  48 => 'Ethnic',
154  49 => 'Gothic',
155  50 => 'Darkwave',
156  51 => 'Techno-Industrial',
157  52 => 'Electronic',
158  53 => 'Pop-Folk',
159  54 => 'Eurodance',
160  55 => 'Dream',
161  56 => 'Southern Rock',
162  57 => 'Comedy',
163  58 => 'Cult',
164  59 => 'Gangsta Rap',
165  60 => 'Top 40',
166  61 => 'Christian Rap',
167  62 => 'Pop/Funk',
168  63 => 'Jungle',
169  64 => 'Native American',
170  65 => 'Cabaret',
171  66 => 'New Wave',
172  67 => 'Psychedelic',
173  68 => 'Rave',
174  69 => 'Showtunes',
175  70 => 'Trailer',
176  71 => 'Lo-Fi',
177  72 => 'Tribal',
178  73 => 'Acid Punk',
179  74 => 'Acid Jazz',
180  75 => 'Polka',
181  76 => 'Retro',
182  77 => 'Musical',
183  78 => 'Rock & Roll',
184  79 => 'Hard Rock',
185  80 => 'Folk',
186  81 => 'Folk/Rock',
187  82 => 'National Folk',
188  83 => 'Swing',
189  84 => 'Fast-Fusion',
190  85 => 'Bebob',
191  86 => 'Latin',
192  87 => 'Revival',
193  88 => 'Celtic',
194  89 => 'Bluegrass',
195  90 => 'Avantgarde',
196  91 => 'Gothic Rock',
197  92 => 'Progressive Rock',
198  93 => 'Psychedelic Rock',
199  94 => 'Symphonic Rock',
200  95 => 'Slow Rock',
201  96 => 'Big Band',
202  97 => 'Chorus',
203  98 => 'Easy Listening',
204  99 => 'Acoustic',
205  100 => 'Humour',
206  101 => 'Speech',
207  102 => 'Chanson',
208  103 => 'Opera',
209  104 => 'Chamber Music',
210  105 => 'Sonata',
211  106 => 'Symphony',
212  107 => 'Booty Bass',
213  108 => 'Primus',
214  109 => 'Porn Groove',
215  110 => 'Satire',
216  111 => 'Slow Jam',
217  112 => 'Club',
218  113 => 'Tango',
219  114 => 'Samba',
220  115 => 'Folklore',
221  116 => 'Ballad',
222  117 => 'Power Ballad',
223  118 => 'Rhythmic Soul',
224  119 => 'Freestyle',
225  120 => 'Duet',
226  121 => 'Punk Rock',
227  122 => 'Drum Solo',
228  123 => 'A Cappella',
229  124 => 'Euro-House',
230  125 => 'Dance Hall',
231  126 => 'Goa',
232  127 => 'Drum & Bass',
233  128 => 'Club-House',
234  129 => 'Hardcore',
235  130 => 'Terror',
236  131 => 'Indie',
237  132 => 'BritPop',
238  133 => 'Negerpunk',
239  134 => 'Polsk Punk',
240  135 => 'Beat',
241  136 => 'Christian Gangsta Rap',
242  137 => 'Heavy Metal',
243  138 => 'Black Metal',
244  139 => 'Crossover',
245  140 => 'Contemporary Christian',
246  141 => 'Christian Rock',
247  142 => 'Merengue',
248  143 => 'Salsa',
249  144 => 'Trash Metal',
250  145 => 'Anime',
251  146 => 'JPop',
252  147 => 'Synthpop',
253 
254  255 => 'Unknown',
255 
256  'CR' => 'Cover',
257  'RX' => 'Remix'
258  );
259 
260  static $GenreLookupSCMPX = array();
261  if ($allowSCMPXextended && empty($GenreLookupSCMPX)) {
262  $GenreLookupSCMPX = $GenreLookup;
263  // http://www.geocities.co.jp/SiliconValley-Oakland/3664/alittle.html#GenreExtended
264  // Extended ID3v1 genres invented by SCMPX
265  // Note that 255 "Japanese Anime" conflicts with standard "Unknown"
266  $GenreLookupSCMPX[240] = 'Sacred';
267  $GenreLookupSCMPX[241] = 'Northern Europe';
268  $GenreLookupSCMPX[242] = 'Irish & Scottish';
269  $GenreLookupSCMPX[243] = 'Scotland';
270  $GenreLookupSCMPX[244] = 'Ethnic Europe';
271  $GenreLookupSCMPX[245] = 'Enka';
272  $GenreLookupSCMPX[246] = 'Children\'s Song';
273  $GenreLookupSCMPX[247] = 'Japanese Sky';
274  $GenreLookupSCMPX[248] = 'Japanese Heavy Rock';
275  $GenreLookupSCMPX[249] = 'Japanese Doom Rock';
276  $GenreLookupSCMPX[250] = 'Japanese J-POP';
277  $GenreLookupSCMPX[251] = 'Japanese Seiyu';
278  $GenreLookupSCMPX[252] = 'Japanese Ambient Techno';
279  $GenreLookupSCMPX[253] = 'Japanese Moemoe';
280  $GenreLookupSCMPX[254] = 'Japanese Tokusatsu';
281  //$GenreLookupSCMPX[255] = 'Japanese Anime';
282  }
283 
284  return ($allowSCMPXextended ? $GenreLookupSCMPX : $GenreLookup);
285  }
+ Here is the caller graph for this function:

◆ cutfield()

getid3_id3v1::cutfield (   $str)

Definition at line 99 of file module.tag.id3v1.php.

Referenced by getid3_id3v1().

99  {
100  return trim(substr($str, 0, strcspn($str, "\x00")));
101  }
+ Here is the caller graph for this function:

◆ GenerateID3v1Tag()

getid3_id3v1::GenerateID3v1Tag (   $title,
  $artist,
  $album,
  $year,
  $genreid,
  $comment,
  $track = '' 
)

Definition at line 321 of file module.tag.id3v1.php.

References $comment.

Referenced by getid3_id3v1(), and getid3_write_id3v1\WriteID3v1().

321  {
322  $ID3v1Tag = 'TAG';
323  $ID3v1Tag .= str_pad(trim(substr($title, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
324  $ID3v1Tag .= str_pad(trim(substr($artist, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
325  $ID3v1Tag .= str_pad(trim(substr($album, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
326  $ID3v1Tag .= str_pad(trim(substr($year, 0, 4)), 4, "\x00", STR_PAD_LEFT);
327  if (!empty($track) && ($track > 0) && ($track <= 255)) {
328  $ID3v1Tag .= str_pad(trim(substr($comment, 0, 28)), 28, "\x00", STR_PAD_RIGHT);
329  $ID3v1Tag .= "\x00";
330  if (gettype($track) == 'string') {
331  $track = (int) $track;
332  }
333  $ID3v1Tag .= chr($track);
334  } else {
335  $ID3v1Tag .= str_pad(trim(substr($comment, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
336  }
337  if (($genreid < 0) || ($genreid > 147)) {
338  $genreid = 255; // 'unknown' genre
339  }
340  switch (gettype($genreid)) {
341  case 'string':
342  case 'integer':
343  $ID3v1Tag .= chr(intval($genreid));
344  break;
345  default:
346  $ID3v1Tag .= chr(255); // 'unknown' genre
347  break;
348  }
349 
350  return $ID3v1Tag;
351  }
$comment
Definition: buildRTE.php:83
+ Here is the caller graph for this function:

◆ getid3_id3v1()

getid3_id3v1::getid3_id3v1 ( $fd,
$ThisFileInfo 
)

Definition at line 20 of file module.tag.id3v1.php.

References cutfield(), GenerateID3v1Tag(), LookupGenreID(), and LookupGenreName().

20  {
21 
22  fseek($fd, -256, SEEK_END);
23  $preid3v1 = fread($fd, 128);
24  $id3v1tag = fread($fd, 128);
25 
26  if (substr($id3v1tag, 0, 3) == 'TAG') {
27 
28  $ThisFileInfo['avdataend'] = $ThisFileInfo['filesize'] - 128;
29 
30  $ParsedID3v1['title'] = $this->cutfield(substr($id3v1tag, 3, 30));
31  $ParsedID3v1['artist'] = $this->cutfield(substr($id3v1tag, 33, 30));
32  $ParsedID3v1['album'] = $this->cutfield(substr($id3v1tag, 63, 30));
33  $ParsedID3v1['year'] = $this->cutfield(substr($id3v1tag, 93, 4));
34  $ParsedID3v1['comment'] = substr($id3v1tag, 97, 30); // can't remove nulls yet, track detection depends on them
35  $ParsedID3v1['genreid'] = ord(substr($id3v1tag, 127, 1));
36 
37  // If second-last byte of comment field is null and last byte of comment field is non-null
38  // then this is ID3v1.1 and the comment field is 28 bytes long and the 30th byte is the track number
39  if (($id3v1tag{125} === "\x00") && ($id3v1tag{126} !== "\x00")) {
40  $ParsedID3v1['track'] = ord(substr($ParsedID3v1['comment'], 29, 1));
41  $ParsedID3v1['comment'] = substr($ParsedID3v1['comment'], 0, 28);
42  }
43  $ParsedID3v1['comment'] = $this->cutfield($ParsedID3v1['comment']);
44 
45  $ParsedID3v1['genre'] = $this->LookupGenreName($ParsedID3v1['genreid']);
46  if (!empty($ParsedID3v1['genre'])) {
47  unset($ParsedID3v1['genreid']);
48  }
49  if (empty($ParsedID3v1['genre']) || (@$ParsedID3v1['genre'] == 'Unknown')) {
50  unset($ParsedID3v1['genre']);
51  }
52 
53  foreach ($ParsedID3v1 as $key => $value) {
54  $ParsedID3v1['comments'][$key][0] = $value;
55  }
56 
57  // ID3v1 data is supposed to be padded with NULL characters, but some taggers pad with spaces
58  $GoodFormatID3v1tag = $this->GenerateID3v1Tag(
59  $ParsedID3v1['title'],
60  $ParsedID3v1['artist'],
61  $ParsedID3v1['album'],
62  $ParsedID3v1['year'],
63  $this->LookupGenreID(@$ParsedID3v1['genre']),
64  $ParsedID3v1['comment'],
65  @$ParsedID3v1['track']);
66  $ParsedID3v1['padding_valid'] = true;
67  if ($id3v1tag !== $GoodFormatID3v1tag) {
68  $ParsedID3v1['padding_valid'] = false;
69  $ThisFileInfo['warning'][] = 'Some ID3v1 fields do not use NULL characters for padding';
70  }
71 
72  $ParsedID3v1['tag_offset_end'] = $ThisFileInfo['filesize'];
73  $ParsedID3v1['tag_offset_start'] = $ParsedID3v1['tag_offset_end'] - 128;
74 
75  $ThisFileInfo['id3v1'] = $ParsedID3v1;
76  }
77 
78  if (substr($preid3v1, 0, 3) == 'TAG') {
79  // The way iTunes handles tags is, well, brain-damaged.
80  // It completely ignores v1 if ID3v2 is present.
81  // This goes as far as adding a new v1 tag *even if there already is one*
82 
83  // A suspected double-ID3v1 tag has been detected, but it could be that
84  // the "TAG" identifier is a legitimate part of an APE or Lyrics3 tag
85  if (substr($preid3v1, 96, 8) == 'APETAGEX') {
86  // an APE tag footer was found before the last ID3v1, assume false "TAG" synch
87  } elseif (substr($preid3v1, 119, 6) == 'LYRICS') {
88  // a Lyrics3 tag footer was found before the last ID3v1, assume false "TAG" synch
89  } else {
90  // APE and Lyrics3 footers not found - assume double ID3v1
91  $ThisFileInfo['warning'][] = 'Duplicate ID3v1 tag detected - this has been known to happen with iTunes';
92  $ThisFileInfo['avdataend'] -= 128;
93  }
94  }
95 
96  return true;
97  }
GenerateID3v1Tag($title, $artist, $album, $year, $genreid, $comment, $track='')
LookupGenreID($genre, $allowSCMPXextended=false)
LookupGenreName($genreid, $allowSCMPXextended=true)
+ Here is the call graph for this function:

◆ LookupGenreID()

getid3_id3v1::LookupGenreID (   $genre,
  $allowSCMPXextended = false 
)

Definition at line 300 of file module.tag.id3v1.php.

References ArrayOfGenres().

Referenced by getid3_writetags\FormatDataForID3v1(), getid3_id3v1(), getid3_id3v2\ParseID3v2GenreString(), and StandardiseID3v1GenreName().

300  {
301  $GenreLookup = getid3_id3v1::ArrayOfGenres($allowSCMPXextended);
302  $LowerCaseNoSpaceSearchTerm = strtolower(str_replace(' ', '', $genre));
303  foreach ($GenreLookup as $key => $value) {
304  foreach ($GenreLookup as $key => $value) {
305  if (strtolower(str_replace(' ', '', $value)) == $LowerCaseNoSpaceSearchTerm) {
306  return $key;
307  }
308  }
309  return false;
310  }
311  return (isset($GenreLookup[$genreid]) ? $GenreLookup[$genreid] : false);
312  }
ArrayOfGenres($allowSCMPXextended=false)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ LookupGenreName()

getid3_id3v1::LookupGenreName (   $genreid,
  $allowSCMPXextended = true 
)

Definition at line 287 of file module.tag.id3v1.php.

References ArrayOfGenres().

Referenced by getid3_id3v1(), getid3_id3v2\ParseID3v2GenreString(), and StandardiseID3v1GenreName().

287  {
288  switch ($genreid) {
289  case 'RX':
290  case 'CR':
291  break;
292  default:
293  $genreid = intval($genreid); // to handle 3 or '3' or '03'
294  break;
295  }
296  $GenreLookup = getid3_id3v1::ArrayOfGenres($allowSCMPXextended);
297  return (isset($GenreLookup[$genreid]) ? $GenreLookup[$genreid] : false);
298  }
ArrayOfGenres($allowSCMPXextended=false)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ StandardiseID3v1GenreName()

getid3_id3v1::StandardiseID3v1GenreName (   $OriginalGenre)

Definition at line 314 of file module.tag.id3v1.php.

References LookupGenreID(), and LookupGenreName().

314  {
315  if (($GenreID = getid3_id3v1::LookupGenreID($OriginalGenre)) !== false) {
316  return getid3_id3v1::LookupGenreName($GenreID);
317  }
318  return $OriginalGenre;
319  }
LookupGenreID($genre, $allowSCMPXextended=false)
LookupGenreName($genreid, $allowSCMPXextended=true)
+ Here is the call graph for this function:

The documentation for this class was generated from the following file: