Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an way to request mathematically correct oscillators #244

Closed
padenot opened this issue Sep 30, 2013 · 18 comments
Closed

Add an way to request mathematically correct oscillators #244

padenot opened this issue Sep 30, 2013 · 18 comments

Comments

@padenot
Copy link
Member

padenot commented Sep 30, 2013

When using an OscillatorNode as an LFO, it can be useful to get rid of the ripples inherent to high frequency limiting to get precise modulation.

This issue is about designing an API to request mathematically correct oscillator, and define them using a mathematical definition (in terms of phase, waveform shape and peak amplitude).

@russellmcc
Copy link

You mean, an aliased version of the oscillators? Why would anyone want that for audio?

@padenot
Copy link
Member Author

padenot commented Sep 30, 2013

This is the whole point. Nobody wants it for audio, but people want it for when an OscillatorNode is fed into an AudioParam.

@russellmcc
Copy link

Well, you still don't want aliasing in the case the oscillator node is being fed into an audio param at audio rates. I think maybe a better way to word this same complaint is to say that low-frequency oscillators have to include high-frequency partials. This could manifest itself as implementors using naive oscillators below a certain frequency. I think needlessly complicating the API with an "aliasing" mode doesn't help much and may incorrectly encourage users to introduce aliasing to their designs.

@jussi-kalliokoski
Copy link
Member

I'd like to disagree even with the claim that no one wants it for audio as it's essential for example for modeling old synthesizers, e.g. the JP-8000 and its legendary "supersaw" waveform. Aliased oscillators also yield in a way more interesting sounds when combined with low-pass filters than anti-aliased oscillators would, especially for high-Q synth sounds, as the high frequency partials will excite the filter.

@ghost
Copy link

ghost commented Oct 2, 2013

On Oct 1, 2013 2:26 AM, "Russell McClellan" notifications@github.com
wrote:

Well, you still don't want aliasing in the case the oscillator node is
being fed into an audio param at audio rates. I think maybe a better way to
word this same complaint is to say that low-frequency oscillators have to
include high-frequency partials. This could manifest itself as implementors
using naive oscillators below a certain frequency. I think needlessly
complicating the API with an "aliasing" mode doesn't help much and may
incorrectly encourage users to introduce aliasing to their designs.


Reply to this email directly or view it on GitHub.

@ghost
Copy link

ghost commented Oct 2, 2013

On Oct 1, 2013 2:22 AM, "Paul ADENOT" notifications@github.com wrote:

This is the whole point. Nobody wants it for audio, but people want it
for when an OscillatorNode is fed into an AudioParam.


Reply to this email directly or view it on GitHub.

@ghost
Copy link

ghost commented Oct 2, 2013

On Sep 30, 2013 8:01 PM, "Paul ADENOT" notifications@github.com wrote:

When using an OscillatorNode as an LFO, it can be useful to get rid of
the ripples inherent to high frequency limiting to get precise modulation.

This issue is about designing an API to request mathematically correct
oscillator, and define them using a mathematical definition (in terms of
phase, waveform shape and peak amplitude).


Reply to this email directly or view it on GitHub.

@padenot
Copy link
Member Author

padenot commented Feb 17, 2014

@opera-mage
Copy link
Member

Just a couple of observations:

The term "mathematically accurate" refers to, I assume, the enumeration
description formulas (e.g. "sine" -> y = sin(t), etc).

First of all, it is not entirely clear how OscillatorType=="custom" is
handled, though I interpret it as if the Fourier series is converted to
the time domain without any band limiting, and then that time-domain
periodic signal is sampled without any Nyquist consideration (how about
interpolation?). Is that the intended behavior?

Secondly, I think that the original idea/implementation of the
OscillatorNode dealt with the "sine", "square", "sawtooth" and
"triangle" types as if they were macros for built-in "custom" waveforms.
This would no longer hold true, since it's not possible to describe an
infinite bandwidth signal using a PeriodicWave, or am I missing something?

/Marcus

2014-02-17 14:20, Paul ADENOT skrev:

Here is a proposal: padenot/web-audio-api@ff13d62
padenot@ff13d62,
or http://padenot.github.io/web-audio-api/#band-limiting.


Reply to this email directly or view it on GitHub
#244 (comment).

Marcus Geelnard
Technical Lead, Mobile Infrastructure
Opera Software

@padenot
Copy link
Member Author

padenot commented Feb 17, 2014

On 17/02/2014 14:36, opera-mage wrote:

Just a couple of observations:

The term "mathematically accurate" refers to, I assume, the enumeration
description formulas (e.g. "sine" -> y = sin(t), etc).

First of all, it is not entirely clear how OscillatorType=="custom" is
handled, though I interpret it as if the Fourier series is converted to
the time domain without any band limiting, and then that time-domain
periodic signal is sampled without any Nyquist consideration (how about
interpolation?). Is that the intended behavior?

I think we can make it so that setting bandLimited to false when using a
custom waveform either throws or is a no-op, because those signal are
inherently band limited (assuming the resampler is good enough, that is).

Secondly, I think that the original idea/implementation of the
OscillatorNode dealt with the "sine", "square", "sawtooth" and
"triangle" types as if they were macros for built-in "custom" waveforms.
This would no longer hold true, since it's not possible to describe an
infinite bandwidth signal using a PeriodicWave, or am I missing something?

Well, yes, but only if .bandLimited is false, which is not the default.
And that's certainly the feature, here. Actually, I'm not sure what is
your concern, here.

Paul.

@jussi-kalliokoski
Copy link
Member

This would no longer hold true, since it's not possible to describe an
infinite bandwidth signal using a PeriodicWave, or am I missing something?

Those predefined waveforms aren't actually implemented as infinite bandwidth signals, at least in the WebKit implementation. Instead they're implemented as PeriodicWaves, IIRC where

  • Sine just has the first real component as 1.
  • Square has blank real part and all odd imaginary components with the value of 1 / π / n where n denotes the imaginary component index.
  • Sawtooth has blank real part and all imaginary parts except the first one (blank) with the value of -cos(π * n) / π / n / 2
  • Triangle has a blank imaginary part and the real components with value of (4 - 4 * cos(π * n)) / (n² * π²)

@russellmcc
Copy link

While I'm a little embarrassed at the harsh tone of my previous two comments upon rereading, I still don't like this feature. First, I think using the term "mathematically accurate" is a little confusing, since you are in fact adding artifacts to the mathematical ideal - perhaps "with aliasing artifacts left in" would be a bit more explicit and understandable.

Second, I'd like to hear a rationale on why it would be better for applications when an oscillator is connected to an AudioParam. If there are any audible ripples, that is a sign that the implementation is buggy and does not contain enough high frequency partials. I think if you're worried about the LFO use case, you should just add language in the spec that says the oscillators have to be accurate even at low frequencies. This way, users wouldn't have to be concerned about setting an extra flag correctly and instead everything would just work.

I do take Jussi's point that aliasing can be useful and wonderful as a special effect (in fact, I wrote an article on that topic in 2011), but I still think that this feature is fringe enough that those who want it can use a scriptprocessor or audio buffer with looping.

@opera-mage
Copy link
Member

Actually, I'm not sure what is your concern, here.

Well, I just wanted to understand the suggested solution and what implications it might have. I see your point: we'd simply add a second mode of operation for the predefined wave forms, so that:

bandLimited -> Use the corresponding PeriodicWave (this should probably be defined clearly in the spec somehow).
!bandLimited -> Use the "mathematical" definitions (possibly throw an exception or do silence for "custom").

IMO it would be nice if the predefined wave forms were defined in terms of a PeriodicWave when bandLimited == true (e.g. define the elements of the discrete real/imag arrays using mathematical formulas) - similar to what Jussi explained. Let's put that in the spec.

@padenot
Copy link
Member Author

padenot commented Feb 17, 2014

On 17/02/2014 15:54, opera-mage wrote:

Actually, I'm not sure what is your concern, here.

Well, I just wanted to understand the suggested solution and what
implications it might have. I see your point: we'd simply add a second
mode of operation for the predefined wave forms, so that:

bandLimited -> Use the corresponding PeriodicWave (this should probably
be defined clearly in the spec somehow).
!bandLimited -> Use the "mathematical" definitions (possibly throw an
exception or do silence for "custom").

IMO it would be nice if the predefined wave forms were defined in terms
of a PeriodicWave when bandLimited == true (e.g. define the elements of
the discrete real/imag arrays using mathematical formulas).

We can certainly do so, but we should talk about that in the appropriate
issue. There is an ongoing discussion on how to properly define those,
in terms of phase and amplitude: #104, #270.

@padenot
Copy link
Member Author

padenot commented Mar 6, 2014

My proposal is at padenot@7c83c01

@karlt
Copy link
Contributor

karlt commented Mar 6, 2014

I'm not clear on the need here.
Comment 35287246 has not been addressed AFAIK.

Even if samples are set to the corresponding points on the continuous
function, sampling is band-limiting, whether it is done well or not.
What is requested here is band-limiting by reflecting higher frequencies into
the represented range. The wiggles are still there, but they are between the
sample points.

Even if only used as sources for AudioParams, on a gain node for example,
an aliased input will introduce aliasing into the audio output.

It sounds like what is wanted here is a "discrete" signal that is not an
attempt to represent any continuous function. That may be useful if the main
processing stream is also discrete, but is not the intended use-case for Web
Audio. If necessary, a looping BufferSource can be used for this purpose, I assume?

@cwilso
Copy link
Contributor

cwilso commented Mar 7, 2014

I'm not in support of this. This does not address the amplitude normalization (which is necessary to avoid clipping).

@mdjp
Copy link
Member

mdjp commented Nov 6, 2017

This is a niche use case which can be covered by the Audio Worklet. Closing.

@mdjp mdjp closed this as completed Nov 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants