Просмотр файла system/inc/library/class_mp3/class_mp3.php

Размер файла: 65.16Kb
  1. <?
  2. /**
  3. * PEAR, the PHP Extension and Application Repository
  4. *
  5. * PEAR class and PEAR_Error class
  6. *
  7. * PHP versions 4 and 5
  8. *
  9. * @category pear
  10. * @package PEAR
  11. * @author Sterling Hughes <sterling@php.net>
  12. * @author Stig Bakken <ssb@php.net>
  13. * @Authors: Sandy McArthur Jr. <Leknor@Leknor.com>
  14. * @author Tomas V.V.Cox <cox@idecnet.com>
  15. * @author Greg Beaver <cellog@php.net>
  16. * @copyright 1997-2010 The Authors
  17. * @license http://opensource.org/licenses/bsd-license.php New BSD License
  18. * @version CVS: $Id: PEAR.php 313023 2011-07-06 19:17:11Z dufuz $
  19. * @link http://pear.php.net/package/PEAR
  20. * @since File available since Release 0.1
  21. */
  22.  
  23. /**#@+
  24. * ERROR constants
  25. */
  26. define('PEAR_ERROR_RETURN', 1);
  27. define('PEAR_ERROR_PRINT', 2);
  28. define('PEAR_ERROR_TRIGGER', 4);
  29. define('PEAR_ERROR_DIE', 8);
  30. define('PEAR_ERROR_CALLBACK', 16);
  31. /**
  32. * WARNING: obsolete
  33. * @deprecated
  34. */
  35. define('PEAR_ERROR_EXCEPTION', 32);
  36. /**#@-*/
  37. define('PEAR_ZE2', (function_exists('version_compare') &&
  38. version_compare(zend_version(), "2-dev", "ge")));
  39.  
  40. if (substr(PHP_OS, 0, 3) == 'WIN') {
  41. define('OS_WINDOWS', true);
  42. define('OS_UNIX', false);
  43. define('PEAR_OS', 'Windows');
  44. } else {
  45. define('OS_WINDOWS', false);
  46. define('OS_UNIX', true);
  47. define('PEAR_OS', 'Unix'); // blatant assumption
  48. }
  49.  
  50. $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
  51. $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
  52. $GLOBALS['_PEAR_destructor_object_list'] = array();
  53. $GLOBALS['_PEAR_shutdown_funcs'] = array();
  54. $GLOBALS['_PEAR_error_handler_stack'] = array();
  55.  
  56. @ini_set('track_errors', true);
  57.  
  58. /**
  59. * Base class for other PEAR classes. Provides rudimentary
  60. * emulation of destructors.
  61. *
  62. * If you want a destructor in your class, inherit PEAR and make a
  63. * destructor method called _yourclassname (same name as the
  64. * constructor, but with a "_" prefix). Also, in your constructor you
  65. * have to call the PEAR constructor: $this->PEAR();.
  66. * The destructor method will be called without parameters. Note that
  67. * at in some SAPI implementations (such as Apache), any output during
  68. * the request shutdown (in which destructors are called) seems to be
  69. * discarded. If you need to get any debug information from your
  70. * destructor, use error_log(), syslog() or something similar.
  71. *
  72. * IMPORTANT! To use the emulated destructors you need to create the
  73. * objects by reference: $obj =& new PEAR_child;
  74. *
  75. * @category pear
  76. * @package PEAR
  77. * @author Stig Bakken <ssb@php.net>
  78. * @author Tomas V.V. Cox <cox@idecnet.com>
  79. * @author Greg Beaver <cellog@php.net>
  80. * @copyright 1997-2006 The PHP Group
  81. * @license http://opensource.org/licenses/bsd-license.php New BSD License
  82. * @version Release: 1.9.4
  83. * @link http://pear.php.net/package/PEAR
  84. * @see PEAR_Error
  85. * @since Class available since PHP 4.0.2
  86. * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear
  87. */
  88. class PEAR
  89. {
  90. /**
  91. * Whether to enable internal debug messages.
  92. *
  93. * @var bool
  94. * @access private
  95. */
  96. var $_debug = false;
  97.  
  98. /**
  99. * Default error mode for this object.
  100. *
  101. * @var int
  102. * @access private
  103. */
  104. var $_default_error_mode = null;
  105.  
  106. /**
  107. * Default error options used for this object when error mode
  108. * is PEAR_ERROR_TRIGGER.
  109. *
  110. * @var int
  111. * @access private
  112. */
  113. var $_default_error_options = null;
  114.  
  115. /**
  116. * Default error handler (callback) for this object, if error mode is
  117. * PEAR_ERROR_CALLBACK.
  118. *
  119. * @var string
  120. * @access private
  121. */
  122. var $_default_error_handler = '';
  123.  
  124. /**
  125. * Which class to use for error objects.
  126. *
  127. * @var string
  128. * @access private
  129. */
  130. var $_error_class = 'PEAR_Error';
  131.  
  132. /**
  133. * An array of expected errors.
  134. *
  135. * @var array
  136. * @access private
  137. */
  138. var $_expected_errors = array();
  139.  
  140. /**
  141. * Constructor. Registers this object in
  142. * $_PEAR_destructor_object_list for destructor emulation if a
  143. * destructor object exists.
  144. *
  145. * @param string $error_class (optional) which class to use for
  146. * error objects, defaults to PEAR_Error.
  147. * @access public
  148. * @return void
  149. */
  150. function PEAR($error_class = null)
  151. {
  152. $classname = strtolower(get_class($this));
  153. if ($this->_debug) {
  154. print "PEAR constructor called, class=$classname\n";
  155. }
  156.  
  157. if ($error_class !== null) {
  158. $this->_error_class = $error_class;
  159. }
  160.  
  161. while ($classname && strcasecmp($classname, "pear")) {
  162. $destructor = "_$classname";
  163. if (method_exists($this, $destructor)) {
  164. global $_PEAR_destructor_object_list;
  165. $_PEAR_destructor_object_list[] = &$this;
  166. if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
  167. register_shutdown_function("_PEAR_call_destructors");
  168. $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
  169. }
  170. break;
  171. } else {
  172. $classname = get_parent_class($classname);
  173. }
  174. }
  175. }
  176.  
  177. /**
  178. * Destructor (the emulated type of...). Does nothing right now,
  179. * but is included for forward compatibility, so subclass
  180. * destructors should always call it.
  181. *
  182. * See the note in the class desciption about output from
  183. * destructors.
  184. *
  185. * @access public
  186. * @return void
  187. */
  188. function _PEAR() {
  189. if ($this->_debug) {
  190. printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
  191. }
  192. }
  193.  
  194. /**
  195. * If you have a class that's mostly/entirely static, and you need static
  196. * properties, you can use this method to simulate them. Eg. in your method(s)
  197. * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
  198. * You MUST use a reference, or they will not persist!
  199. *
  200. * @access public
  201. * @param string $class The calling classname, to prevent clashes
  202. * @param string $var The variable to retrieve.
  203. * @return mixed A reference to the variable. If not set it will be
  204. * auto initialised to NULL.
  205. */
  206. function &getStaticProperty($class, $var)
  207. {
  208. static $properties;
  209. if (!isset($properties[$class])) {
  210. $properties[$class] = array();
  211. }
  212.  
  213. if (!array_key_exists($var, $properties[$class])) {
  214. $properties[$class][$var] = null;
  215. }
  216.  
  217. return $properties[$class][$var];
  218. }
  219.  
  220. /**
  221. * Use this function to register a shutdown method for static
  222. * classes.
  223. *
  224. * @access public
  225. * @param mixed $func The function name (or array of class/method) to call
  226. * @param mixed $args The arguments to pass to the function
  227. * @return void
  228. */
  229. function registerShutdownFunc($func, $args = array())
  230. {
  231. // if we are called statically, there is a potential
  232. // that no shutdown func is registered. Bug #6445
  233. if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
  234. register_shutdown_function("_PEAR_call_destructors");
  235. $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
  236. }
  237. $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
  238. }
  239.  
  240. /**
  241. * Tell whether a value is a PEAR error.
  242. *
  243. * @param mixed $data the value to test
  244. * @param int $code if $data is an error object, return true
  245. * only if $code is a string and
  246. * $obj->getMessage() == $code or
  247. * $code is an integer and $obj->getCode() == $code
  248. * @access public
  249. * @return bool true if parameter is an error
  250. */
  251. function isError($data, $code = null)
  252. {
  253. if (!is_a($data, 'PEAR_Error')) {
  254. return false;
  255. }
  256.  
  257. if (is_null($code)) {
  258. return true;
  259. } elseif (is_string($code)) {
  260. return $data->getMessage() == $code;
  261. }
  262.  
  263. return $data->getCode() == $code;
  264. }
  265.  
  266. /**
  267. * Sets how errors generated by this object should be handled.
  268. * Can be invoked both in objects and statically. If called
  269. * statically, setErrorHandling sets the default behaviour for all
  270. * PEAR objects. If called in an object, setErrorHandling sets
  271. * the default behaviour for that object.
  272. *
  273. * @param int $mode
  274. * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
  275. * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
  276. * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
  277. *
  278. * @param mixed $options
  279. * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
  280. * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
  281. *
  282. * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
  283. * to be the callback function or method. A callback
  284. * function is a string with the name of the function, a
  285. * callback method is an array of two elements: the element
  286. * at index 0 is the object, and the element at index 1 is
  287. * the name of the method to call in the object.
  288. *
  289. * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
  290. * a printf format string used when printing the error
  291. * message.
  292. *
  293. * @access public
  294. * @return void
  295. * @see PEAR_ERROR_RETURN
  296. * @see PEAR_ERROR_PRINT
  297. * @see PEAR_ERROR_TRIGGER
  298. * @see PEAR_ERROR_DIE
  299. * @see PEAR_ERROR_CALLBACK
  300. * @see PEAR_ERROR_EXCEPTION
  301. *
  302. * @since PHP 4.0.5
  303. */
  304. function setErrorHandling($mode = null, $options = null)
  305. {
  306. if (isset($this) && is_a($this, 'PEAR')) {
  307. $setmode = &$this->_default_error_mode;
  308. $setoptions = &$this->_default_error_options;
  309. } else {
  310. $setmode = &$GLOBALS['_PEAR_default_error_mode'];
  311. $setoptions = &$GLOBALS['_PEAR_default_error_options'];
  312. }
  313.  
  314. switch ($mode) {
  315. case PEAR_ERROR_EXCEPTION:
  316. case PEAR_ERROR_RETURN:
  317. case PEAR_ERROR_PRINT:
  318. case PEAR_ERROR_TRIGGER:
  319. case PEAR_ERROR_DIE:
  320. case null:
  321. $setmode = $mode;
  322. $setoptions = $options;
  323. break;
  324.  
  325. case PEAR_ERROR_CALLBACK:
  326. $setmode = $mode;
  327. // class/object method callback
  328. if (is_callable($options)) {
  329. $setoptions = $options;
  330. } else {
  331. trigger_error("invalid error callback", E_USER_WARNING);
  332. }
  333. break;
  334.  
  335. default:
  336. trigger_error("invalid error mode", E_USER_WARNING);
  337. break;
  338. }
  339. }
  340.  
  341. /**
  342. * This method is used to tell which errors you expect to get.
  343. * Expected errors are always returned with error mode
  344. * PEAR_ERROR_RETURN. Expected error codes are stored in a stack,
  345. * and this method pushes a new element onto it. The list of
  346. * expected errors are in effect until they are popped off the
  347. * stack with the popExpect() method.
  348. *
  349. * Note that this method can not be called statically
  350. *
  351. * @param mixed $code a single error code or an array of error codes to expect
  352. *
  353. * @return int the new depth of the "expected errors" stack
  354. * @access public
  355. */
  356. function expectError($code = '*')
  357. {
  358. if (is_array($code)) {
  359. array_push($this->_expected_errors, $code);
  360. } else {
  361. array_push($this->_expected_errors, array($code));
  362. }
  363. return count($this->_expected_errors);
  364. }
  365.  
  366. /**
  367. * This method pops one element off the expected error codes
  368. * stack.
  369. *
  370. * @return array the list of error codes that were popped
  371. */
  372. function popExpect()
  373. {
  374. return array_pop($this->_expected_errors);
  375. }
  376.  
  377. /**
  378. * This method checks unsets an error code if available
  379. *
  380. * @param mixed error code
  381. * @return bool true if the error code was unset, false otherwise
  382. * @access private
  383. * @since PHP 4.3.0
  384. */
  385. function _checkDelExpect($error_code)
  386. {
  387. $deleted = false;
  388. foreach ($this->_expected_errors as $key => $error_array) {
  389. if (in_array($error_code, $error_array)) {
  390. unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
  391. $deleted = true;
  392. }
  393.  
  394. // clean up empty arrays
  395. if (0 == count($this->_expected_errors[$key])) {
  396. unset($this->_expected_errors[$key]);
  397. }
  398. }
  399.  
  400. return $deleted;
  401. }
  402.  
  403. /**
  404. * This method deletes all occurences of the specified element from
  405. * the expected error codes stack.
  406. *
  407. * @param mixed $error_code error code that should be deleted
  408. * @return mixed list of error codes that were deleted or error
  409. * @access public
  410. * @since PHP 4.3.0
  411. */
  412. function delExpect($error_code)
  413. {
  414. $deleted = false;
  415. if ((is_array($error_code) && (0 != count($error_code)))) {
  416. // $error_code is a non-empty array here; we walk through it trying
  417. // to unset all values
  418. foreach ($error_code as $key => $error) {
  419. $deleted = $this->_checkDelExpect($error) ? true : false;
  420. }
  421.  
  422. return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
  423. } elseif (!empty($error_code)) {
  424. // $error_code comes alone, trying to unset it
  425. if ($this->_checkDelExpect($error_code)) {
  426. return true;
  427. }
  428.  
  429. return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
  430. }
  431.  
  432. // $error_code is empty
  433. return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
  434. }
  435.  
  436. /**
  437. * This method is a wrapper that returns an instance of the
  438. * configured error class with this object's default error
  439. * handling applied. If the $mode and $options parameters are not
  440. * specified, the object's defaults are used.
  441. *
  442. * @param mixed $message a text error message or a PEAR error object
  443. *
  444. * @param int $code a numeric error code (it is up to your class
  445. * to define these if you want to use codes)
  446. *
  447. * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
  448. * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
  449. * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
  450. *
  451. * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
  452. * specifies the PHP-internal error level (one of
  453. * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
  454. * If $mode is PEAR_ERROR_CALLBACK, this
  455. * parameter specifies the callback function or
  456. * method. In other error modes this parameter
  457. * is ignored.
  458. *
  459. * @param string $userinfo If you need to pass along for example debug
  460. * information, this parameter is meant for that.
  461. *
  462. * @param string $error_class The returned error object will be
  463. * instantiated from this class, if specified.
  464. *
  465. * @param bool $skipmsg If true, raiseError will only pass error codes,
  466. * the error message parameter will be dropped.
  467. *
  468. * @access public
  469. * @return object a PEAR error object
  470. * @see PEAR::setErrorHandling
  471. * @since PHP 4.0.5
  472. */
  473. function &raiseError($message = null,
  474. $code = null,
  475. $mode = null,
  476. $options = null,
  477. $userinfo = null,
  478. $error_class = null,
  479. $skipmsg = false)
  480. {
  481. // The error is yet a PEAR error object
  482. if (is_object($message)) {
  483. $code = $message->getCode();
  484. $userinfo = $message->getUserInfo();
  485. $error_class = $message->getType();
  486. $message->error_message_prefix = '';
  487. $message = $message->getMessage();
  488. }
  489.  
  490. if (
  491. isset($this) &&
  492. isset($this->_expected_errors) &&
  493. count($this->_expected_errors) > 0 &&
  494. count($exp = end($this->_expected_errors))
  495. ) {
  496. if ($exp[0] == "*" ||
  497. (is_int(reset($exp)) && in_array($code, $exp)) ||
  498. (is_string(reset($exp)) && in_array($message, $exp))
  499. ) {
  500. $mode = PEAR_ERROR_RETURN;
  501. }
  502. }
  503.  
  504. // No mode given, try global ones
  505. if ($mode === null) {
  506. // Class error handler
  507. if (isset($this) && isset($this->_default_error_mode)) {
  508. $mode = $this->_default_error_mode;
  509. $options = $this->_default_error_options;
  510. // Global error handler
  511. } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
  512. $mode = $GLOBALS['_PEAR_default_error_mode'];
  513. $options = $GLOBALS['_PEAR_default_error_options'];
  514. }
  515. }
  516.  
  517. if ($error_class !== null) {
  518. $ec = $error_class;
  519. } elseif (isset($this) && isset($this->_error_class)) {
  520. $ec = $this->_error_class;
  521. } else {
  522. $ec = 'PEAR_Error';
  523. }
  524.  
  525. if (intval(PHP_VERSION) < 5) {
  526. // little non-eval hack to fix bug #12147
  527. include 'PEAR/FixPHP5PEARWarnings.php';
  528. return $a;
  529. }
  530.  
  531. if ($skipmsg) {
  532. $a = new $ec($code, $mode, $options, $userinfo);
  533. } else {
  534. $a = new $ec($message, $code, $mode, $options, $userinfo);
  535. }
  536.  
  537. return $a;
  538. }
  539.  
  540. /**
  541. * Simpler form of raiseError with fewer options. In most cases
  542. * message, code and userinfo are enough.
  543. *
  544. * @param mixed $message a text error message or a PEAR error object
  545. *
  546. * @param int $code a numeric error code (it is up to your class
  547. * to define these if you want to use codes)
  548. *
  549. * @param string $userinfo If you need to pass along for example debug
  550. * information, this parameter is meant for that.
  551. *
  552. * @access public
  553. * @return object a PEAR error object
  554. * @see PEAR::raiseError
  555. */
  556. function &throwError($message = null, $code = null, $userinfo = null)
  557. {
  558. if (isset($this) && is_a($this, 'PEAR')) {
  559. $a = &$this->raiseError($message, $code, null, null, $userinfo);
  560. return $a;
  561. }
  562.  
  563. $a = &PEAR::raiseError($message, $code, null, null, $userinfo);
  564. return $a;
  565. }
  566.  
  567. function staticPushErrorHandling($mode, $options = null)
  568. {
  569. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  570. $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
  571. $def_options = &$GLOBALS['_PEAR_default_error_options'];
  572. $stack[] = array($def_mode, $def_options);
  573. switch ($mode) {
  574. case PEAR_ERROR_EXCEPTION:
  575. case PEAR_ERROR_RETURN:
  576. case PEAR_ERROR_PRINT:
  577. case PEAR_ERROR_TRIGGER:
  578. case PEAR_ERROR_DIE:
  579. case null:
  580. $def_mode = $mode;
  581. $def_options = $options;
  582. break;
  583.  
  584. case PEAR_ERROR_CALLBACK:
  585. $def_mode = $mode;
  586. // class/object method callback
  587. if (is_callable($options)) {
  588. $def_options = $options;
  589. } else {
  590. trigger_error("invalid error callback", E_USER_WARNING);
  591. }
  592. break;
  593.  
  594. default:
  595. trigger_error("invalid error mode", E_USER_WARNING);
  596. break;
  597. }
  598. $stack[] = array($mode, $options);
  599. return true;
  600. }
  601.  
  602. function staticPopErrorHandling()
  603. {
  604. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  605. $setmode = &$GLOBALS['_PEAR_default_error_mode'];
  606. $setoptions = &$GLOBALS['_PEAR_default_error_options'];
  607. array_pop($stack);
  608. list($mode, $options) = $stack[sizeof($stack) - 1];
  609. array_pop($stack);
  610. switch ($mode) {
  611. case PEAR_ERROR_EXCEPTION:
  612. case PEAR_ERROR_RETURN:
  613. case PEAR_ERROR_PRINT:
  614. case PEAR_ERROR_TRIGGER:
  615. case PEAR_ERROR_DIE:
  616. case null:
  617. $setmode = $mode;
  618. $setoptions = $options;
  619. break;
  620.  
  621. case PEAR_ERROR_CALLBACK:
  622. $setmode = $mode;
  623. // class/object method callback
  624. if (is_callable($options)) {
  625. $setoptions = $options;
  626. } else {
  627. trigger_error("invalid error callback", E_USER_WARNING);
  628. }
  629. break;
  630.  
  631. default:
  632. trigger_error("invalid error mode", E_USER_WARNING);
  633. break;
  634. }
  635. return true;
  636. }
  637.  
  638. /**
  639. * Push a new error handler on top of the error handler options stack. With this
  640. * you can easily override the actual error handler for some code and restore
  641. * it later with popErrorHandling.
  642. *
  643. * @param mixed $mode (same as setErrorHandling)
  644. * @param mixed $options (same as setErrorHandling)
  645. *
  646. * @return bool Always true
  647. *
  648. * @see PEAR::setErrorHandling
  649. */
  650. function pushErrorHandling($mode, $options = null)
  651. {
  652. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  653. if (isset($this) && is_a($this, 'PEAR')) {
  654. $def_mode = &$this->_default_error_mode;
  655. $def_options = &$this->_default_error_options;
  656. } else {
  657. $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
  658. $def_options = &$GLOBALS['_PEAR_default_error_options'];
  659. }
  660. $stack[] = array($def_mode, $def_options);
  661.  
  662. if (isset($this) && is_a($this, 'PEAR')) {
  663. $this->setErrorHandling($mode, $options);
  664. } else {
  665. PEAR::setErrorHandling($mode, $options);
  666. }
  667. $stack[] = array($mode, $options);
  668. return true;
  669. }
  670.  
  671. /**
  672. * Pop the last error handler used
  673. *
  674. * @return bool Always true
  675. *
  676. * @see PEAR::pushErrorHandling
  677. */
  678. function popErrorHandling()
  679. {
  680. $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  681. array_pop($stack);
  682. list($mode, $options) = $stack[sizeof($stack) - 1];
  683. array_pop($stack);
  684. if (isset($this) && is_a($this, 'PEAR')) {
  685. $this->setErrorHandling($mode, $options);
  686. } else {
  687. PEAR::setErrorHandling($mode, $options);
  688. }
  689. return true;
  690. }
  691.  
  692. /**
  693. * OS independant PHP extension load. Remember to take care
  694. * on the correct extension name for case sensitive OSes.
  695. *
  696. * @param string $ext The extension name
  697. * @return bool Success or not on the dl() call
  698. */
  699. function loadExtension($ext)
  700. {
  701. if (extension_loaded($ext)) {
  702. return true;
  703. }
  704.  
  705. // if either returns true dl() will produce a FATAL error, stop that
  706. if (
  707. function_exists('dl') === false ||
  708. ini_get('enable_dl') != 1 ||
  709. ini_get('safe_mode') == 1
  710. ) {
  711. return false;
  712. }
  713.  
  714. if (OS_WINDOWS) {
  715. $suffix = '.dll';
  716. } elseif (PHP_OS == 'HP-UX') {
  717. $suffix = '.sl';
  718. } elseif (PHP_OS == 'AIX') {
  719. $suffix = '.a';
  720. } elseif (PHP_OS == 'OSX') {
  721. $suffix = '.bundle';
  722. } else {
  723. $suffix = '.so';
  724. }
  725.  
  726. return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
  727. }
  728. }
  729.  
  730. if (PEAR_ZE2) {
  731. include_once 'PEAR5.php';
  732. }
  733.  
  734. function _PEAR_call_destructors()
  735. {
  736. global $_PEAR_destructor_object_list;
  737. if (is_array($_PEAR_destructor_object_list) &&
  738. sizeof($_PEAR_destructor_object_list))
  739. {
  740. reset($_PEAR_destructor_object_list);
  741. if (PEAR_ZE2) {
  742. $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo');
  743. } else {
  744. $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
  745. }
  746.  
  747. if ($destructLifoExists) {
  748. $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
  749. }
  750.  
  751. while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
  752. $classname = get_class($objref);
  753. while ($classname) {
  754. $destructor = "_$classname";
  755. if (method_exists($objref, $destructor)) {
  756. $objref->$destructor();
  757. break;
  758. } else {
  759. $classname = get_parent_class($classname);
  760. }
  761. }
  762. }
  763. // Empty the object list to ensure that destructors are
  764. // not called more than once.
  765. $_PEAR_destructor_object_list = array();
  766. }
  767.  
  768. // Now call the shutdown functions
  769. if (
  770. isset($GLOBALS['_PEAR_shutdown_funcs']) &&
  771. is_array($GLOBALS['_PEAR_shutdown_funcs']) &&
  772. !empty($GLOBALS['_PEAR_shutdown_funcs'])
  773. ) {
  774. foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
  775. call_user_func_array($value[0], $value[1]);
  776. }
  777. }
  778. }
  779.  
  780. /**
  781. * Standard PEAR error class for PHP 4
  782. *
  783. * This class is supserseded by {@link PEAR_Exception} in PHP 5
  784. *
  785. * @category pear
  786. * @package PEAR
  787. * @author Stig Bakken <ssb@php.net>
  788. * @author Tomas V.V. Cox <cox@idecnet.com>
  789. * @author Gregory Beaver <cellog@php.net>
  790. * @copyright 1997-2006 The PHP Group
  791. * @license http://opensource.org/licenses/bsd-license.php New BSD License
  792. * @version Release: 1.9.4
  793. * @link http://pear.php.net/manual/en/core.pear.pear-error.php
  794. * @see PEAR::raiseError(), PEAR::throwError()
  795. * @since Class available since PHP 4.0.2
  796. */
  797. class PEAR_Error
  798. {
  799. var $error_message_prefix = '';
  800. var $mode = PEAR_ERROR_RETURN;
  801. var $level = E_USER_NOTICE;
  802. var $code = -1;
  803. var $message = '';
  804. var $userinfo = '';
  805. var $backtrace = null;
  806.  
  807. /**
  808. * PEAR_Error constructor
  809. *
  810. * @param string $message message
  811. *
  812. * @param int $code (optional) error code
  813. *
  814. * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
  815. * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
  816. * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
  817. *
  818. * @param mixed $options (optional) error level, _OR_ in the case of
  819. * PEAR_ERROR_CALLBACK, the callback function or object/method
  820. * tuple.
  821. *
  822. * @param string $userinfo (optional) additional user/debug info
  823. *
  824. * @access public
  825. *
  826. */
  827. function PEAR_Error($message = 'unknown error', $code = null,
  828. $mode = null, $options = null, $userinfo = null)
  829. {
  830. if ($mode === null) {
  831. $mode = PEAR_ERROR_RETURN;
  832. }
  833. $this->message = $message;
  834. $this->code = $code;
  835. $this->mode = $mode;
  836. $this->userinfo = $userinfo;
  837.  
  838. if (PEAR_ZE2) {
  839. $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace');
  840. } else {
  841. $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
  842. }
  843.  
  844. if (!$skiptrace) {
  845. $this->backtrace = debug_backtrace();
  846. if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
  847. unset($this->backtrace[0]['object']);
  848. }
  849. }
  850.  
  851. if ($mode & PEAR_ERROR_CALLBACK) {
  852. $this->level = E_USER_NOTICE;
  853. $this->callback = $options;
  854. } else {
  855. if ($options === null) {
  856. $options = E_USER_NOTICE;
  857. }
  858.  
  859. $this->level = $options;
  860. $this->callback = null;
  861. }
  862.  
  863. if ($this->mode & PEAR_ERROR_PRINT) {
  864. if (is_null($options) || is_int($options)) {
  865. $format = "%s";
  866. } else {
  867. $format = $options;
  868. }
  869.  
  870. printf($format, $this->getMessage());
  871. }
  872.  
  873. if ($this->mode & PEAR_ERROR_TRIGGER) {
  874. trigger_error($this->getMessage(), $this->level);
  875. }
  876.  
  877. if ($this->mode & PEAR_ERROR_DIE) {
  878. $msg = $this->getMessage();
  879. if (is_null($options) || is_int($options)) {
  880. $format = "%s";
  881. if (substr($msg, -1) != "\n") {
  882. $msg .= "\n";
  883. }
  884. } else {
  885. $format = $options;
  886. }
  887. die(sprintf($format, $msg));
  888. }
  889.  
  890. if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) {
  891. call_user_func($this->callback, $this);
  892. }
  893.  
  894. if ($this->mode & PEAR_ERROR_EXCEPTION) {
  895. trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
  896. eval('$e = new Exception($this->message, $this->code);throw($e);');
  897. }
  898. }
  899.  
  900. /**
  901. * Get the error mode from an error object.
  902. *
  903. * @return int error mode
  904. * @access public
  905. */
  906. function getMode()
  907. {
  908. return $this->mode;
  909. }
  910.  
  911. /**
  912. * Get the callback function/method from an error object.
  913. *
  914. * @return mixed callback function or object/method array
  915. * @access public
  916. */
  917. function getCallback()
  918. {
  919. return $this->callback;
  920. }
  921.  
  922. /**
  923. * Get the error message from an error object.
  924. *
  925. * @return string full error message
  926. * @access public
  927. */
  928. function getMessage()
  929. {
  930. return ($this->error_message_prefix . $this->message);
  931. }
  932.  
  933. /**
  934. * Get error code from an error object
  935. *
  936. * @return int error code
  937. * @access public
  938. */
  939. function getCode()
  940. {
  941. return $this->code;
  942. }
  943.  
  944. /**
  945. * Get the name of this error/exception.
  946. *
  947. * @return string error/exception name (type)
  948. * @access public
  949. */
  950. function getType()
  951. {
  952. return get_class($this);
  953. }
  954.  
  955. /**
  956. * Get additional user-supplied information.
  957. *
  958. * @return string user-supplied information
  959. * @access public
  960. */
  961. function getUserInfo()
  962. {
  963. return $this->userinfo;
  964. }
  965.  
  966. /**
  967. * Get additional debug information supplied by the application.
  968. *
  969. * @return string debug information
  970. * @access public
  971. */
  972. function getDebugInfo()
  973. {
  974. return $this->getUserInfo();
  975. }
  976.  
  977. /**
  978. * Get the call backtrace from where the error was generated.
  979. * Supported with PHP 4.3.0 or newer.
  980. *
  981. * @param int $frame (optional) what frame to fetch
  982. * @return array Backtrace, or NULL if not available.
  983. * @access public
  984. */
  985. function getBacktrace($frame = null)
  986. {
  987. if (defined('PEAR_IGNORE_BACKTRACE')) {
  988. return null;
  989. }
  990. if ($frame === null) {
  991. return $this->backtrace;
  992. }
  993. return $this->backtrace[$frame];
  994. }
  995.  
  996. function addUserInfo($info)
  997. {
  998. if (empty($this->userinfo)) {
  999. $this->userinfo = $info;
  1000. } else {
  1001. $this->userinfo .= " ** $info";
  1002. }
  1003. }
  1004.  
  1005. function __toString()
  1006. {
  1007. return $this->getMessage();
  1008. }
  1009.  
  1010. /**
  1011. * Make a string representation of this object.
  1012. *
  1013. * @return string a string with an object summary
  1014. * @access public
  1015. */
  1016. function toString()
  1017. {
  1018. $modes = array();
  1019. $levels = array(E_USER_NOTICE => 'notice',
  1020. E_USER_WARNING => 'warning',
  1021. E_USER_ERROR => 'error');
  1022. if ($this->mode & PEAR_ERROR_CALLBACK) {
  1023. if (is_array($this->callback)) {
  1024. $callback = (is_object($this->callback[0]) ?
  1025. strtolower(get_class($this->callback[0])) :
  1026. $this->callback[0]) . '::' .
  1027. $this->callback[1];
  1028. } else {
  1029. $callback = $this->callback;
  1030. }
  1031. return sprintf('[%s: message="%s" code=%d mode=callback '.
  1032. 'callback=%s prefix="%s" info="%s"]',
  1033. strtolower(get_class($this)), $this->message, $this->code,
  1034. $callback, $this->error_message_prefix,
  1035. $this->userinfo);
  1036. }
  1037. if ($this->mode & PEAR_ERROR_PRINT) {
  1038. $modes[] = 'print';
  1039. }
  1040. if ($this->mode & PEAR_ERROR_TRIGGER) {
  1041. $modes[] = 'trigger';
  1042. }
  1043. if ($this->mode & PEAR_ERROR_DIE) {
  1044. $modes[] = 'die';
  1045. }
  1046. if ($this->mode & PEAR_ERROR_RETURN) {
  1047. $modes[] = 'return';
  1048. }
  1049. return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
  1050. 'prefix="%s" info="%s"]',
  1051. strtolower(get_class($this)), $this->message, $this->code,
  1052. implode("|", $modes), $levels[$this->level],
  1053. $this->error_message_prefix,
  1054. $this->userinfo);
  1055. }
  1056. }
  1057.  
  1058.  
  1059. // Uncomment the folling define if you want the class to automatically
  1060. // read the MPEG frame info to get bitrate, mpeg version, layer, etc.
  1061. //
  1062. // NOTE: This is needed to maintain pre-version 1.0 behavior which maybe
  1063. // needed if you are using info that is from the mpeg frame. This includes
  1064. // the length of the song.
  1065. //
  1066. // This is discouraged because it will siginfincantly lengthen script
  1067. // execution time if all you need is the ID3 tag info.
  1068. // define('ID3_AUTO_STUDY', true);
  1069.  
  1070. // Uncomment the following define if you want tons of debgging info.
  1071. // Tip: make sure you use a <PRE> block so the print_r's are readable.
  1072. // define('ID3_SHOW_DEBUG', true);
  1073.  
  1074. /**
  1075. * File not opened
  1076. * @const PEAR_MP3_ID_FNO
  1077. */
  1078. define('PEAR_MP3_ID_FNO', 1);
  1079.  
  1080. /**
  1081. * Read error
  1082. * @const PEAR_MP3_ID_RE
  1083. */
  1084. define('PEAR_MP3_ID_RE', 2);
  1085.  
  1086. /**
  1087. * Tag not found
  1088. * @const PEAR_MP3_ID_TNF
  1089. */
  1090. define('PEAR_MP3_ID_TNF', 3);
  1091.  
  1092. /**
  1093. * File is not a MP3 file (corrupted?)
  1094. * @const PEAR_MP3_ID_NOMP3
  1095. */
  1096. define('PEAR_MP3_ID_NOMP3', 4);
  1097.  
  1098. /**
  1099. * A Class for reading/writing MP3 ID3 tags
  1100. *
  1101. * Note: This code doesn't try to deal with corrupt mp3s. So if you get
  1102. * incorrect length times or something else it may be your mp3. To fix just
  1103. * re-enocde from the CD. :~)
  1104. *
  1105. * eg:
  1106. * require_once("MP3/Id.php");
  1107. * $file = "Some Song.mp3";
  1108. *
  1109. * $id3 = &new MP3_Id();
  1110. * $id3->read($file);
  1111. * print_r($id3);
  1112. *
  1113. * echo $id3->getTag('artists');
  1114. *
  1115. * $id3->comment = "Be gentle with that file.";
  1116. * $id3->write();
  1117. * $id3->read($file);
  1118. * print_r($id3 );
  1119. *
  1120. * @package MP3_Id
  1121. * @author Sandy McArthur Jr. <Leknor@Leknor.com>
  1122. * @version $Id: Id.php 315617 2011-08-27 14:36:36Z alexmerz $
  1123. */
  1124. class MP3_Id {
  1125.  
  1126. /**
  1127. * mp3/mpeg file name
  1128. * @var boolean
  1129. */
  1130. var $file = false;
  1131. /**
  1132. * ID3 v1 tag found? (also true if v1.1 found)
  1133. * @var boolean
  1134. */
  1135. var $id3v1 = false;
  1136. /**
  1137. * ID3 v1.1 tag found?
  1138. * @var boolean
  1139. */
  1140. var $id3v11 = false;
  1141. /**
  1142. * ID3 v2 tag found? (not used yet)
  1143. * @var boolean
  1144. */
  1145. var $id3v2 = false;
  1146.  
  1147. // ID3v1.1 Fields:
  1148. /**
  1149. * trackname
  1150. * @var string
  1151. */
  1152. var $name = '';
  1153. /**
  1154. * artists
  1155. * @var string
  1156. */
  1157. var $artists = '';
  1158. /**
  1159. * album
  1160. * @var string
  1161. */
  1162. var $album = '';
  1163. /**
  1164. * year
  1165. * @var string
  1166. */
  1167. var $year = '';
  1168. /**
  1169. * comment
  1170. * @var string
  1171. */
  1172. var $comment = '';
  1173. /**
  1174. * track number
  1175. * @var integer
  1176. */
  1177. var $track = 0;
  1178. /**
  1179. * genre name
  1180. * @var string
  1181. */
  1182. var $genre = '';
  1183. /**
  1184. * genre number
  1185. * @var integer
  1186. */
  1187. var $genreno = 255;
  1188.  
  1189. // MP3 Frame Stuff
  1190. /**
  1191. * Was the file studied to learn more info?
  1192. * @var boolean
  1193. */
  1194. var $studied = false;
  1195.  
  1196. /**
  1197. * version of mpeg
  1198. * @var integer
  1199. */
  1200. var $mpeg_ver = 0;
  1201. /**
  1202. * version of layer
  1203. * @var integer
  1204. */
  1205. var $layer = 0;
  1206. /**
  1207. * version of bitrate
  1208. * @var integer
  1209. */
  1210. var $bitrate = 0;
  1211. /**
  1212. * Frames are crc protected?
  1213. * @var boolean
  1214. */
  1215. var $crc = false;
  1216. /**
  1217. * frequency
  1218. * @var integer
  1219. */
  1220. var $frequency = 0;
  1221. /**
  1222. * encoding type (CBR or VBR)
  1223. * @var string
  1224. */
  1225. var $encoding_type = 0;
  1226. /**
  1227. * number of samples per MPEG audio frame
  1228. * @var integer
  1229. */
  1230. var $samples_per_frame = 0;
  1231. /**
  1232. * samples in file
  1233. * @var integer
  1234. */
  1235. var $samples = 0;
  1236. /**
  1237. * Bytes in file without tag overhead
  1238. * @var integer
  1239. */
  1240. var $musicsize = -1;
  1241. /**
  1242. * number of MPEG audio frames
  1243. * @var integer
  1244. */
  1245. var $frames = 0;
  1246. /**
  1247. * quality indicator (0% - 100%)
  1248. * @var integer
  1249. */
  1250. var $quality = 0;
  1251. /**
  1252. * Frames padded
  1253. * @var boolean
  1254. */
  1255. var $padding = false;
  1256. /**
  1257. * private bit set
  1258. * @var boolean
  1259. */
  1260. var $private = false;
  1261. /**
  1262. * Mode (Stero etc)
  1263. * @var string
  1264. */
  1265. var $mode = '';
  1266. /**
  1267. * Copyrighted
  1268. * @var string
  1269. */
  1270. var $copyright = false;
  1271. /**
  1272. * On Original Media? (never used)
  1273. * @var boolean
  1274. */
  1275. var $original = false;
  1276. /**
  1277. * Emphasis (also never used)
  1278. * @var boolean
  1279. */
  1280. var $emphasis = '';
  1281. /**
  1282. * Bytes in file
  1283. * @var integer
  1284. */
  1285. var $filesize = -1;
  1286. /**
  1287. * Byte at which the first mpeg header was found
  1288. * @var integer
  1289. */
  1290. var $frameoffset = -1;
  1291. /**
  1292. * length of mp3 format hh:mm:ss
  1293. * @var string
  1294. */
  1295. var $lengthh = false;
  1296. /**
  1297. * length of mp3 format mm:ss
  1298. * @var string
  1299. */
  1300. var $length = false;
  1301. /**
  1302. * length of mp3 in seconds
  1303. * @var string
  1304. */
  1305. var $lengths = false;
  1306.  
  1307. /**
  1308. * if any errors they will be here
  1309. * @var string
  1310. */
  1311. var $error = false;
  1312.  
  1313. /**
  1314. * print debugging info?
  1315. * @var boolean
  1316. */
  1317. var $debug = false;
  1318. /**
  1319. * print debugg
  1320. * @var string
  1321. */
  1322. var $debugbeg = '<DIV STYLE="margin: 0.5 em; padding: 0.5 em; border-width: thin; border-color: black; border-style: solid">';
  1323. /**
  1324. * print debugg
  1325. * @var string
  1326. */
  1327. var $debugend = '</DIV>';
  1328.  
  1329. /*
  1330. * creates a new id3 object
  1331. * and loads a tag from a file.
  1332. *
  1333. * @param string $study study the mpeg frame to get extra info like bitrate and frequency
  1334. * You should advoid studing alot of files as it will siginficantly
  1335. * slow this down.
  1336. * @access public
  1337. */
  1338. function MP3_Id($study = false) {
  1339. if(defined('ID3_SHOW_DEBUG')) $this->debug = true;
  1340. $this->study=($study || defined('ID3_AUTO_STUDY'));
  1341.  
  1342. } // id3()
  1343.  
  1344. /**
  1345. * reads the given file and parse it
  1346. *
  1347. * @param string $file the name of the file to parse
  1348. * @return mixed PEAR_Error on error
  1349. * @access public
  1350. */
  1351. function read( $file="") {
  1352. if ($this->debug) print($this->debugbeg . "id3('$file')<HR>\n");
  1353.  
  1354. if(!empty($file))$this->file = $file;
  1355. if ($this->debug) print($this->debugend);
  1356.  
  1357. return $this->_read_v1();
  1358. }
  1359.  
  1360. /**
  1361. * sets a field
  1362. *
  1363. * possible names of tags are:
  1364. * artists - Name of band or artist
  1365. * album - Name of the album
  1366. * year - publishing year of the album or song
  1367. * comment - song comment
  1368. * track - the number of the track
  1369. * genre - genre of the song
  1370. * genreno - Number of the genre
  1371. *
  1372. * @param mixed $name Name of the tag to set or hash with the key as fieldname
  1373. * @param mixed $value the value to set
  1374. *
  1375. * @access public
  1376. */
  1377. function setTag($name, $value) {
  1378. if( is_array($name)) {
  1379. foreach( $name as $n => $v) {
  1380. $this -> $n = $v ;
  1381. }
  1382. } else {
  1383. $this -> $name = $value ;
  1384. }
  1385. }
  1386.  
  1387. /**
  1388. * get the value of a tag
  1389. *
  1390. * @param string $name the name of the field to get
  1391. * @param mixed $default returned if the field not exists
  1392. *
  1393. * @return mixed The value of the field
  1394. * @access public
  1395. * @see setTag
  1396. */
  1397. function getTag($name, $default = 0) {
  1398. if(empty($this -> $name)) {
  1399. return $default ;
  1400. } else {
  1401. return $this -> $name ;
  1402. }
  1403. }
  1404.  
  1405. /**
  1406. * update the id3v1 tags on the file.
  1407. * Note: If/when ID3v2 is implemented this method will probably get another
  1408. * parameters.
  1409. *
  1410. * @param boolean $v1 if true update/create an id3v1 tag on the file. (defaults to true)
  1411. *
  1412. * @access public
  1413. */
  1414. function write($v1 = true) {
  1415. if ($this->debug) print($this->debugbeg . "write()<HR>\n");
  1416. if ($v1) {
  1417. $this->_write_v1();
  1418. }
  1419. if ($this->debug) print($this->debugend);
  1420. } // write()
  1421.  
  1422. /**
  1423. * study() - does extra work to get the MPEG frame info.
  1424. *
  1425. * @access public
  1426. */
  1427. function study() {
  1428. $this->studied = true;
  1429. $this->_readframe();
  1430. } // study()
  1431.  
  1432. /**
  1433. * copy($from) - set's the ID3 fields to the same as the fields in $from
  1434. *
  1435. * @param string $from fields to copy
  1436. * @access public
  1437. */
  1438. function copy($from) {
  1439. if ($this->debug) print($this->debugbeg . "copy(\$from)<HR>\n");
  1440. $this->name = $from->name;
  1441. $this->artists = $from->artists;
  1442. $this->album = $from->album;
  1443. $this->year = $from->year;
  1444. $this->comment = $from->comment;
  1445. $this->track = $from->track;
  1446. $this->genre = $from->genre;
  1447. $this->genreno = $from->genreno;
  1448. if ($this->debug) print($this->debugend);
  1449. } // copy($from)
  1450.  
  1451. /**
  1452. * remove - removes the id3 tag(s) from a file.
  1453. *
  1454. * @param boolean $id3v1 true to remove the tag
  1455. * @param boolean $id3v2 true to remove the tag (Not yet implemented)
  1456. *
  1457. * @access public
  1458. */
  1459. function remove($id3v1 = true, $id3v2 = true) {
  1460. if ($this->debug) print($this->debugbeg . "remove()<HR>\n");
  1461.  
  1462. if ($id3v1) {
  1463. $this->_remove_v1();
  1464. }
  1465.  
  1466. if ($id3v2) {
  1467. // TODO: write ID3v2 code
  1468. }
  1469.  
  1470. if ($this->debug) print($this->debugend);
  1471. } // remove
  1472.  
  1473.  
  1474. /**
  1475. * read a ID3 v1 or v1.1 tag from a file
  1476. *
  1477. * $file should be the path to the mp3 to look for a tag.
  1478. * When in doubt use the full path.
  1479. *
  1480. * @return mixed PEAR_Error if fails
  1481. * @access private
  1482. */
  1483. function _read_v1() {
  1484. if ($this->debug) print($this->debugbeg . "_read_v1()<HR>\n");
  1485.  
  1486. if (! ($f = @fopen($this->file, 'rb')) ) {
  1487. return PEAR::raiseError( "Unable to open " . $this->file, PEAR_MP3_ID_FNO);
  1488. }
  1489.  
  1490. if (fseek($f, -128, SEEK_END) == -1) {
  1491. return PEAR::raiseError( 'Unable to see to end - 128 of ' . $this->file, PEAR_MP3_ID_RE);
  1492. }
  1493.  
  1494. $r = fread($f, 128);
  1495. fclose($f);
  1496.  
  1497. if ($this->debug) {
  1498. $unp = unpack('H*raw', $r);
  1499. print_r($unp);
  1500. }
  1501.  
  1502. $id3tag = $this->_decode_v1($r);
  1503.  
  1504. if(!PEAR::isError( $id3tag)) {
  1505. $this->id3v1 = true;
  1506.  
  1507. $tmp = explode(Chr(0), $id3tag['NAME']);
  1508. $this->name = $tmp[0];
  1509.  
  1510. $tmp = explode(Chr(0), $id3tag['ARTISTS']);
  1511. $this->artists = $tmp[0];
  1512.  
  1513. $tmp = explode(Chr(0), $id3tag['ALBUM']);
  1514. $this->album = $tmp[0];
  1515.  
  1516. $tmp = explode(Chr(0), $id3tag['YEAR']);
  1517. $this->year = $tmp[0];
  1518.  
  1519. $tmp = explode(Chr(0), $id3tag['COMMENT']);
  1520. $this->comment = $tmp[0];
  1521.  
  1522. if (isset($id3tag['TRACK'])) {
  1523. $this->id3v11 = true;
  1524. $this->track = $id3tag['TRACK'];
  1525. }
  1526.  
  1527. $this->genreno = $id3tag['GENRENO'];
  1528. $this->genre = $id3tag['GENRE'];
  1529. } else {
  1530. return $id3tag ;
  1531. }
  1532.  
  1533. if ($this->debug) print($this->debugend);
  1534. } // _read_v1()
  1535.  
  1536. /**
  1537. * decodes that ID3v1 or ID3v1.1 tag
  1538. *
  1539. * false will be returned if there was an error decoding the tag
  1540. * else an array will be returned
  1541. *
  1542. * @param string $rawtag tag to decode
  1543. * @return string decoded tag
  1544. * @access private
  1545. */
  1546. function _decode_v1($rawtag) {
  1547. if ($this->debug) print($this->debugbeg . "_decode_v1(\$rawtag)<HR>\n");
  1548.  
  1549. if ($rawtag[125] == Chr(0) and $rawtag[126] != Chr(0)) {
  1550. // ID3 v1.1
  1551. $format = 'a3TAG/a30NAME/a30ARTISTS/a30ALBUM/a4YEAR/a28COMMENT/x1/C1TRACK/C1GENRENO';
  1552. } else {
  1553. // ID3 v1
  1554. $format = 'a3TAG/a30NAME/a30ARTISTS/a30ALBUM/a4YEAR/a30COMMENT/C1GENRENO';
  1555. }
  1556.  
  1557. $id3tag = unpack($format, $rawtag);
  1558. if ($this->debug) print_r($id3tag);
  1559.  
  1560. if ($id3tag['TAG'] == 'TAG') {
  1561. $id3tag['GENRE'] = $this->getgenre($id3tag['GENRENO']);
  1562. } else {
  1563. $id3tag = PEAR::raiseError( 'TAG not found', PEAR_MP3_ID_TNF);
  1564. }
  1565. if ($this->debug) print($this->debugend);
  1566. return $id3tag;
  1567. } // _decode_v1()
  1568.  
  1569.  
  1570. /**
  1571. * writes a ID3 v1 or v1.1 tag to a file
  1572. *
  1573. * @return mixed returns PEAR_Error when fails
  1574. * @access private
  1575. */
  1576. function _write_v1() {
  1577. if ($this->debug) print($this->debugbeg . "_write_v1()<HR>\n");
  1578.  
  1579. $file = $this->file;
  1580.  
  1581. if (! ($f = @fopen($file, 'r+b')) ) {
  1582. return PEAR::raiseError( "Unable to open " . $file, PEAR_MP3_ID_FNO);
  1583. }
  1584.  
  1585. if (fseek($f, -128, SEEK_END) == -1) {
  1586. // $this->error = 'Unable to see to end - 128 of ' . $file;
  1587. return PEAR::raiseError( "Unable to see to end - 128 of " . $file, PEAR_MP3_ID_RE);
  1588. }
  1589.  
  1590. $this->genreno = $this->getgenreno($this->genre, $this->genreno);
  1591.  
  1592. $newtag = $this->_encode_v1();
  1593.  
  1594. $r = fread($f, 128);
  1595.  
  1596. if ( !PEAR::isError( $this->_decode_v1($r))) {
  1597. if (fseek($f, -128, SEEK_END) == -1) {
  1598. // $this->error = 'Unable to see to end - 128 of ' . $file;
  1599. return PEAR::raiseError( "Unable to see to end - 128 of " . $file, PEAR_MP3_ID_RE);
  1600. }
  1601. fwrite($f, $newtag);
  1602. } else {
  1603. if (fseek($f, 0, SEEK_END) == -1) {
  1604. // $this->error = 'Unable to see to end of ' . $file;
  1605. return PEAR::raiseError( "Unable to see to end of " . $file, PEAR_MP3_ID_RE);
  1606. }
  1607. fwrite($f, $newtag);
  1608. }
  1609. fclose($f);
  1610.  
  1611. if ($this->debug) print($this->debugend);
  1612. } // _write_v1()
  1613.  
  1614. /*
  1615. * encode the ID3 tag
  1616. *
  1617. * the newly built tag will be returned
  1618. *
  1619. * @return string the new tag
  1620. * @access private
  1621. */
  1622. function _encode_v1() {
  1623. if ($this->debug) print($this->debugbeg . "_encode_v1()<HR>\n");
  1624.  
  1625. if ($this->track) {
  1626. // ID3 v1.1
  1627. $id3pack = 'a3a30a30a30a4a28x1C1C1';
  1628. $newtag = pack($id3pack,
  1629. 'TAG',
  1630. $this->name,
  1631. $this->artists,
  1632. $this->album,
  1633. $this->year,
  1634. $this->comment,
  1635. $this->track,
  1636. $this->genreno
  1637. );
  1638. } else {
  1639. // ID3 v1
  1640. $id3pack = 'a3a30a30a30a4a30C1';
  1641. $newtag = pack($id3pack,
  1642. 'TAG',
  1643. $this->name,
  1644. $this->artists,
  1645. $this->album,
  1646. $this->year,
  1647. $this->comment,
  1648. $this->genreno
  1649. );
  1650. }
  1651.  
  1652. if ($this->debug) {
  1653. print('id3pack: ' . $id3pack . "\n");
  1654. $unp = unpack('H*new', $newtag);
  1655. print_r($unp);
  1656. }
  1657.  
  1658. if ($this->debug) print($this->debugend);
  1659. return $newtag;
  1660. } // _encode_v1()
  1661.  
  1662. /**
  1663. * if exists it removes an ID3v1 or v1.1 tag
  1664. *
  1665. * returns true if the tag was removed or none was found
  1666. * else false if there was an error
  1667. *
  1668. * @return boolean true, if the tag was removed
  1669. * @access private
  1670. */
  1671. function _remove_v1() {
  1672. if ($this->debug) print($this->debugbeg . "_remove_v1()<HR>\n");
  1673.  
  1674. $file = $this->file;
  1675.  
  1676. if (! ($f = fopen($file, 'r+b')) ) {
  1677. return PEAR::raiseError( "Unable to open " . $file, PEAR_MP3_ID_FNO);
  1678. }
  1679.  
  1680. if (fseek($f, -128, SEEK_END) == -1) {
  1681. return PEAR::raiseError( 'Unable to see to end - 128 of ' . $file, PEAR_MP3_ID_RE);
  1682. }
  1683.  
  1684. $r = fread($f, 128);
  1685.  
  1686. $success = false;
  1687. if ( !PEAR::isError( $this->_decode_v1($r))) {
  1688. $size = filesize($this->file) - 128;
  1689. if ($this->debug) print('size: old: ' . filesize($this->file));
  1690. $success = ftruncate($f, $size);
  1691. clearstatcache();
  1692. if ($this->debug) print(' new: ' . filesize($this->file));
  1693. }
  1694. fclose($f);
  1695.  
  1696. if ($this->debug) print($this->debugend);
  1697. return $success;
  1698. } // _remove_v1()
  1699.  
  1700. /**
  1701. * reads a frame from the file
  1702. *
  1703. * @return mixed PEAR_Error when fails
  1704. * @access private
  1705. */
  1706. function _readframe() {
  1707. if ($this->debug) print($this->debugbeg . "_readframe()<HR>\n");
  1708.  
  1709. $file = $this->file;
  1710.  
  1711. if (! ($f = fopen($file, 'rb')) ) {
  1712. if ($this->debug) print($this->debugend);
  1713. return PEAR::raiseError( "Unable to open " . $file, PEAR_MP3_ID_FNO) ;
  1714. }
  1715.  
  1716. $this->filesize = filesize($file);
  1717.  
  1718. do {
  1719. while (fread($f,1) != Chr(255)) { // Find the first frame
  1720. if ($this->debug) echo "Find...\n";
  1721. if (feof($f)) {
  1722. if ($this->debug) print($this->debugend);
  1723. return PEAR::raiseError( "No mpeg frame found", PEAR_MP3_ID_NOMP3) ;
  1724. }
  1725. }
  1726. fseek($f, ftell($f) - 1); // back up one byte
  1727.  
  1728. $frameoffset = ftell($f);
  1729.  
  1730. $r = fread($f, 4);
  1731. // Binary to Hex to a binary sting. ugly but best I can think of.
  1732. // $bits = unpack('H*bits', $r);
  1733. // $bits = base_convert($bits['bits'],16,2);
  1734. $bits = sprintf("%'08b%'08b%'08b%'08b", ord($r{0}), ord($r{1}), ord($r{2}), ord($r{3}));
  1735. } while (!$bits[8] and !$bits[9] and !$bits[10]); // 1st 8 bits true from the while
  1736. if ($this->debug) print('Bits: ' . $bits . "\n");
  1737.  
  1738. $this->frameoffset = $frameoffset;
  1739.  
  1740. // Detect VBR header
  1741. if ($bits[11] == 0) {
  1742. if (($bits[24] == 1) && ($bits[25] == 1)) {
  1743. $vbroffset = 9; // MPEG 2.5 Mono
  1744. } else {
  1745. $vbroffset = 17; // MPEG 2.5 Stereo
  1746. }
  1747. } else if ($bits[12] == 0) {
  1748. if (($bits[24] == 1) && ($bits[25] == 1)) {
  1749. $vbroffset = 9; // MPEG 2 Mono
  1750. } else {
  1751. $vbroffset = 17; // MPEG 2 Stereo
  1752. }
  1753. } else {
  1754. if (($bits[24] == 1) && ($bits[25] == 1)) {
  1755. $vbroffset = 17; // MPEG 1 Mono
  1756. } else {
  1757. $vbroffset = 32; // MPEG 1 Stereo
  1758. }
  1759. }
  1760.  
  1761. fseek($f, ftell($f) + $vbroffset);
  1762. $r = fread($f, 4);
  1763.  
  1764. switch ($r) {
  1765. case 'Xing':
  1766. $this->encoding_type = 'VBR';
  1767. case 'Info':
  1768. // Extract info from Xing header
  1769.  
  1770. if ($this->debug) print('Encoding Header: ' . $r . "\n");
  1771.  
  1772. $r = fread($f, 4);
  1773. $vbrbits = sprintf("%'08b", ord($r{3}));
  1774.  
  1775. if ($this->debug) print('XING Header Bits: ' . $vbrbits . "\n");
  1776.  
  1777. if ($vbrbits[7] == 1) {
  1778. // Next 4 bytes contain number of frames
  1779. $r = fread($f, 4);
  1780. $this->frames = unpack('N', $r);
  1781. $this->frames = $this->frames[1];
  1782. }
  1783.  
  1784. if ($vbrbits[6] == 1) {
  1785. // Next 4 bytes contain number of bytes
  1786. $r = fread($f, 4);
  1787. $this->musicsize = unpack('N', $r);
  1788. $this->musicsize = $this->musicsize[1];
  1789. }
  1790.  
  1791. if ($vbrbits[5] == 1) {
  1792. // Next 100 bytes contain TOC entries, skip
  1793. fseek($f, ftell($f) + 100);
  1794. }
  1795.  
  1796. if ($vbrbits[4] == 1) {
  1797. // Next 4 bytes contain Quality Indicator
  1798. $r = fread($f, 4);
  1799. $this->quality = unpack('N', $r);
  1800. $this->quality = $this->quality[1];
  1801. }
  1802.  
  1803. break;
  1804.  
  1805. case 'VBRI':
  1806. default:
  1807. if ($vbroffset != 32) {
  1808. // VBRI Header is fixed after 32 bytes, so maybe we are looking at the wrong place.
  1809. fseek($f, ftell($f) + 32 - $vbroffset);
  1810. $r = fread($f, 4);
  1811.  
  1812. if ($r != 'VBRI') {
  1813. $this->encoding_type = 'CBR';
  1814. break;
  1815. }
  1816. } else {
  1817. $this->encoding_type = 'CBR';
  1818. break;
  1819. }
  1820.  
  1821. if ($this->debug) print('Encoding Header: ' . $r . "\n");
  1822.  
  1823. $this->encoding_type = 'VBR';
  1824.  
  1825. // Next 2 bytes contain Version ID, skip
  1826. fseek($f, ftell($f) + 2);
  1827.  
  1828. // Next 2 bytes contain Delay, skip
  1829. fseek($f, ftell($f) + 2);
  1830.  
  1831. // Next 2 bytes contain Quality Indicator
  1832. $r = fread($f, 2);
  1833. $this->quality = unpack('n', $r);
  1834. $this->quality = $this->quality[1];
  1835.  
  1836. // Next 4 bytes contain number of bytes
  1837. $r = fread($f, 4);
  1838. $this->musicsize = unpack('N', $r);
  1839. $this->musicsize = $this->musicsize[1];
  1840.  
  1841. // Next 4 bytes contain number of frames
  1842. $r = fread($f, 4);
  1843. $this->frames = unpack('N', $r);
  1844. $this->frames = $this->frames[1];
  1845. }
  1846.  
  1847. fclose($f);
  1848.  
  1849. if ($bits[11] == 0) {
  1850. $this->mpeg_ver = "2.5";
  1851. $bitrates = array(
  1852. '1' => array(0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0),
  1853. '2' => array(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),
  1854. '3' => array(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),
  1855. );
  1856. } else if ($bits[12] == 0) {
  1857. $this->mpeg_ver = "2";
  1858. $bitrates = array(
  1859. '1' => array(0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0),
  1860. '2' => array(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),
  1861. '3' => array(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0),
  1862. );
  1863. } else {
  1864. $this->mpeg_ver = "1";
  1865. $bitrates = array(
  1866. '1' => array(0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0),
  1867. '2' => array(0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0),
  1868. '3' => array(0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0),
  1869. );
  1870. }
  1871. if ($this->debug) print('MPEG' . $this->mpeg_ver . "\n");
  1872.  
  1873. $layer = array(
  1874. array(0,3),
  1875. array(2,1),
  1876. );
  1877. $this->layer = $layer[$bits[13]][$bits[14]];
  1878. if ($this->debug) print('layer: ' . $this->layer . "\n");
  1879.  
  1880. if ($bits[15] == 0) {
  1881. // It's backwards, if the bit is not set then it is protected.
  1882. if ($this->debug) print("protected (crc)\n");
  1883. $this->crc = true;
  1884. }
  1885.  
  1886. $bitrate = 0;
  1887. if ($bits[16] == 1) $bitrate += 8;
  1888. if ($bits[17] == 1) $bitrate += 4;
  1889. if ($bits[18] == 1) $bitrate += 2;
  1890. if ($bits[19] == 1) $bitrate += 1;
  1891. $this->bitrate = $bitrates[$this->layer][$bitrate];
  1892.  
  1893. $frequency = array(
  1894. '1' => array(
  1895. '0' => array(44100, 48000),
  1896. '1' => array(32000, 0),
  1897. ),
  1898. '2' => array(
  1899. '0' => array(22050, 24000),
  1900. '1' => array(16000, 0),
  1901. ),
  1902. '2.5' => array(
  1903. '0' => array(11025, 12000),
  1904. '1' => array(8000, 0),
  1905. ),
  1906. );
  1907. $this->frequency = $frequency[$this->mpeg_ver][$bits[20]][$bits[21]];
  1908.  
  1909. $this->padding = $bits[22];
  1910. $this->private = $bits[23];
  1911.  
  1912. $mode = array(
  1913. array('Stereo', 'Joint Stereo'),
  1914. array('Dual Channel', 'Mono'),
  1915. );
  1916. $this->mode = $mode[$bits[24]][$bits[25]];
  1917.  
  1918. // XXX: I dunno what the mode extension is for bits 26,27
  1919.  
  1920. $this->copyright = $bits[28];
  1921. $this->original = $bits[29];
  1922.  
  1923. $emphasis = array(
  1924. array('none', '50/15ms'),
  1925. array('', 'CCITT j.17'),
  1926. );
  1927. $this->emphasis = $emphasis[$bits[30]][$bits[31]];
  1928.  
  1929. $samplesperframe = array(
  1930. '1' => array(
  1931. '1' => 384,
  1932. '2' => 1152,
  1933. '3' => 1152
  1934. ),
  1935. '2' => array(
  1936. '1' => 384,
  1937. '2' => 1152,
  1938. '3' => 576
  1939. ),
  1940. '2.5' => array(
  1941. '1' => 384,
  1942. '2' => 1152,
  1943. '3' => 576
  1944. ),
  1945. );
  1946. $this->samples_per_frame = $samplesperframe[$this->mpeg_ver][$this->layer];
  1947.  
  1948. if ($this->encoding_type != 'VBR') {
  1949. if ($this->bitrate == 0) {
  1950. $s = -1;
  1951. } else {
  1952. $s = ((8*filesize($this->file))/1000) / $this->bitrate;
  1953. }
  1954. $this->length = sprintf('%02d:%02d',floor($s/60),floor($s-(floor($s/60)*60)));
  1955. $this->lengthh = sprintf('%02d:%02d:%02d',floor($s/3600),floor($s/60),floor($s-(floor($s/60)*60)));
  1956. $this->lengths = (int)$s;
  1957.  
  1958. $this->samples = ceil($this->lengths * $this->frequency);
  1959. if(0 != $this->samples_per_frame) {
  1960. $this->frames = ceil($this->samples / $this->samples_per_frame);
  1961. } else {
  1962. $this->frames = 0;
  1963. }
  1964. $this->musicsize = ceil($this->lengths * $this->bitrate * 1000 / 8);
  1965. } else {
  1966. $this->samples = $this->samples_per_frame * $this->frames;
  1967. $s = $this->samples / $this->frequency;
  1968.  
  1969. $this->length = sprintf('%02d:%02d',floor($s/60),floor($s-(floor($s/60)*60)));
  1970. $this->lengthh = sprintf('%02d:%02d:%02d',floor($s/3600),floor($s/60),floor($s-(floor($s/60)*60)));
  1971. $this->lengths = (int)$s;
  1972.  
  1973. $this->bitrate = (int)(($this->musicsize / $s) * 8 / 1000);
  1974. }
  1975.  
  1976. if ($this->debug) print($this->debugend);
  1977. } // _readframe()
  1978.  
  1979. /**
  1980. * getGenre - return the name of a genre number
  1981. *
  1982. * if no genre number is specified the genre number from
  1983. * $this->genreno will be used.
  1984. *
  1985. * the genre is returned or false if an error or not found
  1986. * no error message is ever returned
  1987. *
  1988. * @param integer $genreno Number of the genre
  1989. * @return mixed false, if no genre found, else string
  1990. *
  1991. * @access public
  1992. */
  1993. function getGenre($genreno) {
  1994. if ($this->debug) print($this->debugbeg . "getgenre($genreno)<HR>\n");
  1995.  
  1996. $genres = $this->genres();
  1997. if (isset($genres[$genreno])) {
  1998. $genre = $genres[$genreno];
  1999. if ($this->debug) print($genre . "\n");
  2000. } else {
  2001. $genre = '';
  2002. }
  2003.  
  2004. if ($this->debug) print($this->debugend);
  2005. return $genre;
  2006. } // getGenre($genreno)
  2007.  
  2008. /*
  2009. * getGenreNo - return the number of the genre name
  2010. *
  2011. * the genre number is returned or 0xff (255) if a match is not found
  2012. * you can specify the default genreno to use if one is not found
  2013. * no error message is ever returned
  2014. *
  2015. * @param string $genre Name of the genre
  2016. * @param integer $default Genre number in case of genre not found
  2017. *
  2018. * @access public
  2019. */
  2020. function getGenreNo($genre, $default = 0xff) {
  2021. if ($this->debug) print($this->debugbeg . "getgenreno('$genre',$default)<HR>\n");
  2022.  
  2023. $genres = $this->genres();
  2024. $genreno = false;
  2025. if ($genre) {
  2026. foreach ($genres as $no => $name) {
  2027. if (strtolower($genre) == strtolower($name)) {
  2028. if ($this->debug) print("$no:'$name' == '$genre'");
  2029. $genreno = $no;
  2030. }
  2031. }
  2032. }
  2033. if ($genreno === false) $genreno = $default;
  2034. if ($this->debug) print($this->debugend);
  2035. return $genreno;
  2036. } // getGenreNo($genre, $default = 0xff)
  2037.  
  2038. /*
  2039. * genres - returns an array of the ID3v1 genres
  2040. *
  2041. * @return array
  2042. *
  2043. * @access public
  2044. */
  2045. function genres() {
  2046. return array(
  2047. 0 => 'Blues',
  2048. 1 => 'Classic Rock',
  2049. 2 => 'Country',
  2050. 3 => 'Dance',
  2051. 4 => 'Disco',
  2052. 5 => 'Funk',
  2053. 6 => 'Grunge',
  2054. 7 => 'Hip-Hop',
  2055. 8 => 'Jazz',
  2056. 9 => 'Metal',
  2057. 10 => 'New Age',
  2058. 11 => 'Oldies',
  2059. 12 => 'Other',
  2060. 13 => 'Pop',
  2061. 14 => 'R&B',
  2062. 15 => 'Rap',
  2063. 16 => 'Reggae',
  2064. 17 => 'Rock',
  2065. 18 => 'Techno',
  2066. 19 => 'Industrial',
  2067. 20 => 'Alternative',
  2068. 21 => 'Ska',
  2069. 22 => 'Death Metal',
  2070. 23 => 'Pranks',
  2071. 24 => 'Soundtrack',
  2072. 25 => 'Euro-Techno',
  2073. 26 => 'Ambient',
  2074. 27 => 'Trip-Hop',
  2075. 28 => 'Vocal',
  2076. 29 => 'Jazz+Funk',
  2077. 30 => 'Fusion',
  2078. 31 => 'Trance',
  2079. 32 => 'Classical',
  2080. 33 => 'Instrumental',
  2081. 34 => 'Acid',
  2082. 35 => 'House',
  2083. 36 => 'Game',
  2084. 37 => 'Sound Clip',
  2085. 38 => 'Gospel',
  2086. 39 => 'Noise',
  2087. 40 => 'Alternative Rock',
  2088. 41 => 'Bass',
  2089. 42 => 'Soul',
  2090. 43 => 'Punk',
  2091. 44 => 'Space',
  2092. 45 => 'Meditative',
  2093. 46 => 'Instrumental Pop',
  2094. 47 => 'Instrumental Rock',
  2095. 48 => 'Ethnic',
  2096. 49 => 'Gothic',
  2097. 50 => 'Darkwave',
  2098. 51 => 'Techno-Industrial',
  2099. 52 => 'Electronic',
  2100. 53 => 'Pop-Folk',
  2101. 54 => 'Eurodance',
  2102. 55 => 'Dream',
  2103. 56 => 'Southern Rock',
  2104. 57 => 'Comedy',
  2105. 58 => 'Cult',
  2106. 59 => 'Gangsta',
  2107. 60 => 'Top 40',
  2108. 61 => 'Christian Rap',
  2109. 62 => 'Pop/Funk',
  2110. 63 => 'Jungle',
  2111. 64 => 'Native US',
  2112. 65 => 'Cabaret',
  2113. 66 => 'New Wave',
  2114. 67 => 'Psychadelic',
  2115. 68 => 'Rave',
  2116. 69 => 'Showtunes',
  2117. 70 => 'Trailer',
  2118. 71 => 'Lo-Fi',
  2119. 72 => 'Tribal',
  2120. 73 => 'Acid Punk',
  2121. 74 => 'Acid Jazz',
  2122. 75 => 'Polka',
  2123. 76 => 'Retro',
  2124. 77 => 'Musical',
  2125. 78 => 'Rock & Roll',
  2126. 79 => 'Hard Rock',
  2127. 80 => 'Folk',
  2128. 81 => 'Folk-Rock',
  2129. 82 => 'National Folk',
  2130. 83 => 'Swing',
  2131. 84 => 'Fast Fusion',
  2132. 85 => 'Bebob',
  2133. 86 => 'Latin',
  2134. 87 => 'Revival',
  2135. 88 => 'Celtic',
  2136. 89 => 'Bluegrass',
  2137. 90 => 'Avantgarde',
  2138. 91 => 'Gothic Rock',
  2139. 92 => 'Progressive Rock',
  2140. 93 => 'Psychedelic Rock',
  2141. 94 => 'Symphonic Rock',
  2142. 95 => 'Slow Rock',
  2143. 96 => 'Big Band',
  2144. 97 => 'Chorus',
  2145. 98 => 'Easy Listening',
  2146. 99 => 'Acoustic',
  2147. 100 => 'Humour',
  2148. 101 => 'Speech',
  2149. 102 => 'Chanson',
  2150. 103 => 'Opera',
  2151. 104 => 'Chamber Music',
  2152. 105 => 'Sonata',
  2153. 106 => 'Symphony',
  2154. 107 => 'Booty Bass',
  2155. 108 => 'Primus',
  2156. 109 => 'Porn Groove',
  2157. 110 => 'Satire',
  2158. 111 => 'Slow Jam',
  2159. 112 => 'Club',
  2160. 113 => 'Tango',
  2161. 114 => 'Samba',
  2162. 115 => 'Folklore',
  2163. 116 => 'Ballad',
  2164. 117 => 'Power Ballad',
  2165. 118 => 'Rhytmic Soul',
  2166. 119 => 'Freestyle',
  2167. 120 => 'Duet',
  2168. 121 => 'Punk Rock',
  2169. 122 => 'Drum Solo',
  2170. 123 => 'Acapella',
  2171. 124 => 'Euro-House',
  2172. 125 => 'Dance Hall',
  2173. 126 => 'Goa',
  2174. 127 => 'Drum & Bass',
  2175. 128 => 'Club-House',
  2176. 129 => 'Hardcore',
  2177. 130 => 'Terror',
  2178. 131 => 'Indie',
  2179. 132 => 'BritPop',
  2180. 133 => 'Negerpunk',
  2181. 134 => 'Polsk Punk',
  2182. 135 => 'Beat',
  2183. 136 => 'Christian Gangsta Rap',
  2184. 137 => 'Heavy Metal',
  2185. 138 => 'Black Metal',
  2186. 139 => 'Crossover',
  2187. 140 => 'Contemporary Christian',
  2188. 141 => 'Christian Rock',
  2189. 142 => 'Merengue',
  2190. 143 => 'Salsa',
  2191. 144 => 'Trash Metal',
  2192. 145 => 'Anime',
  2193. 146 => 'Jpop',
  2194. 147 => 'Synthpop'
  2195. );
  2196. }
  2197. }
  2198.  
  2199.  
  2200.  
  2201. ?>