Discussion:
[linux-audio-dev] TAP Scaling Limiter - how's it work?
Paul Winkler
2004-02-17 15:47:59 UTC
Permalink
Hi folks, and Tom if you're listening,

The description of the TAP Scaling Limiter is
very interesting - http://tap-plugins.sourceforge.net/#limiter
I'm just curious, having done no real DSP coding -
it must do some internal buffering, right?

So how does it deal with half-cycles that fall on the edge of a
buffer? It seems to me that you can't process the final
half-cycle without refilling the buffer, but you can't refill the
buffer until you've processed all its data - or can you?
--
Paul Winkler
http://www.slinkp.com
Look! Up in the sky! It's FIGHTER CARBOHYDRATE!
(random hero from isometric.spaceninja.com)
Steve Harris
2004-02-17 16:02:26 UTC
Permalink
Post by Paul Winkler
Hi folks, and Tom if you're listening,
The description of the TAP Scaling Limiter is
very interesting - http://tap-plugins.sourceforge.net/#limiter
I'm just curious, having done no real DSP coding -
it must do some internal buffering, right?
So how does it deal with half-cycles that fall on the edge of a
buffer? It seems to me that you can't process the final
half-cycle without refilling the buffer, but you can't refill the
buffer until you've processed all its data - or can you?
I havent looked at the code, but generally you use a ring-buffer to keep
the past N samples and refer to that, rather that dealing with
LADSPA-sized buffers.

- Steve
Tom Szilagyi
2004-02-17 23:29:41 UTC
Permalink
Post by Paul Winkler
Hi folks, and Tom if you're listening,
The description of the TAP Scaling Limiter is
very interesting - http://tap-plugins.sourceforge.net/#limiter
I'm just curious, having done no real DSP coding -
it must do some internal buffering, right?
Right, i have to admit it does :)
That's why the plugin has to have latency.
Post by Paul Winkler
So how does it deal with half-cycles that fall on the edge of a
buffer? It seems to me that you can't process the final
half-cycle without refilling the buffer, but you can't refill the
buffer until you've processed all its data - or can you?
Yes you can. No, you can't actually, but you can eliminate the problem
so you don't have to solve it. There is a ringbuffer, with a length
chosen so it is capable of containing a whole half-cycle even at low
frequencies (40 Hz is the limit in my implementation, which means
varying number of samples at varying samplerates). Incoming audio is
streamed into the ringbuffer (which actually works like a FIFO), and
the half-cycles are being scanned starting from the other end of the
buffer (that is, where output falls out).

Now let's say the buffer is just full of audio. The host calls run(),
and the plugin starts scanning backwards (from the oldest sample, that
is, the one just about to fall out of the FIFO, towards the newest one),
and marks zero-crosses and scales the marked individual zero-crosses. It
keeps track of the half-cycle boundaries, and when it reaches (or more
likely, overgoes) the N samples the plugin was asked to process in this
run() call, it pushes out the N samples, but that of course will be in
no relation with the half-cycle boundaries. Some piece of the last
half-cycle will remain, and at the next run(), the plugin will continue
the zero-cross scan from that point, not from the buffer boundary. But
it counts the N samples needed to be pushed out from the buffer
boundary, of course. I'm afraid i can't explain it very clearly, but i
hope you get the feeling.


Tom

ps. stay tuned, more plugins are about to arrive... expect them
in a week or two. :)
Paul Winkler
2004-02-18 00:55:57 UTC
Permalink
Post by Tom Szilagyi
Yes you can. No, you can't actually, but you can eliminate the problem
so you don't have to solve it. There is a ringbuffer, with a length
chosen so it is capable of containing a whole half-cycle even at low
frequencies (40 Hz is the limit in my implementation, which means
varying number of samples at varying samplerates).
ok - what happens if the input is a 30 hz sine wave?
assume it's coming from a particularly evil keyboard player ;-)

(explanation snipped)

OK, I think I have just never really grokked ringbuffers before.
Thanks!
--
Paul Winkler
http://www.slinkp.com
Look! Up in the sky! It's FLYING FJUKER KO!
(random hero from isometric.spaceninja.com)
Tom Szilagyi
2004-02-18 07:48:02 UTC
Permalink
Post by Paul Winkler
ok - what happens if the input is a 30 hz sine wave?
assume it's coming from a particularly evil keyboard player ;-)
That's a particularly evil situation. :) The fact is, if you have a
normal musical signal, it will have much higher frequency components so
zero-crosses occur much more frequently than this limit. I investigated
this problem a bit before i settled on that 40 Hz... a mixed signal
(a few instruments together), or higher pitched instruments usually
give average zero-cross frequencies of 8-12 kHz. I tried it with bass
guitar as well (real, no synth) and i didn't run into this limitation.

So if you take a 30 Hz sinusoidal from an oscillator and feed it into
this plugin, then there will be unprocessed segments of audio because of
not fitting in the ringbuffer. But if you really need that (do you?),
you can increase the ringbuf size and thus decrease this freq lower
limit in the code... at the expense of increasing latency.


Tom
Paul Winkler
2004-02-18 14:17:38 UTC
Permalink
Post by Tom Szilagyi
Post by Paul Winkler
ok - what happens if the input is a 30 hz sine wave?
assume it's coming from a particularly evil keyboard player ;-)
That's a particularly evil situation. :)
i know :-)
Post by Tom Szilagyi
The fact is, if you have a
normal musical signal, it will have much higher frequency components so
zero-crosses occur much more frequently than this limit. I investigated
this problem a bit before i settled on that 40 Hz... a mixed signal
(a few instruments together), or higher pitched instruments usually
give average zero-cross frequencies of 8-12 kHz.
that high? no kidding?
Post by Tom Szilagyi
I tried it with bass
guitar as well (real, no synth) and i didn't run into this limitation.
Unless you tried a 5-string, there's no way you'd even get a fundamental
below about 40 Hz - low E is just above 40. Low B on a 5-string
is somewhere around 30 IIRC.

Not too many instruments get below 40 Hz that I know of ... synths
and pipe organs, mostly. And they *usually* have a lot of higher
freqs mixed in.
Post by Tom Szilagyi
So if you take a 30 Hz sinusoidal from an oscillator and feed it into
this plugin, then there will be unprocessed segments
just one, right?
Post by Tom Szilagyi
of audio because of
not fitting in the ringbuffer.
OK. I wondered if it would try to process the last partial segment
which might get quite different scaling than the following
part of the segment when the next batch of data comes in.
Post by Tom Szilagyi
But if you really need that (do you?),
No, just satisfying my curiosity :-)
Post by Tom Szilagyi
you can increase the ringbuf size and thus decrease this freq lower
limit in the code... at the expense of increasing latency.
That's about what I figured. Thanks!!
--
Paul Winkler
http://www.slinkp.com
Look! Up in the sky! It's GUILDMASTER SEGWAY!
(random hero from isometric.spaceninja.com)
Tom Szilagyi
2004-02-18 17:46:47 UTC
Permalink
Post by Paul Winkler
Post by Tom Szilagyi
The fact is, if you have a
normal musical signal, it will have much higher frequency components so
zero-crosses occur much more frequently than this limit. I investigated
this problem a bit before i settled on that 40 Hz... a mixed signal
(a few instruments together), or higher pitched instruments usually
give average zero-cross frequencies of 8-12 kHz.
that high? no kidding?
Yes, mostly, because higher harmonics also cause zero crosses. Musical
instruments are not sinusoidal waveform generators. :-) (also, the
numbers above were the average frequency of zero-crosses, which mean
actually half that audio frequency, because every cycle has 2
half-cycles... so that 8-12 kHz is not really surprising...)
Post by Paul Winkler
Not too many instruments get below 40 Hz that I know of ... synths
and pipe organs, mostly. And they *usually* have a lot of higher
freqs mixed in.
That's why there is many zero-crosses in almost any case... more than
what the instrument's base frequency would yield.
Post by Paul Winkler
Post by Tom Szilagyi
So if you take a 30 Hz sinusoidal from an oscillator and feed it into
this plugin, then there will be unprocessed segments
just one, right?
One per LADSPA buffer, in the worst (but not very unlikely) case.


Tom

Loading...