
manuels
@jameslo said:
Teach a man to fish: you know this because you looked at source code, or some other way?
I just compared the output of both filters, and it turned out to be exactly the same.
Oh look, and they take the cube root for vcf_hp6~ when they chain 3 filters. I wasn't aware that Q worked that way. Do you know what they are doing with the cutoff freq signal, [iem_cot4~]?
Not sure if you can say in general that Q works this way. It might depend on how the filter is normalized. [vcf~], for example, has unit gain at the resonant frequency, but other filters produce higher gains at the resonant frequency. So if you put them in series the gains potentiate, and there has to be some compensation for that. What the [iem_cot4~] does, I don't know. Unfortunately I can't read C code.

manuels
@jameslo With just vanilla objects that's gonna be difficult, because you'd have to use the raw filters like [cpole~]. Since the iemlib filter is a series of two 2nd order filters, my first guess would be to do the same with ELSE's [highpass~], which is also 2nd order. Its exact formula might be different though.
Edit: It actually seems to be the same, but you also have to take the square root of the Q factor!

manuels
So here's the fixed version: velvetnoisefixed.pd
It wasn't just the issue with small floating point numbers, but more importantly it now didn't work with integer periods. In this case, of course, the period must never be reduced by one sample!

manuels
@ben.wes Thanks again for testing, really helpful!
Yes, it's true, that I didn't care about consecutive nonzero samples. For now I'm not sure what's more important: to comply to this constraint or to behave properly above nyquist.
The problems with frequencies above nyquist, that you found, probably have to do with the representation of small floating point numbers. I should have used [expr~ int($v1)] to get real zero values. Can't fix it right now, but I'll try tomorrow ...

manuels
@porres said:
I'm trying to find a better and more sophisticated idea for the algorithm. We need to find the number of samples in a period and then randomly choose where to place it.
I'm not in C, but I think I kind of did exactly that in my latest version, trying to solve the problem with noninteger periods. Here it is (commented in the patch) ...
Could certainly be optimized in some ways (especially using ELSE objects). But does it even work? I don't have a good method to test it, unfortunately.

manuels
@ben.wes Thanks! So no surprise that it doesn't work ....

manuels
@sebharmonik.ar said:
I do think @manuels original idea of having a sampleincrement offset still works without missing periods?
Why don't you think it works with noninteger period lengths?a phasor~ is always guaranteed to have its last sample be within the last sample increment regardless of whether an integerperiod or not, and
[wrap~]
will pretty much perfectly wrap the phasor~'s phase..With noninteger period lengths you have effectively a changing number of samples per period. That in itself I don't think would be a problem, but adding a random value and wrapping the result can give you sampleincrements that are either smaller or bigger than the calculated value.
Maybe an extreme example can help to clarify: Consider a period length of 2.5 samples. The sample increment is in this case 0.4. If you have a period with the sample values 0.3 and 0.7, add 0.8 as a random value and wrap, what you get is 0.1 and 0.5, so the last sample doesn't get above 1 when you add the calculated sampleincrement of 0.4. Am I missing something?
@ben.wes Did you do the testing with noninteger fractions of your sampling frequency? You mentioned 3kHz at 48kHz SR as an example, which shouldn't make problems ....

manuels
@manuels said:
By multiplying the frequency with 1/SR you get the phase increment of the phasor. Since there is exactly one sample in each cycle where the sum of the current phase and the increment gets bigger (or equal to) 1, you get the impulse. Now all you have to do is to randomize the phase to get the impulse at a random position.
Just realised, that I didn't consider one important thing here: If the period isn't an integer number of samples, then the method of adding a random number and wrap doesn't work anymore!

manuels
@porres said:
Never liked using the samplerate to add an increment, and wrap~ and everything, so what we need is just being able to catch the transition above 1 and make it an impulse out of it, so [op~ >= 1] into [status~] solves that!
Well, it may not be nice, but it was my attempt to solve the problem of missing periods (see further up in the thread). If you have a phasor cycle of, say, 0.1  0.3  0.5  0.7  0.9  0.1  etc., then adding small random values to it won't give you any transition above 1.
Edit: ... and the critical case of a cycle 0  0.2  0.4  0.6  0.8  0  etc. may illustrate why you need >= instead of > in the [op~].

manuels
@porres Ah, now I see the problem ... (so I'll try to explain anyway)
By multiplying the frequency with 1/SR you get the phase increment of the phasor. Since there is exactly one sample in each cycle where the sum of the current phase and the increment gets bigger (or equal to) 1, you get the impulse. Now all you have to do is to randomize the phase to get the impulse at a random position.
I'll have to take a look at your new version ... (Still I don't think the noise scaling and [+~ 0.5] are necessary.)
Edit: Just noticed that you have ">" instead of ">=" in the [op~].

manuels
@porres I leave the explaining to @sebharmonik.ar, but I'm wondering if further optimizations may be possible:

Do we really have to scale the white noise going into [samphold~]? I don't think so.

Couldn't we use just one noise generator for both random variables? I mean, they are sampled at different times, so shouldn't this guarantee an uncorrelated outcome anyway? Not sure about that ...


manuels
It seems that the original version of the velvet noise generator finally didn't work hundred percent correctly (see the unresolved problems mentioned above). So here's a slightly different algorithm ... velvetnoise.pd
This one doesn't use any externals, in fact not even [expr~]. Hope it works!
Or is there another solution for this in the meantime?

manuels
@jameslo said:
Edit: aw crap, doesn't work for negative numbers. Can it be salvaged with an extra quadrant signal?
You could take the log of the absolute values of each signal instead and fix the sign at the end: output 1 for each [clone] instance if the signal is negative (otherwise 0) and take the sum, mutiply the output of [exp~] by 1 if that sum is pair and by 1 if it's impair. More complaints from the efficiency police expected ... But I love the idea!

manuels
@atux The circular thing is a bit tricky .... Maybe you could just give [list store] a list of twice the length (the source list appended to itself)? That's not elegant at all but for the moment I don't have other ideas.

manuels
@atux You can use [list store] for that. It takes messages like [get 1 3( to output a sublist of three items starting with the first item of the list. Take a look at the help file to find out how it works in detail.

manuels
I found this old thread as I was just about to open a new topic about the numerical error of [hip~] at low frequencies ... Well, to me at least the issue seems to be more of a "biggie" than you might have thought, because this kind of noise is added to the signal whenever [hip~] is used as a DC blocker (which is, after all, one of its main use cases). With good headphones this can become quite audible: Just try feeding [osc~ 0.1] into [hip~ 5] and listen to it at high gain!
Trying to understand what's going on here, I found this hint in Julius Smith's introduction to digital filters. So it really seems to be a result of the specific implementation structure of [hip~], where the zero is placed after instead of before the pole. I tried both implementations and can confirm that there is no (or much less) noise added if the zero precedes the pole.
As a simpler workaround I suggest to use [lop~] and subtract its output from the input signal.
Edit: So here's a little patch to demonstrate this ... hipnoise.pd

manuels
@jameslo I agree with both of your points. Except that I thought a hardsync oscillator would do exactly what you describe: reset the phase of the output phasor regardless of its current phase. So unless I'm mistaken here (which is very possible), my approach should be usable for that.
Wheter it can be used for a synchronized system with a central phasor I'm not so sure ... Maybe the mode (sync or nonsync) should depend on wheter the scaling factor is an integer or not? On the other hand: If it is an integer, the multiplywrap method suggested by @PDPi is of course much simpler and probably more precise.

manuels
@jameslo said:
Can you show me a patch that, say, generates all 12 equally tempered tones starting with middle C from 1 phasor?
You could do something like this ... phasorsync.pd
Note sure if that's anywhere close to what's going on inside Max's [rate~], though.

manuels
@lacuna Just because anyone else has replied yet ...
I don't really understand the code of IEMlib's [filter~] but I'm pretty sure that it is indeed a biquad filter, that is: if the filter (defined by the first argument) is second order. First order filters use a similar but cheaper algorithm. Higher order filters are implemented as a cascade of first and second order sections depending on whether the filter order is even or uneven.
To get the biquad coefficients right, it's important to notice the differences in implementation. (There has been confusion in the past because Max and Pd use different implementations.) Both Pd's [biquad~] and IEMlib's [filter~] seem to use DirectForm II, but I'm not sure about that.

manuels
@ddw_music Maybe [player~] from the ELSE library could be an option?