FLOSS Manuals

 English |  Español |  Français |  Italiano |  Português |  Русский |  Shqip

CSOUND Español

RECORD AND PLAY BUFFERS

RECORD Y PLAY BUFFERS

Playing Audio From RAM - flooper2

Reproducción de audio desde RAM - flooper2

Csound offers many opcodes for playing back sound files that have first been loaded into a function table (and therefore are loaded into RAM). Some of these offer higher quality at the expense of computation speed; some are simpler and less fully featured.

Csound ofrece muchos opcodes para reproducir archivos de sonido que primero se han cargado en una tabla de funciones (y por lo tanto se cargan en RAM). Algunos de estos ofrecen una mayor calidad a expensas de la velocidad de cálculo; Algunos son más sencillos y menos completos.

One of the newer and easier to use opcodes for this task is flooper2. As its name might suggest it is intended for the playback of files with looping. 'flooper2' can also apply a cross-fade between the end and the beginning of the loop in order to smooth the transition where looping takes place.

Uno de los opcodes más nuevos y fáciles de usar para esta tarea es flooper2. Como su nombre podría sugerir que está destinado a la reproducción de archivos con bucle. Flooper2 también puede aplicar un cross-fade entre el final y el comienzo del bucle con el fin de suavizar la transición donde se realiza el bucle.

In the following example a sound file that has been loaded into a GEN01 function table is played back using 'flooper2'. 'flooper2' also includes a parameter for modulating playback speed/pitch. There is also the option of modulating the loop points at k-rate. In this example the entire file is simply played and looped. You can replace the sound file with one of your own or you can download the one used in the example from here.

En el ejemplo siguiente se reproduce un archivo de sonido que se ha cargado en una tabla de funciones GEN01 con flooper2. Flooper2 también incluye un parámetro para modular la velocidad / paso de reproducción. También existe la opción de modular los puntos de lazo a la velocidad k. En este ejemplo, todo el archivo se reproduce y realiza un bucle. Puede reemplazar el archivo de sonido por uno propio o puede descargar el que se utiliza en el ejemplo desde aquí.

Some notes about GEN01 and function table sizes:

Algunas notas sobre GEN01 y tamaños de tabla de funciones:

When storing sound files in GEN01 function tables we must ensure that we define a table of sufficient size to store our sound file. Normally function table sizes should be powers of 2 (2, 4, 8, 16, 32 etc.). If we know the duration of our sound file, we can derive the required table size by multiplying this duration by the sample rate and then choosing the next power of 2 larger than this. For example when the sampling rate is 44100, we will require 44100 table locations to store 1 second of audio; but 44100 is not a power of 2 so we must choose the next power of 2 larger than this which is 65536. (Hint: you can discover a sound file's duration by using Csound's 'sndinfo' utility.)

Al almacenar archivos de sonido en tablas de funciones GEN01 debemos asegurarnos de que definimos una tabla de tamaño suficiente para almacenar nuestro archivo de sonido. Normalmente los tamaños de las tablas de funciones deben ser potencias de 2 (2, 4, 8, 16, 32 etc.). Si sabemos la duración de nuestro archivo de sonido, podemos derivar el tamaño de la tabla requerida multiplicando esta duración por la frecuencia de muestreo y luego elegir la siguiente potencia de 2 mayor que ésta. Por ejemplo, cuando la velocidad de muestreo es 44100, requeriremos 44100 ubicaciones de tabla para almacenar 1 segundo de audio; Pero 44100 no es una potencia de 2, así que debemos elegir la siguiente potencia de 2 más grande que esta, que es 65536. (Sugerencia: puedes descubrir una duración de archivos de sonido utilizando la utilidad sndinfo de Csounds.)

There are some 'lazy' options however: if we underestimate the table size when we then run Csound, it will warn us that this table size is too small and conveniently inform us via the terminal what the minimum size required to store the entire file would be - we can then substitute this value in our GEN01 table. We can also overestimate the table size in which case Csound won't complain at all, but this is a rather inefficient approach.

Hay algunas opciones perezosas sin embargo: si subestimamos el tamaño de la tabla cuando ejecutamos Csound, nos advertirá que este tamaño de tabla es demasiado pequeño y convenientemente nos informará a través del terminal cuál sería el tamaño mínimo requerido para almacenar el archivo completo - Podemos entonces sustituir este valor en nuestra tabla GEN01. También podemos sobrestimar el tamaño de la tabla, en cuyo caso Csound no se quejará en absoluto, pero este es un enfoque bastante ineficiente.

If we give table size a value of zero we have what is referred to as 'deferred table size'. This means that Csound will calculate the exact table size needed to store our sound file and use this as the table size but this will probably not be a power of 2. Many of Csound's opcodes will work quite happily with non-power of 2 function table sizes, but not all! It is a good idea to know how to deal with power of 2 table sizes. We can also explicitly define non-power of 2 table sizes by prefacing the table size with a minus sign '-'.

Si damos un tamaño de tabla a un valor de cero tenemos lo que se conoce como tamaño de tabla diferido. Esto significa que Csound calculará el tamaño exacto de la tabla necesario para almacenar nuestro archivo de sonido y usarlo como el tamaño de la tabla, pero esto probablemente no será una potencia de 2. Muchos de los opcodes de Csounds funcionarán con bastante alegría con la no potencia de la tabla de 2 funciones Tamaños, pero no todos! Es una buena idea saber cómo lidiar con el poder de 2 tamaños de mesa. También podemos definir explícitamente la no potencia de 2 tamaños de tablas prefiriendo el tamaño de tabla con un signo menos -.

All of the above discussion about required table sizes assumed that the sound file was mono; to store a stereo sound file will naturally require twice the storage space, for example, 1 second of stereo audio will require 88200 storage locations. GEN01 will indeed store stereo sound files and many of Csound's opcodes will read from stereo GEN01 function tables, but again not all! We must be prepared to split stereo sound files, either to two sound files on disk or into two function tables using GEN01's 'channel' parameter (p8), depending on the opcodes we are using.

Toda la discusión anterior sobre los tamaños de tabla requeridos supuso que el archivo de sonido era mono; Para almacenar un archivo de sonido estéreo naturalmente requerirá dos veces el espacio de almacenamiento, por ejemplo, 1 segundo de audio estéreo requerirá 88200 ubicaciones de almacenamiento. Gen01 de hecho almacenará archivos de sonido estéreo y muchos de los opcodes de Csounds leerán desde las tablas de funciones estéreo GEN01, pero ¡de nuevo no todas! Debemos estar preparados para dividir los archivos de sonido estéreo, ya sea a dos archivos de sonido en disco o en dos tablas de función usando el parámetro de canal GEN01 (p8), dependiendo de los códigos de operación que estamos usando.

Storing audio in GEN01 tables as mono channels with non-deferred and power of 2 table sizes will ensure maximum compatibility.

Almacenamiento de audio en tablas GEN01 como canales mono con no diferido y la potencia de 2 tamaños de tabla garantizará la máxima compatibilidad.

   EXAMPLE 06B01_flooper2.csd  

<CsoundSynthesizer>
<CsOptions>
-odac ; activate real-time audio
</CsOptions>

<CsInstruments>
; example written by Iain McCurdy

sr 	= 	44100
ksmps 	= 	32
nchnls 	= 	1	
0dbfs   =       1

; STORE AUDIO IN RAM USING GEN01 FUNCTION TABLE
giSoundFile   ftgen   0, 0, 262144, 1, "loop.wav", 0, 0, 0

  instr	1 ; play audio from function table using flooper2 opcode
kAmp         =         1   ; amplitude
kPitch       =         p4  ; pitch/speed
kLoopStart   =         0   ; point where looping begins (in seconds)
kLoopEnd     =         nsamp(giSoundFile)/sr; loop end (end of file)
kCrossFade   =         0   ; cross-fade time
; read audio from the function table using the flooper2 opcode
aSig         flooper2  kAmp,kPitch,kLoopStart,kLoopEnd,kCrossFade,giSoundFile
             out       aSig ; send audio to output
  endin

</CsInstruments>

<CsScore>
; p4 = pitch
; (sound file duration is 4.224)
i 1 0 [4.224*2] 1
i 1 + [4.224*2] 0.5
i 1 + [4.224*1] 2
e
</CsScore>
</CsoundSynthesizer>

 

Csound's Built-in Record-Play Buffer - sndloop

Csounds Built-in Record-Play Buffer - sndloop

Csound has an opcode called sndloop which provides a simple method of recording some audio into a buffer and then playing it back immediately. The duration of audio storage required is defined when the opcode is initialized. In the following example two seconds is provided. Once activated, as soon as two seconds of live audio has been recorded by 'sndloop', it immediately begins playing it back in a loop. 'sndloop' allows us to modulate the speed/pitch of the played back audio as well as providing the option of defining a crossfade time between the end and the beginning of the loop. In the example pressing 'r' on the computer keyboard activates record followed by looped playback, pressing 's' stops record or playback, pressing '+' increases the speed and therefore the pitch of playback and pressing '-' decreases the speed/pitch of playback. If playback speed is reduced below zero it enters the negative domain, in which case playback will be reversed.

Csound tiene un código de operación llamado sndloop que proporciona un método simple de grabar algo de audio en un búfer y luego reproducirlo de inmediato. La duración del almacenamiento de audio requerido se define cuando el código de operación se inicializa. En el ejemplo siguiente se proporcionan dos segundos. Una vez activado, tan pronto como dos segundos de audio en vivo ha sido grabado por sndloop, inmediatamente comienza a reproducir en un bucle. Sndloop nos permite modular la velocidad / tono del audio reproducido, así como proporcionar la opción de definir un tiempo de crossfade entre el final y el inicio del bucle. En el ejemplo pulsando r en el teclado del ordenador se activa el registro seguido de la reproducción en bucle, pulsando s se detiene el registro o la reproducción, al pulsar se aumenta la velocidad y por lo tanto el tono de la reproducción y la presión - disminuye la velocidad / tono de la reproducción. Si la velocidad de reproducción se reduce por debajo de cero, entra en el dominio negativo, en cuyo caso la reproducción se invertirá.

You will need to have a microphone connected to your computer in order to use this example.

Necesitará tener un micrófono conectado a su computadora para poder usar este ejemplo.

   EXAMPLE 06B02_sndloop.csd  

<CsoundSynthesizer>

<CsOptions>

; real-time audio in and out are both activated
-iadc -odac
</CsOptions>

<CsInstruments>
;example written by Iain McCurdy

sr 	= 	44100
ksmps 	= 	32
nchnls 	= 	1	

  instr	1
; PRINT INSTRUCTIONS
           prints  "Press 'r' to record, 's' to stop playback, "
           prints  "'+' to increase pitch, '-' to decrease pitch.\\n"
; SENSE KEYBOARD ACTIVITY
kKey sensekey; sense activity on the computer keyboard
aIn        inch    1             ; read audio from first input channel
kPitch     init    1             ; initialize pitch parameter
iDur       init    2             ; inititialize duration of loop parameter
iFade      init    0.05          ; initialize crossfade time parameter
 if kKey = 114 then              ; if 'r' has been pressed...
kTrig      =       1             ; set trigger to begin record-playback
 elseif kKey = 115 then          ; if 's' has been pressed...
kTrig      =       0             ; set trigger to turn off record-playback
 elseif kKey = 43 then           ; if '+' has been pressed...
kPitch     =       kPitch + 0.02 ; increment pitch parameter
 elseif kKey = 45 then           ; if '-' has been pressed
kPitch     =       kPitch - 0.02 ; decrement pitch parameter
 endif                           ; end of conditional branches
; CREATE SNDLOOP INSTANCE
aOut, kRec sndloop aIn, kPitch, kTrig, iDur, iFade ; (kRec output is not used)
           out     aOut          ; send audio to output
  endin

</CsInstruments>

<CsScore>
i 1 0 3600 ; instr 1 plays for 1 hour
</CsScore>
</CsoundSynthesizer>

Recording to and Playback from a Function Table

Grabación y reproducción desde una tabla de funciones

Writing to and reading from buffers can also be achieved through the use of Csound's opcodes for table reading and writing operations. Although the procedure is a little more complicated than that required for 'sndloop' it is ultimately more flexible. In the next example separate instruments are used for recording to the table and for playing back from the table. Another instrument which runs constantly scans for activity on the computer keyboard and activates the record or playback instruments accordingly. For writing to the table we will use the tablew opcode and for reading from the table we will use the table opcode (if we were to modulate the playback speed it would be better to use one of Csound's interpolating variations of 'table' such as tablei or table3.

La escritura y la lectura de búferes también se pueden lograr mediante el uso de opcodes Csounds para operaciones de lectura y escritura de tablas. Aunque el procedimiento es un poco más complicado que el requerido para sndloop, es en última instancia más flexible. En el siguiente ejemplo se utilizan instrumentos separados para grabar en la mesa y para reproducirlos desde la mesa. Otro instrumento que se ejecuta constantemente busca la actividad en el teclado del ordenador y activa los instrumentos de grabación o reproducción en consecuencia. Para escribir en la tabla usaremos el opcode de la tabla y para leer de la tabla usaremos el opcode de la tabla (si tuviéramos que modular la velocidad de reproducción sería mejor usar una de Csounds interpolando variaciones de tabla como tablei o table3 .

Csound writes individual values to table locations, the exact table locations being defined by an 'index'. For writing continuous audio to a table this index will need to be continuously moving 1 location for every sample. This moving index (or 'pointer') can be created with an a-rate line or a phasor. The next example uses 'line'. When using Csound's table operation opcodes we first need to create that table, either in the orchestra header or in the score. The duration of the audio buffer can be calculated from the size of the table. In this example the table is 2^17 points long, that is 131072 points. The duration in seconds is this number divided by the sample rate which in our example is 44100Hz. Therefore maximum storage duration for this example is 131072/44100 which is around 2.9 seconds.

Csound escribe valores individuales en ubicaciones de tabla, definiéndose las ubicaciones exactas de la tabla por un índice. Para escribir audio continuo en una tabla, este índice necesitará mover continuamente 1 ubicación para cada muestra. Este índice en movimiento (o puntero) se puede crear con una línea a-rate o un fasor. El siguiente ejemplo usa la línea. Cuando utilice los opcodes de operaciones de tabla de Csounds primero debemos crear esa tabla, ya sea en el encabezado de la orquesta o en la partitura. La duración del búfer de audio se puede calcular a partir del tamaño de la tabla. En este ejemplo la tabla tiene 2 ^ 17 puntos de largo, es decir 131072 puntos. La duración en segundos es este número dividido por la frecuencia de muestreo que en nuestro ejemplo es 44100Hz. Por lo tanto, la duración máxima de almacenamiento para este ejemplo es 131072/44100, que es de alrededor de 2,9 segundos.

 

 

   EXAMPLE 06B03_RecPlayToTable.csd     

<CsoundSynthesizer>
<CsOptions>
; real-time audio in and out are both activated
-iadc -odac -d -m0
</CsOptions>

<CsInstruments>
; example written by Iain McCurdy

sr 	= 	44100
ksmps 	= 	32
nchnls 	= 	1

giBuffer ftgen  0, 0, 2^17, 7, 0; table for audio data storage
maxalloc 2,1 ; allow only one instance of the recording instrument at a time!

  instr	1 ; Sense keyboard activity. Trigger record or playback accordingly.
           prints  "Press 'r' to record, 'p' for playback.\\n"
iTableLen  =       ftlen(giBuffer)  ; derive buffer function table length
idur       =       iTableLen / sr   ; derive storage time in seconds
kKey sensekey                       ; sense activity on the computer keyboard
  if kKey=114 then                  ; if ASCCI value of 114 ('r') is output
event	"i", 2, 0, idur, iTableLen  ; activate recording instrument (2)
  endif
 if kKey=112 then                   ; if ASCCI value of 112 ('p) is output
event	"i", 3, 0, idur, iTableLen  ; activate playback instrument
 endif
  endin

  instr 2 ; record to buffer
iTableLen  =        p4              ; table/recording length in samples
; -- print progress information to terminal --
           prints   "recording"
           printks  ".", 0.25       ; print '.' every quarter of a second
krelease   release                  ; sense when note is in final k-rate pass...
 if krelease=1 then                 ; then ..
           printks  "\\ndone\\n", 0 ; ... print a message
 endif
; -- write audio to table --
ain        inch     1               ; read audio from live input channel 1
andx       line     0,p3,iTableLen  ; create an index for writing to table
           tablew   ain,andx,giBuffer ; write audio to function table
endin

  instr 3 ; playback from buffer
iTableLen  =        p4              ; table/recording length in samples
; -- print progress information to terminal --
           prints   "playback"
           printks  ".", 0.25       ; print '.' every quarter of a second
krelease   release                  ; sense when note is in final k-rate pass
 if krelease=1 then                 ; then ...
           printks  "\\ndone\\n", 0 ; ... print a message
 endif; end of conditional branch
; -- read audio from table --
aNdx       line     0, p3, iTableLen; create an index for reading from table
a1         table    aNdx, giBuffer  ; read audio to audio storage table
           out      a1              ; send audio to output
  endin

</CsInstruments>
<CsScore>
i 1 0 3600 ; Sense keyboard activity. Start recording - playback.
</CsScore>
</CsoundSynthesizer>

Encapsulating Record and Play Buffer Functionality to a UDO

Encapsulando la Función de Buffer de Grabación y Reproducción en un UDO

Recording and playing back of buffers can also be encapsulated into a User Defined Opcode. This time the tabw opcode will be used for writing audio data to a buffer. tabw is slightly faster than tablew but doesn't offer the same number of protections for out of range index values.

La grabación y reproducción de búferes también se pueden encapsular en un código de usuario definido por el usuario. Esta vez, el opcode tabw se utilizará para escribir datos de audio en un búfer. Tabw es ligeramente más rápido que tablew pero no ofrece el mismo número de protecciones para valores de índice fuera de rango.

An empty table (buffer) of any size can be created with a negative number as size. A table for recording 10 seconds of audio data can be created in this way:

Se puede crear una tabla vacía (buffer) de cualquier tamaño con un número negativo como tamaño. De esta manera se puede crear una tabla para grabar 10 segundos de datos de audio:

giBuf1    ftgen    0, 0, -(10*sr), 2, 0

The user can decide whether they want to assign a certain number to the table, or whether to allow Csound do assign one automatically, thereafter calling the table via its variable name, in this case giBuf1. Below follows a UDO for creating a mono buffer, and another UDO for creating a stereo buffer:

El usuario puede decidir si desea asignar un cierto número a la tabla, o si permite que Csound asignar uno automáticamente, después llamando a la tabla a través de su nombre de variable, en este caso giBuf1. A continuación se muestra un UDO para crear un buffer mono y otro UDO para crear un buffer estéreo:

opcode BufCrt1, i, io

ilen, inum xin
ift       ftgen     inum, 0, -(ilen*sr), 2, 0
          xout      ift
 endop

 opcode BufCrt2, ii, io
ilen, inum xin
iftL      ftgen     inum, 0, -(ilen*sr), 2, 0
iftR      ftgen     inum, 0, -(ilen*sr), 2, 0
          xout      iftL, iftR
 endop 

This simplifies the procedure of creating a record/play buffer, because the user is just asked for the length of the buffer. A number can be given, but by default Csound will assign this number. This statement will create an empty stereo table for 5 seconds of recording:

Esto simplifica el procedimiento de creación de un búfer de grabación / reproducción, ya que se pide al usuario la longitud del búfer. Se puede dar un número, pero por defecto Csound asignará este número. Esta declaración creará una tabla estéreo vacía durante 5 segundos de grabación:

iBufL,iBufR BufCrt2   5

A first, simple version of a UDO for recording will just write the incoming audio to sequential locations of the table. This can be done by setting the ksmps value to 1 inside this UDO (setksmps 1), so that each audio sample has its own discrete k-value. In this way the write index for the table can be assigned via the statement andx=kndx, and increased by one for the next k-cycle. An additional k-input turns recording on and off:

Una primera versión simple de un UDO para la grabación sólo escribirá el audio entrante a ubicaciones secuenciales de la tabla. Esto puede hacerse ajustando el valor ksmps a 1 dentro de este UDO (setksmps 1), de manera que cada muestra de audio tenga su propio valor k discreto. De esta manera se puede asignar el índice de escritura de la tabla mediante la sentencia yx = kndx, y se incrementa en uno para el siguiente ciclo k. Una entrada k adicional activa y desactiva la grabación:

opcode BufRec1, 0, aik

ain, ift, krec  xin
          setksmps  1
if krec == 1 then ;record as long as krec=1
kndx      init      0
andx      =         kndx
          tabw      ain, andx, ift
kndx      =         kndx+1
endif
 endop

The reading procedure is just as simple. In fact the same code can be used; it will be sufficient just to replace the opcode for writing (tabw) with the opcode for reading (tab):

El procedimiento de lectura es tan simple. De hecho, se puede utilizar el mismo código; Bastará con sustituir el opcode de escritura (tabw) por el opcode de lectura (tab):

opcode BufPlay1, a, ik

ift, kplay  xin
          setksmps  1
if kplay == 1 then ;play as long as kplay=1
kndx      init      0
andx      =         kndx
aout      tab       andx, ift
kndx      =         kndx+1
endif
 endop

Next we will use these first simple UDOs in a Csound instrument. Press the "r" key as long as you want to record, and the "p" key for playing back. Note that you must disable the key repeats on your computer keyboard for this example (in QuteCsound, disable "Allow key repeats" in Configuration -> General).

A continuación vamos a utilizar estos primeros UDO simples en un instrumento Csound. Pulse la tecla r mientras desee grabar y la tecla p para reproducir. Tenga en cuenta que debe deshabilitar las repeticiones de teclas en el teclado del equipo para este ejemplo (en QuteCsound, deshabilitar Permitir repeticiones de clave en Configuración - General).

   EXAMPLE 06B04_BufRecPlay_UDO.csd 

<CsoundSynthesizer>
<CsOptions>
-i adc -o dac -d -m0
</CsOptions>
<CsInstruments>
;example written by Joachim Heintz
sr = 44100
ksmps = 32
nchnls = 1
0dbfs = 1

  opcode BufCrt1, i, io
ilen, inum xin
ift       ftgen     inum, 0, -(ilen*sr), 2, 0
          xout      ift
  endop

  opcode BufRec1, 0, aik
ain, ift, krec  xin
          setksmps  1
imaxindx  =         ftlen(ift)-1 ;max index to write
knew      changed   krec
if krec == 1 then ;record as long as krec=1
 if knew == 1 then ;reset index if restarted
kndx      =         0
 endif
kndx      =         (kndx > imaxindx ? imaxindx : kndx)
andx      =         kndx
          tabw      ain, andx, ift
kndx      =         kndx+1
endif
  endop

  opcode BufPlay1, a, ik
ift, kplay  xin
          setksmps  1
imaxindx  =         ftlen(ift)-1 ;max index to read
knew      changed   kplay
if kplay == 1 then ;play as long as kplay=1
 if knew == 1 then ;reset index if restarted
kndx      =         0
 endif
kndx      =         (kndx > imaxindx ? imaxindx : kndx)
andx      =         kndx
aout      tab       andx, ift
kndx      =         kndx+1
endif
          xout      aout
  endop

  opcode KeyStay, k, kkk
;returns 1 as long as a certain key is pressed
key, k0, kascii    xin ;ascii code of the key (e.g. 32 for space)
kprev     init      0 ;previous key value
kout      =         (key == kascii || (key == -1 && kprev == kascii) ? 1 : 0)
kprev     =         (key > 0 ? key : kprev)
kprev     =         (kprev == key && k0 == 0 ? 0 : kprev)
          xout      kout
  endop

  opcode KeyStay2, kk, kk
;combines two KeyStay UDO's (this way is necessary
;because just one sensekey opcode is possible in an orchestra)
kasci1, kasci2 xin ;two ascii codes as input
key,k0    sensekey
kout1     KeyStay   key, k0, kasci1
kout2     KeyStay   key, k0, kasci2
          xout      kout1, kout2
  endop


instr 1
ain        inch      1 ;audio input on channel 1
iBuf       BufCrt1   3 ;buffer for 3 seconds of recording
kRec,kPlay KeyStay2  114, 112 ;define keys for record and play
           BufRec1   ain, iBuf, kRec ;record if kRec=1
aout       BufPlay1  iBuf, kPlay ;play if kPlay=1
           out       aout ;send out
endin

</CsInstruments>
<CsScore>
i 1 0 1000
</CsScore>
</CsoundSynthesizer>

Next we will create an extended and easier to use version of these two UDOs for recording and playing back a buffer. The requirements of a user might be the following:

A continuación crearemos una versión extendida y más fácil de usar de estos dos UDOs para grabar y reproducir un buffer. Los requisitos de un usuario pueden ser los siguientes:

Recording:

Grabación:

 

allow recording not just from the beginning of the buffer, but also from any arbitrary starting point kstart

Permiten grabar no sólo desde el principio del buffer, sino también desde cualquier punto de inicio arbitrario kstart

allow circular recording (wrap around) if the end of the buffer has been reached: kwrap=1

Permiten la grabación circular (envolvente) si se ha alcanzado el final del buffer: kwrap = 1

Playing:

Jugando:

play back with different speed kspeed (negative speed means playing backwards)

Reproducir con velocidad diferente kspeed (velocidad negativa significa reproducir hacia atrás)

start playback at any point of the buffer kstart

Iniciar la reproducción en cualquier punto de la memoria intermedia kstart

end playback at any point of the buffer kend

Final en cualquier punto de la memoria intermedia

allow certain modes of wraparound kwrap while playing:

Permiten ciertos modos de envolvente kwrap durante la reproducción:

kwrap=0 stops at the defined end point of the buffer

Kwrap = 0 se detiene en el punto final definido del buffer

kwrap=1 repeats playback between defined end and start points

Kwrap = 1 repite la reproducción entre los puntos finales y de inicio definidos

kwrap=2 starts at a defined starting point but wraps between end point and beginning of the buffer

Kwrap = 2 comienza en un punto de partida definido pero envuelve entre el punto final y el comienzo del buffer

    • kwrap=3 wraps between kstart and the end of the table
    • Kwrap = 3 envuelve entre kstart y el final de la tabla

The following example provides versions of BufRec and BufPlay which do this job. We will use the table3 opcode instead of the simple tab or table opcodes in this case, because we want to translate any number of samples in the table to any number of output samples using different speed values. In short, we will need to read amplitude values that must be 'imagined' between two existing table value.

El siguiente ejemplo proporciona versiones de BufRec y BufPlay que realizan este trabajo. En este caso, utilizaremos el opcode table3 en lugar de los opcodes simples de tabulación o tabla, porque queremos traducir cualquier número de muestras en la tabla a cualquier número de muestras de salida usando diferentes valores de velocidad. En resumen, tendremos que leer valores de amplitud que deben imaginarse entre dos valores de tabla existentes.

101124table3 

For higher or lower speed values than the original record speed, interpolation must be used in between certain sample values if the original shape of the wave is to be reproduced as accurately as possible. This job is performed with high quality by table3 which employs cubic interpolation.

Para valores de velocidad más alta o más baja que la velocidad de registro original, la interpolación se debe utilizar entre ciertos valores de muestra si la forma original de la onda se va a reproducir con la mayor exactitud posible. Este trabajo se realiza con alta calidad por table3 que emplea interpolación cúbica.

In a typical application of recording and playing buffer buffers, the ability to interact with the process will be paramount. We can benefit from having interactive access to the following:

En una aplicación típica de almacenar y de almacenar amortiguadores del almacenador intermediario, la capacidad de obrar recíprocamente con el proceso será suprema. Podemos beneficiarnos de tener acceso interactivo a lo siguiente:

starting and stopping record

Iniciar y detener el registro

adjusting the start and end points of recording

Ajustar los puntos de inicio y fin de la grabación

use or prevent wraparound while recording

Utilizar o evitar el envolvente durante la grabación

starting and stopping playback

Iniciar y detener la reproducción

adjusting the start and end points of playback

Ajustar los puntos inicial y final de la reproducción

adjusting wraparound in playback using one of the specified modes (1 - 4)

Ajustar el envolvente en la reproducción utilizando uno de los modos especificados (1 - 4)

applying volume control to the playback signal

Aplicar el control de volumen a la señal de reproducción

These interactions could be carried out via widgets, MIDI, OSC or something else. As we want to provide examples which can be used with any Csound frontend here, we are restricted to triggering the record and play events by hitting the space bar of the computer keyboard. (See the CsoundQt version of this example for a more interactive version.)

Estas interacciones podrían llevarse a cabo a través de widgets, MIDI, OSC o cualquier otra cosa. Como queremos proporcionar ejemplos que se pueden utilizar con cualquier frontend Csound aquí, estamos limitados a activar los eventos de grabación y reproducción pulsando la barra espaciadora del teclado del ordenador. (Vea la versión CsoundQt de este ejemplo para una versión más interactiva.)

   EXAMPLE 06B05_BufRecPlay_complex.csd  

<CsoundSynthesizer>
<CsOptions>
-i adc -o dac -d
</CsOptions>
<CsInstruments>
;example written by joachim heintz
sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

  opcode BufCrt2, ii, io ;creates a stereo buffer
ilen, inum xin ;ilen = length of the buffer (table) in seconds
iftL      ftgen     inum, 0, -(ilen*sr), 2, 0
iftR      ftgen     inum, 0, -(ilen*sr), 2, 0
          xout      iftL, iftR
  endop

  opcode BufRec1, k, aikkkk ;records to a buffer
ain, ift, krec, kstart, kend, kwrap xin
		setksmps	1
kendsmps	=		kend*sr ;end point in samples
kendsmps	=		(kendsmps == 0 || kendsmps > ftlen(ift) ? ftlen(ift) : kendsmps)
kfinished	=		0
knew		changed	krec ;1 if record just started
 if krec == 1 then
  if knew == 1 then
kndx		=		kstart * sr - 1 ;first index to write
  endif
  if kndx >= kendsmps-1 && kwrap == 1 then
kndx		=		-1
  endif
  if kndx < kendsmps-1 then
kndx		=		kndx + 1
andx		=		kndx
		tabw		ain, andx, ift
  else
kfinished	=		1
  endif
 endif
 		xout		kfinished
  endop

  opcode BufRec2, k, aaiikkkk ;records to a stereo buffer
ainL, ainR, iftL, iftR, krec, kstart, kend, kwrap xin
kfin      BufRec1     ainL, iftL, krec, kstart, kend, kwrap
kfin      BufRec1     ainR, iftR, krec, kstart, kend, kwrap
          xout        kfin
  endop

  opcode BufPlay1, ak, ikkkkkk
ift, kplay, kspeed, kvol, kstart, kend, kwrap xin
;kstart = begin of playing the buffer in seconds
;kend = end of playing in seconds. 0 means the end of the table
;kwrap = 0: no wrapping. stops at kend (positive speed) or kstart
;  (negative speed).this makes just sense if the direction does not
;  change and you just want to play the table once
;kwrap = 1: wraps between kstart and kend
;kwrap = 2: wraps between 0 and kend
;kwrap = 3: wraps between kstart and end of table
;CALCULATE BASIC VALUES
kfin		init		0
iftlen		=		ftlen(ift)/sr ;ftlength in seconds
kend		=		(kend == 0 ? iftlen : kend) ;kend=0 means end of table
kstart01	=		kstart/iftlen ;start in 0-1 range
kend01		=		kend/iftlen ;end in 0-1 range
kfqbas		=		(1/iftlen) * kspeed ;basic phasor frequency
;DIFFERENT BEHAVIOUR DEPENDING ON WRAP:
if kplay == 1 && kfin == 0 then
 ;1. STOP AT START- OR ENDPOINT IF NO WRAPPING REQUIRED (kwrap=0)
 if kwrap == 0 then
; -- phasor freq so that 0-1 values match distance start-end
kfqrel		=		kfqbas / (kend01-kstart01)
andxrel	phasor 	kfqrel ;index 0-1 for distance start-end
; -- final index for reading the table (0-1)
andx		=		andxrel * (kend01-kstart01) + (kstart01)
kfirst		init		1 ;don't check condition below at the first k-cycle (always true)
kndx		downsamp	andx
kprevndx	init		0
 ;end of table check:
  ;for positive speed, check if this index is lower than the previous one
  if kfirst == 0 && kspeed > 0 && kndx < kprevndx then
kfin		=		1
 ;for negative speed, check if this index is higher than the previous one
  else
kprevndx	=		(kprevndx == kstart01 ? kend01 : kprevndx)
   if kfirst == 0 && kspeed < 0 && kndx > kprevndx then
kfin		=		1
   endif
kfirst		=		0 ;end of first cycle in wrap = 0
  endif
 ;sound out if end of table has not yet reached
asig		table3		andx, ift, 1	
kprevndx	=		kndx ;next previous is this index
 ;2. WRAP BETWEEN START AND END (kwrap=1)
 elseif kwrap == 1 then
kfqrel		=		kfqbas / (kend01-kstart01) ;same as for kwarp=0
andxrel	phasor 	kfqrel
andx		=		andxrel * (kend01-kstart01) + (kstart01)
asig		table3		andx, ift, 1	;sound out
 ;3. START AT kstart BUT WRAP BETWEEN 0 AND END (kwrap=2)
 elseif kwrap == 2 then
kw2first	init		1
  if kw2first == 1 then ;at first k-cycle:
		reinit		wrap3phs ;reinitialize for getting the correct start phase
kw2first	=		0
  endif
kfqrel		=		kfqbas / kend01 ;phasor freq so that 0-1 values match distance start-end
wrap3phs:
andxrel	phasor 	kfqrel, i(kstart01) ;index 0-1 for distance start-end
		rireturn	;end of reinitialization
andx		=		andxrel * kend01 ;final index for reading the table
asig		table3		andx, ift, 1	;sound out
 ;4. WRAP BETWEEN kstart AND END OF TABLE(kwrap=3)
 elseif kwrap == 3 then
kfqrel		=		kfqbas / (1-kstart01) ;phasor freq so that 0-1 values match distance start-end
andxrel	phasor 	kfqrel ;index 0-1 for distance start-end
andx		=		andxrel * (1-kstart01) + kstart01 ;final index for reading the table
asig		table3		andx, ift, 1	
 endif
else ;if either not started or finished at wrap=0
asig		=		0 ;don't produce any sound
endif
  		xout		asig*kvol, kfin
  endop

  opcode BufPlay2, aak, iikkkkkk ;plays a stereo buffer
iftL, iftR, kplay, kspeed, kvol, kstart, kend, kwrap xin
aL,kfin   BufPlay1     iftL, kplay, kspeed, kvol, kstart, kend, kwrap
aR,kfin   BufPlay1     iftR, kplay, kspeed, kvol, kstart, kend, kwrap
          xout         aL, aR, kfin
  endop

  opcode In2, aa, kk ;stereo audio input
kchn1, kchn2 xin
ain1      inch      kchn1
ain2      inch      kchn2
          xout      ain1, ain2
  endop

  opcode Key, kk, k
;returns '1' just in the k-cycle a certain key has been pressed (kdown)
;  or released (kup)
kascii    xin ;ascii code of the key (e.g. 32 for space)
key,k0    sensekey
knew      changed   key
kdown     =         (key == kascii && knew == 1 && k0 == 1 ? 1 : 0)
kup       =         (key == kascii && knew == 1 && k0 == 0 ? 1 : 0)
          xout      kdown, kup
  endop

instr 1
giftL,giftR BufCrt2   3 ;creates a stereo buffer for 3 seconds
gainL,gainR In2     1,2 ;read input channels 1 and 2 and write as global audio
          prints    "PLEASE PRESS THE SPACE BAR ONCE AND GIVE AUDIO INPUT
                     ON CHANNELS 1 AND 2.\n"
          prints    "AUDIO WILL BE RECORDED AND THEN AUTOMATICALLY PLAYED
                     BACK IN SEVERAL MANNERS.\n"
krec,k0   Key       32
 if krec == 1 then
          event     "i", 2, 0, 10
 endif
endin

instr 2
; -- records the whole buffer and returns 1 at the end
kfin      BufRec2   gainL, gainR, giftL, giftR, 1, 0, 0, 0
  if kfin == 0 then
          printks   "Recording!\n", 1
  endif
 if kfin == 1 then
ispeed    random    -2, 2
istart    random    0, 1
iend      random    2, 3
iwrap     random    0, 1.999
iwrap     =         int(iwrap)
printks "Playing back with speed = %.3f, start = %.3f, end = %.3f,
                    wrap = %d\n", p3, ispeed, istart, iend, iwrap
aL,aR,kf  BufPlay2  giftL, giftR, 1, ispeed, 1, istart, iend, iwrap
  if kf == 0 then
          printks   "Playing!\n", 1
  endif
 endif
krel      release
 if kfin == 1 && kf == 1 || krel == 1 then
          printks   "PRESS SPACE BAR AGAIN!\n", p3
          turnoff
 endif
          outs      aL, aR
endin

</CsInstruments>
<CsScore>
i 1 0 1000
e
</CsScore>
</CsoundSynthesizer>

 

Further Opcodes for Investigation

 

Opcodes adicionales para la investigación

Csound contains a wide range of opcodes that offer a variety of 'ready-made' methods of playing back audio held in a function table. The oldest group of these opcodes are loscil and loscil3. Despite their age they offer some unique features such as the ability implement both sustain and release stage looping (in a variety of looping modes), their ability to read from stereo as well as mono function tables and their ability to read looping and base frequency data from the sound file stored in the function table. loscil and loscil3 were originally intended as the kernel mechanism for building a sampler.

Csound contiene una amplia gama de opcodes que ofrecen una variedad de métodos listos para reproducir el audio contenido en una tabla de funciones. El grupo más antiguo de estos opcodes son loscil y loscil3. A pesar de su edad que ofrecen algunas características únicas, tales como la capacidad de implementar tanto mantener y liberar la etapa de bucle (en una variedad de modos de bucle), su capacidad de leer desde estéreo, así como tablas de función mono y su capacidad de leer bucle y frecuencia base de datos Desde el archivo de sonido almacenado en la tabla de funciones. Loscil y loscil3 fueron originalmente concebidos como el mecanismo núcleo para la construcción de un muestreador.

For reading multichannel files of more than two channels, the more recent loscilx exists as an option.

Para leer archivos multicanal de más de dos canales, el loscilx más reciente existe como una opción.

loscil and loscil3 will only allow looping points to be defined at i-time. lposcil, lposcil3, lposcila, lposcilsa and lposcilsa2 will allow looping points to be changed a k-rate, while the note is playing.

Loscil y loscil3 sólo permitirán que los puntos de bucle sean definidos en i-time. Lposcil, lposcil3, lposcila, lposcilsa y lposcilsa2 permitirán que los puntos de bucle sean cambiados a k-rate, mientras que la nota está jugando.

It is worth not forgetting Csound's more exotic methods of playback of sample stored in function tables. mincer and temposcal use streaming vocoder techniques to faciliate independent pitch and time-stretch control during playback (this area is covered more fully in the chapter FOURIER ANALYSIS / SPECTRAL PROCESSING. sndwarp and sndwarpst similiarly faciliate independent pitch and playback speed control but through the technique of granular synthesis this area is covered in detail in the chapter GRANULAR SYNTHESIS.

Vale la pena no olvidar Csounds más exóticos métodos de reproducción de la muestra almacenada en las tablas de funciones. Mincer y temposcal utilizan técnicas de vocoder de flujo continuo para facilitar el control independiente del tono y el tiempo de estiramiento durante la reproducción (esta área se cubre con más detalle en el capítulo ANÁLISIS DE FOURIER / SPECTRAL PROCESSING) sndwarp y sndwarpst facilitan similarmente el control independiente de la velocidad de reproducción y reproducción. Síntesis granular esta área se describe en detalle en el capítulo SÍNTESIS GRANULAR.

 

There has been error in communication with Booktype server. Not sure right now where is the problem.

You should refresh this page.