Blog to Ebook Conversion (5)

Suppose you have 3,129 articles in your blog, and each article is stored in of the following files.

blog-entry-1.html
blog-entry-2.html
...
blog-entry-3128.html
blog-entry-3129.html

In such cases you can download all the files by a single command:

wget -r -np -o log.txt --accept "blog-entry-*.html" http://myFBblog.com/

This is almost OK, but when you list the names of all the files, they might appear in an order which may not be convenient for your purposes.

% ls -l blog-entry-*.html
blog-entry-1000.html
blog-entry-1001.html
...
blog-entry-998.html
blog-entry-999.html
blog-entry-99.html
blog-entry-9.html

This happens because the numbers 1 through 3129 are represented not in a fixed length. So here comes a short bash script to change the names of the files so that all digits are in four letters.

#!/bin/bash
FULL_LENGTH=20
MV=/bin/echo # change this to /bin/mv if you are sure.
for file in blog-entry-*.html
do
 myzero=(dummy 0 00 000) # the first element is indexed with zero
 len=${#file}
 if [ $len -ne $FULL_LENGTH ]
 then
  let short=$FULL_LENGTH-$len
  newfile=${file/entry-/entry-${myzero[$short]}}
  $MV $file $newfile
 fi
done
exit 0

What you will have is:

% ls -l blog-entry-*.html
blog-entry-0001.html
blog-entry-0002.html
...
blog-entry-3128.html
blog-entry-3129.html

Blog to Ebook Conversion (4)

I first intended to delete all the tags from the text body of an article, but this is obviously wrong because in that way all paragraphs will be combined to one, thus making the output very unreadable.

So it is necessary to detect a new paragraph, and insert the appropriate tags there. The problem is paragraphs are generated in the original HTML files in various ways. Some examples are:

aaa
bbb
<br />
ccc
ddd

or

<div>
aaa
bbb
</div>
<div>
 
</div>
<div>
ccc
ddd
</div>

Blog to Ebook Conversion (3)

It is possible that you have a one large file that contains all the text in your ebook, but usually we create a single file for each chapter so that ebook readers can handle and navigate the book more easily.

If you define the chapter to contain all the articles in a month, here is one example to split the single large file into the smaller files for each month.

BEGIN{
 outfile="x"
 s1="a"
 s2="a"
 out=(outfile s1 s2 ".html")
 monthb4=""
}
/<h1>/ {
  split($0,array,"/") # array begins with [1]
  if(monthb4 != array[1]) {
  monthb4=array[1]
  if(NR!=1){
  close(out)
  if(s2=="z") {
   if(s1=="z") exit 1
   s1=chr(ord(s1)+1)
   s2="a"
  }
  else
   s2=chr(ord(s2)+1)
  out=(outfile s1 s2 ".html")
  }
  }
 }
 {print > out}

The program assumes that the original file is something like this:

<h1>8/22/2011</h1>
<h2>My first article.</h2>
...
<h1>9/01/2011</h1>
<h2>My second article.</h2>
...

The first number in the line with an h1 tag is the month in which the article is posted, so each time we detect the change of the month, the file name is updated as “xaa.html”, “xab.html” and so on.

Blog to Ebook Conversion (2)

In many cases, your blog contains images which is stored at the site your blog resides. You need to download all the images from the site to be included in your ebook.

Typically, the html code is something like this:

<img border="0" src="http://yourFBblog.com/-BQdcDYPg-yI/UvHQo26PFuI/AAAAAAAABGY/cUzndRZG1lw/s1600/001.jpg" height="213" width="320" /></a>

Out of this code, you will generate % wget command such as:

wget http://yourFBblog.com/-BQdcDYPg-yI/UvHQo26PFuI/AAAAAAAABGY/cUzndRZG1lw/s1600/001.jpg

This wget command will make the file “001.jpg” in your current directory, which is OK, but one thing you must consider is that the URLs are unique but not the file names. If you have some number of different URLs with the same file name such as “001.jpg”, wget will automatically generate the files “001.jpg”, “001.jpg.1”, “001.jpg.2” and so on. This is sometimes inconvenient, and it may also happen that the original file names are either very long or encoded in a character code which you may wish to avoid to handle.

Therefore, my short awk program is:

{
 gsub(/<img.*src="/, "")
 gsub(/\.JPG.*$/     , ".JPG")
 gsub(/\.jpg.*$/     , ".jpg")
 printf("wget -O myfile%03d.jpg %s\n",count, $0)
 count++
}

This program generate a wget command each time it finds an img tag, and the images are stored into serially numbered files, such as “myfile000.jpg”, “myfile001.jpg”, and so on.

BEGIN{
 nrsave_date =-999
 nrsave_title=-999
 img_count=0
}

 /<h2 class='date-header'>/ {nrsave_date=NR}
 /<h3 class='post-title entry-title' itemprop='name'>/ {nrsave_title=NR}
 NR==nrsave_date +2 {print "<h1>" $0 "</h1>"}
 NR==nrsave_title+2 {print "<h2>" $0 "</h2>"}

 /post-body entry-content/, /post-footer/ {
  gsub(" "  , " ")
  if(/^[[:blank:]]+$/) next
  if(/^<img/) {
   printf("<img src=\"../Images/myfile%03d.jpg\" />\n", img_count)
   img_count++
  }
  if(/^</);
  else
  print $0
 }

This is the new awk program to generate an html file, in which img src is rewritten as a local reference. The html file, along with the img files, can be converted into an ebook by using an authoring tool such as SIGIL.

Blog to Ebook Conversion

This is one way to make an ebook out of your blog. It largely depends on what style sheet (CSS) you are using, so actually you need a lot of adjustments before you actually get some practical output.

Here we assume that you want to extract the date, the title and the text body from each of your articles, and they are in an HTML format as in the following manner.

<h2 class='date-header'>
<span>
31/01/2014
</span>
</h2>
...
<h3 class='post-title entry-title'>
<a href='http://yourFBblog.com/2014/01/QRP_and_QRS.html'>
QRP and QRS
</a>
</h3>
...
<div class='post-body entry-content'>
Sometimes you may wish to get all the titles of your previous articles in your or someone else’s blog.
</div>
<div class='post-footer'>
...

Then you will write a short awk program such as:

BEGIN{
 nrsave_date=-999;
 nrsave_title=-999
}

 /post-body entry-content/, /post-footer/ {print}
{
 if(/<h2 class='date-header'>/) nrsave_date=NR
 if(/<h3 class='post-title entry-title' itemprop='name'>/) nrsave_title=NR
 if(NR==nrsave_date+2) print "<h1>" $0 "</h1>"
 if(NR==nrsave_title+2) print "<h2>" $0 "</h2>"
}

The output will be something like the following, if you remove unnecessary tags:

<h1>31/01/2014</h1>
<h2>QRP and QRS</h2>
I love QRP operations, but some people ...
<h1>20/02/2014</h1>
<h2>Snow on my ANT</h2>
Last night, we had a heavy snow...

This can be fed into an Ebook editor, for example, SIGIL to get your own ebook immediately.

Blog Summary (3)

If you would like to make links in HTML, this is one way:

BEGIN {FS = "[<>]"}
/<h2 class='date-header'>/ {date=$5; if(length(date)==9) date="0" date; month=substr(date,1,2); day  =substr(date,4,2); year =substr(date,7,4) }
/post-title entry-title/ {getline;printf("%2s-%2s-%2s <%s>%s</a>\n",year,month,day,$2,$3)}

I know this awk program is not very cool, but it works, and you will get somthing like this:

2011-08-22 <a href='http://yourFBblog.com/2011/08/taxi-driver.html'>Taxi Driver</a>
2011-09-04 <a href='http://yourFBblog.com/2011/09/the-accused'>The Accused</a>
2011-09-09 <a href='http://yourFBblog.com/2011/09/the-silence-of-the-lambs'>The Silence of the Lambs</a>

You can filter the list by checking if the title contains some particular words.

% gawk -f myprog.awk 201*_01_archive.html | sort | egrep -i 'CW|morse|QRP'

This will give you the list of links which seems to relate to ham radio.

One practical example is here:
http://spinorlab.wordpress.com/links/

Blog Summary (2)

Or you may also wish to know each date on which the article is published. Looking into the html file again, you will see the line like this:

<h2 class='date-header'><span>12/31/2013</span></h2>

So your code, myprog.awk, might be:

BEGIN {FS = "[<>]"}
/<h2 class='date-header'>/ {date=$5}
/post-title entry-title/ {getline;print date,$3}

And you will obtain:

12/31/2013 Taxi Driver
12/22/2013 The Accused
12/15/2013 The Silence of the Lambs
12/08/2013 Nell
12/01/2013 Contact

If you wish to make a list spanning many months, you first make a file, say, getlist.txt;

http://yourFBblog.com/2014-01-archive.html
...
http://yourFBblog.com/2011-04-archive.html

And get all the files, and process them.

% wget -i getlist.txt
% gawk -f myprog.awk 201*-archive.html | cat -n

The result will be something like this:

  1  29/01/2014 My Latest Post
...
402  01/04/2011 My First Post

Actually, my current version of myprog.awk is:

BEGIN {FS = "[<>]"}
/<h2 class='date-header'>/ {date=$5; if(length(date)==9) date="0" date; month=substr(date,1,2); day=substr(date,4,2); year=substr(date,7,4) }
/post-title entry-title/ {getline;printf("%2s-%2s-%2s %s\n",year,month,day,$3)}

This minor modification was required because the months from Jan. to Sept. are represented as a one digit (1 to 9), while from Oct. to Dec. as two digits(10 to 12). Therefore, the output is something like:

2013-12-31 Auld Lang Syne
2014-01-01 DX Pedition to Mars

Blog Summary

Sometimes you may wish to get all the titles of your previous articles in your or someone else’s blog. There should be numeours ways to attain the goal, and here is one aproach.

Suppose all the articles in December 2013 are in, say,
http://yourFBblog.com/2013-12-archive.html.

You will first get the file by

% wget http://yourFBblog.com/2012-12-archive.html

And looking into the file, you will see something like this

<h3 class='post-title entry-title' itemprop='name'>
<a href='http://yourFBblog.com/2013/12/taxi-driver.html'>Taxi Driver</a>
</h3>

This suggests you that you need a line just after the one containg the phrase “post-title entry-title”, and the title you wish to obtain is the second element of the line. Therfore, what you need is:

% cat 2013-12-archive.html | gawk ' BEGIN {FS = "[<>]"} /post-title entry-title/ {getline;print $3}'

And you will get something like this:

Taxi Driver
The Accused
The Silence of the Lambs
Nell
Contact

Wavefile Read 3

Minor change in source code. See the hilighted lines.

<!doctype html>
<head>
<meta charset="utf-8" />
<title>Wavefile Read 3</title>
<script src="Three.js"></script>
<script src="flotr2.min.js"></script>
<link href='http://fonts.googleapis.com/css?family=Righteous' rel='stylesheet' type='text/css'>

<style type="text/css">
div#canvas-frame{
  border: none;
  cursor: pointer;
  width:  610px;
  height: 300px;
  background-color: #eeffee;
  margin-top: 5px;
  margin-bottom: 5px;
  margin-left: 5px;
  margin-right: 5px;
}
div#canvas-frame2{
  border: none;
  cursor: pointer;
  width:  300px;
  height: 300px;
  background-color: #eeeeff;
  margin-top: 5px;
  margin-bottom: 5px;
  margin-left: 5px;
  margin-right: 5px;
}
div#canvas-frame3{
  border: none;
  cursor: pointer;
  width:  300px;
  height: 300px;
  background-color: #f5deb3;
  margin-top: 5px;
  margin-bottom: 5px;
  margin-left: 5px;
  margin-right: 5px;
}
div#mymessage {
    margin-top: 5px;
    background-color: #ffffff;
    margin-bottom: 5px;
  }
div#mymessage2 {
    margin-top: 5px;
    width:  190px;
    background-color: #ffffff;
    margin-bottom: 5px;
  }

div#slider {
    margin-top: 5px;
    margin-bottom: 5px;
    margin-left: 0px;
    margin-right: 5px;
    width:  190px;
    padding: 5px 5px 5px 5px;
    border-color: #cccccc;
    border-width: 1px;
    border-style: solid;
    background-color: #ffffff;
  }
  body {
    font-family: 'Righteous', cursive;
  }
</style>

<script>
var t, tb4= -1.0, istep = 0, ijump = 6;
var fsample=11025.0, nch=1;
var dt = 1.0/fsample;
var dsize = 700;
var nbin = 100;
var index;
var start_time, elapsed_time, elapsed_timeb4 = -1.0;

function loop2() {
  var d1 = []; var d2 = []; var d3 = []; var d4 = [];
  var i;


  if(t != tb4) {
    index = Math.floor( t * (fsample*nch) );
    tb4 = t;
    for(i=0;i<nbin;i++) {
       bin[i] = 0;
    }
  }

  if( istep++ % ijump == 0) {

  elapsed_time = new Date().getTime();
  document.getElementById("mymessage2").innerHTML
   = "Frame per second = "
   + (1000.0 / (elapsed_time - elapsed_timeb4)).toFixed(1);
  elapsed_timeb4 = elapsed_time;

  for(i=0;i<dsize;i++) {
   d1.push([i, arr[index  ]/32768.0]);
   d2.push([i, arr[index+1]/32768.0]);
   d3.push([   arr[index  ]/32768.0, arr[index+1]/32768.0]);
   ibin = Math.floor( (nbin/2)*(arr[index]/32768.0+1.0) );
   bin[ibin]++;
   index+=nch;
  }
  for(i=0;i<nbin;i++) {
    d4.push([-1.0+2.0*(i/nbin), bin[i]]);
  }
  basic_legend (document.getElementById("canvas-frame" ), d1, d2);
  basic_legend2(document.getElementById("canvas-frame2"), d3);
  basic_legend3(document.getElementById("canvas-frame3"), d4);
  }
  window.requestAnimationFrame(loop2);
}

  function basic_legend(container, d1, d2) {
    var data, graph, i;
    data = [
      { data : d1, label :'Ch Left'  },
      { data : d2, label :'Ch Right' }
    ];
    function labelFn (label) {
      return label;
    }
    graph = Flotr.draw(container, data, {
      legend : {
        position : 'nw',
        labelFormatter : labelFn,
        backgroundColor : '#ffffcc'
      },
      yaxis : {
              max :  1.1,
              min : -1.1
            },
      HtmlText : false
      });
  }
  function basic_legend2(container, d3) {
    var data, graph, i;
    data = [
      { data : d3, label :'Lissajous' }
    ];
    function labelFn (label) {
      return label;
    }
    graph = Flotr.draw(container, data, {
      legend : {
        position : 'nw',
        labelFormatter : labelFn,
        backgroundColor : '#ffffcc'
      },
      colors : [ '#ffa500' ],
      xaxis : {
              max :  1.1,
              min : -1.1
            },
      yaxis : {
              max :  1.1,
              min : -1.1
            },
      HtmlText : false
      });
  }
  function basic_legend3(container, d4) {
    var data, graph, i;
    data = [
      { data : d4, label :'Histogram' }
    ];
    function labelFn (label) {
      return label;
    }
    graph = Flotr.draw(container, data, {
      legend : {
        position : 'nw',
        labelFormatter : labelFn,
        backgroundColor : '#ffffcc'
      },
      colors : [ '#8a2be2' ],
      xaxis : {
              max :  1.1,
              min : -1.1
            },
      yaxis : {
              max : 420,
              min : -20
            },
      HtmlText : false
      });
  }
</script>

<script>
  function audioPlay() {
    var files = document.getElementById('files').files;
    var file  = files[0];
    if (!files.length) {
      alert('Please select a wave file!');
      return;
    }

        if (file.type.match(/audio.*/)) {
            var reader2 = new FileReader();
            reader2.onload = function(d) {
                e = document.createElement("audio");
                e.src = d.target.result;
                e.setAttribute("type", file.type);
                e.setAttribute("controls", "controls");
                e.setAttribute("autoplay", "true");
                document.getElementById("container").appendChild(e);
                e.addEventListener("timeupdate", function() {
                t=e.currentTime;
                }, false);
            };
            reader2.readAsDataURL(file);
        }
 }

  function readBlob() {
    var files = document.getElementById('files').files;
    if (!files.length) {
      alert('Please select a wave file!');
      return;
    }
    var file  = files[0];

    var header_length = 44;     // wave file
    var start = 0;              // do not skip header
    var stop  = file.size - 1;  // read until EOF
    var nbyte = file.size - header_length;
    var ndata  = nbyte / 2;     // 2 byte per data for 16-bit PCM

    var reader = new FileReader();

    reader.onloadend = function(evt) {
      if (evt.target.readyState == FileReader.DONE) { // DONE == 2
        var buffer = reader.result;
        arr    = new Int16Array(buffer, 44);     // skip wave header
        arr2   = new Uint8Array(buffer,  8, 4);  // "WAVE"
        arr3   = new Int16Array(buffer, 22, 1);  // nch
        arr4   = new Int32Array(buffer, 24, 1);  // fsample
        arrmax = 0;
        arrmin = 0;
        arrmax_pos = 0;
        arrmin_pos = 0;
        arr_pos = 0;
        start_time = new Date().getTime();
        bin = new Array();
        var i;
        for(i=0;i<nbin;i++) {
                bin[i] = 0;
        }
  var istart =  header_length/2; // skip header
        for(i=istart;i<ndata;i++) {
                if(arr[i] > arrmax) {
                        arrmax     = arr[i];
                        arrmax_pos = i;
                }
                if(arr[i] < arrmin) {
                        arrmin     = arr[i];
                        arrmin_pos = i;
                }
        }
        if( arrmax > Math.abs(arrmin) ) {
            arr_pos = arrmax_pos;
        } else {
            arr_pos = arrmin_pos;
        }
        index = 0;
        t = index / (fsample*nch);
  var myString = "";
  for(var i=0;i<arr2.byteLength; i++) {
    myString += String.fromCharCode(arr2[i]);
  }
  if( myString.match(/WAVE/) ) {
        nch     = arr3[0];
        fsample = arr4[0];
        document.getElementById('mymessage').innerHTML = "WAVE file: fsample = " + fsample + ", nch = " + nch;
  } else {
        document.getElementById('mymessage').innerHTML = "not a WAVE file. ";
  }
        loop2();
      }
    };

    var blob = file.slice(start, stop + 1);
    reader.readAsArrayBuffer(blob);
  }
  function upRate() {
        ijump--;
        if(ijump < 1) ijump = 1;
  }
  function downRate() {
        ijump++;
        if(ijump > 10) ijump = 10;
  }

</script>
</head>

<body>

<div id="canvas-frame"  style="float:left"></div>
<div id="canvas-frame2" style="float:left"></div>
<div id="canvas-frame3" style="float:left"></div>

<div style="clear:both"><h1>Wavefile Read</h1></dvi>

<input type="file" id="files" style="width:400px;" multiple/>
<div id="mymessage"></div>
<div id="slider">FPS slider
<input id="range01" type="range" min="1" max="10" step="1" onchange="showValue()"/>
<div id="mymessage2"></div>
</div>
<div id="container"></div>

 <script type="text/javascript">
  function showValue () {
     ijump = document.getElementById("range01").value;
  }
</script>

<script>
  document.getElementById("files").addEventListener("change", readBlob,  false);
  document.getElementById("files").addEventListener("change", audioPlay, false);
</script>

</body>
</html>

Wavefile Read 2

wav1

wav2

Here is a new page with a javascript that reads the header of a wave file to get fsample and nch. Changed lines are highlighted in the code below. I know this is a clumsy job and contains a minor bug, but it is workable.

Just for your information, if you double click anywhere on the code, the entire code is selected, and you can copy them all with a simple Ctrl/Cmd-C. Code selection works normally with your mouse.

You can download (right-click on the link) the following files to your PC to check my new page.

<!doctype html>
<head>
<meta charset="utf-8" />
<title>Wavefile Read 2</title>
<script src="Three.js"></script>
<script src="flotr2.min.js"></script>
<link href='http://fonts.googleapis.com/css?family=Righteous' rel='stylesheet' type='text/css'>

<style type="text/css">
div#canvas-frame{
  border: none;
  cursor: pointer;
  width:  610px;
  height: 300px;
  background-color: #eeffee;
  margin-top: 5px;
  margin-bottom: 5px;
  margin-left: 5px;
  margin-right: 5px;
}
div#canvas-frame2{
  border: none;
  cursor: pointer;
  width:  300px;
  height: 300px;
  background-color: #eeeeff;
  margin-top: 5px;
  margin-bottom: 5px;
  margin-left: 5px;
  margin-right: 5px;
}
div#canvas-frame3{
  border: none;
  cursor: pointer;
  width:  300px;
  height: 300px;
  background-color: #f5deb3;
  margin-top: 5px;
  margin-bottom: 5px;
  margin-left: 5px;
  margin-right: 5px;
}
div#mymessage {
    margin-top: 5px;
    background-color: #ffffff;
    margin-bottom: 5px;
  }
div#mymessage2 {
    margin-top: 5px;
    width:  190px;
    background-color: #ffffff;
    margin-bottom: 5px;
  }

div#slider {
    margin-top: 5px;
    margin-bottom: 5px;
    margin-left: 0px;
    margin-right: 5px;
    width:  190px;
    padding: 5px 5px 5px 5px;
    border-color: #cccccc;
    border-width: 1px;
    border-style: solid;
    background-color: #ffffff;
  }
  body {
    font-family: 'Righteous', cursive;
  }
</style>

<script>
var t, tb4= -1.0, istep = 0, ijump = 6;
var fsample=11025.0, nch=1;
var dt = 1.0/fsample;
var dsize = 700;
var nbin = 100;
var index;
var start_time, elapsed_time, elapsed_timeb4 = -1.0;

function loop2() {
  var d1 = []; var d2 = []; var d3 = []; var d4 = [];
  var i;


  if(t != tb4) {
    index = Math.floor( t * (fsample*nch) );
    tb4 = t;
    for(i=0;i<nbin;i++) {
       bin[i] = 0;
    }
  }

  if( istep++ % ijump == 0) {

  elapsed_time = new Date().getTime();
  document.getElementById("mymessage2").innerHTML
   = "Frame per second = "
   + (1000.0 / (elapsed_time - elapsed_timeb4)).toFixed(1);
  elapsed_timeb4 = elapsed_time;

  for(i=0;i<dsize;i++) {
   d1.push([i, arr[index  ]/32768.0]);
   d2.push([i, arr[index+1]/32768.0]);
   d3.push([   arr[index  ]/32768.0, arr[index+1]/32768.0]);
   ibin = Math.floor( (nbin/2)*(arr[index]/32768.0+1.0) );
   bin[ibin]++;
   index+=nch;
  }
  for(i=0;i<nbin;i++) {
    d4.push([-1.0+2.0*(i/nbin), bin[i]]);
  }
  basic_legend (document.getElementById("canvas-frame" ), d1, d2);
  basic_legend2(document.getElementById("canvas-frame2"), d3);
  basic_legend3(document.getElementById("canvas-frame3"), d4);
  }
  window.requestAnimationFrame(loop2);
}

  function basic_legend(container, d1, d2) {
    var data, graph, i;
    data = [
      { data : d1, label :'Ch Left'  },
      { data : d2, label :'Ch Right' }
    ];
    function labelFn (label) {
      return label;
    }
    graph = Flotr.draw(container, data, {
      legend : {
        position : 'nw',
        labelFormatter : labelFn,
        backgroundColor : '#ffffcc'
      },
      yaxis : {
              max :  1.1,
              min : -1.1
            },
      HtmlText : false
      });
  }
  function basic_legend2(container, d3) {
    var data, graph, i;
    data = [
      { data : d3, label :'Lissajous' }
    ];
    function labelFn (label) {
      return label;
    }
    graph = Flotr.draw(container, data, {
      legend : {
        position : 'nw',
        labelFormatter : labelFn,
        backgroundColor : '#ffffcc'
      },
      colors : [ '#ffa500' ],
      xaxis : {
              max :  1.1,
              min : -1.1
            },
      yaxis : {
              max :  1.1,
              min : -1.1
            },
      HtmlText : false
      });
  }
  function basic_legend3(container, d4) {
    var data, graph, i;
    data = [
      { data : d4, label :'Histogram' }
    ];
    function labelFn (label) {
      return label;
    }
    graph = Flotr.draw(container, data, {
      legend : {
        position : 'nw',
        labelFormatter : labelFn,
        backgroundColor : '#ffffcc'
      },
      colors : [ '#8a2be2' ],
      xaxis : {
              max :  1.1,
              min : -1.1
            },
      yaxis : {
              max : 420,
              min : -20
            },
      HtmlText : false
      });
  }
</script>

<script>
  function audioPlay() {
    var files = document.getElementById('files').files;
    var file  = files[0];
    if (!files.length) {
      alert('Please select a wave file!');
      return;
    }

        if (file.type.match(/audio.*/)) {
            var reader2 = new FileReader();
            reader2.onload = function(d) {
                e = document.createElement("audio");
                e.src = d.target.result;
                e.setAttribute("type", file.type);
                e.setAttribute("controls", "controls");
                e.setAttribute("autoplay", "true");
                document.getElementById("container").appendChild(e);
                e.addEventListener("timeupdate", function() {
                t=e.currentTime;
                }, false);
            };
            reader2.readAsDataURL(file);
        }
 }

  function readBlob() {
    var files = document.getElementById('files').files;
    if (!files.length) {
      alert('Please select a wave file!');
      return;
    }
    var file  = files[0];

    var header_length = 44;     // wave file
    var start = 0;              // do not skip header
    var stop  = file.size - 1;  // read until EOF
    var nbyte = file.size - header_length;
    var ndata  = nbyte / 2;     // 2 byte per data for 16-bit PCM

    var reader = new FileReader();

    reader.onloadend = function(evt) {
      if (evt.target.readyState == FileReader.DONE) { // DONE == 2

        var buffer = reader.result;
        arr    = new Int16Array(buffer);
        arr2   = new Uint8Array(buffer);
        arrmax = 0;
        arrmin = 0;
        arrmax_pos = 0;
        arrmin_pos = 0;
        arr_pos = 0;
        start_time = new Date().getTime();
        bin = new Array();
        var i;
        for(i=0;i<nbin;i++) {
                bin[i] = 0;
        }
        var istart =  header_length/2; // skip header
        for(i=istart;i<ndata;i++) {
                if(arr[i] > arrmax) {
                        arrmax     = arr[i];
                        arrmax_pos = i;
                }
                if(arr[i] < arrmin) {
                        arrmin     = arr[i];
                        arrmin_pos = i;
                }
        }
        if( arrmax > Math.abs(arrmin) ) {
            arr_pos = arrmax_pos;
        } else {
            arr_pos = arrmin_pos;
        }
        index = 0;
        t = index / (fsample*nch);
  if(arr2[8]==0x57 && arr2[9]==0x41 && arr2[10]==0x56 && arr2[11]==0x45) {
        fsample = arr2[24]+256*arr2[25]+256*256*arr2[26]+256*256*256*arr2[27];
        nch     = arr2[22]+256*arr2[23];
        document.getElementById('mymessage').innerHTML = "WAVE file: fsample = " + fsample + ", nch = " + nch;
  } else {
        document.getElementById('mymessage').innerHTML = "not a WAVE file. ";
  }
        loop2();
      }
    };

    var blob = file.slice(start, stop + 1);
    reader.readAsArrayBuffer(blob);
  }
  function upRate() {
        ijump--;
        if(ijump < 1) ijump = 1;
  }
  function downRate() {
        ijump++;
        if(ijump > 10) ijump = 10;
  }

</script>
</head>

<body>

<div id="canvas-frame"  style="float:left"></div>
<div id="canvas-frame2" style="float:left"></div>
<div id="canvas-frame3" style="float:left"></div>

<div style="clear:both"><h1>Wavefile Read</h1></dvi>

<input type="file" id="files" style="width:400px;" multiple/>
<div id="mymessage"></div>
<div id="slider">FPS slider
<input id="range01" type="range" min="1" max="10" step="1" onchange="showValue()"/>
<div id="mymessage2"></div>
</div>
<div id="container"></div>

 <script type="text/javascript">
  function showValue () {
     ijump = document.getElementById("range01").value;
  }
</script>

<script>
  document.getElementById("files").addEventListener("change", readBlob,  false);
  document.getElementById("files").addEventListener("change", audioPlay, false);
</script>

</body>
</html>