ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
getid3_id3v1 Class Reference

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

+ Inheritance diagram for getid3_id3v1:
+ 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='')
 
 Analyze ()
 
- Public Member Functions inherited from getid3_handler
 __construct (getID3 $getid3, $call_module=null)
 
 Analyze ()
 
 AnalyzeString ($string)
 
 setStringMode ($string)
 
 saveAttachment ($name, $offset, $length, $image_mime=null)
 

Static Public Member Functions

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

Additional Inherited Members

- Protected Member Functions inherited from getid3_handler
 ftell ()
 
 fread ($bytes)
 
 fseek ($bytes, $whence=SEEK_SET)
 
 feof ()
 
 isDependencyFor ($module)
 
 error ($text)
 
 warning ($text)
 
 notice ($text)
 
- Protected Attributes inherited from getid3_handler
 $getid3
 
 $data_string_flag = false
 
 $data_string = ''
 
 $data_string_position = 0
 
 $data_string_length = 0
 

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

◆ Analyze()

getid3_id3v1::Analyze ( )

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

References $info, cutfield(), getid3_handler\fread(), getid3_handler\fseek(), GenerateID3v1Tag(), getid3_lib\intValueSupported(), LookupGenreID(), and LookupGenreName().

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

◆ ArrayOfGenres() [1/2]

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:

◆ ArrayOfGenres() [2/2]

static getid3_id3v1::ArrayOfGenres (   $allowSCMPXextended = false)
static

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

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

◆ cutfield() [1/2]

getid3_id3v1::cutfield (   $str)

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

Referenced by Analyze(), and getid3_id3v1().

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

◆ cutfield() [2/2]

static getid3_id3v1::cutfield (   $str)
static

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

106  {
107  return trim(substr($str, 0, strcspn($str, "\x00")));
108  }

◆ GenerateID3v1Tag() [1/2]

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

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

References $comment.

Referenced by Analyze(), 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:

◆ GenerateID3v1Tag() [2/2]

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

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

References $comment.

328  {
329  $ID3v1Tag = 'TAG';
330  $ID3v1Tag .= str_pad(trim(substr($title, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
331  $ID3v1Tag .= str_pad(trim(substr($artist, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
332  $ID3v1Tag .= str_pad(trim(substr($album, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
333  $ID3v1Tag .= str_pad(trim(substr($year, 0, 4)), 4, "\x00", STR_PAD_LEFT);
334  if (!empty($track) && ($track > 0) && ($track <= 255)) {
335  $ID3v1Tag .= str_pad(trim(substr($comment, 0, 28)), 28, "\x00", STR_PAD_RIGHT);
336  $ID3v1Tag .= "\x00";
337  if (gettype($track) == 'string') {
338  $track = (int) $track;
339  }
340  $ID3v1Tag .= chr($track);
341  } else {
342  $ID3v1Tag .= str_pad(trim(substr($comment, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
343  }
344  if (($genreid < 0) || ($genreid > 147)) {
345  $genreid = 255; // 'unknown' genre
346  }
347  switch (gettype($genreid)) {
348  case 'string':
349  case 'integer':
350  $ID3v1Tag .= chr(intval($genreid));
351  break;
352  default:
353  $ID3v1Tag .= chr(255); // 'unknown' genre
354  break;
355  }
356 
357  return $ID3v1Tag;
358  }
$comment
Definition: buildRTE.php:83

◆ getid3_id3v1()

getid3_id3v1::getid3_id3v1 ( $fd,
$ThisFileInfo 
)

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

References cutfield(), getid3_handler\fread(), getid3_handler\fseek(), 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='')
fread($bytes)
Definition: getid3.php:1685
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
LookupGenreID($genre, $allowSCMPXextended=false)
LookupGenreName($genreid, $allowSCMPXextended=true)
+ Here is the call graph for this function:

◆ LookupGenreID() [1/2]

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

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

References ArrayOfGenres().

Referenced by Analyze(), 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:

◆ LookupGenreID() [2/2]

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

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

310  {
311  $GenreLookup = self::ArrayOfGenres($allowSCMPXextended);
312  $LowerCaseNoSpaceSearchTerm = strtolower(str_replace(' ', '', $genre));
313  foreach ($GenreLookup as $key => $value) {
314  if (strtolower(str_replace(' ', '', $value)) == $LowerCaseNoSpaceSearchTerm) {
315  return $key;
316  }
317  }
318  return false;
319  }

◆ LookupGenreName() [1/2]

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

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

References ArrayOfGenres().

Referenced by Analyze(), getid3_id3v1(), getid3_id3v2\ParseID3v2GenreString(), getid3_quicktime\QuicktimeParseAtom(), 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:

◆ LookupGenreName() [2/2]

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

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

294  {
295  switch ($genreid) {
296  case 'RX':
297  case 'CR':
298  break;
299  default:
300  if (!is_numeric($genreid)) {
301  return false;
302  }
303  $genreid = intval($genreid); // to handle 3 or '3' or '03'
304  break;
305  }
306  $GenreLookup = self::ArrayOfGenres($allowSCMPXextended);
307  return (isset($GenreLookup[$genreid]) ? $GenreLookup[$genreid] : false);
308  }

◆ StandardiseID3v1GenreName() [1/2]

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:

◆ StandardiseID3v1GenreName() [2/2]

static getid3_id3v1::StandardiseID3v1GenreName (   $OriginalGenre)
static

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

321  {
322  if (($GenreID = self::LookupGenreID($OriginalGenre)) !== false) {
323  return self::LookupGenreName($GenreID);
324  }
325  return $OriginalGenre;
326  }

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