}
     switch ($byte) {
         // get value for 8-bit wav
         case 1:
             $data = findValues($bytes[0], $bytes[1]);
             break;
             // get value for 16-bit wav
         // 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(findValues($bytes[0], $temp) / 256);
             break;
     }
     // skip bytes for memory optimization
     fseek($handle, $ratio, SEEK_CUR);
     // draw this data point
     // data values can range between 0 and 255
     $x1 = $x2 = number_format($data_point / $data_size * 100, 2);
     $y1 = number_format($data / 255 * 100, 2);
     $y2 = 100 - $y1;
     // don't bother plotting if it is a zero point
     if ($y1 != $y2) {
         $svg .= "<line x1=\"{$x1}%\" y1=\"{$y1}%\" x2=\"{$x2}%\" y2=\"{$y2}%\" />";
     }
 } else {
     // skip this one due to lack of detail
Esempio n. 2
0
function generateSoundWave($input, $output, $width, $height, $foreground, $background)
{
    /**
     * PROCESS THE FILE
     */
    // temporary file name
    $tmpname = substr(md5(time()), 0, 10);
    $draw_flat = false;
    // copy from temp upload directory to current
    copy($input, "{$tmpname}_o.mp3");
    // array of wavs that need to be processed
    $wavs_to_process = array();
    /**
     * 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");
    $wavs_to_process[] = "{$tmpname}.wav";
    // delete temporary files
    unlink("{$tmpname}_o.mp3");
    unlink("{$tmpname}.mp3");
    $img = false;
    // generate foreground color
    list($r, $g, $b) = html2rgb($foreground);
    // process each wav individually
    for ($wav = 1; $wav <= sizeof($wavs_to_process); $wav++) {
        $filename = $wavs_to_process[$wav - 1];
        /**
         * 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($filename, "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($filename) - 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 (!$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)
            $img = imagecreatetruecolor($data_size / DETAIL, $height * sizeof($wavs_to_process));
            // fill background of image
            if ($background == "") {
                // transparent background specified
                imagesavealpha($img, true);
                $transparentColor = imagecolorallocatealpha($img, 0, 0, 0, 127);
                imagefill($img, 0, 0, $transparentColor);
            } else {
                list($br, $bg, $bb) = html2rgb($background);
                imagefilledrectangle($img, 0, 0, (int) ($data_size / DETAIL), $height * sizeof($wavs_to_process), imagecolorallocate($img, $br, $bg, $bb));
            }
        }
        while (!feof($handle) && $data_point < $data_size) {
            if ($data_point++ % 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 = findValues($bytes[0], $bytes[1]);
                        break;
                        // get value for 16-bit wav
                    // 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(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 * $height);
                // don't print flat values on the canvas if not necessary
                if (!($v / $height == 0.5 && !$draw_flat)) {
                    // draw the line on the image using the $v value and centering it vertically on the canvas
                    imageline($img, (int) ($data_point / DETAIL), $height * $wav - $v, (int) ($data_point / DETAIL), $height * $wav - ($height - $v), imagecolorallocate($img, $r, $g, $b));
                }
            } else {
                // skip this one due to lack of detail
                fseek($handle, $ratio + $byte, SEEK_CUR);
            }
        }
        fclose($handle);
        // delete the processed wav file
        unlink($filename);
    }
    // want it resized?
    $rimg = imagecreatetruecolor($width, $height);
    // save alpha from original image
    imagesavealpha($rimg, true);
    imagealphablending($rimg, false);
    // copy to resized
    imagecopyresampled($rimg, $img, 0, 0, 0, 0, $width, $height, imagesx($img), imagesy($img));
    imagepng($rimg, $output, 5);
    imagedestroy($rimg);
    imagedestroy($img);
}
Esempio n. 3
0
function mp3toWavForm($fname, $width = 500, $height = 50, $foreground = '#E2E2FF', $background = '#000000', $detail = 3)
{
    $fileInfo = new SplFileInfo($fname);
    $finalFilename = preg_split('/\\./', $fileInfo->getFilename());
    $finalFilename = md5($finalFilename[0]) . '.png';
    /**
     * PROCESS THE FILE
     */
    // temporary file name
    $tmpname = substr(md5(time()), 0, 10);
    // copy from temp upload directory to current
    copy($fname, "{$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.exe {$tmpname}_o.mp3 -f -m m -b 16 --resample 8 {$tmpname}.mp3 && lame --decode {$tmpname}.mp3 {$tmpname}.wav");
    // delete temporary files
    @unlink("{$tmpname}_o.mp3");
    @unlink("{$tmpname}.mp3");
    $filename = "{$tmpname}.wav";
    /**
     * 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($filename, "r");
    //dohvacanje zaglavlja wav datoteke
    $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));
    //bitrate wav datoteke
    $peek = hexdec(substr($heading[10], 0, 2));
    $byte = $peek / 8;
    //provjera da li se radi o mono ili stereo wavu
    $channel = hexdec(substr($heading[6], 0, 2));
    if ($channel == 2) {
        $omjer = 40;
    } else {
        $omjer = 80;
    }
    while (!feof($handle)) {
        $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[] = findValues($bytes[0], $bytes[1]);
                break;
                //get value for 16-bit wav
            //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(findValues($bytes[0], $temp) / 256);
                break;
        }
        //skip bytes for memory optimization
        fread($handle, $omjer);
    }
    // close and cleanup
    fclose($handle);
    unlink("{$tmpname}.wav");
    /**
     * Image generation
     */
    // header("Content-Type: image/png");
    // 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
    // get user vars from form
    // create original image width based on amount of detail
    $img = imagecreatetruecolor(sizeof($data) / $detail, $height);
    // fill background of image
    list($r, $g, $b) = html2rgb($background);
    imagefilledrectangle($img, 0, 0, sizeof($data) / $detail, $height, imagecolorallocate($img, $r, $g, $b));
    // generate background color
    list($r, $g, $b) = html2rgb($foreground);
    // loop through frames/bytes of wav data as genearted above
    for ($d = 0; $d < sizeof($data); $d += $detail) {
        // relative value based on height of image being generated
        // data values can range between 0 and 255
        $v = (int) ($data[$d] / 255 * $height);
        // draw the line on the image using the $v value and centering it vertically on the canvas
        imageline($img, $d / $detail, 0 + ($height - $v), $d / $detail, $height - ($height - $v), imagecolorallocate($img, $r, $g, $b));
    }
    //create file
    $fp = fopen('images/' . $finalFilename, 'w');
    fclose($fp);
    // want it resized?
    if ($width) {
        // resample the image to the proportions defined in the form
        $rimg = imagecreatetruecolor($width, $height);
        imagecopyresampled($rimg, $img, 0, 0, 0, 0, $width, $height, sizeof($data) / $detail, $height);
        imagepng($rimg, 'images/' . $finalFilename);
        imagedestroy($rimg);
    } else {
        // print out at it's raw width (size of $data / detail level)
        imagepng($img, 'images/' . $finalFilename);
        imagedestroy($img);
    }
    return 'images/' . $finalFilename;
}
function mp3_waveform($fname, $width, $height, $foreground, $background)
{
    /**
     * PROCESS THE FILE
     */
    // temporary file name
    $tmpname = '/tmp/' . substr(md5(time()), 0, 10);
    // copy from temp upload directory to current
    copy($fname, "{$tmpname}_o.mp3");
    $imagename = preg_replace('%^(.*)\\.[^.]+$%', '\\1-wave', $fname) . '.png';
    /**
     * 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("/usr/local/bin/lame {$tmpname}_o.mp3 --quiet -f -m s -b 64 --resample 8 {$tmpname}.mp3 &&"
    //	." /usr/local/bin/lame --quiet --decode {$tmpname}.mp3 {$tmpname}.wav");
    exec("/usr/local/bin/sox --norm {$tmpname}_o.mp3 -r 8k -b 8 -e unsigned -c 2 {$tmpname}.wav");
    // delete temporary files
    @unlink("{$tmpname}_o.mp3");
    //@unlink("{$tmpname}.mp3");
    $filename = "{$tmpname}.wav";
    if (!file_exists($filename)) {
        print "Error: WAV file not generated. Please verify directory write and execute permissions.";
        exit;
    }
    /**
     * 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($filename, "r");
    // format: see http://web.archive.org/web/19991115123323/http://www.borg.com/~jglatt/tech/wave.htm
    $heading[0] = fread($handle, 4);
    // "RIFF"
    $heading[1] = bin2hex(fread($handle, 4));
    // lSize
    $heading[2] = fread($handle, 4);
    // "WAVE"
    $heading[3] = fread($handle, 4);
    // "fmt " (format chunk)
    $heading[4] = bin2hex(fread($handle, 4));
    // lChunkSize
    $heading[5] = bin2hex(fread($handle, 2));
    // wFormatTag (=1)
    $heading[6] = bin2hex(fread($handle, 2));
    // wChannels (=2 for stereo)
    $heading[7] = bin2hex(fread($handle, 4));
    // dwSamplesPerSec
    $heading[8] = bin2hex(fread($handle, 4));
    // dwAvgBytesPerSec
    $heading[9] = bin2hex(fread($handle, 2));
    // wBlockAlign
    $heading[10] = bin2hex(fread($handle, 2));
    // wBitsPerSample
    $heading[11] = fread($handle, 4);
    // "data"
    $heading[12] = bin2hex(fread($handle, 4));
    // lChunkSize
    //bitrate wav datoteke
    $peek = hexdec(substr($heading[10], 0, 2));
    $byte = $peek / 8;
    //provjera da li se radi o mono ili stereo wavu
    $channel = hexdec(substr($heading[6], 0, 2));
    $datasize = hexdec(substr($heading[12], 6, 2) . substr($heading[12], 4, 2) . substr($heading[12], 2, 2) . substr($heading[12], 0, 2));
    $omjer = floor($datasize / 512 / 4);
    error_log('data size = ' . $datasize . ' (' . $heading[12] . ') / omjer = ' . $omjer);
    //if($channel == 2){
    //  $omjer = 40;
    //}
    //else{
    //  $omjer = 80;
    //}
    //error_log('channels: '.$channel);
    while (!feof($handle)) {
        for ($ch = 0; $ch < $channel; $ch++) {
            $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[$ch][] = abs(findValues($bytes[0], $bytes[1]) - 128);
                    break;
                    //get value for 16-bit wav
                //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[$ch][] = abs(floor(findValues($bytes[0], $temp) / 256) - 128);
                    break;
            }
        }
        //skip bytes for memory optimization
        fread($handle, $omjer);
    }
    // close and cleanup
    fclose($handle);
    unlink("{$tmpname}.wav");
    /**
     * Image generation
     */
    // 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
    $size = sizeof($data[0]);
    $step = min(array(1, 2 * round($size / $width)));
    //1
    // create original image width based on amount of detail
    $img = imagecreatetruecolor($size / $step, $height);
    // fill background of image
    if ($background == "") {
        imagesavealpha($img, true);
        $transparentColor = imagecolorallocatealpha($img, 0, 0, 0, 127);
        imagefill($img, 0, 0, $transparentColor);
    } else {
        list($r, $g, $b) = html2rgb($background);
        imagefilledrectangle($img, 0, 0, $size / $step, $height, imagecolorallocate($img, $r, $g, $b));
    }
    // generate foreground color
    list($r, $g, $b) = html2rgb($foreground);
    //error_log('size:'.$size);
    if ($size < $width) {
        $thickness = 1;
    } else {
        $thickness = $size / ($width * 2);
    }
    imagesetthickness($img, $thickness);
    $mx = 0;
    for ($d = 0; $d < $size; $d += $step) {
        if (abs($data[0][$d]) > $mx) {
            $mx = abs($data[0][$d]);
        }
        if (abs($data[1][$d]) > $mx) {
            $mx = abs($data[1][$d]);
        }
    }
    $mx *= 1.1;
    // loop through frames/bytes of wav data as genearted above
    for ($d = 0; $d < $size; $d += $step) {
        // relative value based on height of image being generated
        // data values can range between 0 and 255
        $c1 = (int) ($data[0][$d] * $height / 2 / $mx);
        $c2 = (int) ($data[1][$d] * $height / 2 / $mx);
        //error_log('L='.$data[0][$d].' / R='.$data[1][$d]);
        // draw the line on the image using the $v value and centering it vertically on the canvas
        //imageline($img, $d / $step, round($c1), $d / $step, round($height-$c2), imagecolorallocate($img, $r, $g, $b));
        imageline($img, $d / $step, $height / 2, $d / $step, $height / 2 - $c1, imagecolorallocate($img, $r, $g, $b));
        imageline($img, $d / $step, $height / 2, $d / $step, $height / 2 + $c2, imagecolorallocate($img, $r, $g, $b));
    }
    // want it resized?
    if ($width) {
        // resample the image to the proportions defined in the form
        $rimg = imagecreatetruecolor($width, $height);
        // save alpha from original image
        imagesavealpha($rimg, true);
        imagealphablending($rimg, false);
        // copy to resized
        imagecopyresampled($rimg, $img, 0, 0, 0, 0, $width, $height, $size / $step, $height);
        imagepng($rimg, $imagename);
        imagedestroy($rimg);
    } else {
        // print out at it's raw width (size of $data / detail level)
        imagepng($img, $imagename);
        imagedestroy($img);
    }
    unset($data);
    return $imagename;
}