Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  panner-model-testing.js   Sprache: JAVA

 
var sampleRate = 48000.0;

var numberOfChannels = 1;

// Time step when each panner node starts.
var timeStep = 0.001;

// Length of the impulse signal.
var pulseLengthFrames = Math.round(timeStep * sampleRate);

// How many panner nodes to create for the test
var nodesToCreate = 100;

// Be sure we render long enough for all of our nodes.
var renderLengthSeconds = timeStep * (nodesToCreate + 1);

// These are global mostly for debugging.
var context;
var impulse;
var bufferSource;
var panner;
var position;
var time;
      
var renderedBuffer;
var renderedLeft;
var renderedRight;

function createGraph(context, nodeCount) {
    bufferSource = new Array(nodeCount);
    panner = new Array(nodeCount);
    position = new Array(nodeCount);
    time = new Array(nodeCount);
    // Angle between panner locations.  (nodeCount - 1 because we want
    // to include both 0 and 180 deg.
    var angleStep = Math.PI / (nodeCount - 1);

    if (numberOfChannels == 2) {
        impulse = createStereoImpulseBuffer(context, pulseLengthFrames);
    }
    else
        impulse = createImpulseBuffer(context, pulseLengthFrames);

    for (var k = 0; k < nodeCount; ++k) {
        bufferSource[k] = context.createBufferSource();
        bufferSource[k].buffer = impulse;

        panner[k] = context.createPanner();
        panner[k].panningModel = "equalpower";
        panner[k].distanceModel = "linear";

        var angle = angleStep * k;
        position[k] = {angle : angle, x : Math.cos(angle), z : Math.sin(angle)};
        panner[k].positionX.value = position[k].x;
        panner[k].positionZ.value = position[k].z;

        bufferSource[k].connect(panner[k]);
        panner[k].connect(context.destination);

        // Start the source
        time[k] = k * timeStep;
        bufferSource[k].start(time[k]);
    }
}

function createTestAndRun(context, nodeCount, numberOfSourceChannels) {
    numberOfChannels = numberOfSourceChannels;

    createGraph(context, nodeCount);

    context.oncomplete = checkResult;
    context.startRendering();
}

// Map our position angle to the azimuth angle (in degrees).
//
// An angle of 0 corresponds to an azimuth of 90 deg; pi, to -90 deg.
function angleToAzimuth(angle) {
    return 90 - angle * 180 / Math.PI;
}

// The gain caused by the EQUALPOWER panning model
function equalPowerGain(angle) {
    var azimuth = angleToAzimuth(angle);

    if (numberOfChannels == 1) {
        var panPosition = (azimuth + 90) / 180;

        var gainL = Math.cos(0.5 * Math.PI * panPosition);
        var gainR = Math.sin(0.5 * Math.PI * panPosition);

        return { left : gainL, right : gainR };
    } else {
        if (azimuth <= 0) {
            var panPosition = (azimuth + 90) / 90;
    
            var gainL = 1 + Math.cos(0.5 * Math.PI * panPosition);
            var gainR = Math.sin(0.5 * Math.PI * panPosition);
    
            return { left : gainL, right : gainR };
        } else {
            var panPosition = azimuth / 90;
    
            var gainL = Math.cos(0.5 * Math.PI * panPosition);
            var gainR = 1 + Math.sin(0.5 * Math.PI * panPosition);
    
            return { left : gainL, right : gainR };
        }
    }
}

function checkResult(event) {
    renderedBuffer = event.renderedBuffer;
    renderedLeft = renderedBuffer.getChannelData(0);
    renderedRight = renderedBuffer.getChannelData(1);

    // The max error we allow between the rendered impulse and the
    // expected value.  This value is experimentally determined.  Set
    // to 0 to make the test fail to see what the actual error is.
    var maxAllowedError = 1.3e-6;
  
    var success = true;

    // Number of impulses found in the rendered result.
    var impulseCount = 0;

    // Max (relative) error and the index of the maxima for the left
    // and right channels.
    var maxErrorL = 0;
    var maxErrorIndexL = 0;
    var maxErrorR = 0;
    var maxErrorIndexR = 0;

    // Number of impulses that don't match our expected locations.
    var timeCount = 0;

    // Locations of where the impulses aren't at the expected locations.
    var timeErrors = new Array();

    for (var k = 0; k < renderedLeft.length; ++k) {
        // We assume that the left and right channels start at the same instant.
        if (renderedLeft[k] != 0 || renderedRight[k] != 0) {
            // The expected gain for the left and right channels.
            var pannerGain = equalPowerGain(position[impulseCount].angle);
            var expectedL = pannerGain.left;
            var expectedR = pannerGain.right;

            // Absolute error in the gain.
            var errorL = Math.abs(renderedLeft[k] - expectedL);
            var errorR = Math.abs(renderedRight[k] - expectedR);

            if (Math.abs(errorL) > maxErrorL) {
                maxErrorL = Math.abs(errorL);
                maxErrorIndexL = impulseCount;
            }
            if (Math.abs(errorR) > maxErrorR) {
                maxErrorR = Math.abs(errorR);
                maxErrorIndexR = impulseCount;
            }

            // Keep track of the impulses that didn't show up where we
            // expected them to be.
            var expectedOffset = timeToSampleFrame(time[impulseCount], sampleRate);
            if (k != expectedOffset) {
                timeErrors[timeCount] = { actual : k, expected : expectedOffset};
                ++timeCount;
            }
            ++impulseCount;
        }
    }

    if (impulseCount == nodesToCreate) {
        testPassed("Number of impulses matches the number of panner nodes.");
    } else {
        testFailed("Number of impulses is incorrect. (Found " + impulseCount + " but expected " + nodesToCreate + ")");
        success = false;
    }

    if (timeErrors.length > 0) {
        success = false;
        testFailed(timeErrors.length + " timing errors found in " + nodesToCreate + " panner nodes.");
        for (var k = 0; k < timeErrors.length; ++k) {
            testFailed("Impulse at sample " + timeErrors[k].actual + " but expected " + timeErrors[k].expected);
        }
    } else {
        testPassed("All impulses at expected offsets.");
    }

    if (maxErrorL <= maxAllowedError) {
        testPassed("Left channel gain values are correct.");
    } else {
        testFailed("Left channel gain values are incorrect. Max error = " + maxErrorL + " at time " + time[maxErrorIndexL] + " (threshold = " + maxAllowedError + ")");
        success = false;
    }

    if (maxErrorR <= maxAllowedError) {
        testPassed("Right channel gain values are correct.");
    } else {
        testFailed("Right channel gain values are incorrect. Max error = " + maxErrorR + " at time " + time[maxErrorIndexR] + " (threshold = " + maxAllowedError + ")");
        success = false;
    }

    if (success) {
        testPassed("EqualPower panner test passed");
    } else {
        testFailed("EqualPower panner test failed");
    }

    finishJSTest();
}

Messung V0.5
C=84 H=95 G=89

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge