Javascript Audio play <body onload>

355 views
Skip to first unread message

John Papenheim

unread,
Nov 12, 2017, 10:42:21 AM11/12/17
to MIT App Inventor Forum
Hello- Below is a Javascript Function (it's also attached) that generates audio/ modem data to the headphone jack then to Arduino. At the moment, it just sends a bunch of J characters on <body onload> and an i character when a button is pushed <form onsubmit> . (this is so I can hear the difference)

 generate() is the main function here...

In browsers like Chrome or Firefox, this script works as expected. However, when I use the App Inventor Web Viewer, the page loads, the 
<body onload= "generate('jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj')">  function seems to run, but no sound is played like it does in other browsers. The  <form onsubmit="generate('i'); return false;">  plays the expected sound in the web viewer, though.

My eventual goal is to pass data from App Inventor using webview.string  to the javascript, then via headphone jack modem to the Arduino... But I need that script to run/ audio to play automatically each time the page is refreshed. In my debuging thus far, it seems to run the generate() function when I do the <body onload>, but the sound does not play.

My app inventor code is just a webviewer and a button to refresh it:


Is there something about the webviewer that is different from other browsers???



Here is the Javascript/ html:



<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>FSK Serial Generator in JavaScript for SoftModem board</title>

<script type="text/javascript">


function chr8() {

return Array.prototype.map.call(arguments, function(a){

return String.fromCharCode(a&0xff)

}).join('');

}

function chr16() {

return Array.prototype.map.call(arguments, function(a){

return String.fromCharCode(a&0xff, (a>>8)&0xff)

}).join('');

}

function chr32() {

return Array.prototype.map.call(arguments, function(a){

return String.fromCharCode(a&0xff, (a>>8)&0xff,(a>>16)&0xff, (a>>24)&0xff);

}).join('');

}

function toUTF8(str) {

var utf8 = [];

for (var i = 0; i < str.length; i++) {

var c = str.charCodeAt(i);

if (c <= 0x7f)

utf8.push(c);

else if (c <= 0x7ff) {

utf8.push(0xc0 | (c >>> 6));

utf8.push(0x80 | (c & 0x3f));

} else if (c <= 0xffff) {

utf8.push(0xe0 | (c >>> 12));

utf8.push(0x80 | ((c >>> 6) & 0x3f));

utf8.push(0x80 | (c & 0x3f));

} else {

var j = 4;

while (c >>> (6*j)) j++;

utf8.push(((0xff00 >>> j) & 0xff) | (c >>> (6*--j)));

while (j--) 

utf8[idx++] = 0x80 | ((c >>> (6*j)) & 0x3f);

}

}

return utf8;

}



var dataURI, audio;

function generate(str) {

if (str.length == 0) return;

var utf8 = toUTF8(str);

//console.log(utf8);

var sampleRate = 29400;

var baud = 1225;

var freqHigh = 7350;

var freqLow  = 4900;

var spb = sampleRate/baud; // 24 samples per bit

var preCarrierBits = Math.ceil(sampleRate*40/1000/spb); // 49 bits

var postCarrierBits = Math.ceil(sampleRate*5/1000/spb); // 6.125 bits => 7 bits

var size = (preCarrierBits + postCarrierBits + 10*utf8.length) * spb;


var data = "RIFF" + chr32(size+36) + "WAVE" +

"fmt " + chr32(16, 0x00010001, sampleRate, sampleRate, 0x00080001) +

"data" + chr32(size);

function pushData(freq, samples) {

for (var i = 0; i < samples; i++) {

var v = 128 + 127 * Math.sin((2 * Math.PI) * (i / sampleRate) * freq);

data += chr8(v);

}

}

pushData(freqHigh, preCarrierBits*spb);

for (var x in utf8) {

var c = (utf8[x] << 1) | 0x200;

for (var i = 0; i < 10; i++, c >>>= 1)

pushData((c&1) ? freqHigh : freqLow, spb);

}

pushData(freqHigh, postCarrierBits*spb);

if (size+44 != data.length) alert("wrong size: " + size+44 + " != " + data.length);

dataURI = "data:audio/wav;base64," + escape(btoa(data));

audio = new Audio(dataURI);

audio.play();

}

</script>

</head>


<body onload= "generate('jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj')">


<h1>Softmodem for Arduino </h1>





<form onsubmit="generate('i'); return false;">

<input type="submit" value="Send via Form">

</form>

</body>


</html>







fsk-gen.html

John Papenheim

unread,
Nov 12, 2017, 11:24:42 AM11/12/17
to MIT App Inventor Forum
After a bit of research, I do believe this is an Android issue, not an App Inventor issue. It seems Android and other mobile browsers are set up so you cannot auto-play audio or video... presumably to save data costs or prevent  your phone from blasting noise in the middle of the night if you left your browser open.

This makes it tough for developers, but there MUST be some work around?



Juan Antonio

unread,
Nov 12, 2017, 6:12:50 PM11/12/17
to MIT App Inventor Forum
Hi John,

maybe this is not what you are looking for, ...but... in this post I put a JavaScript with sounds.


This extension is a tone generator:



You can try with WebViewer of Thunkable:



Regards.




John Papenheim

unread,
Nov 13, 2017, 7:03:57 AM11/13/17
to MIT App Inventor Forum
Juan- Great suggestions. I will study those examples and see if I can adapt to what I am attempting. Thanks!
Reply all
Reply to author
Forward
0 new messages