kramann.info
© Guido Kramann

Login: Passwort:










kramann.info
© Guido Kramann

Login: Passwort:




Hinzufügen der sende-Funktionalität

(EN google-translate)

(PL google-translate)

02_senden.zip - Projektdateien.
function Audiotransfer()
{
    const TONDAUER_PROZ_ZYKLEN = 20; //Hiervon hängt die Geschwindigkeit der Datenübertragung ab.
    const SCHWELLE = 5;      //Faktor zwischen kennzahlen von gefundenem und nicht gefundenem Ton
    const AUDIO_PUFFER_GROESSE = 1024;

    const TOENE = [500,63,42,28];

    var audiopuffer = new Array(AUDIO_PUFFER_GROESSE);
    var DATA_IN = null;

    var ZAEHLER  = 0;
    var DURCHLAUF = 0; // Anzahl Durchläaufe von prozess(e) wg. tonwechsel()
    var DZ = TOENE[0];

    var kennzahl = [0,0,0];
    var kennzahl_phase = [63,42,28];

    var signal_nummer = 0; //0==kein Signal, 1==Ton 1, 2==Ton2, 3==Ton3

    var sendepuffer = new Array();
    var merker = new Array(8); //Hilfsvariable für sendeZahl()

    //*************************************
    //*** Funktionen zu Wartungszwecken ***
    //*************************************

    //Um den Audiopuffer zu visualiseren:
    this.holeAudiopuffer = function() 
    {
        if(DATA_IN!=null && DATA_IN.length==AUDIO_PUFFER_GROESSE)
        {
            for(var i=0;i<DATA_IN.length;i++)
                audiopuffer[i] = DATA_IN[i];
        }
        return audiopuffer;
    }

    //..um bei langsamem Verlauf den aktuell erkannten Ton anzeigen zu können.
    this.holeSignalnummer = function()
    {
        return signal_nummer;
    }

    //**************************
    //*** Private Funktionen ***
    //**************************

    function tonwechsel()
    {
        //Falls mehr als 0 Einträge in sendepuffer,
        //Dann ersten Toneintrag übernehmen und löschen.
        //andernfalls KEIN TON senden.
        if(sendepuffer!=null && sendepuffer.length>0)
        {
            DZ = sendepuffer[0];
            sendepuffer.shift(); //entfernt erstes Element, vergl. http://www.w3schools.com/jsref/jsref_shift.asp
        }
        else
        {
            DZ = TOENE[0]; //KEIN (DEFINIERTER) TON
        }
    }

    function prozess(e)
    {
        var data_in  = e.inputBuffer.getChannelData(1);
        var data_out = e.outputBuffer.getChannelData(1);

        //Um den Audiopuffer zu visualiseren:
        DATA_IN = data_in;

        for (var i = 0; i < data_out.length; ++i) 
        {
            if(ZAEHLER<14)
                data_out[i] = 0.5;
            else
                data_out[i] = 0.0;
            ZAEHLER++;
            ZAEHLER%=DZ;
        }

        //Berechnung der drei Kennzahlen:

        for(var k=0;k<kennzahl.length;k++)
        {
            kennzahl[k]=0;
            var phase = kennzahl_phase[k];
            var wert  = 0;
            for(var i=0;i<data_in.length;i++)
            {
                wert = data_in[i] - data_in[(i+phase)%data_in.length];
                wert = wert*wert;
                kennzahl[k]+=wert;
            }
        }

        //Signalnummer aus Kennzahl bestimmen:
        if(kennzahl[1]/kennzahl[0]>SCHWELLE && kennzahl[2]/kennzahl[0]>SCHWELLE)
            signal_nummer = 1;
        else if(kennzahl[0]/kennzahl[1]>SCHWELLE && kennzahl[2]/kennzahl[1]>SCHWELLE)
            signal_nummer = 2;
        else if(kennzahl[0]/kennzahl[2]>SCHWELLE && kennzahl[1]/kennzahl[2]>SCHWELLE)
            signal_nummer = 3;
        else
            signal_nummer = 0;

        if(DURCHLAUF>=TONDAUER_PROZ_ZYKLEN)
        {
            tonwechsel();
            DURCHLAUF=0;
        }
        DURCHLAUF++;
    }


    function init(e)
    {
        var context = new (window.AudioContext || window.webkitAudioContext)();
        var volume = context.createGain(); //Ohne Volume-Knoten bleibt der Eingang stumm!
        var audioInput = context.createMediaStreamSource(e);
        audioInput.connect(volume);

        var node = context.createScriptProcessor(AUDIO_PUFFER_GROESSE, 2, 2);
        node.onaudioprocess = function(e) { prozess(e) };
        volume.connect (node);
        volume.gain.value=1.0;
        node.connect(context.destination);
    }

    //*****************************************************
    //*** Funktionen der Programmierschnittstelle (API) ***
    //*****************************************************

    this.sendeZahl = function(zahl)
    {
        if(zahl==null || typeof(zahl)!="number" || zahl<0 || zahl>255)
        {
             return false;
        }
        else
        {
             zahl = Math.floor(zahl); //sicherheitshalber nachkommastellen abschneiden.

             //sendepuffer[sendepuffer.length] = zahl;
             //besser:
             //Zahl gleich in Tonfolgen zerlegen und diese in sendepuffer ablegen:
             for(var i=7;i>=0;i--)
             {
                 merker[i] = zahl%2;
                 zahl/=2;
                 zahl = Math.floor(zahl);
             }

             //sendepuffer[sendepuffer.length] = ..
             //besser:
             sendepuffer.push(TOENE[0]); //Länger KEIN TON
             sendepuffer.push(TOENE[0]);

             //Dann Bits senden, also in Puffer Tonwechselfolge eintragen:
             for(var i=0;i<merker.length;i++)
             {
                 sendepuffer.push(TOENE[1]);
                 if(merker[i]==0)
                     sendepuffer.push(TOENE[2]);
                 else
                     sendepuffer.push(TOENE[3]);
             }

             sendepuffer.push(TOENE[0]); //Länger KEIN TON
             sendepuffer.push(TOENE[0]);

             return true;
        }
    }

    this.sendeText = function(text)
    {
        if(text==null || typeof(text)!="string" || text.length==0)
        {
            return true;
        }
        else
        {
            for(var i=0;i<text.length;i++)
            {
                this.sendeZahl(text.charCodeAt(i));
            }
        }
    }

    this.initialisieren = function()
    {
        if (!navigator.getUserMedia)
        {
              navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
                  navigator.mozGetUserMedia || navigator.msGetUserMedia;
        }
        if (navigator.getUserMedia) 
        {
            //Mikrofon-Zugriff beim Benutzer anfordern
            navigator.getUserMedia({audio:true}, init, function(e) {
            alert('Error capturing audio.');
            });
        } 
        else 
        {
            alert('getUserMedia not supported in this browser.');
        }
    }    
}

Code 0-1: Klasse Audiotransfer in Datei Audiotransfer.js

<!DOCTYPE html>
<html>
    <head lang="de">
        <meta charset="iso-8859-1">
        <script type="text/javascript" src="Audiotransfer.js"></script>
        <script language:javascript>
            var audiotransfer = null;
            var malkontext = null;

            function senden()
            {
                var text = document.getElementById("sendetext").value;
                audiotransfer.sendeText(text);
            }

            function zeigeAudiopuffer()
            {
                var data_in = audiotransfer.holeAudiopuffer();
                malkontext.fillStyle = "#000000";
                malkontext.fillRect(0,0,1024,1000);
                malkontext.strokeStyle="#ffffff";
                malkontext.beginPath();
                var x1 = 0;
                var y1 = data_in[0]*200+200;
                malkontext.moveTo(x1,y1);
                for (var i = 0; i < data_in.length; i++) 
                {
                    var x2 = i;
                    var y2 = data_in[i]*200+200;
                    malkontext.lineTo(x2,y2);
                }
                malkontext.stroke();

                document.getElementById("SIGNALNUMMER").innerHTML=audiotransfer.holeSignalnummer();
            }

            function initialisieren()
            {
                malkontext = document.getElementById("grafik").getContext("2d"); 

                audiotransfer = new Audiotransfer();
                audiotransfer.initialisieren();

                setInterval(zeigeAudiopuffer,50);
            }
        </script>
    </head>
    <body onload="javascript:initialisieren()">
    <canvas id="grafik" width="1024" height="400"></canvas>    
    <h2>Erkannt wird Signalnummer: <span id="SIGNALNUMMER"></span></h2>
    <br/>
    <fieldset>
        <input id="sendetext" type="text" style="width:200px;" value=""/>
        <input id="senden" type="button" value="SENDEN" onclick="javascript:senden();"/>
    </fieldset>
    </body>
</html>

Code 0-2: Anwendungsteil in Datei Teste_Audiotransfer.html