mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-28 16:23:49 +01:00
Move library tree where it belongs
This commit is contained in:
59
lib-src/libnyquist/nyquist/tran/alpassvv.alg
Normal file
59
lib-src/libnyquist/nyquist/tran/alpassvv.alg
Normal file
@@ -0,0 +1,59 @@
|
||||
(ALPASSVC-ALG
|
||||
;;
|
||||
;; delay is variable -- but we don't want to reallocate the delay buffer, so
|
||||
;; use an additional parameter for the maximum allowable delay. The sound will
|
||||
;; be written into the buffer every sample, but read using linear
|
||||
;; interpolation. As in tapv, duplicate the sample at the first and last
|
||||
;; locations in the buffer.
|
||||
;;
|
||||
(NAME "alpassvv")
|
||||
(ARGUMENTS ("sound_type" "input") ("sound_type" "delaysnd") ("sound_type" "feedback")
|
||||
("double" "maxdelay"))
|
||||
(START (MAX input delaysnd))
|
||||
(STATE ("float" "delay_scale_factor" "(float) (input->sr * delaysnd->scale)")
|
||||
("long" "buflen" "max(2, (long) (input->sr * maxdelay + 2.5))")
|
||||
("sample_type *" "delaybuf"
|
||||
"(sample_type *) calloc (susp->buflen + 1, sizeof(sample_type))")
|
||||
("sample_type *" "delayptr" "susp->delaybuf")
|
||||
;; since we allocate one extra sample, endptr points to the last sample
|
||||
("sample_type *" "endptr" "susp->delaybuf + susp->buflen"))
|
||||
(CONSTANT "delaylen" "endptr" "delay_scale_factor")
|
||||
(NOT-REGISTER delaybuf)
|
||||
(LINEAR input)
|
||||
(TERMINATE (MIN input))
|
||||
(INNER-LOOP-LOCALS " register sample_type y, z, delaysamp;
|
||||
register int delayi;
|
||||
register sample_type *yptr;\n")
|
||||
(INNER-LOOP "
|
||||
/* compute where to read y, we want y to be delay_snd samples
|
||||
* after delay_ptr, where we write the new sample. First,
|
||||
* conver from seconds to samples. Note: don't use actual sound_type
|
||||
* names in comments! The translator isn't smart enough.
|
||||
*/
|
||||
register sample_type fb = feedback;
|
||||
delaysamp = delaysnd * delay_scale_factor;
|
||||
delayi = (int) delaysamp; /* get integer part */
|
||||
delaysamp = delaysamp - delayi; /* get phase */
|
||||
yptr = delayptr + buflen - (delayi + 1);
|
||||
if (yptr >= endptr) yptr -= buflen;
|
||||
/* now get y, the out-put of the delay, using interpolation */
|
||||
/* note that as phase increases, we use more of yptr[0] because
|
||||
positive phase means longer buffer means read earlier sample */
|
||||
y = (float) ((yptr[0] * delaysamp) + (yptr[1] * (1.0 - delaysamp)));
|
||||
/* WARNING: no check to keep delaysamp in range, so do this in LISP */
|
||||
|
||||
*delayptr++ = z = (sample_type) (fb * y + input);
|
||||
/* Time out to update the buffer:
|
||||
* this is a tricky buffer: buffer[0] == buffer[bufflen]
|
||||
* the logical length is bufflen, but the actual length
|
||||
* is bufflen + 1 to allow for a repeated sample at the
|
||||
* end. This allows for efficient interpolation.
|
||||
*/
|
||||
if (delayptr > endptr) {
|
||||
delayptr = susp->delaybuf;
|
||||
*delayptr++ = *endptr;
|
||||
}
|
||||
output = (sample_type) (y - fb * z);")
|
||||
(FINALIZATION "free(susp->delaybuf);")
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user