#1
  1. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Sep 2004
    Location
    Croatia
    Posts
    628
    Rep Power
    0

    Reading 16 bit wav file


    hi! i'm having problem reading 16 bit wav files with php and it is starting to drive me crazy!
    i have written a small and simple script that will read wav file and create graph from it.
    now, it works as it should with 8 bit wav files. i'm getting all data as i'm supose to, but when it comes to 16 bit files i'm getting crap.
    i thought that in wav file you read chuncks as it is marked in header - so at 8 bit wav chunck is 8 bit long, at 16 bit wav 16 bit...
    anyway, here is part of the script where i read wav and put that in array:
    PHP Code:
    $filename $_GET['wav'];
        
    $handle fopen ($filename"r");
        
    //dohvačanje zaglavlja wav datoteke
            //here i read wav headers
        
    $zaglavlje[] = bin2hex (fread ($handle4));
        
    $zaglavlje[] = bin2hex (fread ($handle4));
        
    $zaglavlje[] = bin2hex (fread ($handle4));
        
    $zaglavlje[] = bin2hex (fread ($handle4));
        
    $zaglavlje[] = bin2hex (fread ($handle4));
        
    $zaglavlje[] = bin2hex (fread ($handle2));
        
    $zaglavlje[] = bin2hex (fread ($handle2));
        
    $zaglavlje[] = bin2hex (fread ($handle4));
        
    $zaglavlje[] = bin2hex (fread ($handle4));
        
    $zaglavlje[] = bin2hex (fread ($handle2));
        
    $zaglavlje[] = bin2hex (fread ($handle2));
        
    $zaglavlje[] = bin2hex (fread ($handle4));
        
    $zaglavlje[] = bin2hex (fread ($handle4));
        
        
    //bitrate wav datoteke
            //this is wav bitrate
        
    $peek hexdec(substr($zaglavlje[10], 02));
        
        
    //provjera da li se radi o mono ili stereo wavu
            //here i check if it's stereo or mono wav
        
    $kanala hexdec(substr($zaglavlje[6], 02));
        if(
    $kanala == 2){
            
    $omjer 20;
        }
        else{
            
    $omjer 40;
        }
        
        
    //čitanje podataka iz datoteke - čita se samo 600 elemenata za mono wav ili 1200 za stereo radi uštede na memoriji i procesorskom vremenu
        
    while(!feof($handle)){
                    
    //read number of bytes determend by bitrate
            
    $bps fread($handle$peek 8);
            if(
    strlen($bps) == 0){
                break;
            }
                    
    //put value of wav chunk in array
            
    $data[] = hexdec(bin2hex($bps));
                    
    //skip some chunks for memory optimization
            
    fread($handle, ($peek 8) * $omjer);
        }
        
    fclose ($handle); 
    test script you can see at http://www.next.hr/tempZ/obrada_signala/
    go to dir zvukovi and then muski. there are some wav files. check pr_m1.wav and pr_m1-8bit.wav. they are identical just one is 16 and one is 8 bit. same is with test6.wav and test6-8bit.wav at test -> novi dir.
    all 8 bit wavs are drawn as they should and 16 bit are just noise.
    i'm doing something wrong with reading wavs just i don't knaw what!

    thanx for any help!
  2. #2
  3. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Sep 2004
    Location
    Croatia
    Posts
    628
    Rep Power
    0
    ok, to make it more clear here are link to txt files of output of aray that i get reading two identical wavs (one 8 bit and another 16 version)
    http://www.next.hr/tempZ/obrada_signala/8bit.txt
    http://www.next.hr/tempZ/obrada_signala/16bit.txt
    as you can see in 8 bit version values are ok. 128 is silence (that would resault in flat line on graph) but on 16 bit i get all sort of values
  4. #3
  5. Rocking my php-ness
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Dec 2004
    Location
    Boston, MA
    Posts
    1,961
    Rep Power
    155
    I know nothing about the wav file format, but does this help at all:

    http://www.sonicspot.com/guide/wavefiles.html
  6. #4
  7. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Sep 2004
    Location
    Croatia
    Posts
    628
    Rep Power
    0
    well, on http://ccrma.stanford.edu/CCRMA/Cour...ts/WaveFormat/ i found that 16-bit samples are stored as 2's-complement signed integers, ranging from -32768 to 32767
    now i onley need to calculate that
  8. #5
  9. I fail at spelling
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Sep 2003
    Location
    NDAuNjIxMTExLC03OS4xNTU=
    Posts
    3,219
    Rep Power
    1778
    Is it bad that I had no idea that PHP could read a wav file? I think that is super cool and man if I had any use for it and tried it before I would help you out. That's cool though. What do you do with the PHP script that can read in a wav file? What are you using it for?

    Chad
    I am working now with Symfony2, Twig, Doctrine, Composer, Assetic, and HTML5. Enjoying doing what I do everyday!
  10. #6
  11. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Sep 2004
    Location
    Croatia
    Posts
    628
    Rep Power
    0
    Originally Posted by chads2k2
    Is it bad that I had no idea that PHP could read a wav file? I think that is super cool and man if I had any use for it and tried it before I would help you out. That's cool though. What do you do with the PHP script that can read in a wav file? What are you using it for?
    Chad
    php can read any binary data, so it read can wav files. i'm using this to do wav file graph like in audio editors. you can see test script at http://www.next.hr/tempZ/obrada_signala/
    it works perfectly with 8 bit wav, but when it comes to 16 bit, everything falls apart. i just can't get it

    i wrote new script to get date for graph:
    PHP Code:
    $data file_get_contents($filename);
        
    //discard wav heared
        
    $data substr($data44strlen($data));
        if(
    $peek == 8){
            
    //for 8 bit wav split at 1 byte
            
    $data str_split($data);
        }
        else{
            
    //for 16 bit wav split at 2 bytes
            
    $data str_split($data2);
        }
        for(
    $i 0$i count($data); $i += $omjer){
            if(
    $peek == 8){
                
    //for 8 bit wav convert segment to char
                
    $data2[] = unpack("C*"$data[$i]);
            }
            else{
                
    //for 16 bit wav convert segment to unsigned integer
                
    $temp unpack("s*"$data[$i]);
                
    //convert to 8 bit format
                
    $temp round(($temp[1] / 256) + 128);
                
    $data2[] = $temp;
            }
        }
        unset(
    $data);
        if(
    $peek == 8){
            
    //change from 2 dimensional array to list
            
    foreach($data2 as $value){
                
    $data[] = $value[1];
            }
        }
        else{
            
    $data $data2;
        }
        unset(
    $data2);
        
    //print_r($data);
        //slanje headera da bi se slika ispravno prikazala
        
    header("Content-Type: image/png");
        
    crtajGraf($data8$kanala$filenamefilesize($filename)); 
    but i still get the same resault. data that i get from 16 bit file (even when i don't conver it to 8 bit format) is not what its supose to be, but it play perfectly!
    sigh!
  12. #7
  13. I fail at spelling
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Sep 2003
    Location
    NDAuNjIxMTExLC03OS4xNTU=
    Posts
    3,219
    Rep Power
    1778
    Did you know your site doesn't work with Firefox? It needs a plugin, then it can't find the plugin to install.

    Chad
    I am working now with Symfony2, Twig, Doctrine, Composer, Assetic, and HTML5. Enjoying doing what I do everyday!
  14. #8
  15. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Sep 2004
    Location
    Croatia
    Posts
    628
    Rep Power
    0
    it works with mine.
    plugin (quick time player) is needed onley to listen wav and that is not that important.
    picture is important (it's plain png)
  16. #9
  17. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Sep 2004
    Location
    Croatia
    Posts
    628
    Rep Power
    0
    solved!

    mod can delete this topic
  18. #10
  19. doesn't like link-rollover ads
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2003
    Posts
    1,818
    Rep Power
    154
    post the solution.
  20. #11
  21. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Sep 2004
    Location
    Croatia
    Posts
    628
    Rep Power
    0
    ok. here is code for reading wav files (8 and 16 bit):
    PHP Code:
    function nadjiVrijednosti($byte1$byte2){
            
    $byte1 hexdec(bin2hex($byte1));                        
            
    $byte2 hexdec(bin2hex($byte2));                        
            return (
    $byte1 + ($byte2*256));
        }
        
        
    $filename $_GET['wav'];
        
    $handle fopen ($filename"r");
        
    //dohvačanje zaglavlja wav datoteke
        
    $zaglavlje[] = fread ($handle4);
        
    $zaglavlje[] = bin2hex(fread ($handle4));
        
    $zaglavlje[] = fread ($handle4);
        
    $zaglavlje[] = fread ($handle4);
        
    $zaglavlje[] = bin2hex(fread ($handle4));
        
    $zaglavlje[] = bin2hex(fread ($handle2));
        
    $zaglavlje[] = bin2hex(fread ($handle2));
        
    $zaglavlje[] = bin2hex(fread ($handle4));
        
    $zaglavlje[] = bin2hex(fread ($handle4));
        
    $zaglavlje[] = bin2hex(fread ($handle2));
        
    $zaglavlje[] = bin2hex(fread ($handle2));
        
    $zaglavlje[] = fread ($handle4);
        
    $zaglavlje[] = bin2hex(fread ($handle4));
        
        
    //bitrate wav datoteke
        
    $peek hexdec(substr($zaglavlje[10], 02));
        
    $bajta $peek 8;
        
        
    //provjera da li se radi o mono ili stereo wavu
        
    $kanala hexdec(substr($zaglavlje[6], 02));
        
        if(
    $kanala == 2){
            
    $omjer 40;
        }
        else{
            
    $omjer 80;
        }
        
        while(!
    feof($handle)){
            
    $bytes = array();
            
    //get number of bytes depending on bitrate
            
    for ($i 0$i $bajta$i++){
                
    $bytes[$i] = fgetc($handle);
            }
            switch(
    $bajta){
                
    //get value for 8-bit wav
                
    case 1:
                    
    $data[] = nadjiVrijednosti($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(nadjiVrijednosti($bytes[0], $temp) / 256);
                    break;
            }
            
    //skip bytes for memory optimization
            
    fread ($handle$omjer);
        }
        
        
    fclose ($handle);
        
        
    print_r($data); 
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    1
    Rep Power
    0
    Hi. I'm trying to create a php script that will read mp3 files and draw wav forms for them.

    Do you think you could help me out?


    Thanks!

IMN logo majestic logo threadwatch logo seochat tools logo