summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/set-target-conv.html
blob: 2ed076cccf758caaec1c381e89254b10ff7cd7d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Test convergence of setTargetAtTime</title>
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <script src="/webaudio/resources/audit.js"></script>
    <script src='/webaudio/resources/audio-param.js'></script>
  </head>

  <body>
    <script>
      let audit = Audit.createTaskRunner();

      audit.define(
          {task: 'setTargetAtTime', label: 'convergence handled correctly'},
          (task, should) => {
            // Two channels:
            //  0 - actual result
            //  1 - expected result
            const context = new OfflineAudioContext(
                {numberOfChannels: 2, sampleRate: 8000, length: 8000});

            const merger = new ChannelMergerNode(
                context, {numberOfChannels: context.destination.channelCount});
            merger.connect(context.destination);

            // Construct test source that will have tha AudioParams being tested
            // to verify that the AudioParams are working correctly.
            let src;

            should(
                () => src = new ConstantSourceNode(context),
                'src = new ConstantSourceNode(context)')
                .notThrow();

            src.connect(merger, 0, 0);
            src.offset.setValueAtTime(1, 0);

            const timeConstant = 0.01;

            // testTime must be at least 10*timeConstant. Also, this must not
            // lie on a render boundary.
            const testTime = 0.15;
            const rampEnd = testTime + 0.001;

            should(
                () => src.offset.setTargetAtTime(0.5, 0.01, timeConstant),
                `src.offset.setTargetAtTime(0.5, 0.01, ${timeConstant})`)
                .notThrow();
            should(
                () => src.offset.setValueAtTime(0.5, testTime),
                `src.offset.setValueAtTime(0.5, ${testTime})`)
                .notThrow();
            should(
                () => src.offset.linearRampToValueAtTime(1, rampEnd),
                `src.offset.linearRampToValueAtTime(1, ${rampEnd})`)
                .notThrow();

            // The reference node that will generate the expected output.  We do
            // the same automations, except we don't apply the setTarget
            // automation.
            const refSrc = new ConstantSourceNode(context);
            refSrc.connect(merger, 0, 1);

            refSrc.offset.setValueAtTime(0.5, 0);
            refSrc.offset.setValueAtTime(0.5, testTime);
            refSrc.offset.linearRampToValueAtTime(1, rampEnd);

            src.start();
            refSrc.start();

            context.startRendering()
                .then(audio => {
                  const actual = audio.getChannelData(0);
                  const expected = audio.getChannelData(1);

                  // Just verify that the actual output matches the expected
                  // starting a little bit before testTime.
                  let testFrame =
                      Math.floor(testTime * context.sampleRate) - 128;
                  should(actual.slice(testFrame), `output[${testFrame}:]`)
                      .beCloseToArray(
                          expected.slice(testFrame),
                          {relativeThreshold: 4.1724e-6});
                })
                .then(() => task.done());
          });

      audit.run();
    </script>
  </body>
</html>