ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
GetId3\Module\Audio\Bonk Class Reference

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

+ Inheritance diagram for GetId3\Module\Audio\Bonk:
+ Collaboration diagram for GetId3\Module\Audio\Bonk:

Public Member Functions

 analyze ()
 
 HandleBonkTags ($BonkTagName)
 
- Public Member Functions inherited from GetId3\Handler\BaseHandler
 __construct (GetId3Core $getid3, $call_module=null)
 
 analyze ()
 Analyze from file pointer. More...
 
 AnalyzeString (&$string)
 Analyze from string instead. More...
 
 saveAttachment (&$ThisFileInfoIndex, $filename, $offset, $length)
 

Static Public Member Functions

static BonkIsValidTagName ($PossibleBonkTag, $ignorecase=false)
 @staticvar array $BonkIsValidTagName More...
 

Additional Inherited Members

- Protected Member Functions inherited from GetId3\Handler\BaseHandler
 ftell ()
 
 fread ($bytes)
 
 fseek ($bytes, $whence=SEEK_SET)
 
 feof ()
 
 isDependencyFor ($module)
 
 error ($text)
 
 warning ($text)
 
- Protected Attributes inherited from GetId3\Handler\BaseHandler
 $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 //.

module for analyzing BONK audio files

Author
James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g http://www.getid3.org

Definition at line 31 of file Bonk.php.

Member Function Documentation

◆ analyze()

GetId3\Module\Audio\Bonk::analyze ( )
Returns
boolean

Reimplemented from GetId3\Handler\BaseHandler.

Definition at line 37 of file Bonk.php.

38 {
39 $info = &$this->getid3->info;
40
41 // shortcut
42 $info['bonk'] = array();
43 $thisfile_bonk = &$info['bonk'];
44
45 $thisfile_bonk['dataoffset'] = $info['avdataoffset'];
46 $thisfile_bonk['dataend'] = $info['avdataend'];
47
48 if (!Helper::intValueSupported($thisfile_bonk['dataend'])) {
49
50 $info['warning'][] = 'Unable to parse BONK file from end (v0.6+ preferred method) because PHP filesystem functions only support up to '.round(PHP_INT_MAX / 1073741824).'GB';
51
52 } else {
53
54 // scan-from-end method, for v0.6 and higher
55 fseek($this->getid3->fp, $thisfile_bonk['dataend'] - 8, SEEK_SET);
56 $PossibleBonkTag = fread($this->getid3->fp, 8);
57 while ($this->BonkIsValidTagName(substr($PossibleBonkTag, 4, 4), true)) {
58 $BonkTagSize = Helper::LittleEndian2Int(substr($PossibleBonkTag, 0, 4));
59 fseek($this->getid3->fp, 0 - $BonkTagSize, SEEK_CUR);
60 $BonkTagOffset = ftell($this->getid3->fp);
61 $TagHeaderTest = fread($this->getid3->fp, 5);
62 if (($TagHeaderTest{0} != "\x00") || (substr($PossibleBonkTag, 4, 4) != strtolower(substr($PossibleBonkTag, 4, 4)))) {
63 $info['error'][] = 'Expecting "'.Helper::PrintHexBytes("\x00".strtoupper(substr($PossibleBonkTag, 4, 4))).'" at offset '.$BonkTagOffset.', found "'.Helper::PrintHexBytes($TagHeaderTest).'"';
64
65 return false;
66 }
67 $BonkTagName = substr($TagHeaderTest, 1, 4);
68
69 $thisfile_bonk[$BonkTagName]['size'] = $BonkTagSize;
70 $thisfile_bonk[$BonkTagName]['offset'] = $BonkTagOffset;
71 $this->HandleBonkTags($BonkTagName);
72 $NextTagEndOffset = $BonkTagOffset - 8;
73 if ($NextTagEndOffset < $thisfile_bonk['dataoffset']) {
74 if (empty($info['audio']['encoder'])) {
75 $info['audio']['encoder'] = 'Extended BONK v0.9+';
76 }
77
78 return true;
79 }
80 fseek($this->getid3->fp, $NextTagEndOffset, SEEK_SET);
81 $PossibleBonkTag = fread($this->getid3->fp, 8);
82 }
83
84 }
85
86 // seek-from-beginning method for v0.4 and v0.5
87 if (empty($thisfile_bonk['BONK'])) {
88 fseek($this->getid3->fp, $thisfile_bonk['dataoffset'], SEEK_SET);
89 do {
90 $TagHeaderTest = fread($this->getid3->fp, 5);
91 switch ($TagHeaderTest) {
92 case "\x00".'BONK':
93 if (empty($info['audio']['encoder'])) {
94 $info['audio']['encoder'] = 'BONK v0.4';
95 }
96 break;
97
98 case "\x00".'INFO':
99 $info['audio']['encoder'] = 'Extended BONK v0.5';
100 break;
101
102 default:
103 break 2;
104 }
105 $BonkTagName = substr($TagHeaderTest, 1, 4);
106 $thisfile_bonk[$BonkTagName]['size'] = $thisfile_bonk['dataend'] - $thisfile_bonk['dataoffset'];
107 $thisfile_bonk[$BonkTagName]['offset'] = $thisfile_bonk['dataoffset'];
108 $this->HandleBonkTags($BonkTagName);
109
110 } while (true);
111 }
112
113 // parse META block for v0.6 - v0.8
114 if (empty($thisfile_bonk['INFO']) && isset($thisfile_bonk['META']['tags']['info'])) {
115 fseek($this->getid3->fp, $thisfile_bonk['META']['tags']['info'], SEEK_SET);
116 $TagHeaderTest = fread($this->getid3->fp, 5);
117 if ($TagHeaderTest == "\x00".'INFO') {
118 $info['audio']['encoder'] = 'Extended BONK v0.6 - v0.8';
119
120 $BonkTagName = substr($TagHeaderTest, 1, 4);
121 $thisfile_bonk[$BonkTagName]['size'] = $thisfile_bonk['dataend'] - $thisfile_bonk['dataoffset'];
122 $thisfile_bonk[$BonkTagName]['offset'] = $thisfile_bonk['dataoffset'];
123 $this->HandleBonkTags($BonkTagName);
124 }
125 }
126
127 if (empty($info['audio']['encoder'])) {
128 $info['audio']['encoder'] = 'Extended BONK v0.9+';
129 }
130 if (empty($thisfile_bonk['BONK'])) {
131 unset($info['bonk']);
132 }
133
134 return true;
135
136 }
fseek($bytes, $whence=SEEK_SET)
static intValueSupported($num)
@staticvar null $hasINT64
Definition: Helper.php:130
static LittleEndian2Int($byteword, $signed=false)
Definition: Helper.php:413
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
Definition: Helper.php:36
static BonkIsValidTagName($PossibleBonkTag, $ignorecase=false)
@staticvar array $BonkIsValidTagName
Definition: Bonk.php:249
HandleBonkTags($BonkTagName)
Definition: Bonk.php:142
$info
Definition: example_052.php:80

References $info, GetId3\Module\Audio\Bonk\BonkIsValidTagName(), GetId3\Handler\BaseHandler\fread(), GetId3\Handler\BaseHandler\fseek(), GetId3\Handler\BaseHandler\ftell(), GetId3\Module\Audio\Bonk\HandleBonkTags(), GetId3\Lib\Helper\intValueSupported(), GetId3\Lib\Helper\LittleEndian2Int(), and GetId3\Lib\Helper\PrintHexBytes().

+ Here is the call graph for this function:

◆ BonkIsValidTagName()

static GetId3\Module\Audio\Bonk::BonkIsValidTagName (   $PossibleBonkTag,
  $ignorecase = false 
)
static

@staticvar array $BonkIsValidTagName

Parameters
type$PossibleBonkTag
type$ignorecase
Returns
boolean

Definition at line 249 of file Bonk.php.

250 {
251 static $BonkIsValidTagName = array('BONK', 'INFO', ' ID3', 'META');
252 foreach ($BonkIsValidTagName as $validtagname) {
253 if ($validtagname == $PossibleBonkTag) {
254 return true;
255 } elseif ($ignorecase && (strtolower($validtagname) == strtolower($PossibleBonkTag))) {
256 return true;
257 }
258 }
259
260 return false;
261 }

Referenced by GetId3\Module\Audio\Bonk\analyze(), and GetId3\Module\Audio\Bonk\HandleBonkTags().

+ Here is the caller graph for this function:

◆ HandleBonkTags()

GetId3\Module\Audio\Bonk::HandleBonkTags (   $BonkTagName)
Parameters
type$BonkTagName

Definition at line 142 of file Bonk.php.

143 {
144 $info = &$this->getid3->info;
145 switch ($BonkTagName) {
146 case 'BONK':
147 // shortcut
148 $thisfile_bonk_BONK = &$info['bonk']['BONK'];
149
150 $BonkData = "\x00".'BONK'.fread($this->getid3->fp, 17);
151 $thisfile_bonk_BONK['version'] = Helper::LittleEndian2Int(substr($BonkData, 5, 1));
152 $thisfile_bonk_BONK['number_samples'] = Helper::LittleEndian2Int(substr($BonkData, 6, 4));
153 $thisfile_bonk_BONK['sample_rate'] = Helper::LittleEndian2Int(substr($BonkData, 10, 4));
154
155 $thisfile_bonk_BONK['channels'] = Helper::LittleEndian2Int(substr($BonkData, 14, 1));
156 $thisfile_bonk_BONK['lossless'] = (bool) Helper::LittleEndian2Int(substr($BonkData, 15, 1));
157 $thisfile_bonk_BONK['joint_stereo'] = (bool) Helper::LittleEndian2Int(substr($BonkData, 16, 1));
158 $thisfile_bonk_BONK['number_taps'] = Helper::LittleEndian2Int(substr($BonkData, 17, 2));
159 $thisfile_bonk_BONK['downsampling_ratio'] = Helper::LittleEndian2Int(substr($BonkData, 19, 1));
160 $thisfile_bonk_BONK['samples_per_packet'] = Helper::LittleEndian2Int(substr($BonkData, 20, 2));
161
162 $info['avdataoffset'] = $thisfile_bonk_BONK['offset'] + 5 + 17;
163 $info['avdataend'] = $thisfile_bonk_BONK['offset'] + $thisfile_bonk_BONK['size'];
164
165 $info['fileformat'] = 'bonk';
166 $info['audio']['dataformat'] = 'bonk';
167 $info['audio']['bitrate_mode'] = 'vbr'; // assumed
168 $info['audio']['channels'] = $thisfile_bonk_BONK['channels'];
169 $info['audio']['sample_rate'] = $thisfile_bonk_BONK['sample_rate'];
170 $info['audio']['channelmode'] = ($thisfile_bonk_BONK['joint_stereo'] ? 'joint stereo' : 'stereo');
171 $info['audio']['lossless'] = $thisfile_bonk_BONK['lossless'];
172 $info['audio']['codec'] = 'bonk';
173
174 $info['playtime_seconds'] = $thisfile_bonk_BONK['number_samples'] / ($thisfile_bonk_BONK['sample_rate'] * $thisfile_bonk_BONK['channels']);
175 if ($info['playtime_seconds'] > 0) {
176 $info['audio']['bitrate'] = (($info['bonk']['dataend'] - $info['bonk']['dataoffset']) * 8) / $info['playtime_seconds'];
177 }
178 break;
179
180 case 'INFO':
181 // shortcut
182 $thisfile_bonk_INFO = &$info['bonk']['INFO'];
183
184 $thisfile_bonk_INFO['version'] = Helper::LittleEndian2Int(fread($this->getid3->fp, 1));
185 $thisfile_bonk_INFO['entries_count'] = 0;
186 $NextInfoDataPair = fread($this->getid3->fp, 5);
187 if (!$this->BonkIsValidTagName(substr($NextInfoDataPair, 1, 4))) {
188 while (!feof($this->getid3->fp)) {
189 //$CurrentSeekInfo['offset'] = GetId3_lib::LittleEndian2Int(substr($NextInfoDataPair, 0, 4));
190 //$CurrentSeekInfo['nextbit'] = GetId3_lib::LittleEndian2Int(substr($NextInfoDataPair, 4, 1));
191 //$thisfile_bonk_INFO[] = $CurrentSeekInfo;
192
193 $NextInfoDataPair = fread($this->getid3->fp, 5);
194 if ($this->BonkIsValidTagName(substr($NextInfoDataPair, 1, 4))) {
195 fseek($this->getid3->fp, -5, SEEK_CUR);
196 break;
197 }
198 $thisfile_bonk_INFO['entries_count']++;
199 }
200 }
201 break;
202
203 case 'META':
204 $BonkData = "\x00".'META'.fread($this->getid3->fp, $info['bonk']['META']['size'] - 5);
205 $info['bonk']['META']['version'] = Helper::LittleEndian2Int(substr($BonkData, 5, 1));
206
207 $MetaTagEntries = floor(((strlen($BonkData) - 8) - 6) / 8); // BonkData - xxxxmeta - ØMETA
208 $offset = 6;
209 for ($i = 0; $i < $MetaTagEntries; $i++) {
210 $MetaEntryTagName = substr($BonkData, $offset, 4);
211 $offset += 4;
212 $MetaEntryTagOffset = Helper::LittleEndian2Int(substr($BonkData, $offset, 4));
213 $offset += 4;
214 $info['bonk']['META']['tags'][$MetaEntryTagName] = $MetaEntryTagOffset;
215 }
216 break;
217
218 case ' ID3':
219 $info['audio']['encoder'] = 'Extended BONK v0.9+';
220
221 // ID3v2 checking is optional
222 if (class_exists('GetId3\\Module\\Tag\\Id3v2')) {
223 $getid3_temp = new GetId3Core();
224 $getid3_temp->openfile($this->getid3->filename);
225 $getid3_id3v2 = new Id3v2($getid3_temp);
226 $getid3_id3v2->StartingOffset = $info['bonk'][' ID3']['offset'] + 2;
227 $info['bonk'][' ID3']['valid'] = $getid3_id3v2->analyze();
228 if ($info['bonk'][' ID3']['valid']) {
229 $info['id3v2'] = $getid3_temp->info['id3v2'];
230 }
231 unset($getid3_temp, $getid3_id3v2);
232 }
233 break;
234
235 default:
236 $info['warning'][] = 'Unexpected Bonk tag "'.$BonkTagName.'" at offset '.$info['bonk'][$BonkTagName]['offset'];
237 break;
238
239 }
240 }

References $info, GetId3\Module\Audio\Bonk\BonkIsValidTagName(), GetId3\Handler\BaseHandler\feof(), GetId3\Handler\BaseHandler\fread(), GetId3\Handler\BaseHandler\fseek(), and GetId3\Lib\Helper\LittleEndian2Int().

Referenced by GetId3\Module\Audio\Bonk\analyze().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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