Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php defined('SYSPATH') OR die('No direct access allowed.');
- class Wave_Core {
- public $width = 1906;
- public $height = 100;
- public $foreground = "#cccccc";
- public $background = "";
- public $draw_flat = false;
- public $stereo = true;
- public $path = null;
- public $img = false;
- public $converted_wav = null;
- // how much detail we want. Larger number means less detail
- // (basically, how many bytes/frames to skip processing)
- // the lower the number means longer processing time
- public $detail = 5;
- public static function instance(){
- return new self;
- }
- /**
- * Input song data
- *
- * @path string image path
- * @stereo_support bool
- *
- * @return instance
- */
- public function input_file($path, $stereo_support){
- $this->path = $path;
- $this->stereo = $stereo_support;
- return $this;
- }
- /**
- * Convert MP3 file to Wav
- *
- * @return void
- */
- public function convert(){
- $tmpname = "temp/".Helper::uuid1();
- //make file copy
- copy($this->path, $tmpname."_o.mp3");
- // convert mp3 to wav using lame decoder
- // First, resample the original mp3 using as mono (-m m), 16 bit (-b 16), and 8 KHz (--resample 8)
- // Secondly, convert that resampled mp3 into a wav
- // We don't necessarily need high quality audio to produce a waveform, doing this process reduces the WAV
- // to it's simplest form and makes processing significantly faster
- exec("lame {$tmpname}_o.mp3 -m m -S -f -b 16 --resample 8 {$tmpname}.mp3 && lame -S --decode {$tmpname}.mp3 {$tmpname}.wav");
- $this->converted_wav = "{$tmpname}.wav";
- // delete temporary files
- unlink("{$tmpname}_o.mp3");
- unlink("{$tmpname}.mp3");
- }
- /**
- * Convert file
- *
- * @return instance
- */
- public function generate_wave(){
- //convert to wav
- $this->convert();
- // generate foreground color
- list($r, $g, $b) = $this->html2rgb($this->foreground);
- /**
- * Below as posted by "zvoneM" on
- * http://forums.devshed.com/php-development-5/reading-16-bit-wav-file-318740.html
- * as findValues() defined above
- * Translated from Croation to English - July 11, 2011
- */
- $handle = fopen($this->converted_wav, "r");
- // wav file header retrieval
- $heading[] = fread($handle, 4);
- $heading[] = bin2hex(fread($handle, 4));
- $heading[] = fread($handle, 4);
- $heading[] = fread($handle, 4);
- $heading[] = bin2hex(fread($handle, 4));
- $heading[] = bin2hex(fread($handle, 2));
- $heading[] = bin2hex(fread($handle, 2));
- $heading[] = bin2hex(fread($handle, 4));
- $heading[] = bin2hex(fread($handle, 4));
- $heading[] = bin2hex(fread($handle, 2));
- $heading[] = bin2hex(fread($handle, 2));
- $heading[] = fread($handle, 4);
- $heading[] = bin2hex(fread($handle, 4));
- // wav bitrate
- $peek = hexdec(substr($heading[10], 0, 2));
- $byte = $peek / 8;
- // checking whether a mono or stereo wav
- $channel = hexdec(substr($heading[6], 0, 2));
- $ratio = ($channel == 2 ? 40 : 80);
- // start putting together the initial canvas
- // $data_size = (size_of_file - header_bytes_read) / skipped_bytes + 1
- $data_size = floor((filesize($this->converted_wav) - 44) / ($ratio + $byte) + 1);
- $data_point = 0;
- // now that we have the data_size for a single channel (they both will be the same)
- // we can initialize our image canvas
- if (!$this->img) {
- // create original image width based on amount of detail
- // each waveform to be processed with be $height high, but will be condensed
- // and resized later (if specified)
- $this->img = imagecreatetruecolor($data_size / $this->detail, $this->height * sizeof($this->converted_wav));
- // fill background of image
- if ($this->background == "") {
- // transparent background specified
- imagesavealpha($this->img, true);
- $transparentColor = imagecolorallocatealpha($this->img, 0, 0, 0, 127);
- imagefill($this->img, 0, 0, $transparentColor);
- } else {
- list($br, $bg, $bb) = $this->html2rgb($this->background);
- imagefilledrectangle($this->img, 0, 0, (int) ($data_size / $this->detail), $this->height * sizeof($this->converted_wav), imagecolorallocate($this->img, $br, $bg, $bb));
- }
- }
- imagesetthickness($this->img, 3);
- while(!feof($handle) && $data_point < $data_size){
- if ($data_point++ % $this->detail == 0) {
- $bytes = array();
- // get number of bytes depending on bitrate
- for ($i = 0; $i < $byte; $i++)
- $bytes[$i] = fgetc($handle);
- switch($byte){
- // get value for 8-bit wav
- case 1:
- $data = $this->findValues($bytes[0], $bytes[1]);
- break;
- // get value for 16-bit wav
- case 2:
- if(ord($bytes[1]) & 128)
- $temp = 0;
- else
- $temp = 128;
- $temp = chr((ord($bytes[1]) & 127) + $temp);
- $data = floor($this->findValues($bytes[0], $temp) / 256);
- break;
- }
- // skip bytes for memory optimization
- fseek($handle, $ratio, SEEK_CUR);
- // draw this data point
- // relative value based on height of image being generated
- // data values can range between 0 and 255
- $v = (int) ($data / 255 * $this->height);
- if($v < 20)
- $v = 20;
- // don't print flat values on the canvas if not necessary
- if (!($v / $this->height == 0.5 && !$this->draw_flat))
- // draw the line on the image using the $v value and centering it vertically on the canvas
- imageline(
- $this->img,
- // x1
- (int) ($data_point / $this->detail),
- // y1: height of the image minus $v as a percentage of the height for the wave amplitude
- $this->height - $v,
- // x2
- (int) ($data_point / $this->detail),
- // y2: same as y1, but from the bottom of the image
- $this->height,
- imagecolorallocate($this->img, 56, 56, 56)
- );
- } else {
- // skip this one due to lack of detail
- fseek($handle, $ratio + $byte, SEEK_CUR);
- }
- }
- // close and cleanup
- fclose($handle);
- // delete the processed wav file
- unlink($this->converted_wav);
- return $this;
- }
- /**
- * Save wave file
- *
- * @return void
- */
- public function save($path){
- // resample the image to the proportions defined in the form
- $rimg = imagecreatetruecolor($this->width, $this->height);
- // save alpha from original image
- imagesavealpha($rimg, true);
- imagealphablending($rimg, false);
- // copy to resized
- imagecopyresampled($rimg, $this->img, 0, 0, 0, 0, $this->width, $this->height, imagesx($this->img), imagesy($this->img));
- //save
- imagepng($rimg, $path);
- imagedestroy($rimg);
- imagedestroy($this->img);
- }
- /**
- *
- */
- private function findValues($byte1, $byte2){
- $byte1 = hexdec(bin2hex($byte1));
- $byte2 = hexdec(bin2hex($byte2));
- return ($byte1 + ($byte2*256));
- }
- /**
- * Convert HEX to RGB
- *
- * @return array
- */
- private function html2rgb($input) {
- $input=($input[0]=="#")?substr($input, 1,6):substr($input, 0,6);
- return array(
- hexdec(substr($input, 0, 2)),
- hexdec(substr($input, 2, 2)),
- hexdec(substr($input, 4, 2))
- );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement