mirror of
https://github.com/SerenityOS/serenity
synced 2024-09-06 17:06:31 +00:00
LibWeb: Implement OscillatorNode.frequency
Which is an AudioParam clamped by the nyquist_frequency.
This commit is contained in:
parent
5f57596520
commit
e2b5ff2450
|
@ -8,3 +8,5 @@ Error creating node: 'InvalidStateError: Oscillator node type cannot be set to '
|
|||
oscillator node type: 'sine'
|
||||
Error: 'InvalidStateError: Oscillator node type cannot be set to 'custom'', type is: sine
|
||||
oscillator node type: 'triangle'
|
||||
[object AudioParam] current: 440, default: 440, min: -22050, max: 22050, rate: a-rate
|
||||
[object AudioParam] current: -52, default: 440, min: -22050, max: 22050, rate: a-rate
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<script src="../include.js"></script>
|
||||
<script>
|
||||
function dumpAudioParam(param) {
|
||||
println(`${param} current: ${param.value}, default: ${param.defaultValue}, min: ${param.minValue}, max: ${param.maxValue}, rate: ${param.automationRate}`);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const audioContext = new OfflineAudioContext(1, 5000, 44100);
|
||||
|
||||
|
@ -32,5 +36,11 @@
|
|||
}
|
||||
oscillator.type = 'triangle';
|
||||
println(`oscillator node type: '${oscillator.type}'`);
|
||||
|
||||
// Frequency attribute
|
||||
let frequency = oscillator.frequency;
|
||||
dumpAudioParam(frequency);
|
||||
frequency.value = -52;
|
||||
dumpAudioParam(frequency);
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -13,6 +13,21 @@ namespace Web::WebAudio {
|
|||
|
||||
JS_DEFINE_ALLOCATOR(AudioParam);
|
||||
|
||||
AudioParam::AudioParam(JS::Realm& realm, float default_value, float min_value, float max_value, Bindings::AutomationRate automation_rate)
|
||||
: Bindings::PlatformObject(realm)
|
||||
, m_current_value(default_value)
|
||||
, m_default_value(default_value)
|
||||
, m_min_value(min_value)
|
||||
, m_max_value(max_value)
|
||||
, m_automation_rate(automation_rate)
|
||||
{
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<AudioParam> AudioParam::create(JS::Realm& realm, float default_value, float min_value, float max_value, Bindings::AutomationRate automation_rate)
|
||||
{
|
||||
return realm.vm().heap().allocate<AudioParam>(realm, realm, default_value, min_value, max_value, automation_rate);
|
||||
}
|
||||
|
||||
AudioParam::~AudioParam() = default;
|
||||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audioparam-value
|
||||
|
|
|
@ -18,6 +18,8 @@ class AudioParam final : public Bindings::PlatformObject {
|
|||
JS_DECLARE_ALLOCATOR(AudioParam);
|
||||
|
||||
public:
|
||||
static JS::NonnullGCPtr<AudioParam> create(JS::Realm&, float default_value, float min_value, float max_value, Bindings::AutomationRate);
|
||||
|
||||
virtual ~AudioParam() override;
|
||||
|
||||
float value() const;
|
||||
|
@ -39,6 +41,8 @@ public:
|
|||
WebIDL::ExceptionOr<JS::NonnullGCPtr<AudioParam>> cancel_and_hold_at_time(double cancel_time);
|
||||
|
||||
private:
|
||||
AudioParam(JS::Realm&, float default_value, float min_value, float max_value, Bindings::AutomationRate);
|
||||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audioparam-current-value-slot
|
||||
float m_current_value {}; // [[current value]]
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/OscillatorNodePrototype.h>
|
||||
#include <LibWeb/WebAudio/AudioParam.h>
|
||||
#include <LibWeb/WebAudio/BaseAudioContext.h>
|
||||
#include <LibWeb/WebAudio/OscillatorNode.h>
|
||||
|
||||
namespace Web::WebAudio {
|
||||
|
@ -28,8 +30,9 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<OscillatorNode>> OscillatorNode::construct_
|
|||
return node;
|
||||
}
|
||||
|
||||
OscillatorNode::OscillatorNode(JS::Realm& realm, JS::NonnullGCPtr<BaseAudioContext> context, OscillatorOptions const&)
|
||||
OscillatorNode::OscillatorNode(JS::Realm& realm, JS::NonnullGCPtr<BaseAudioContext> context, OscillatorOptions const& options)
|
||||
: AudioScheduledSourceNode(realm, context)
|
||||
, m_frequency(AudioParam::create(realm, options.frequency, -context->nyquist_frequency(), context->nyquist_frequency(), Bindings::AutomationRate::ARate))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -69,6 +72,7 @@ void OscillatorNode::initialize(JS::Realm& realm)
|
|||
void OscillatorNode::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_frequency);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ public:
|
|||
Bindings::OscillatorType type() const;
|
||||
WebIDL::ExceptionOr<void> set_type(Bindings::OscillatorType);
|
||||
|
||||
JS::NonnullGCPtr<AudioParam const> frequency() const { return m_frequency; }
|
||||
|
||||
protected:
|
||||
OscillatorNode(JS::Realm&, JS::NonnullGCPtr<BaseAudioContext>, OscillatorOptions const& = {});
|
||||
|
||||
|
@ -44,6 +46,9 @@ private:
|
|||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-oscillatornode-type
|
||||
Bindings::OscillatorType m_type { Bindings::OscillatorType::Sine };
|
||||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-oscillatornode-frequency
|
||||
JS::NonnullGCPtr<AudioParam> m_frequency;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ dictionary OscillatorOptions : AudioNodeOptions {
|
|||
interface OscillatorNode : AudioScheduledSourceNode {
|
||||
constructor(BaseAudioContext context, optional OscillatorOptions options = {});
|
||||
attribute OscillatorType type;
|
||||
// FIXME: readonly attribute AudioParam frequency;
|
||||
readonly attribute AudioParam frequency;
|
||||
// FIXME: readonly attribute AudioParam detune;
|
||||
// FIXME: undefined setPeriodicWave(PeriodicWave periodicWave);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue