plugin nyquist no devuelve sonido

Hola, estoy intentando hacer un plugin y Audacity me dice que el plugin no devuelve audio, el código es el siguiente:

;nyquist plug-in
;version 3
;type generate
;name "Test-001"
;action "Test-002"
;info "Test-003"

;control Fs "Sample rate" int "Hz" 44100 44000 88000
;control f "First armonic" real "Hz" 8ooo 0.1 20000
;control duracion "Duración" real "s" 3.0 0.001 10.0

;length-y = long. de array "y"
(setf length-y (truncate (* Fs duracion)))

;crea el array "y" de long. "length-y"
(setf y (make-array length-y))

;calcula la cantidad de armónicas "N"
(setf N (truncate (/ Fs 2) f))

(loop
(while (< k length-y)
	(setf A (/ (* 3.141592 (* f k)) Fs))
	(setf (aref y k) (/ (* (sin (* A (+ N 1))) (cos (* A N))) (sin A)))))

;devuelve un sonido "y-sound" a partir del array "y"
(snd-from-array 0 Fs y)

Pueden haber cosas mal, es mi primer intento de plugin.
Quisiera que me digan en donde me equivoco y también acepto sugerencias.
No se si estoy usando bien las sentencias, o si podrían ser más eficientes.
Uso Audacity 1.3.13-beta
Gracias.

Lo siento, no hablo español

(setf N (truncate (/ Fs 2) f))

f?

(while (< k length-y)

k?

Hi, I can try english:
“f” is a user entry for First Harmonic, see the “;control” line
“k” was wrong, but I have a new version of the file, see:

;nyquist plug-in
;version 1
;type generate
;name "Test pulses..."
;action "Generating pulse train..."
;info "Pulse Train for exciting..."

;control Fs "Sample Rate" int "Hz" 44100 44000 88000
;control f "First Harmonic" real "Hz" 8000 0.1 20000
;control duracion "Duration" real "s" 3.0 0.001 10.0

;asign correct length to "lengthY"
(setf lengthY (truncate (* Fs duracion)))

;create the "y" array with "lengthY" length
(setf y (make-array lengthY))

;calculate the harmonics amount "N"
(setf N (truncate (/ Fs 2) f))

;fill the array "y"
(setf k 0)
(while (< k lengthY)
	(setf A (/ (* 3.141592 (* f k)) Fs))
	(setf (aref y k) (/ (* (sin (* A (+ N 1))) (cos (* A N))) (sin A)))
	(setf k (+ k 1)))

;return a sound from array "y"
(snd-from-array 0 Fs y)

Thanks for answer.

(setf N (truncate (/ Fs 2) f))

There are too many arguments given for “truncate”. There should be just one expression to be truncated
http://www.cs.cmu.edu/~rbd/doc/nyquist/part19.html#index1456

Thanks, I managed to get output, finally.
The code:

;nyquist plug-in
;version 1
;type generate
;name "Test pulses..."
;action "Generating pulse train..."
;info "Tono para excitar filtros"

;control Fs "Sample Rate" int "Hz" 44100 44000 88000
;control f "First Harmonic" real "Hz" 8000.0 0.1 20000.0
;control duracion "Duration" real "s" 3.0 0.001 10.0

;asigna a "lengthY" la long. de array "y"
(setf lengthY (+ (truncate (* Fs duracion)) 1))

;crea el array "y" de long. "lengthY"
(setf y (make-array lengthY))

;calcula la cantidad de armónicas "N"
(setf N (truncate (/ (/ Fs 2) f)))

;llena el array "y"
(setf (aref y 0) 0)
(setf k 1)
(while (< k lengthY)
	(setf A (/ (* 3.141592 (* f k)) Fs))
	(setf (aref y k) (/ (* (sin (* A (+ N 1))) (cos (* A N))) (sin A)))
	(setf k (+ k 1)))

;devuelve un sonido a partir del array "y"
(snd-from-array 0 Fs y)

Now I will see about “normalization” because it gets
clipping, thank you again.

In Audacity the sample rate of generated audio is determined by the Project Rate (bottom left of the Audacity screen) so rather than using a ;control you can just read it from sound-srate

An easy way to loop: XLISP dotimes

You could do something like:

;nyquist plug-in
;version 1
;type generate
;name "Test pulses..."
;action "Generating pulse train..."
;info "Tono para excitar filtros"

;control f "First Harmonic" real "Hz" 8000.0 0.1 20000.0
;control duracion "Duration" real "s" 3.0 0.0 10.0

; <= cero no permitir
(setq duracion (max duracion 0.001))
(setq f (min (max f (/ duracion)) (/ *sound-srate* 2.0)))

;asigna a "lengthY" la long. de array "y"
(setf lengthY (truncate (* *sound-srate* duracion)))

;crea el array "y" de long. "lengthY"
(setf y (make-array lengthY))

;calcula la cantidad de armónicas "N"
(setf N (truncate (/ *sound-srate* 2.0 f)))

(setq maxval 0) ; inicializar maxval

(dotimes (k lengthY)
  (let* ((A (/ (* pi f k) *sound-srate*))
            (diminuto (power 10 -100))
            (denom (sin A)))
    ; (sin A) no debe ser cero
    (if (= denom 0)(setq denom diminuto))
    (setq val (/ (* (sin (* A (+ N 1)))(cos (* A N))) denom))
    (if (> (abs val) maxval)(setq maxval val))
    (setf (aref y k) val)))

;devuelve un sonido a partir del array "y"
(mult (/ maxval) (snd-from-array 0 (truncate *sound-srate*) y))

Hi steve, 3 questions:

  1. Is (/ maxval) the same that (/ 1 maxval) ?
  2. Is setq faster than setf for numbers? Because you sometimes use setq and sometimes setf
  3. I use the constant pi like 3.141592, but I don’t know the maximun number of decimals in Nyquist. May be 3.14 is fine.

Thanks!

Yes it’s identical, but less typing :wink:
Note that “1” is an integer, and if you divide an integer by another integer it will be calculated using integer arithmetic, so you will get an integer result.

(/ 1.0 2)     ; returns 0.500000
(/ 1 2.0)     ; returns 0.500000
(/ 1 2)       ; returns 0
(/ 2)         ; returns 0
(/ 2.0)       ; returns 0.500000



Edgar may be able to answer this one better than I can.
I’m not aware of any difference in speed, but they do slightly different things.

setq sets the value of a symbol.
The name stands for “set quoted”.
http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-ref/xlisp-ref-239.htm

setf is a more powerful function that can, for example, set the value of a specific field in an array, or can set the value of a specific item in a list.
The name stands for “set field”.
http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-ref/xlisp-ref-238.htm
Example:

(setq mylist (list 1 2 3 4 5 6))  ; can use setq because it is assigning the list '(1 2 3 4 5 6) to the symbol mylist
(setq (nth 3 mylist) 99)         ; Error. (nth 3 mylist) is the third value (counting from 0) in mylist. It is not a symbol.
(setf (nth 3 mylist) 99)         ; Sets the third field to the value 99
(print mylist)                   ; returns (1 2 3 99 5 6)

So for giving a value to a simple variable (a symbol) you can use setq, but for setting the value of a place within a bigger structure [such as an array or list] then you must use setf.
setf can be used to set the value of a symbol but it is probably better to setq for that purpose.

Nyquist works to something like 20 decimal places.
It takes no extra time for Nyquist to calculate using 3.14159265358979000737 than using 3.14. They are both floating point values so they use exactly the same number of bits. pi is a predefined constant and is accurate to 20 decimal places, so you may as well use pi.