Functional syntax is very common in many programming languages. It takes the form of fun(), where fun is any function which encloses its arguments in parentheses. Even in "old" Csound, there existed some rudiments of this functional syntax in some mathematical functions, such as sqrt(), log(), int(), frac(). For instance, the following code
La sintaxis funcional es muy común en muchos lenguajes de programación. Se toma la forma de fun (), donde diversión es cualquier función que encierra sus argumentos entre paréntesis. Incluso en el antiguo Csound, existían algunos rudimentos de esta sintaxis funcional en algunas funciones matemáticas, como sqrt (), log (), int (), frac (). Por ejemplo, el siguiente código
iNum = 1.234
print int(iNum) print frac(iNum)
would print:
instr 1: #i0 = 1.000
instr 1: #i1 = 0.230
Here the integer part and the fractional part of the number 1.234 are passed directly as an argument to the print opcode, without needing to be stored at any point as a variable.
Aquí la parte entera y la parte fraccionaria del número 1.234 se pasan directamente como argumento al opcode de impresión, sin necesidad de ser almacenados en ningún punto como una variable.
This alternative way of formulating code can now be used with many opcodes in Csound61. In the future many more opcodes will be incorporated into this system. First we shall look at some examples.
Esta forma alternativa de formular código ahora se puede usar con muchos opcodes en Csound61. En el futuro muchos más opcodes serán incorporados en este sistema. Primero veremos algunos ejemplos.
The traditional way of applying a fade and a sliding pitch (glissando) to a tone is something like this:
La forma tradicional de aplicar un desvanecimiento y un tono deslizante (glissando) a un tono es algo así:
EXAMPLE 03I01_traditional_syntax.csd
<CsoundSynthesizer> <CsOptions> -odac </CsOptions> <CsInstruments> sr = 44100 nchnls = 1 ksmps = 32 0dbfs = 1 instr 1 kFade linseg 0, p3/2, 1, p3/2, 0 kSlide expseg 400, p3/2, 800, p3/2, 600 aTone poscil kFade, kSlide out aTone endin </CsInstruments> <CsScore> i 1 0 5 </CsScore> </CsoundSynthesizer> ;example by joachim heintz
In plain English what is happening is:
En inglés claro lo que está sucediendo es:
We create a line signal with the opcode linseg. It starts at zero, moves to one in half of the instrument's duration (p3/2), and moves back to zero for the second half of the instrument's duration. We store this signal in the variable kFade.
Creamos una señal de línea con el opcode linseg. Comienza en cero, se mueve a uno en la mitad de la duración de los instrumentos (p3 / 2) y regresa a cero para la segunda mitad de la duración de los instrumentos. Almacenamos esta señal en la variable kFade.
We create an exponential2 signal with the opcode expseg. It starts at 400, moves to 800 in half the instrument's duration, and moves to 600 for the second half of the instrument's duration. We store this signal in the variable kSlide.
Creamos una señal exponencial2 con el opcode expseg. Comienza en 400, se mueve a 800 en la mitad de la duración de los instrumentos, y se mueve a 600 para la segunda mitad de la duración de los instrumentos. Almacenamos esta señal en la variable kSlide.
We create a sine audio signal with the opcode poscil. We feed in the signal stored in the variable kFade as amplitude, and the signal stored in the variable kSlide as frequency input. We store the audio signal in the variable aTone.
Creamos una señal de audio sinusoidal con el opcode poscil. Alimentamos la señal almacenada en la variable kFade como amplitud, y la señal almacenada en la variable kSlide como entrada de frecuencia. Almacenamos la señal de audio en la variable aTone.
Finally, we write the audio signal to the output with the opcode out.
Finalmente, escribimos la señal de audio a la salida con el opcode out.
Each of these four lines can be considered as a "function call", as we call the opcodes (functions) linseg, expseg, poscil and out with certain arguments (input parameters). If we now transform this example to functional syntax, we will avoid storing the result of a function call in a variable. Rather we will feed the function and its arguments directly into the appropriate slot, by means of the fun() syntax.
Cada una de estas cuatro líneas se puede considerar como una llamada de función, como llamamos los opcodes (funciones) linseg, expseg, poscil y out con ciertos argumentos (parámetros de entrada). Si ahora transformamos este ejemplo en sintaxis funcional, evitaremos almacenar el resultado de una llamada de función en una variable. Por el contrario, vamos a alimentar la función y sus argumentos directamente en la ranura adecuada, mediante la sintaxis fun ().
If we write the first line in functional syntax, it will look like this:
Si escribimos la primera línea en la sintaxis funcional, se verá así:
linseg(0, p3/2, 1, p3/2, 0)
And the second line will look like this:
Y la segunda línea se verá así:
expseg(400, p3/2, 800, p3/2, 600)
So we can reduce our code from four lines to two lines:
Así podemos reducir nuestro código de cuatro líneas a dos líneas:
EXAMPLE 03I02_functional_syntax_1.csd
<CsoundSynthesizer> <CsOptions> -odac </CsOptions> <CsInstruments> sr = 44100 nchnls = 1 ksmps = 32 0dbfs = 1 instr 1 aTone poscil linseg(0, p3/2, 1, p3/2, 0), expseg(400, p3/2, 800, p3/2, 600) out aTone endin </CsInstruments> <CsScore> i 1 0 5 </CsScore> </CsoundSynthesizer> ;example by joachim heintz
Or would you prefer the "all-in-one" solution?
¿O preferiría la solución todo en uno?
EXAMPLE 03I03_functional_syntax_2.csd
<CsoundSynthesizer> <CsOptions> -odac </CsOptions> <CsInstruments> sr = 44100 nchnls = 1 ksmps = 32 0dbfs = 1 instr 1 out poscil(linseg(0, p3/2, 1, p3/2, 0), expseg(400, p3/2, 800, p3/2, 600)) endin </CsInstruments> <CsScore> i 1 0 5 </CsScore> </CsoundSynthesizer> ;example by joachim heintz
Most of the Csound opcodes work not only at one rate. You can, for instance, produce random numbers at i-, k- or a-rate:3
La mayoría de los opcodes Csound funcionan no sólo a una velocidad. Puede, por ejemplo, producir números aleatorios a i, k o a-rate: 3
ires random imin, imax
kres random kmin, kmax ares random kmin, kmax
Let us assume we want to change the highest frequency in our example from 800 to a random value between 700 and 1400 Hz, so that we hear a different movement for each tone. In this case, we can simply write random(700, 1400), because the context demands an i-rate result of the random operation here:4
Supongamos que queremos cambiar la frecuencia más alta en nuestro ejemplo de 800 a un valor aleatorio entre 700 y 1400 Hz, de modo que escuchamos un movimiento diferente para cada tono. En este caso, podemos simplemente escribir aleatorios (700, 1400), porque el contexto exige un resultado de tasa i de la operación aleatoria aquí: 4
EXAMPLE 03I04_functional_syntax_rate_1.csd
<CsoundSynthesizer> <CsOptions> -odac </CsOptions> <CsInstruments> sr = 44100 nchnls = 1 ksmps = 32 0dbfs = 1 instr 1 out poscil(linseg(0, p3/2, 1, p3/2, 0), expseg(400, p3/2, random(700, 1400), p3/2, 600)) endin </CsInstruments> <CsScore> r 5 i 1 0 3 </CsScore> </CsoundSynthesizer> ;example by joachim heintz
But it is much clearer both, for the Csound parser and for the Csound user, if you explicitly declare at which rate a function is to be performed. This code claims that poscil runs at a-rate, linseg and expseg run at k-rate, and random runs at i-rate here:
Pero es mucho más claro, tanto para el analizador Csound como para el usuario Csound, si declara explícitamente a qué velocidad debe realizarse una función. Este código afirma que el poscil se ejecuta a una velocidad, linseg y expseg se ejecutan en k-rate y se ejecuta al azar en i-rate aquí:
EXAMPLE 03I05_functional_syntax_rate_2.csd
<CsoundSynthesizer> <CsOptions> -odac </CsOptions> <CsInstruments> sr = 44100 nchnls = 1 ksmps = 32 0dbfs = 1 instr 1 out poscil:a(linseg:k(0, p3/2, 1, p3/2, 0), expseg:k(400, p3/2, random:i(700, 1400), p3/2, 600)) endin </CsInstruments> <CsScore> r 5 i 1 0 3 </CsScore> </CsoundSynthesizer> ;example by joachim heintz
As you can see, rate declaration is done with simply :a, :k or :i after the function. It would represent good practice to include it all the time, to be clear about what is happening.
Como puede ver, la declaración de velocidad se hace simplemente :a, :k o :i después de la función. Sería una buena práctica incluirla todo el tiempo, para ser claro sobre lo que está sucediendo.
Only one output
Currently, there is a limitation in that only opcodes which have one or no outputs can be written using functional syntax. For instance, reading a stereo file using soundin
Actualmente, hay una limitación en que sólo los opcodes que tienen una o ninguna salida se pueden escribir usando la sintaxis funcional. Por ejemplo, leer un archivo estéreo usando
aL, aR soundin "my_file.wav"
cannot be written using functional syntax. This limitation is likely to be removed in the future.
No se puede escribir usando sintaxis funcional. Es probable que esta limitación se elimine en el futuro.
fun() with UDOs
It should be mentioned that you can use the functional style also with self created opcodes ("User Defined Opcodes"):
Debe mencionarse que puede utilizar el estilo funcional también con opcodes creados por usted mismo (User Ops Definidos por el Usuario):
EXAMPLE 03I06_functional_syntax_udo.csd
<CsoundSynthesizer> <CsOptions> -odac </CsOptions> <CsInstruments> sr = 44100 nchnls = 1 ksmps = 32 0dbfs = 1 opcode FourModes, a, akk[] ;kFQ[] contains four frequency-quality pairs aIn, kBasFreq, kFQ[] xin aOut1 mode aIn, kBasFreq*kFQ[0], kFQ[1] aOut2 mode aIn, kBasFreq*kFQ[2], kFQ[3] aOut3 mode aIn, kBasFreq*kFQ[4], kFQ[5] aOut4 mode aIn, kBasFreq*kFQ[6], kFQ[7] xout (aOut1+aOut2+aOut3+aOut4) / 4 endop instr 1 kArr[] fillarray 1, 2000, 2.8, 2000, 5.2, 2000, 8.2, 2000 aImp mpulse .3, 1 out FourModes(aImp, 200, kArr) endin </CsInstruments> <CsScore> i 1 0 10 </CsScore> </CsoundSynthesizer> ;example by joachim heintz, based on an example of iain mccurdy
Only you, and perhaps your spiritual consultant, can know ...
Sólo usted, y tal vez su consultor espiritual, puede saber ...
But seriously, this is mostly a matter of style. Some people consider it most elegant if all is written in one single expression, whilst others prefer to see the signal flow from line to line. Certainly excessive numbers of parentheses may not result in the best looking code ...
Pero en serio, esto es sobre todo una cuestión de estilo. Algunas personas lo consideran más elegante si todo está escrito en una sola expresión, mientras que otros prefieren ver el flujo de la señal de línea en línea. Ciertamente, un número excesivo de paréntesis puede no resultar en el mejor código de aspecto ...
At least the functional syntax allows the user to emphasize his or her own personal style and to avoid some awkwardness:
Al menos la sintaxis funcional permite al usuario enfatizar su propio estilo personal y evitar alguna incomodidad:
"If i new value of kIn has been received, do this and that", can be written:
Si i nuevo valor de kIn ha sido recibido, hacer esto y que, se puede escribir:
if changed(kIn)==1 then
<do this and that> endif
"If you understand what happens here, you will have been moved to the next level", can be written:
Si entiendes lo que sucede aquí, habrás sido trasladado al siguiente nivel, puede escribirse:
EXAMPLE 03I07_functional_syntax_you_win.csd
<CsoundSynthesizer> <CsOptions> -odac -m128 </CsOptions> <CsInstruments> sr = 44100 nchnls = 1 ksmps = 32 0dbfs = 1 seed 0 opcode FourModes, a, akk[] ;kFQ[] contains four frequency-quality pairs aIn, kBasFreq, kFQ[] xin aOut1 mode aIn, kBasFreq*kFQ[0], kFQ[1] aOut2 mode aIn, kBasFreq*kFQ[2], kFQ[3] aOut3 mode aIn, kBasFreq*kFQ[4], kFQ[5] aOut4 mode aIn, kBasFreq*kFQ[6], kFQ[7] xout (aOut1+aOut2+aOut3+aOut4) / 4 endop instr ham gkPchMovement = randomi:k(50, 1000, (random:i(.2, .4)), 3) schedule("hum", 0, p3) endin instr hum if metro(randomh:k(1, 10, random:k(1, 4), 3)) == 1 then event("i", "play", 0, 5, gkPchMovement) endif endin instr play iQ1 = random(100, 1000) kArr[] fillarray 1*random:i(.9, 1.1), iQ1, 2.8*random:i(.8, 1.2), iQ1*random:i(.5, 2), 5.2*random:i(.7, 1.4), iQ1*random:i(.5, 2), 8.2*random:i(.6, 1.8), iQ1*random:i(.5, 2) aImp mpulse ampdb(random:k(-30, 0)), p3 out FourModes(aImp, p4, kArr)*linseg(1, p3/2, 1, p3/2, 0) endin </CsInstruments> <CsScore> i "ham" 0 60 </CsScore> </CsoundSynthesizer> ;example by joachim heintz, with thanks to steven and iain
So enjoy, and stay in contact with the spirit ...
Así que disfruta, y mantente en contacto con el espíritu ...
There has been error in communication with Booktype server. Not sure right now where is the problem.
You should refresh this page.