Beispiel #1
0
 /**
  * Create waves in GD images format from WAV (PCM) file
  * Wave file reading based on a post by "zvoneM" on
  * 	http://forums.devshed.com/php-development-5/reading-16-bit-wav-file-318740.html
  * Completely rewritten the file read loop, kept the header reading intact.
  *
  * Waveform drawing from https://github.com/afreiday/php-waveform-png
  *
  * Reads width * ACCURACY data points from the file and takes the peak value of accuracy values.
  *	The peak is the highest value if mean is > 127 and the lowest value otherwise.
  * Data point is the average of ACCURACY points in the data block.
  */
 private function createWaves($wavfilename)
 {
     define('ACCURACY', 100);
     // default optimal accuracy
     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     // Create palette based image
     // if background == '' we convert it to true color image later then
     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     $this->waveImg = imagecreate($this->width, $this->height);
     // fill background of image
     if ($this->backgroundColor == '') {
         // try to choose color that does not match
         // waveColor or progressColor
         // three colors should be sufficient
         $colors = array('#FFFFFF', '#000000', '#FF0000');
         foreach ($colors as $col) {
             $tempBackground = $col;
             if ($tempBackground != strtoupper($this->waveColor) && $tempBackground != strtoupper($this->progressColor)) {
                 break;
             }
         }
     } else {
         $tempBackground = $this->backgroundColor;
     }
     list($r, $g, $b) = JustWave::html2rgb($tempBackground);
     $transparentColor = imagecolorallocate($this->waveImg, $r, $g, $b);
     imagefilledrectangle($this->waveImg, 0, 0, $this->width, $this->height, $transparentColor);
     // generate foreground color
     list($r, $g, $b) = JustWave::html2rgb($this->waveColor);
     $waveColor = imagecolorallocate($this->waveImg, $r, $g, $b);
     //		$subColor = imagecolorallocate($this->waveImg, (int)$r * 0.5 , (int)$g * 0.5, (int) $b * 0.5);
     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     // Read wave header
     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     $handle = fopen($wavfilename, 'rb');
     $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));
     if ($heading[5] != '0100') {
         $this->raiseError('Wave file should be a PCM file');
         return false;
     }
     $peek = hexdec(substr($heading[10], 0, 2));
     $byte = $peek / 8;
     $channel = hexdec(substr($heading[6], 0, 2));
     // point = one data point (pixel), width total
     // block = one block, there are $accuracy blocks per point
     // chunk = one data point 8 or 16 bit, mono or stereo
     $filesize = filesize($wavfilename);
     $chunksize = $byte * $channel;
     $file_chunks = ($filesize - 44) / $chunksize;
     if ($file_chunks < $this->width) {
         $this->raiseError("Wave file has {$file_chunks} chunks, " . $this->width . ' required');
         return false;
     }
     if ($file_chunks < $this->width * ACCURACY) {
         $accuracy = 1;
     } else {
         $accuracy = ACCURACY;
     }
     $point_chunks = $file_chunks / $this->width;
     $block_chunks = $file_chunks / ($this->width * $accuracy);
     $blocks = array();
     $points = 0;
     $current_file_position = 44.0;
     // float, because chunks/point and clunks/block are floats too.
     fseek($handle, 44);
     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     // Read the data points and draw the image
     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     while (!feof($handle)) {
         // The next file position is the float value rounded to the closest chunk
         // Read the next block, take the first value (of the first channel)
         $real_pos_diff = ($current_file_position - 44) % $chunksize;
         if ($real_pos_diff > $chunksize / 2) {
             $real_pos_diff -= $chunksize;
         }
         fseek($handle, $current_file_position - $real_pos_diff);
         $chunk = fread($handle, $chunksize);
         if (feof($handle) && !strlen($chunk)) {
             break;
         }
         $current_file_position += $block_chunks * $chunksize;
         if ($byte == 1) {
             $blocks[] = ord($chunk[0]);
         } else {
             $blocks[] = ord($chunk[1]) ^ 128;
         }
         // 16 bit
         // Do we have enough blocks for the current point?
         if (count($blocks) >= $accuracy) {
             // Calculate the mean and add the peak value to the array of blocks
             sort($blocks);
             $mean = count($blocks) % 2 ? $blocks[(count($blocks) - 1) / 2] : ($blocks[count($blocks) / 2] + $blocks[count($blocks) / 2 - 1]) / 2;
             if ($mean > 127) {
                 $point = array_pop($blocks);
             } else {
                 $point = array_shift($blocks);
             }
             // Draw
             $lineheight = round($point / 255 * $this->height);
             imageline($this->waveImg, $points, 0 + ($this->height - $lineheight), $points, $this->height - ($this->height - $lineheight), $waveColor);
             // update vars
             $points++;
             $blocks = array();
         }
     }
     // close wave file
     fclose($handle);
     // final line
     imageline($this->waveImg, 0, round($this->height / 2), $this->width, round($this->height / 2), $waveColor);
     if ($this->waveColor != $this->progressColor) {
         $this->progressImg = imagecreate($this->width, $this->height);
         imagecopy($this->progressImg, $this->waveImg, 0, 0, 0, 0, $this->width, $this->height);
         // change waveColor to progressColor
         $index = imagecolorclosest($this->waveImg, $r, $g, $b);
         list($r, $g, $b) = JustWave::html2rgb($this->progressColor);
         imagecolorset($this->progressImg, $index, $r, $g, $b);
     }
     // try to save transparency
     if ($this->backgroundColor == '') {
         imagealphablending($this->waveImg, false);
         imagesavealpha($this->waveImg, true);
         imagealphablending($this->waveImg, true);
         imagecolortransparent($this->waveImg, $transparentColor);
         if ($this->waveColor != $this->progressColor) {
             imagealphablending($this->progressImg, false);
             imagesavealpha($this->progressImg, true);
             imagealphablending($this->progressImg, true);
             imagecolortransparent($this->progressImg, $transparentColor);
         }
     }
     return true;
 }
Beispiel #2
0
$mask = array_shift($argv);
// default prog_color must be the same as wave_color
// in order to generate one image instead of two
$argv[] = 'prog_color=#909296';
// we need set prog_color to wave_color
// in order to get one wave image instead of two
foreach ($argv as $val) {
    if (preg_match('/^wave_color=(.*)$/', $val, $m)) {
        $argv[] = 'prog_color=' . $m[1];
    }
}
// always use file mode
$argv[] = 'mode=file';
require_once 'JustWave.class.php';
// make class instance with ARGV parameters
$justwave = new JustWave('ARGV', $argv);
$numOfTotalFiles = $numOfSuccessFiles = 0;
foreach (glob($mask) as $fileName) {
    // create waves' images
    printf('Creating wave for %s', $fileName);
    $justwave->create($fileName);
    // rename image wave from key name to audio name
    if ($justwave->status == 'ok') {
        $name = pathinfo($justwave->audio, PATHINFO_FILENAME);
        $newName = str_replace($justwave->key, $name, $justwave->dataUrlWave);
        if ($newName) {
            rename($justwave->dataUrlWave, $newName);
            $justwave->dataUrlWave = $newName;
        }
        $numOfSuccessFiles++;
    } else {
Beispiel #3
0
<?php

if (!isset($_GET['mode'])) {
    header('Location: script.php?mode=file&wave_color=F00&prog_color=F00&back_color=00AC00');
    die;
}
require_once 'JustWave.class.php';
// we accept parameters as GET data
// e.g.: script.php?mode=file&wave_color=F00&prog_color=F00&back_color=00AC00
$justwave = new JustWave('GET');
// create waveform image(s)
$justwave->create('media/We Wish You.mp3');
if ($justwave->status == 'ok') {
    echo 'Duration of We Wish You.mp3 = ' . $justwave->duration . '<br>';
    echo 'See waveform image under the link: <a href="' . $justwave->dataUrlWave . '">waveform</a>';
} else {
    echo 'Failed! Message = ' . $justwave->message;
}
Beispiel #4
0
<?php

/* ***************************** */
/*  		JustWave project				 */
/*	(c) beotiger 2014-2015 AD		 */
/*	http://justwave.beotiger.com */
/*	https://github.com/beotiger  */
/*	email: beotiger@gmail.com		 */
/* ***************************** */
require_once 'JustWave.class.php';
if (isset($_POST['audio'])) {
    // make class instance with default to POST parameters
    $justwave = new JustWave();
    // create waveform image(s)
    $justwave->create($_POST['audio']);
    // return as JSON data
    die($justwave->json());
}
die(json_encode(array('status' => 'err', 'message' => 'No source audio parameter')));