tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio-testing.js (5982B)


      1 if (window.testRunner)
      2    testRunner.overridePreference("WebKitWebAudioEnabled", "1");
      3 
      4 function writeString(s, a, offset) {
      5    for (var i = 0; i < s.length; ++i) {
      6        a[offset + i] = s.charCodeAt(i);
      7    }
      8 }
      9 
     10 function writeInt16(n, a, offset) {
     11    n = Math.floor(n);
     12   
     13    var b1 = n & 255;
     14    var b2 = (n >> 8) & 255;
     15 
     16    a[offset + 0] = b1;
     17    a[offset + 1] = b2;
     18 }
     19 
     20 function writeInt32(n, a, offset) {
     21    n = Math.floor(n);
     22    var b1 = n & 255;
     23    var b2 = (n >> 8) & 255;
     24    var b3 = (n >> 16) & 255;
     25    var b4 = (n >> 24) & 255;
     26 
     27    a[offset + 0] = b1;
     28    a[offset + 1] = b2;
     29    a[offset + 2] = b3;
     30    a[offset + 3] = b4;
     31 }
     32 
     33 function writeAudioBuffer(audioBuffer, a, offset) {
     34    var n = audioBuffer.length;
     35    var channels = audioBuffer.numberOfChannels;
     36   
     37    for (var i = 0; i < n; ++i) {
     38        for (var k = 0; k < channels; ++k) {
     39            var buffer = audioBuffer.getChannelData(k);
     40            var sample = buffer[i] * 32768.0;
     41 
     42            // Clip samples to the limitations of 16-bit.
     43            // If we don't do this then we'll get nasty wrap-around distortion.
     44            if (sample < -32768)
     45                sample = -32768;
     46            if (sample > 32767)
     47                sample = 32767;
     48 
     49            writeInt16(sample, a, offset);
     50            offset += 2;
     51        }
     52    }
     53 }
     54 
     55 function createWaveFileData(audioBuffer) {
     56    var frameLength = audioBuffer.length;
     57    var numberOfChannels = audioBuffer.numberOfChannels;
     58    var sampleRate = audioBuffer.sampleRate;
     59    var bitsPerSample = 16;
     60    var byteRate = sampleRate * numberOfChannels * bitsPerSample/8;
     61    var blockAlign = numberOfChannels * bitsPerSample/8;
     62    var wavDataByteLength = frameLength * numberOfChannels * 2; // 16-bit audio
     63    var headerByteLength = 44;
     64    var totalLength = headerByteLength + wavDataByteLength;
     65 
     66    var waveFileData = new Uint8Array(totalLength);
     67   
     68    var subChunk1Size = 16; // for linear PCM
     69    var subChunk2Size = wavDataByteLength;
     70    var chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size);
     71 
     72    writeString("RIFF", waveFileData, 0);
     73    writeInt32(chunkSize, waveFileData, 4);
     74    writeString("WAVE", waveFileData, 8);
     75    writeString("fmt ", waveFileData, 12);
     76   
     77    writeInt32(subChunk1Size, waveFileData, 16);      // SubChunk1Size (4)
     78    writeInt16(1, waveFileData, 20);                  // AudioFormat (2)
     79    writeInt16(numberOfChannels, waveFileData, 22);   // NumChannels (2)
     80    writeInt32(sampleRate, waveFileData, 24);         // SampleRate (4)
     81    writeInt32(byteRate, waveFileData, 28);           // ByteRate (4)
     82    writeInt16(blockAlign, waveFileData, 32);         // BlockAlign (2)
     83    writeInt32(bitsPerSample, waveFileData, 34);      // BitsPerSample (4)
     84                                                     
     85    writeString("data", waveFileData, 36);            
     86    writeInt32(subChunk2Size, waveFileData, 40);      // SubChunk2Size (4)
     87   
     88    // Write actual audio data starting at offset 44.
     89    writeAudioBuffer(audioBuffer, waveFileData, 44);
     90   
     91    return waveFileData;
     92 }
     93 
     94 function createAudioData(audioBuffer) {
     95    return createWaveFileData(audioBuffer);
     96 }
     97 
     98 function finishAudioTest(event) {
     99    var audioData = createAudioData(event.renderedBuffer);
    100    testRunner.setAudioData(audioData);
    101    testRunner.notifyDone();
    102 }
    103 
    104 // Create an impulse in a buffer of length sampleFrameLength
    105 function createImpulseBuffer(context, sampleFrameLength) {
    106    var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);
    107    var n = audioBuffer.length;
    108    var dataL = audioBuffer.getChannelData(0);
    109 
    110    for (var k = 0; k < n; ++k) {
    111        dataL[k] = 0;
    112    }
    113    dataL[0] = 1;
    114 
    115    return audioBuffer;
    116 }
    117 
    118 // Create a buffer of the given length with a linear ramp having values 0 <= x < 1.
    119 function createLinearRampBuffer(context, sampleFrameLength) {
    120    var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);
    121    var n = audioBuffer.length;
    122    var dataL = audioBuffer.getChannelData(0);
    123 
    124    for (var i = 0; i < n; ++i)
    125        dataL[i] = i / n;
    126 
    127    return audioBuffer;
    128 }
    129 
    130 // Create a buffer of the given length having a constant value.
    131 function createConstantBuffer(context, sampleFrameLength, constantValue) {
    132    var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleRate);
    133    var n = audioBuffer.length;
    134    var dataL = audioBuffer.getChannelData(0);
    135 
    136    for (var i = 0; i < n; ++i)
    137        dataL[i] = constantValue;
    138 
    139    return audioBuffer;
    140 }
    141 
    142 // Create a stereo impulse in a buffer of length sampleFrameLength
    143 function createStereoImpulseBuffer(context, sampleFrameLength) {
    144    var audioBuffer = context.createBuffer(2, sampleFrameLength, context.sampleRate);
    145    var n = audioBuffer.length;
    146    var dataL = audioBuffer.getChannelData(0);
    147    var dataR = audioBuffer.getChannelData(1);
    148 
    149    for (var k = 0; k < n; ++k) {
    150        dataL[k] = 0;
    151        dataR[k] = 0;
    152    }
    153    dataL[0] = 1;
    154    dataR[0] = 1;
    155 
    156    return audioBuffer;
    157 }
    158 
    159 // Convert time (in seconds) to sample frames.
    160 function timeToSampleFrame(time, sampleRate) {
    161    return Math.floor(0.5 + time * sampleRate);
    162 }
    163 
    164 // Compute the number of sample frames consumed by start with
    165 // the specified |grainOffset|, |duration|, and |sampleRate|.
    166 function grainLengthInSampleFrames(grainOffset, duration, sampleRate) {
    167    var startFrame = timeToSampleFrame(grainOffset, sampleRate);
    168    var endFrame = timeToSampleFrame(grainOffset + duration, sampleRate);
    169 
    170    return endFrame - startFrame;
    171 }
    172 
    173 // True if the number is not an infinity or NaN
    174 function isValidNumber(x) {
    175    return !isNaN(x) && (x != Infinity) && (x != -Infinity);
    176 }
    177 
    178 function shouldThrowTypeError(func, text) {
    179    var ok = false;
    180    try {
    181        func();
    182    } catch (e) {
    183        if (e instanceof TypeError) {
    184            ok = true;
    185        }
    186    }
    187    if (ok) {
    188        testPassed(text + " threw TypeError.");
    189    } else {
    190        testFailed(text + " should throw TypeError.");
    191    }
    192 }