mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-03 13:02:09 +02:00
LibWeb/WebAudio: Manage channelCountMode and channelCount for PannerNode
This commit is contained in:
committed by
Alexander Kalenik
parent
15a96e841b
commit
884599f1df
Notes:
github-actions[bot]
2024-12-18 09:21:00 +00:00
Author: https://github.com/shlyakpavel Commit: https://github.com/LadybirdBrowser/ladybird/commit/884599f1df4 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2944 Reviewed-by: https://github.com/gmta
@@ -0,0 +1,292 @@
|
||||
// Test that constructor for the node with name |nodeName| handles the
|
||||
// various possible values for channelCount, channelCountMode, and
|
||||
// channelInterpretation.
|
||||
|
||||
// The |should| parameter is the test function from new |Audit|.
|
||||
function testAudioNodeOptions(should, context, nodeName, expectedNodeOptions) {
|
||||
if (expectedNodeOptions === undefined)
|
||||
expectedNodeOptions = {};
|
||||
let node;
|
||||
|
||||
// Test that we can set channelCount and that errors are thrown for
|
||||
// invalid values
|
||||
let testChannelCount = 17;
|
||||
if (expectedNodeOptions.channelCount) {
|
||||
testChannelCount = expectedNodeOptions.channelCount.value;
|
||||
}
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context, Object.assign({}, expectedNodeOptions.additionalOptions, {
|
||||
channelCount: testChannelCount
|
||||
}));
|
||||
},
|
||||
'new ' + nodeName + '(c, {channelCount: ' + testChannelCount + '})')
|
||||
.notThrow();
|
||||
should(node.channelCount, 'node.channelCount').beEqualTo(testChannelCount);
|
||||
|
||||
if (expectedNodeOptions.channelCount &&
|
||||
expectedNodeOptions.channelCount.isFixed) {
|
||||
// The channel count is fixed. Verify that we throw an error if
|
||||
// we try to change it. Arbitrarily set the count to be one more
|
||||
// than the expected value.
|
||||
testChannelCount = expectedNodeOptions.channelCount.value + 1;
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionalOptions,
|
||||
{channelCount: testChannelCount}));
|
||||
},
|
||||
'new ' + nodeName + '(c, {channelCount: ' + testChannelCount + '})')
|
||||
.throw(DOMException,
|
||||
expectedNodeOptions.channelCount.exceptionType);
|
||||
// And test that setting it to the fixed value does not throw.
|
||||
testChannelCount = expectedNodeOptions.channelCount.value;
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionalOptions,
|
||||
{channelCount: testChannelCount}));
|
||||
node.channelCount = testChannelCount;
|
||||
},
|
||||
'(new ' + nodeName + '(c, {channelCount: ' + testChannelCount + '})).channelCount = ' + testChannelCount)
|
||||
.notThrow();
|
||||
} else {
|
||||
// The channel count is not fixed. Try to set the count to invalid
|
||||
// values and make sure an error is thrown.
|
||||
[0, 99].forEach(testValue => {
|
||||
should(() => {
|
||||
node = new window[nodeName](
|
||||
context, Object.assign({}, expectedNodeOptions.additionalOptions, {
|
||||
channelCount: testValue
|
||||
}));
|
||||
}, `new ${nodeName}(c, {channelCount: ${testValue}})`)
|
||||
.throw(DOMException, 'NotSupportedError');
|
||||
});
|
||||
}
|
||||
|
||||
// Test channelCountMode
|
||||
let testChannelCountMode = 'max';
|
||||
if (expectedNodeOptions.channelCountMode) {
|
||||
testChannelCountMode = expectedNodeOptions.channelCountMode.value;
|
||||
}
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context, Object.assign({}, expectedNodeOptions.additionalOptions, {
|
||||
channelCountMode: testChannelCountMode
|
||||
}));
|
||||
},
|
||||
'new ' + nodeName + '(c, {channelCountMode: "' + testChannelCountMode +
|
||||
'"}')
|
||||
.notThrow();
|
||||
should(node.channelCountMode, 'node.channelCountMode')
|
||||
.beEqualTo(testChannelCountMode);
|
||||
|
||||
if (expectedNodeOptions.channelCountMode &&
|
||||
expectedNodeOptions.channelCountMode.isFixed) {
|
||||
// Channel count mode is fixed. Test setting to something else throws.
|
||||
['max', 'clamped-max', 'explicit'].forEach(testValue => {
|
||||
if (testValue !== expectedNodeOptions.channelCountMode.value) {
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionalOptions,
|
||||
{channelCountMode: testValue}));
|
||||
},
|
||||
`new ${nodeName}(c, {channelCountMode: "${testValue}"})`)
|
||||
.throw(DOMException,
|
||||
expectedNodeOptions.channelCountMode.exceptionType);
|
||||
} else {
|
||||
// Test that explicitly setting the the fixed value is allowed.
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionalOptions,
|
||||
{channelCountMode: testValue}));
|
||||
node.channelCountMode = testValue;
|
||||
},
|
||||
`(new ${nodeName}(c, {channelCountMode: "${testValue}"})).channelCountMode = "${testValue}"`)
|
||||
.notThrow();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Mode is not fixed. Verify that we can set the mode to all valid
|
||||
// values, and that we throw for invalid values.
|
||||
|
||||
let testValues = ['max', 'clamped-max', 'explicit'];
|
||||
|
||||
testValues.forEach(testValue => {
|
||||
should(() => {
|
||||
node = new window[nodeName](
|
||||
context, Object.assign({}, expectedNodeOptions.additionalOptions, {
|
||||
channelCountMode: testValue
|
||||
}));
|
||||
}, `new ${nodeName}(c, {channelCountMode: "${testValue}"})`).notThrow();
|
||||
should(
|
||||
node.channelCountMode, 'node.channelCountMode after valid setter')
|
||||
.beEqualTo(testValue);
|
||||
|
||||
});
|
||||
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionalOptions,
|
||||
{channelCountMode: 'foobar'}));
|
||||
},
|
||||
'new ' + nodeName + '(c, {channelCountMode: "foobar"}')
|
||||
.throw(TypeError);
|
||||
should(node.channelCountMode, 'node.channelCountMode after invalid setter')
|
||||
.beEqualTo(testValues[testValues.length - 1]);
|
||||
}
|
||||
|
||||
// Test channelInterpretation
|
||||
if (expectedNodeOptions.channelInterpretation &&
|
||||
expectedNodeOptions.channelInterpretation.isFixed) {
|
||||
// The channel interpretation is fixed. Verify that we throw an
|
||||
// error if we try to change it.
|
||||
['speakers', 'discrete'].forEach(testValue => {
|
||||
if (testValue !== expectedNodeOptions.channelInterpretation.value) {
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionOptions,
|
||||
{channelInterpretation: testValue}));
|
||||
},
|
||||
`new ${nodeName}(c, {channelInterpretation: "${testValue}"})`)
|
||||
.throw(DOMException,
|
||||
expectedNodeOptions.channelCountMode.exceptionType);
|
||||
} else {
|
||||
// Check that assigning the fixed value is OK.
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionOptions,
|
||||
{channelInterpretation: testValue}));
|
||||
node.channelInterpretation = testValue;
|
||||
},
|
||||
`(new ${nodeName}(c, {channelInterpretation: "${testValue}"})).channelInterpretation = "${testValue}"`)
|
||||
.notThrow();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Channel interpretation is not fixed. Verify that we can set it
|
||||
// to all possible values.
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionalOptions,
|
||||
{channelInterpretation: 'speakers'}));
|
||||
},
|
||||
'new ' + nodeName + '(c, {channelInterpretation: "speakers"})')
|
||||
.notThrow();
|
||||
should(node.channelInterpretation, 'node.channelInterpretation')
|
||||
.beEqualTo('speakers');
|
||||
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionalOptions,
|
||||
{channelInterpretation: 'discrete'}));
|
||||
},
|
||||
'new ' + nodeName + '(c, {channelInterpretation: "discrete"})')
|
||||
.notThrow();
|
||||
should(node.channelInterpretation, 'node.channelInterpretation')
|
||||
.beEqualTo('discrete');
|
||||
|
||||
should(
|
||||
() => {
|
||||
node = new window[nodeName](
|
||||
context,
|
||||
Object.assign(
|
||||
{}, expectedNodeOptions.additionalOptions,
|
||||
{channelInterpretation: 'foobar'}));
|
||||
},
|
||||
'new ' + nodeName + '(c, {channelInterpretation: "foobar"})')
|
||||
.throw(TypeError);
|
||||
should(
|
||||
node.channelInterpretation,
|
||||
'node.channelInterpretation after invalid setter')
|
||||
.beEqualTo('discrete');
|
||||
}
|
||||
}
|
||||
|
||||
function initializeContext(should) {
|
||||
let c;
|
||||
should(() => {
|
||||
c = new OfflineAudioContext(1, 1, 48000);
|
||||
}, 'context = new OfflineAudioContext(...)').notThrow();
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
function testInvalidConstructor(should, name, context) {
|
||||
should(() => {
|
||||
new window[name]();
|
||||
}, 'new ' + name + '()').throw(TypeError);
|
||||
should(() => {
|
||||
new window[name](1);
|
||||
}, 'new ' + name + '(1)').throw(TypeError);
|
||||
should(() => {
|
||||
new window[name](context, 42);
|
||||
}, 'new ' + name + '(context, 42)').throw(TypeError);
|
||||
}
|
||||
|
||||
function testDefaultConstructor(should, name, context, options) {
|
||||
let node;
|
||||
|
||||
let message = options.prefix + ' = new ' + name + '(context';
|
||||
if (options.constructorOptions)
|
||||
message += ', ' + JSON.stringify(options.constructorOptions);
|
||||
message += ')'
|
||||
|
||||
should(() => {
|
||||
node = new window[name](context, options.constructorOptions);
|
||||
}, message).notThrow();
|
||||
|
||||
should(node instanceof window[name], options.prefix + ' instanceof ' + name)
|
||||
.beEqualTo(true);
|
||||
should(node.numberOfInputs, options.prefix + '.numberOfInputs')
|
||||
.beEqualTo(options.numberOfInputs);
|
||||
should(node.numberOfOutputs, options.prefix + '.numberOfOutputs')
|
||||
.beEqualTo(options.numberOfOutputs);
|
||||
should(node.channelCount, options.prefix + '.channelCount')
|
||||
.beEqualTo(options.channelCount);
|
||||
should(node.channelCountMode, options.prefix + '.channelCountMode')
|
||||
.beEqualTo(options.channelCountMode);
|
||||
should(node.channelInterpretation, options.prefix + '.channelInterpretation')
|
||||
.beEqualTo(options.channelInterpretation);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function testDefaultAttributes(should, node, prefix, items) {
|
||||
items.forEach((item) => {
|
||||
let attr = node[item.name];
|
||||
if (attr instanceof AudioParam) {
|
||||
should(attr.value, prefix + '.' + item.name + '.value')
|
||||
.beEqualTo(item.value);
|
||||
} else {
|
||||
should(attr, prefix + '.' + item.name).beEqualTo(item.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user