This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Feb 16th, 2013  |  syntax: PHP  |  size: 7.02 KB  |  views: 167  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php defined('SYSPATH') OR die('No direct access allowed.');
  2.  
  3. class Wave_Core {
  4.  
  5.         public $width = 1906;
  6.         public $height = 100;
  7.         public $foreground = "#cccccc";
  8.         public $background = "";
  9.         public $draw_flat = false;
  10.         public $stereo = true;
  11.         public $path = null;
  12.  
  13.         public $img = false;
  14.  
  15.         public $converted_wav = null;
  16.  
  17.         // how much detail we want. Larger number means less detail
  18.         // (basically, how many bytes/frames to skip processing)
  19.         // the lower the number means longer processing time
  20.         public $detail = 5;
  21.  
  22.         public static function instance(){
  23.                
  24.                 return new self;
  25.         }
  26.  
  27.         /**
  28.         * Input song data
  29.         *
  30.         * @path string image path
  31.         * @stereo_support bool
  32.         *
  33.         * @return instance
  34.         */
  35.         public function input_file($path, $stereo_support){
  36.  
  37.                 $this->path = $path;
  38.  
  39.                 $this->stereo = $stereo_support;
  40.  
  41.                 return $this;
  42.         }
  43.  
  44.         /**
  45.         * Convert MP3 file to Wav
  46.         *
  47.         * @return void
  48.         */
  49.         public function convert(){
  50.                 $tmpname = "temp/".Helper::uuid1();
  51.  
  52.                 //make file copy
  53.                 copy($this->path, $tmpname."_o.mp3");
  54.  
  55.                 // convert mp3 to wav using lame decoder
  56.                 // First, resample the original mp3 using as mono (-m m), 16 bit (-b 16), and 8 KHz (--resample 8)
  57.                 // Secondly, convert that resampled mp3 into a wav
  58.                 // We don't necessarily need high quality audio to produce a waveform, doing this process reduces the WAV
  59.                 // to it's simplest form and makes processing significantly faster
  60.  
  61.                 exec("lame {$tmpname}_o.mp3 -m m -S -f -b 16 --resample 8 {$tmpname}.mp3 && lame -S --decode {$tmpname}.mp3 {$tmpname}.wav");
  62.                 $this->converted_wav = "{$tmpname}.wav";
  63.  
  64.                 // delete temporary files
  65.                 unlink("{$tmpname}_o.mp3");
  66.                 unlink("{$tmpname}.mp3");
  67.         }
  68.  
  69.         /**
  70.         * Convert file
  71.         *
  72.         * @return instance
  73.         */
  74.         public function generate_wave(){
  75.                 //convert to wav
  76.                 $this->convert();
  77.  
  78.                 // generate foreground color
  79.                 list($r, $g, $b) = $this->html2rgb($this->foreground);
  80.  
  81.                 /**
  82.                 * Below as posted by "zvoneM" on
  83.                 * http://forums.devshed.com/php-development-5/reading-16-bit-wav-file-318740.html
  84.                 * as findValues() defined above
  85.                 * Translated from Croation to English - July 11, 2011
  86.                 */
  87.                 $handle = fopen($this->converted_wav, "r");
  88.                 // wav file header retrieval
  89.                 $heading[] = fread($handle, 4);
  90.                 $heading[] = bin2hex(fread($handle, 4));
  91.                 $heading[] = fread($handle, 4);
  92.                 $heading[] = fread($handle, 4);
  93.                 $heading[] = bin2hex(fread($handle, 4));
  94.                 $heading[] = bin2hex(fread($handle, 2));
  95.                 $heading[] = bin2hex(fread($handle, 2));
  96.                 $heading[] = bin2hex(fread($handle, 4));
  97.                 $heading[] = bin2hex(fread($handle, 4));
  98.                 $heading[] = bin2hex(fread($handle, 2));
  99.                 $heading[] = bin2hex(fread($handle, 2));
  100.                 $heading[] = fread($handle, 4);
  101.                 $heading[] = bin2hex(fread($handle, 4));
  102.      
  103.                 // wav bitrate
  104.                 $peek = hexdec(substr($heading[10], 0, 2));
  105.                 $byte = $peek / 8;
  106.  
  107.                 // checking whether a mono or stereo wav
  108.                 $channel = hexdec(substr($heading[6], 0, 2));
  109.  
  110.                 $ratio = ($channel == 2 ? 40 : 80);
  111.  
  112.                 // start putting together the initial canvas
  113.                 // $data_size = (size_of_file - header_bytes_read) / skipped_bytes + 1
  114.                 $data_size = floor((filesize($this->converted_wav) - 44) / ($ratio + $byte) + 1);
  115.                 $data_point = 0;
  116.      
  117.                 // now that we have the data_size for a single channel (they both will be the same)
  118.                 // we can initialize our image canvas
  119.                 if (!$this->img) {
  120.                         // create original image width based on amount of detail
  121.                         // each waveform to be processed with be $height high, but will be condensed
  122.                         // and resized later (if specified)
  123.                         $this->img = imagecreatetruecolor($data_size / $this->detail, $this->height * sizeof($this->converted_wav));
  124.  
  125.                         // fill background of image
  126.                         if ($this->background == "") {
  127.                                 // transparent background specified
  128.                                 imagesavealpha($this->img, true);
  129.                                 $transparentColor = imagecolorallocatealpha($this->img, 0, 0, 0, 127);
  130.                                 imagefill($this->img, 0, 0, $transparentColor);
  131.                         } else {
  132.                                 list($br, $bg, $bb) = $this->html2rgb($this->background);
  133.                                 imagefilledrectangle($this->img, 0, 0, (int) ($data_size / $this->detail), $this->height * sizeof($this->converted_wav), imagecolorallocate($this->img, $br, $bg, $bb));
  134.                         }
  135.                 }
  136.  
  137.                 imagesetthickness($this->img, 3);
  138.  
  139.                 while(!feof($handle) && $data_point < $data_size){
  140.                         if ($data_point++ % $this->detail == 0) {
  141.                                 $bytes = array();
  142.  
  143.                                 // get number of bytes depending on bitrate
  144.                                 for ($i = 0; $i < $byte; $i++)
  145.                                         $bytes[$i] = fgetc($handle);
  146.  
  147.                                 switch($byte){
  148.                                        
  149.                                         // get value for 8-bit wav
  150.                                         case 1:
  151.                                                 $data = $this->findValues($bytes[0], $bytes[1]);
  152.                                         break;
  153.  
  154.                                         // get value for 16-bit wav
  155.                                         case 2:
  156.                                                 if(ord($bytes[1]) & 128)
  157.                                                         $temp = 0;
  158.                                                 else
  159.                                                         $temp = 128;
  160.  
  161.                                                 $temp = chr((ord($bytes[1]) & 127) + $temp);
  162.                                                 $data = floor($this->findValues($bytes[0], $temp) / 256);
  163.                                         break;
  164.                                 }
  165.  
  166.                                 // skip bytes for memory optimization
  167.                                 fseek($handle, $ratio, SEEK_CUR);
  168.  
  169.                                 // draw this data point
  170.                                 // relative value based on height of image being generated
  171.                                 // data values can range between 0 and 255
  172.                                 $v = (int) ($data / 255 * $this->height);
  173.  
  174.                                 if($v < 20)
  175.                                         $v = 20;
  176.  
  177.                                 // don't print flat values on the canvas if not necessary
  178.                                 if (!($v / $this->height == 0.5 && !$this->draw_flat))
  179.                                         // draw the line on the image using the $v value and centering it vertically on the canvas
  180.                                         imageline(
  181.                                                 $this->img,
  182.                                                 // x1
  183.                                                 (int) ($data_point / $this->detail),
  184.                                                 // y1: height of the image minus $v as a percentage of the height for the wave amplitude
  185.                                                 $this->height - $v,
  186.                                                 // x2
  187.                                                 (int) ($data_point / $this->detail),
  188.                                                 // y2: same as y1, but from the bottom of the image
  189.                                                 $this->height,
  190.                                                 imagecolorallocate($this->img, 56, 56, 56)
  191.                                         );        
  192.  
  193.                         } else {
  194.                                 // skip this one due to lack of detail
  195.                                 fseek($handle, $ratio + $byte, SEEK_CUR);
  196.                         }
  197.                 }
  198.      
  199.                 // close and cleanup
  200.                 fclose($handle);
  201.  
  202.                 // delete the processed wav file
  203.                 unlink($this->converted_wav);
  204.  
  205.                 return $this;
  206.         }
  207.  
  208.         /**
  209.         * Save wave file
  210.         *
  211.         * @return void
  212.         */
  213.         public function save($path){
  214.                 // resample the image to the proportions defined in the form
  215.                 $rimg = imagecreatetruecolor($this->width, $this->height);
  216.  
  217.                 // save alpha from original image
  218.                 imagesavealpha($rimg, true);
  219.                 imagealphablending($rimg, false);
  220.  
  221.                 // copy to resized
  222.                 imagecopyresampled($rimg, $this->img, 0, 0, 0, 0, $this->width, $this->height, imagesx($this->img), imagesy($this->img));
  223.                
  224.                 //save
  225.                 imagepng($rimg, $path);
  226.  
  227.                 imagedestroy($rimg);
  228.  
  229.                 imagedestroy($this->img);
  230.         }
  231.  
  232.         /**
  233.         *
  234.         */
  235.         private function findValues($byte1, $byte2){
  236.  
  237.                 $byte1 = hexdec(bin2hex($byte1));
  238.                 $byte2 = hexdec(bin2hex($byte2));
  239.  
  240.                 return ($byte1 + ($byte2*256));
  241.         }
  242.  
  243.         /**
  244.         * Convert HEX to RGB
  245.         *
  246.         * @return array
  247.         */
  248.         private function html2rgb($input) {
  249.                 $input=($input[0]=="#")?substr($input, 1,6):substr($input, 0,6);
  250.  
  251.                 return array(
  252.                         hexdec(substr($input, 0, 2)),
  253.                         hexdec(substr($input, 2, 2)),
  254.                         hexdec(substr($input, 4, 2))
  255.                 );
  256.         }
  257. }
clone this paste RAW Paste Data