Hi Frode,
I have tried the following code as demo :-
*Sample 1 of Action Script code is as follows ( guacamole.swf ) :-*
package
> {
> import flash.display.*;
> import flash.events.*;
> import flash.external.*;
> import flash.media.*;
> public class guacamole extends Sprite
> {
> public var bufferSize:Number = 2048;
> public var sound:Sound = null;
> public var buffer:Array;
> public function guacamole()
> {
> this.buffer = [];
> super();
> ExternalInterface.addCallback("write", this.write);
> }
> public function write(param1:String) : void
> {
> var _loc_3:String = null;
> if(!this.sound)
> {
> this.sound = new Sound();
> this.sound.addEventListener(SampleDataEvent.SAMPLE_DATA,
> this.waveGenerator);
> this.sound.play();
> }
> var _loc_2:Number = 1 / 32768;
> var _loc_4:* = 0;
> var _loc_5:* = param1.split(" ");
> for each(_loc_3 in _loc_5)
> {
> this.buffer.push(Number(_loc_3) * _loc_2);
> }
> }
> public function waveGenerator(param1:SampleDataEvent) : void
> {
> var _loc_2:* = 0;
> var _loc_4:* = NaN;
> if(this.buffer.length < (this.bufferSize * 2))
> {
> _loc_2 = 0;
> while(_loc_2 < 4096)
> {
> param1.data.writeFloat(0.00);
> _loc_2++;
> }
> return;
> }
> var _loc_3:Number = Math.min(this.buffer.length, 16384);
> var _loc_5:* = 0;
> var _loc_6:* = this.buffer.slice(0, _loc_3);
> for each(_loc_4 in _loc_6)
> {
> param1.data.writeFloat(_loc_4);
> }
> this.buffer = this.buffer.slice(_loc_3, this.buffer.length);
> }
> }
> }
*Sample 2 of Action Script code is as follows ( guacamole.swf ) :- //
with few changes *
package
> {
> import flash.display.*;
> import flash.events.*;
> import flash.external.*;
> import flash.media.*;
> public class guacamole extends Sprite
> {
> public var sound:Sound = null;
> public var buffer:Array;
> public function guacamole()
> {
> this.buffer = [];
> super();
> ExternalInterface.addCallback("write", this.write);
> }
> public function write(param1:String) : void
> {
> if(!this.sound)
> {
> this.sound = new Sound();
> this.sound.addEventListener(SampleDataEvent.SAMPLE_DATA,
> this.waveGenerator);
> this.sound.play();
> }
> this.buffer = this.buffer.concat(param1.split(","));
> }
> public function waveGenerator(param1:SampleDataEvent) : void
> {
> var _loc_2:int = 0;
> var _loc_3:Function = param1.data.writeFloat;
> if(this.buffer.length < 4096)
> {
> _loc_2 = 0;
> while(_loc_2 < 4096)
> {
> _loc_3(0.00);
> _loc_2++;
> }
> return;
> }
> var _loc_4:Number = Math.min(this.buffer.length, 16384);
> _loc_2 = 0;
> while(_loc_2 < _loc_4)
> {
> _loc_3(this.buffer[_loc_2]);
> _loc_2++;
> }
> this.buffer = this.buffer.slice(_loc_4, this.buffer.length);
> }
> }
> }
*Code of SWFObject is as follows : // you can get it online as well *
*https://github.com/swfobject/swfobject
<https://github.com/swfobject/swfobject>*
/*! SWFObject v2.2 <http://code.google.com/p/swfobject/>
> is released under the MIT License <http://www.opensource.org/
> licenses/mit-license.php>
> */
> var swfobject = function() {
>
> var UNDEF = "undefined",
> OBJECT = "object",
> SHOCKWAVE_FLASH = "Shockwave Flash",
> SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
> FLASH_MIME_TYPE = "application/x-shockwave-flash",
> EXPRESS_INSTALL_ID = "SWFObjectExprInst",
> ON_READY_STATE_CHANGE = "onreadystatechange",
>
> win = window,
> doc = document,
> nav = navigator,
>
> plugin = false,
> domLoadFnArr = [main],
> regObjArr = [],
> objIdArr = [],
> listenersArr = [],
> storedAltContent,
> storedAltContentId,
> storedCallbackFn,
> storedCallbackObj,
> isDomLoaded = false,
> isExpressInstallActive = false,
> dynamicStylesheet,
> dynamicStylesheetMedia,
> autoHideShow = true,
>
> /* Centralized function for browser feature detection
> - User agent string detection is only used when no good alternative is
> possible
> - Is executed directly for optimal performance
> */
> ua = function() {
> var w3cdom = typeof doc.getElementById != UNDEF && typeof
> doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
> u = nav.userAgent.toLowerCase(),
> p = nav.platform.toLowerCase(),
> windows = p ? /win/.test(p) : /win/.test(u),
> mac = p ? /mac/.test(p) : /mac/.test(u),
> webkit = /webkit/.test(u) ?
> parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,
> "$1")) : false, // returns either the webkit version or false if not webkit
> ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution:
> http://webreflection.blogspot.com/2009/01/32-bytes-to-know-
> if-your-browser-is-ie.html
> playerVersion = [0,0,0],
> d = null;
> if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] ==
> OBJECT) {
> d = nav.plugins[SHOCKWAVE_FLASH].description;
> if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE]
> && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { //
> navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin
> indicates whether plug-ins are enabled or disabled in Safari 3+
> plugin = true;
> ie = false; // cascaded feature detection for Internet Explorer
> d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
> playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
> playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
> playerVersion[2] = /[a-zA-Z]/.test(d) ?
> parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/,
> "$1"), 10) : 0;
> }
> }
> else if (typeof win.ActiveXObject != UNDEF) {
> try {
> var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
> if (a) { // a will return null when ActiveX is disabled
> d = a.GetVariable("$version");
> if (d) {
> ie = true; // cascaded feature detection for Internet Explorer
> d = d.split(" ")[1].split(",");
> playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2],
> 10)];
> }
> }
> }
> catch(e) {}
> }
> return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows,
> mac:mac };
> }(),
>
> /* Cross-browser onDomLoad
> - Will fire an event as soon as the DOM of a web page is loaded
> - Internet Explorer workaround based on Diego Perini's solution:
> http://javascript.nwbox.com/IEContentLoaded/
> - Regular onload serves as fallback
> */
> onDomLoad = function() {
> if (!ua.w3) { return; }
> if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") ||
> (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0]
> || doc.body))) { // function is fired after onload, e.g. when script is
> inserted dynamically
> callDomLoadFunctions();
> }
> if (!isDomLoaded) {
> if (typeof doc.addEventListener != UNDEF) {
> doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
> }
> if (ua.ie && ua.win) {
> doc.attachEvent(ON_READY_STATE_CHANGE, function() {
> if (doc.readyState == "complete") {
> doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
> callDomLoadFunctions();
> }
> });
> if (win == top) { // if not inside an iframe
> (function(){
> if (isDomLoaded) { return; }
> try {
> doc.documentElement.doScroll("left");
> }
> catch(e) {
> setTimeout(arguments.callee, 0);
> return;
> }
> callDomLoadFunctions();
> })();
> }
> }
> if (ua.wk) {
> (function(){
> if (isDomLoaded) { return; }
> if (!/loaded|complete/.test(doc.readyState)) {
> setTimeout(arguments.callee, 0);
> return;
> }
> callDomLoadFunctions();
> })();
> }
> addLoadEvent(callDomLoadFunctions);
> }
> }();
>
> function callDomLoadFunctions() {
> if (isDomLoaded) { return; }
> try { // test if we can really add/remove elements to/from the DOM; we
> don't want to fire it too early
> var t = doc.getElementsByTagName("body")[0].appendChild(
> createElement("span"));
> t.parentNode.removeChild(t);
> }
> catch (e) { return; }
> isDomLoaded = true;
> var dl = domLoadFnArr.length;
> for (var i = 0; i < dl; i++) {
> domLoadFnArr[i]();
> }
> }
>
> function addDomLoadEvent(fn) {
> if (isDomLoaded) {
> fn();
> }
> else {
> domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available
> in IE5.5+
> }
> }
>
> /* Cross-browser onload
> - Based on James Edwards' solution: http://brothercake.com/site/
> resources/scripts/onload/
> - Will fire an event as soon as a web page including all of its assets are
> loaded
> */
> function addLoadEvent(fn) {
> if (typeof win.addEventListener != UNDEF) {
> win.addEventListener("load", fn, false);
> }
> else if (typeof doc.addEventListener != UNDEF) {
> doc.addEventListener("load", fn, false);
> }
> else if (typeof win.attachEvent != UNDEF) {
> addListener(win, "onload", fn);
> }
> else if (typeof win.onload == "function") {
> var fnOld = win.onload;
> win.onload = function() {
> fnOld();
> fn();
> };
> }
> else {
> win.onload = fn;
> }
> }
>
> /* Main function
> - Will preferably execute onDomLoad, otherwise onload (as a fallback)
> */
> function main() {
> if (plugin) {
> testPlayerVersion();
> }
> else {
> matchVersions();
> }
> }
>
> /* Detect the Flash Player version for non-Internet Explorer browsers
> - Detecting the plug-in version via the object element is more precise
> than using the plugins collection item's description:
> a. Both release and build numbers can be detected
> b. Avoid wrong descriptions by corrupt installers provided by Adobe
> c. Avoid wrong descriptions by multiple Flash Player entries in the
> plugin Array, caused by incorrect browser imports
> - Disadvantage of this method is that it depends on the availability of
> the DOM, while the plugins collection is immediately available
> */
> function testPlayerVersion() {
> var b = doc.getElementsByTagName("body")[0];
> var o = createElement(OBJECT);
> o.setAttribute("type", FLASH_MIME_TYPE);
> var t = b.appendChild(o);
> if (t) {
> var counter = 0;
> (function(){
> if (typeof t.GetVariable != UNDEF) {
> var d = t.GetVariable("$version");
> if (d) {
> d = d.split(" ")[1].split(",");
> ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
> }
> }
> else if (counter < 10) {
> counter++;
> setTimeout(arguments.callee, 10);
> return;
> }
> b.removeChild(o);
> t = null;
> matchVersions();
> })();
> }
> else {
> matchVersions();
> }
> }
>
> /* Perform Flash Player and SWF version matching; static publishing only
> */
> function matchVersions() {
> var rl = regObjArr.length;
> if (rl > 0) {
> for (var i = 0; i < rl; i++) { // for each registered object element
> var id = regObjArr[i].id;
> var cb = regObjArr[i].callbackFn;
> var cbObj = {success:false, id:id};
> if (ua.pv[0] > 0) {
> var obj = getElementById(id);
> if (obj) {
> if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312))
> { // Flash Player version >= published SWF version: Houston, we have a
> match!
> setVisibility(id, true);
> if (cb) {
> cbObj.success = true;
> cbObj.ref = getObjectById(id);
> cb(cbObj);
> }
> }
> else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the
> Adobe Express Install dialog if set by the web page author and if supported
> var att = {};
> att.data = regObjArr[i].expressInstall;
> att.width = obj.getAttribute("width") || "0";
> att.height = obj.getAttribute("height") || "0";
> if (obj.getAttribute("class")) { att.styleclass =
> obj.getAttribute("class"); }
> if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
> // parse HTML object param element's name-value pairs
> var par = {};
> var p = obj.getElementsByTagName("param");
> var pl = p.length;
> for (var j = 0; j < pl; j++) {
> if (p[j].getAttribute("name").toLowerCase() != "movie") {
> par[p[j].getAttribute("name")] = p[j].getAttribute("value");
> }
> }
> showExpressInstall(att, par, id, cb);
> }
> else { // Flash Player and SWF version mismatch or an older Webkit engine
> that ignores the HTML object element's nested param elements: display
> alternative content instead of SWF
> displayAltContent(obj);
> if (cb) { cb(cbObj); }
> }
> }
> }
> else { // if no Flash Player is installed or the fp version cannot be
> detected we let the HTML object element do its job (either show a SWF or
> alternative content)
> setVisibility(id, true);
> if (cb) {
> var o = getObjectById(id); // test whether there is an HTML object element
> or not
> if (o && typeof o.SetVariable != UNDEF) {
> cbObj.success = true;
> cbObj.ref = o;
> }
> cb(cbObj);
> }
> }
> }
> }
> }
>
> function getObjectById(objectIdStr) {
> var r = null;
> var o = getElementById(objectIdStr);
> if (o && o.nodeName == "OBJECT") {
> if (typeof o.SetVariable != UNDEF) {
> r = o;
> }
> else {
> var n = o.getElementsByTagName(OBJECT)[0];
> if (n) {
> r = n;
> }
> }
> }
> return r;
> }
>
> /* Requirements for Adobe Express Install
> - only one instance can be active at a time
> - fp 6.0.65 or higher
> - Win/Mac OS only
> - no Webkit engines older than version 312
> */
> function canExpressInstall() {
> return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win ||
> ua.mac) && !(ua.wk && ua.wk < 312);
> }
>
> /* Show the Adobe Express Install dialog
> - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=
> 6a253b75
> */
> function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
> isExpressInstallActive = true;
> storedCallbackFn = callbackFn || null;
> storedCallbackObj = {success:false, id:replaceElemIdStr};
> var obj = getElementById(replaceElemIdStr);
> if (obj) {
> if (obj.nodeName == "OBJECT") { // static publishing
> storedAltContent = abstractAltContent(obj);
> storedAltContentId = null;
> }
> else { // dynamic publishing
> storedAltContent = obj;
> storedAltContentId = replaceElemIdStr;
> }
> att.id = EXPRESS_INSTALL_ID;
> if (typeof att.width == UNDEF || (!/%$/.test(att.width) &&
> parseInt(att.width, 10) < 310)) { att.width = "310"; }
> if (typeof att.height == UNDEF || (!/%$/.test(att.height) &&
> parseInt(att.height, 10) < 137)) { att.height = "137"; }
> doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
> var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
> fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") +
> "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
> if (typeof par.flashvars != UNDEF) {
> par.flashvars += "&" + fv;
> }
> else {
> par.flashvars = fv;
> }
> // IE only: when a SWF is loading (AND: not available in cache) wait for
> the readyState of the object element to become 4 before removing it,
> // because you cannot properly cancel a loading SWF file without breaking
> browser load references, also obj.onreadystatechange doesn't work
> if (ua.ie && ua.win && obj.readyState != 4) {
> var newObj = createElement("div");
> replaceElemIdStr += "SWFObjectNew";
> newObj.setAttribute("id", replaceElemIdStr);
> obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that
> will be replaced by the object element that loads expressinstall.swf
> obj.style.display = "none";
> (function(){
> if (obj.readyState == 4) {
> obj.parentNode.removeChild(obj);
> }
> else {
> setTimeout(arguments.callee, 10);
> }
> })();
> }
> createSWF(att, par, replaceElemIdStr);
> }
> }
>
> /* Functions to abstract and display alternative content
> */
> function displayAltContent(obj) {
> if (ua.ie && ua.win && obj.readyState != 4) {
> // IE only: when a SWF is loading (AND: not available in cache) wait for
> the readyState of the object element to become 4 before removing it,
> // because you cannot properly cancel a loading SWF file without breaking
> browser load references, also obj.onreadystatechange doesn't work
> var el = createElement("div");
> obj.parentNode.insertBefore(el, obj); // insert placeholder div that will
> be replaced by the alternative content
> el.parentNode.replaceChild(abstractAltContent(obj), el);
> obj.style.display = "none";
> (function(){
> if (obj.readyState == 4) {
> obj.parentNode.removeChild(obj);
> }
> else {
> setTimeout(arguments.callee, 10);
> }
> })();
> }
> else {
> obj.parentNode.replaceChild(abstractAltContent(obj), obj);
> }
> }
> function abstractAltContent(obj) {
> var ac = createElement("div");
> if (ua.win && ua.ie) {
> ac.innerHTML = obj.innerHTML;
> }
> else {
> var nestedObj = obj.getElementsByTagName(OBJECT)[0];
> if (nestedObj) {
> var c = nestedObj.childNodes;
> if (c) {
> var cl = c.length;
> for (var i = 0; i < cl; i++) {
> if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType
> == 8)) {
> ac.appendChild(c[i].cloneNode(true));
> }
> }
> }
> }
> }
> return ac;
> }
>
> /* Cross-browser dynamic SWF creation
> */
> function createSWF(attObj, parObj, id) {
> var r, el = getElementById(id);
> if (ua.wk && ua.wk < 312) { return r; }
> if (el) {
> if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object
> element, it will inherit the 'id' from the alternative content
> attObj.id = id;
> }
> if (ua.ie && ua.win) { // Internet Explorer + the HTML object element +
> W3C DOM methods do not combine: fall back to outerHTML
> var att = "";
> for (var i in attObj) {
> if (attObj[i] != Object.prototype[i]) { // filter out prototype additions
> from other potential libraries
> if (i.toLowerCase() == "data") {
> parObj.movie = attObj[i];
> }
> else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4
> reserved keyword
> att += ' class="' + attObj[i] + '"';
> }
> else if (i.toLowerCase() != "classid") {
> att += ' ' + i + '="' + attObj[i] + '"';
> }
> }
> }
> var par = "";
> for (var j in parObj) {
> if (parObj[j] != Object.prototype[j]) { // filter out prototype additions
> from other potential libraries
> par += '<param name="' + j + '" value="' + parObj[j] + '" />';
> }
> }
> el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'
> + att + '>' + par + '</object>';
> objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on
> unload (dynamic publishing only)
> r = getElementById(attObj.id);
> }
> else { // well-behaving browsers
> var o = createElement(OBJECT);
> o.setAttribute("type", FLASH_MIME_TYPE);
> for (var m in attObj) {
> if (attObj[m] != Object.prototype[m]) { // filter out prototype additions
> from other potential libraries
> if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved
> keyword
> o.setAttribute("class", attObj[m]);
> }
> else if (m.toLowerCase() != "classid") { // filter out IE specific
> attribute
> o.setAttribute(m, attObj[m]);
> }
> }
> }
> for (var n in parObj) {
> if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { //
> filter out prototype additions from other potential libraries and IE
> specific param element
> createObjParam(o, n, parObj[n]);
> }
> }
> el.parentNode.replaceChild(o, el);
> r = o;
> }
> }
> return r;
> }
>
> function createObjParam(el, pName, pValue) {
> var p = createElement("param");
> p.setAttribute("name", pName);
> p.setAttribute("value", pValue);
> el.appendChild(p);
> }
>
> /* Cross-browser SWF removal
> - Especially needed to safely and completely remove a SWF in Internet
> Explorer
> */
> function removeSWF(id) {
> var obj = getElementById(id);
> if (obj && obj.nodeName == "OBJECT") {
> if (ua.ie && ua.win) {
> obj.style.display = "none";
> (function(){
> if (obj.readyState == 4) {
> removeObjectInIE(id);
> }
> else {
> setTimeout(arguments.callee, 10);
> }
> })();
> }
> else {
> obj.parentNode.removeChild(obj);
> }
> }
> }
>
> function removeObjectInIE(id) {
> var obj = getElementById(id);
> if (obj) {
> for (var i in obj) {
> if (typeof obj[i] == "function") {
> obj[i] = null;
> }
> }
> obj.parentNode.removeChild(obj);
> }
> }
>
> /* Functions to optimize JavaScript compression
> */
> function getElementById(id) {
> var el = null;
> try {
> el = doc.getElementById(id);
> }
> catch (e) {}
> return el;
> }
>
> function createElement(el) {
> return doc.createElement(el);
> }
>
> /* Updated attachEvent function for Internet Explorer
> - Stores attachEvent information in an Array, so on unload the detachEvent
> functions can be called to avoid memory leaks
> */
> function addListener(target, eventType, fn) {
> target.attachEvent(eventType, fn);
> listenersArr[listenersArr.length] = [target, eventType, fn];
> }
>
> /* Flash Player and SWF content version matching
> */
> function hasPlayerVersion(rv) {
> var pv = ua.pv, v = rv.split(".");
> v[0] = parseInt(v[0], 10);
> v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9"
> instead of "9.0.0"
> v[2] = parseInt(v[2], 10) || 0;
> return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0]
> && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
> }
>
> /* Cross-browser dynamic CSS creation
> - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.
> com/articles/dynamicCSS.php
> */
> function createCSS(sel, decl, media, newStyle) {
> if (ua.ie && ua.mac) { return; }
> var h = doc.getElementsByTagName("head")[0];
> if (!h) { return; } // to also support badly authored HTML pages that lack
> a head element
> var m = (media && typeof media == "string") ? media : "screen";
> if (newStyle) {
> dynamicStylesheet = null;
> dynamicStylesheetMedia = null;
> }
> if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
> // create dynamic stylesheet + get a global reference to it
> var s = createElement("style");
> s.setAttribute("type", "text/css");
> s.setAttribute("media", m);
> dynamicStylesheet = h.appendChild(s);
> if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF &&
> doc.styleSheets.length > 0) {
> dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
> }
> dynamicStylesheetMedia = m;
> }
> // add style rule
> if (ua.ie && ua.win) {
> if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
> dynamicStylesheet.addRule(sel, decl);
> }
> }
> else {
> if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
> dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl +
> "}"));
> }
> }
> }
>
> function setVisibility(id, isVisible) {
> if (!autoHideShow) { return; }
> var v = isVisible ? "visible" : "hidden";
> if (isDomLoaded && getElementById(id)) {
> getElementById(id).style.visibility = v;
> }
> else {
> createCSS("#" + id, "visibility:" + v);
> }
> }
> /* Filter to avoid XSS attacks
> */
> function urlEncodeIfNecessary(s) {
> var regex = /[\\\"<>\.;]/;
> var hasBadChars = regex.exec(s) != null;
> return hasBadChars && typeof encodeURIComponent != UNDEF ?
> encodeURIComponent(s) : s;
> }
>
> /* Release memory to avoid memory leaks caused by closures, fix hanging
> audio/video threads and force open sockets/NetConnections to disconnect
> (Internet Explorer only)
> */
> var cleanup = function() {
> if (ua.ie && ua.win) {
> window.attachEvent("onunload", function() {
> // remove listeners to avoid memory leaks
> var ll = listenersArr.length;
> for (var i = 0; i < ll; i++) {
> listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
> }
> // cleanup dynamically embedded objects to fix audio/video threads and
> force open sockets and NetConnections to disconnect
> var il = objIdArr.length;
> for (var j = 0; j < il; j++) {
> removeSWF(objIdArr[j]);
> }
> // cleanup library's main closures to avoid memory leaks
> for (var k in ua) {
> ua[k] = null;
> }
> ua = null;
> for (var l in swfobject) {
> swfobject[l] = null;
> }
> swfobject = null;
> });
> }
> }();
>
> return {
> /* Public API
> - Reference: http://code.google.com/p/swfobject/wiki/documentation
> */
> registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr,
> callbackFn) {
> if (ua.w3 && objectIdStr && swfVersionStr) {
> var regObj = {};
> regObj.id = objectIdStr;
> regObj.swfVersion = swfVersionStr;
> regObj.expressInstall = xiSwfUrlStr;
> regObj.callbackFn = callbackFn;
> regObjArr[regObjArr.length] = regObj;
> setVisibility(objectIdStr, false);
> }
> else if (callbackFn) {
> callbackFn({success:false, id:objectIdStr});
> }
> },
>
> getObjectById: function(objectIdStr) {
> if (ua.w3) {
> return getObjectById(objectIdStr);
> }
> },
>
> embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr,
> swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
> var callbackObj = {success:false, id:replaceElemIdStr};
> if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr &&
> widthStr && heightStr && swfVersionStr) {
> setVisibility(replaceElemIdStr, false);
> addDomLoadEvent(function() {
> widthStr += ""; // auto-convert to string
> heightStr += "";
> var att = {};
> if (attObj && typeof attObj === OBJECT) {
> for (var i in attObj) { // copy object to avoid the use of references,
> because web authors often reuse attObj for multiple SWFs
> att[i] = attObj[i];
> }
> }
> att.data = swfUrlStr;
> att.width = widthStr;
> att.height = heightStr;
> var par = {};
> if (parObj && typeof parObj === OBJECT) {
> for (var j in parObj) { // copy object to avoid the use of references,
> because web authors often reuse parObj for multiple SWFs
> par[j] = parObj[j];
> }
> }
> if (flashvarsObj && typeof flashvarsObj === OBJECT) {
> for (var k in flashvarsObj) { // copy object to avoid the use of
> references, because web authors often reuse flashvarsObj for multiple SWFs
> if (typeof par.flashvars != UNDEF) {
> par.flashvars += "&" + k + "=" + flashvarsObj[k];
> }
> else {
> par.flashvars = k + "=" + flashvarsObj[k];
> }
> }
> }
> if (hasPlayerVersion(swfVersionStr)) { // create SWF
> var obj = createSWF(att, par, replaceElemIdStr);
> if (att.id == replaceElemIdStr) {
> setVisibility(replaceElemIdStr, true);
> }
> callbackObj.success = true;
> callbackObj.ref = obj;
> }
> else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express
> Install
> att.data = xiSwfUrlStr;
> showExpressInstall(att, par, replaceElemIdStr, callbackFn);
> return;
> }
> else { // show alternative content
> setVisibility(replaceElemIdStr, true);
> }
> if (callbackFn) { callbackFn(callbackObj); }
> });
> }
> else if (callbackFn) { callbackFn(callbackObj); }
> },
>
> switchOffAutoHideShow: function() {
> autoHideShow = false;
> },
>
> ua: ua,
>
> getFlashPlayerVersion: function() {
> return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
> },
>
> hasFlashPlayerVersion: hasPlayerVersion,
>
> createSWF: function(attObj, parObj, replaceElemIdStr) {
> if (ua.w3) {
> return createSWF(attObj, parObj, replaceElemIdStr);
> }
> else {
> return undefined;
> }
> },
>
> showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
> if (ua.w3 && canExpressInstall()) {
> showExpressInstall(att, par, replaceElemIdStr, callbackFn);
> }
> },
>
> removeSWF: function(objElemIdStr) {
> if (ua.w3) {
> removeSWF(objElemIdStr);
> }
> },
>
> createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
> if (ua.w3) {
> createCSS(selStr, declStr, mediaStr, newStyleBoolean);
> }
> },
>
> addDomLoadEvent: addDomLoadEvent,
>
> addLoadEvent: addLoadEvent,
>
> getQueryParamValue: function(param) {
> var q = doc.location.search || doc.location.hash;
> if (q) {
> if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark
> if (param == null) {
> return urlEncodeIfNecessary(q);
> }
> var pairs = q.split("&");
> for (var i = 0; i < pairs.length; i++) {
> if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
> return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") +
> 1)));
> }
> }
> }
> return "";
> },
>
> // For internal usage only
> expressInstallCallback: function() {
> if (isExpressInstallActive) {
> var obj = getElementById(EXPRESS_INSTALL_ID);
> if (obj && storedAltContent) {
> obj.parentNode.replaceChild(storedAltContent, obj);
> if (storedAltContentId) {
> setVisibility(storedAltContentId, true);
> if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
> }
> if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
> }
> isExpressInstallActive = false;
> }
> }
> };
> }();
*Code of guacamoleaudio.js is as follows which loads SWF :-*
> function GuacamoleFlashAudio(args) {
> if (typeof this.init === "function") {
> this.init.apply(this, (args && args.callee) ? args :
> arguments);
> }
> }
> GuacamoleFlashAudio.nextId = 1;
> GuacamoleFlashAudio.prototype = {
> nextId: null,
> swf: 'dynamicaudio.swf',
>
> audioContext: null,
> flashWrapper: null,
> flashElement: null,
> init: function(opts) {
> var self = this;
> self.id = GuacamoleFlashAudio.nextId++;
>
> if (opts && typeof opts['swf'] !== 'undefined') {
> self.swf = opts['swf'];
> }
> self.flashWrapper = document.createElement('div');
> self.flashWrapper.id = 'guacamole-audio-flashwrapper-'+self.id
> ;
> var s = self.flashWrapper.style;
> s['position'] = 'fixed';
> s['width'] = s['height'] = '8px';
> s['bottom'] = s['left'] = '0px';
> s['overflow'] = 'hidden';
> self.flashElement = document.createElement('div');
> self.flashElement.id = 'guacamole-audio-flashelement-'+self.id
> ;
> self.flashWrapper.appendChild(self.flashElement);
> document.body.appendChild(self.flashWrapper);
> swfobject.embedSWF(
> self.swf,
> self.flashElement.id,
> "8",
> "8",
> "9.0.0",
> null,
> null,
> {'allowScriptAccess': 'always'},
> null,
> function(e) {
> self.flashElement = e.ref;
> }
> );
>
> },
> write: function(samples) {
> if (this.flashElement !== null) {
> var out = new Array(samples.length);
> for (var i = samples.length-1; i !== 0; i--) {
> out[i] = this.floatToIntSample(samples[i]);
> }
> * this.flashElement.write(out.join(' ')); // This method
> calls flash ( action script method of write )*
> }
> },
> writeInt: function(samples) {
> if (this.flashElement !== null) {
> this.flashElement.write(samples.join(' '));
> }
> },
> intToFloatSample: function(value) {
> return value / 32768; // from -32767..32768 to -1..1 range
> },
> floatToIntSample: function(value) {
> return Math.floor(value * 32768); // from -1..1 to
> -32767..32768 range
> }
> };
*Code of demo.html is as follows : - *
<!DOCTYPE html>
> <html>
> <head>
> <title>Gucamole Demo of Audio with flash</title>
> </head>
> <body>
>
> <script type="text/javascript" src="swfobject.js"></script>
> <script type="text/javascript" src="guacamoleaudio.js"></script>
> <script type="text/javascript" charset="utf-8">
>
> var audioData = [];
> var frequency = 440;
> var interval = null;
> var gucamoleAudio = new GuacamoleFlashAudio({'swf':
> 'dynamicaudio.swf'});
>
> function start() {
> interval = setInterval(function() {
> var n = Math.ceil(frequency / 100) * 2;
> for (var i=0; i < n; i++) {
> * gucamoleAudio.write(audioData); *
> }
> }, 10);
> }
> function playSound() {
> var samples = 44100 / frequency;
> audioData = Array(Math.round(samples));
> for (var i=0; i < audioData.length; i++) {
> audioData[i] = Math.sin(2*Math.PI * (i /
> audioData.length));
> }
> }
> playSound();
> start();
> </script>
> </body>
That is how I am configuring from this demo to integrate into Gucamole.
On Tue, Nov 14, 2017 at 12:01 AM, Frode Langelo <[email protected]> wrote:
> Hi Amarjeet,
>
> Your attachment was stripped so I do not see what your added log
> statement reads.
>
> At this point your main problem is still getting JavaScript to
> communicate with your Flash object.
>
> I would look at this answer and add similar code and logging to ensure
> your Flash code is working correctly:
> https://stackoverflow.com/questions/10050562/calling-
> actionscript-function-from-js?answertab=active#tab-top
>
> How you are getting the handle to the Flash object. I assume something
> like document.getElementById('mySWF')?
>
> I would create a simple test HTML page to exercise only loading your
> SWF and test JavaScript to Flash communication to make sure that part
> works fine before integrating this into Guacamole.
>
> Frode
>
> On Mon, Nov 13, 2017 at 10:06 AM, Amarjeet Singh <[email protected]>
> wrote:
> > I diged into it but nothing came out so far.
> > I tried online forums as well but they used almost same method but with
> mp3
> > files.. I looked into sound Manager 2 and many other fallback API's but
> > they play sound with mp3 files. Use of IE is huge and people haven't
> > upgraded to Windows 10. Sound is very important.
> > If anyone have any ideas please share.
> >
> > Thanks and Regards,
> > Amarjeet Singh
> >
> > On Nov 11, 2017 12:57, "Amarjeet Singh" <[email protected]> wrote:
> >
> > Hi Frode,
> >
> > I tried what you said in the above mail thread.
> >
> >
> > console.log(this.flashElement);
> >
> >
> > *T**he response I get in the console ( Please refer the attachment ):-*
> >
> > Couldn't create AudioContext:ReferenceError: 'AudioContext' is undefined,
> >> falling back to flash player
> >
> >
> > <object width="8" height="8" id="guacamole-flashelement-1"
> >> data="guacamole.swf" type="application/x-shockwave-flash"
> >> style="visibility: visible;"><param name="allowScriptAccess"
> >> value="always"></object>
> >
> >
> > Error : *SCRIPT438: Object doesn't support property or method 'write'*
> >
> >
> >
> > Regards,
> > Amarjeet
> >
> >
> > On Sat, Nov 11, 2017 at 4:30 AM, Frode Langelo <[email protected]> wrote:
> >
> >> Hi Amarjeet,
> >>
> >> I am assuming the line this.flashElement.write(...) causes this:
> >> Error : *SCRIPT438: Object doesn't support property or method 'write'*
> >>
> >> Unfortunately I am not a Flash expert.. I'd check some of the Flash
> >> related forums for JavaScript/Flash integration.
> >> How are you loading your Flash element? I would start looking there..
> >> the culprit appears to be JavaScript not able to access the 'write'
> >> method exposed via ExternalInterface.addCallback in the ActionScript.
> >> Perhaps Flash was not yet ready when you call the write method? What
> >> does console.log(this.flashElement); say, just before calling
> >> this.flashElement.write(...) ?
> >>
> >> Kind regards.
> >> Frode
> >>
> >> On Fri, Nov 10, 2017 at 12:03 PM, Amarjeet Singh <[email protected]>
> >> wrote:
> >> >>
> >> >> varfloatBuffer = toAudioBuffer(new SampleArray(arrayBuffer));
> >> >> sendToFlash(floatBuffer.buffer);
> >> >
> >> >
> >> > It doesn't worked. I am getting the error in the console log while
> >> calling
> >> > flash.write method
> >> >
> >> > Error : *SCRIPT438: Object doesn't support property or method 'write'*
> >> >
> >> > While I am trying the below code it is playing the sound with no
> errors:-
> >> >
> >> > var sampledata = [];
> >> >> var freq = 440;
> >> >> var interval = null;
> >> >> var guacamole= new Guacamole({'swf': 'guacamole.swf'});
> >> >>
> >> >> function start() {
> >> >> interval = setInterval(function() {
> >> >> var n = Math.ceil(freq / 100) * 2;
> >> >> for (var i=0; i < n; i++) {
> >> >> guacamole.write(sampledata); // calls
> >> Guacamole.write
> >> >> }
> >> >> }, 10);
> >> >> }
> >> >
> >> > function createSound() {
> >> >> var samples = 44100 / freq;
> >> >> sampledata = Array(Math.round(samples));
> >> >> for (var i=0; i < sampledata.length; i++) {
> >> >> sampledata[i] = Math.sin(2*Math.PI * (i /
> >> >> sampledata.length));
> >> >> }
> >> >> }
> >> >
> >> > createSound();start();
> >> >
> >> >
> >> >
> >> >
> >> >> Guacamole.write: function(samples) {
> >> >> var out = new Array(samples.length);
> >> >> for (var i = 0;i < samples.length; i++) {
> >> >> out[i] = this.floatToIntSample(samples[i]);
> >> >> }
> >> >> as = out.join(' ');
> >> >> this.flashElement.write(as); // this write calls the
> >> >> flash.write
> >> >> },
> >> >
> >> > floatToIntSample: function(value) {
> >> >> return Math.floor(value * 32768); // from -1..1 to
> -32767..32768
> >> >> range
> >> >> }
> >> >
> >> >
> >> > swf is embedded in HTML document ..
> >> >
> >> >
> >> >
> >> > Please give any suggestions ... What I am missing here ?
> >> > I have data coming in audio stream and I have swf to play the sound
> but
> >> > something with the flow of PCM data to swf is missing.
> >> >
> >> >
> >> > On Fri, Nov 10, 2017 at 10:50 PM, Frode Langelo <[email protected]>
> >> wrote:
> >> >
> >> >> On Fri, Nov 10, 2017 at 3:12 AM, Amarjeet Singh <
> [email protected]>
> >> >> wrote:
> >> >> > Hi Frode,
> >> >> >
> >> >> > I really appreciate the response and guidance you provided. It
> helped
> >> me
> >> >> to
> >> >> > look for more options and created lot of questions in my mind as
> well.
> >> >> >
> >> >> > *1. How can I skip these lines in toAudioBuffer ?*
> >> >> >
> >> >> > var packetTime = context.currentTime;
> >> >> > if (nextPacketTime < packetTime)
> >> >> > nextPacketTime = packetTime;
> >> >> > var audioBuffer = context.createBuffer(format.channels, samples,
> >> >> > format.rate);
> >> >> >
> >> >> > It requires *context.currentTime* but in case of IE context is NULL
> >> and
> >> >> > nothing will be returned in *packetTime*.
> >> >>
> >> >> For the purpose of only converting to a float array, you could try
> >> >> something like:
> >> >>
> >> >> var toAudioBuffer = function toAudioBuffer(data) {
> >> >>
> >> >> // Calculate total number of samples
> >> >> var samples = data.length / format.channels;
> >> >>
> >> >> // Create the Float output audio buffer
> >> >> var audioBuffer = new window.Float32Array(data.length);
> >> >>
> >> >> // Convert each channel
> >> >> for (var channel = 0; channel < format.channels; channel++) {
> >> >>
> >> >> // Fill audio buffer with data for channel
> >> >> var offset = channel;
> >> >> for (var i = 0; i < samples; i++) {
> >> >> audioData[offset] = data[offset] / maxSampleValue;
> >> >> offset += format.channels;
> >> >> }
> >> >>
> >> >> }
> >> >>
> >> >> return audioBuffer;
> >> >>
> >> >> };
> >> >>
> >> >>
> >> >> > *2. Can I skip pushAudioPacket () and shiftAudioPacket() methods as
> >> well
> >> >> ?
> >> >> > ( I don't know what these methods are trying to do.. )*
> >> >>
> >> >> These methods are used to buffer, synchronize audio packet playback,
> >> >> and rearrange (and split) the packets so that the packets are cut
> >> >> where the audio volume is at a low point to reduce the amount of
> >> >> audible clipping between packets played back. Fot the purpose of
> >> >> getting your prototype working I wouldn't worry about this for now;
> >> >> but when you are going for a complete implementation you should look
> >> >> at creating a new AudioPlayer implementation for your Flash audio
> >> >> player.
> >> >>
> >> >> > *3. Do I need nextPacketTime as well ? *
> >> >> >
> >> >> > ( source.start(nextPacketTime); )
> >> >>
> >> >> Not yet (see above comment)
> >> >>
> >> >> > *4. Can I directly call toAudioBuffer function passing
> ArrayBuffer of
> >> >> 6048
> >> >> > byte and skip the packetTime and context.createBuffer ?*
> >> >>
> >> >> The toAudioBuffer function expects a SampleArray which in this case
> is
> >> >> an Int16Array. You could do toAudioBuffer(new
> >> >> SampleArray(arrayBuffer));
> >> >> If you look at the implementation of RawAudioPlayer, it receives the
> >> >> raw audio data in playReceivedAudio from ArrayBufferReader.ondata.
> >> >>
> >> >> > *5. If I use Int16Array over ArrayBuffer It view the data in
> integers
> >> of
> >> >> 16
> >> >> > byte and if use the following for loop:
> >> >> > [snip]
> >> >> > It will push the data for left channel together and right channel
> >> >> together
> >> >> > into an array.
> >> >> > Now, Can I pass this data to my Flash Action Script in a string to
> >> play
> >> >> at
> >> >> > 44.1Khz with 2 channels ?
> >> >>
> >> >> You would need to pass the underlying ArrayBuffer to your Flash
> >> >> script. I am not sure if it can consume it directly though.
> >> >>
> >> >> var floatBuffer = toAudioBuffer(new SampleArray(arrayBuffer));
> >> >> sendToFlash(floatBuffer.buffer);
> >> >>
> >> >>
> >> >> > I would be very grateful if you look into the above queries and
> give
> >> some
> >> >> > guidance so that I can move forward.
> >> >> >
> >> >> > Thanks and Regards,
> >> >> > Amarjeet Singh
> >> >> >
> >> >>
> >>
>