summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html
blob: 136abedaa8458f3ce5d003e8cc52db8c346f1a15 (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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
<!DOCTYPE html>
<html>
  <head>
    <title>
      Test AudioContextOptions
    </title>
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <script src="/webaudio/resources/audit.js"></script>
  </head>
  <body>
    <script id="layout-test-code">
      let context;
      let defaultLatency;
      let interactiveLatency;
      let balancedLatency;
      let playbackLatency;

      let audit = Audit.createTaskRunner();

      audit.define(
          {
            label: 'test-audiocontextoptions-latencyHint-basic',
            description: 'Test creating contexts with basic latencyHint types.'
          },
          function(task, should) {
            let closingPromises = [];

            // Verify that an AudioContext can be created with default options.
            should(function() {
              context = new AudioContext()
            }, 'context = new AudioContext()').notThrow();

            should(context.sampleRate,
              `context.sampleRate (${context.sampleRate} Hz)`).beGreaterThan(0);

            defaultLatency = context.baseLatency;
            should(defaultLatency, 'default baseLatency').beGreaterThanOrEqualTo(0);

            // Verify that an AudioContext can be created with the expected
            // latency types.
            should(
                function() {
                  context = new AudioContext({'latencyHint': 'interactive'})
                },
                'context = new AudioContext({\'latencyHint\': \'interactive\'})')
                .notThrow();

            interactiveLatency = context.baseLatency;
            should(interactiveLatency, 'interactive baseLatency')
                .beEqualTo(defaultLatency);
            closingPromises.push(context.close());

            should(
                function() {
                  context = new AudioContext({'latencyHint': 'balanced'})
                },
                'context = new AudioContext({\'latencyHint\': \'balanced\'})')
                .notThrow();

            balancedLatency = context.baseLatency;
            should(balancedLatency, 'balanced baseLatency')
                .beGreaterThanOrEqualTo(interactiveLatency);
            closingPromises.push(context.close());

            should(
                function() {
                  context = new AudioContext({'latencyHint': 'playback'})
                },
                'context = new AudioContext({\'latencyHint\': \'playback\'})')
                .notThrow();

            playbackLatency = context.baseLatency;
            should(playbackLatency, 'playback baseLatency')
                .beGreaterThanOrEqualTo(balancedLatency);
            closingPromises.push(context.close());

            Promise.all(closingPromises).then(function() {
              task.done();
            });
          });

      audit.define(
          {
            label: 'test-audiocontextoptions-latencyHint-double',
            description:
                'Test creating contexts with explicit latencyHint values.'
          },
          function(task, should) {
            let closingPromises = [];

            // Verify too small exact latency clamped to 'interactive'
            should(
                function() {
                  context =
                      new AudioContext({'latencyHint': interactiveLatency / 2})
                },
                'context = new AudioContext({\'latencyHint\': ' +
                    'interactiveLatency/2})')
                .notThrow();
            should(context.baseLatency, 'double-constructor baseLatency small')
                .beLessThanOrEqualTo(interactiveLatency);
            closingPromises.push(context.close());

            // Verify that exact latency in range works as expected
            let validLatency = (interactiveLatency + playbackLatency) / 2;
            should(
                function() {
                  context = new AudioContext({'latencyHint': validLatency})
                },
                'context = new AudioContext({\'latencyHint\': validLatency})')
                .notThrow();
            should(
                context.baseLatency, 'double-constructor baseLatency inrange 1')
                .beGreaterThanOrEqualTo(interactiveLatency);
            should(
                context.baseLatency, 'double-constructor baseLatency inrange 2')
                .beLessThanOrEqualTo(playbackLatency);
            closingPromises.push(context.close());

            // Verify too big exact latency clamped to some value
            let context1;
            let context2;
            should(function() {
              context1 =
                  new AudioContext({'latencyHint': playbackLatency * 10});
              context2 =
                  new AudioContext({'latencyHint': playbackLatency * 20});
            }, 'creating two high latency contexts').notThrow();
            should(context1.baseLatency, 'high latency context baseLatency')
                .beEqualTo(context2.baseLatency);
            should(context1.baseLatency, 'high latency context baseLatency')
                .beGreaterThanOrEqualTo(interactiveLatency);
            closingPromises.push(context1.close());
            closingPromises.push(context2.close());

            // Verify that invalid latencyHint values are rejected.
            should(
                function() {
                  context = new AudioContext({'latencyHint': 'foo'})
                },
                'context = new AudioContext({\'latencyHint\': \'foo\'})')
                .throw(TypeError);

            // Verify that no extra options can be passed into the
            // AudioContextOptions.
            should(
                function() {
                  context = new AudioContext('latencyHint')
                },
                'context = new AudioContext(\'latencyHint\')')
                .throw(TypeError);

            Promise.all(closingPromises).then(function() {
              task.done();
            });
          });

      audit.define(
          {
            label: 'test-audiocontextoptions-sampleRate',
            description:
                'Test creating contexts with non-default sampleRate values.'
          },
          function(task, should) {
            // A sampleRate of 1 is unlikely to be supported on any browser,
            // test that this rate is rejected.
            should(
                () => {
                  context = new AudioContext({sampleRate: 1})
                },
                'context = new AudioContext({sampleRate: 1})')
                .throw(DOMException, 'NotSupportedError');

            // A sampleRate of 1,000,000 is unlikely to be supported on any
            // browser, test that this rate is also rejected.
            should(
                () => {
                  context = new AudioContext({sampleRate: 1000000})
                },
                'context = new AudioContext({sampleRate: 1000000})')
                .throw(DOMException, 'NotSupportedError');
            // A negative sample rate should not be accepted
            should(
                () => {
                  context = new AudioContext({sampleRate: -1})
                },
                'context = new AudioContext({sampleRate: -1})')
                .throw(DOMException, 'NotSupportedError');
            // A null sample rate should not be accepted
            should(
                () => {
                  context = new AudioContext({sampleRate: 0})
                },
                'context = new AudioContext({sampleRate: 0})')
                .throw(DOMException, 'NotSupportedError');

            should(
                () => {
                  context = new AudioContext({sampleRate: 24000})
                },
                'context = new AudioContext({sampleRate: 24000})')
                .notThrow();
            should(
                context.sampleRate, 'sampleRate inrange')
                .beEqualTo(24000);

            context.close();
            task.done();
          });

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