FLOSS Manuals

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

CSOUND Español

WORKING WITH CONTROLLERS TRABAJO CON LOS CONTROLADORES

Scanning MIDI Continuous Controllers Exploración de controladores MIDI continuos

The most useful opcode for reading in midi continuous controllers is ctrl7. ctrl7's input arguments allow us to specify midi channel and controller number of the controller to be scanned in addition to giving us the option of rescaling the received midi values between a new minimum and maximum value as defined by the 3rd and 4th input arguments. Further possibilities for modifying the data output are provided by the 5th (optional) argument which is used to point to a function table that reshapes the controller's output response to something possibly other than linear. This can be useful when working with parameters which are normally expressed on a logarithmic scale such as frequency.

El código de operación más útil para la lectura en controladores MIDI continuos es ctrl7. Los argumentos de entrada de ctrl7s nos permiten especificar el canal midi y el número de controlador del controlador a escanear, además de darnos la opción de reescalar los valores midi recibidos entre un nuevo valor mínimo y máximo definido por los argumentos de entrada 3 y 4. Otras posibilidades para modificar la salida de datos son proporcionadas por el quinto argumento (opcional) que se utiliza para apuntar a una tabla de funciones que cambia la respuesta de salida de los controladores a algo posiblemente distinto de lineal. Esto puede ser útil cuando se trabaja con parámetros que normalmente se expresan en una escala logarítmica como la frecuencia.

The following example scans midi controller 1 on channel 1 and prints values received to the console. The minimum and maximum values are given as 0 and 127 therefore they are not rescaled at all. Controller 1 is also the modulation wheel on a midi keyboard.

En el ejemplo siguiente se escanea el controlador MIDI 1 en el canal 1 e imprime los valores recibidos en la consola. Los valores mínimo y máximo se dan como 0 y 127, por lo tanto no se vuelven a escala en absoluto. El controlador 1 es también la rueda de modulación en un teclado midi.

  EXAMPLE 07C01_ctrl7_print.csd

<CsoundSynthesizer>

<CsOptions>
-Ma -odac
; activate all MIDI devices
</CsOptions>

<CsInstruments>
; 'sr' and 'nchnls' are irrelevant so are omitted
ksmps = 32

  instr 1
kCtrl    ctrl7    1,1,0,127    ; read in controller 1 on channel 1
kTrigger changed  kCtrl        ; if 'kCtrl' changes generate a trigger ('bang')
 if kTrigger=1 then
; Print kCtrl to console with formatting, but only when its value changes.
printks "Controller Value: %d%n", 0, kCtrl
 endif
  endin

</CsInstruments>

<CsScore>
i 1 0 3600
e
</CsScore>

<CsoundSynthesizer>

There are also 14 bit and 21 bit versions of ctrl7 (ctrl14 and ctrl21) which improve upon the 7 bit resolution of 'ctrl7' but hardware that outputs 14 or 21 bit controller information is rare so these opcodes are seldom used.

También hay versiones de 14 bits y 21 bits de ctrl7 (ctrl14 y ctrl21) que mejoran la resolución de 7 bits de ctrl7, pero el hardware que genera información de controlador de 14 o 21 bits es raro, por lo que estos códigos de operación rara vez se utilizan.

Scanning Pitch Bend and Aftertouch

Escaneado Pitch Bend y Aftertouch

 

We can scan pitch bend and aftertouch in a similar way by using the opcodes pchbend and aftouch. Once again we can specify minimum and maximum values with which to rescale the output. In the case of 'pchbend' we specify the value it outputs when the pitch bend wheel is at rest followed by a value which defines the entire range from when it is pulled to its minimum to when it is pushed to its maximum. In this example, playing a key on the keyboard will play a note, the pitch of which can be bent up or down two semitones by using the pitch bend wheel. Aftertouch can be used to modify the amplitude of the note while it is playing. Pitch bend and aftertouch data is also printed at the terminal whenever they change. One thing to bear in mind is that for 'pchbend' to function the Csound instrument that contains it needs to have been activated by a MIDI event, i.e. you will need to play a midi note on your keyboard and then move the pitch bend wheel.

Podemos explorar pitch bend y aftertouch de una manera similar usando los opcodes pchbend y aftouch. Una vez más, podemos especificar valores mínimos y máximos con los que volver a escalar la salida. En el caso de pchbend se especifica el valor que se genera cuando la rueda de curvatura de tono está en reposo seguida de un valor que define todo el rango desde cuando se tira a su mínimo hasta cuando se empuja a su máximo. En este ejemplo, al tocar una tecla en el teclado se reproducirá una nota, cuyo tono puede doblarse hacia arriba o hacia abajo dos semitonos utilizando la rueda de tono de tono. Aftertouch se puede utilizar para modificar la amplitud de la nota mientras se está reproduciendo. Los datos de curvatura de la torsión y de aftertouch también se imprimen en el terminal cada vez que cambian. Una cosa a tener en cuenta es que para que pchbend funcione, el instrumento Csound que lo contiene debe haber sido activado por un evento MIDI, es decir, necesitará tocar una nota midi en su teclado y luego mover la rueda de tono de tono.


 

  EXAMPLE 07C02_pchbend_aftouch.csd

<CsoundSynthesizer>

<CsOptions>
-odac -Ma
</CsOptions>

<CsInstruments>
sr = 44100
ksmps = 32
nchnls = 1
0dbfs = 1

giSine  ftgen  0,0,2^10,10,1  ; a sine wave

  instr 1
; -- pitch bend --
kPchBnd  pchbend  0,4                ; read in pitch bend (range -2 to 2)
kTrig1   changed  kPchBnd            ; if 'kPchBnd' changes generate a trigger
 if kTrig1=1 then
printks "Pitch Bend:%f%n",0,kPchBnd  ; print kPchBnd to console when it changes
 endif

; -- aftertouch --
kAfttch  aftouch 0,0.9               ; read in aftertouch (range 0 to 0.9)
kTrig2   changed kAfttch             ; if 'kAfttch' changes generate a trigger
 if kTrig2=1 then
printks "Aftertouch:%d%n",0,kAfttch  ; print kAfttch to console when it changes
 endif

; -- create a sound --
iNum     notnum                      ; read in MIDI note number
; MIDI note number + pitch bend are converted to cycles per seconds
aSig     poscil   0.1,cpsmidinn(iNum+kPchBnd),giSine
         out      aSig               ; audio to output
  endin

</CsInstruments>

<CsScore>
f 0 300
e
</CsScore>

<CsoundSynthesizer>

Initialising MIDI Controllers Inicialización de controladores MIDI

 

It may be useful to be able to define the initial value of a midi controller, that is, the value any ctrl7s will adopt until their corresponding hardware controls have been moved. Midi hardware controls only send messages when they change so until this happens their values in Csound defaults to their minimum settings unless additional initialisation has been carried out. As an example, if we imagine we have a Csound instrument in which the output volume is controlled by a midi controller it might prove to be slightly frustrating that each time the orchestra is launched, this instrument will remain silent until the volume control is moved. This frustration might become greater when many midi controllers are begin utilised. It would be more useful to be able to define the starting value for each of these controllers. The initc7 opcode allows us to do this. If initc7 is placed within the instrument itself it will be reinitialised each time the instrument is called, if it is placed in instrument 0 (just after the header statements) then it will only be initialised when the orchestra is first launched. The latter case is probably most useful.

Puede ser útil poder definir el valor inicial de un controlador midi, es decir, el valor que cualquier ctrl7s adopte hasta que se hayan movido sus correspondientes controles de hardware. Los controles MIDI de hardware sólo envían mensajes cuando cambian hasta que esto suceda, sus valores en Csound son los valores por defecto a su configuración mínima a menos que se haya realizado una inicialización adicional. Por ejemplo, si imaginamos que tenemos un instrumento Csound en el que el volumen de salida es controlado por un controlador midi, puede resultar un poco frustrante que cada vez que se lance la orquesta, este instrumento permanecerá en silencio hasta que se mueva el control de volumen. Esta frustración puede llegar a ser mayor cuando se utilizan muchos controladores midi. Sería más útil poder definir el valor inicial para cada uno de estos controladores. El código de operación initc7 nos permite hacerlo. Si initc7 se coloca dentro del instrumento mismo se reinicializará cada vez que se pida el instrumento, si se coloca en el instrumento 0 (justo después de las instrucciones del encabezado), sólo se inicializará cuando se lance la orquesta. Este último caso es probablemente el más útil.

In the following example a simple synthesizer is created. Midi controller 1 controls the output volume of this instrument but the initc7 statement near the top of the orchestra ensures that this control does not default to its minimum setting. The arguments that initc7 takes are for midi channel, controller number and initial value. Initial value is defined within the range 0-1, therefore a value of 1 will set this controller to its maximum value (midi value 127), and a value of 0.5 will set it to its halfway value (midi value 64), and so on.

En el ejemplo siguiente se crea un sintetizador simple. El controlador Midi 1 controla el volumen de salida de este instrumento, pero la instrucción initc7 cerca de la parte superior de la orquesta asegura que este control no se ajuste por defecto a su configuración mínima. Los argumentos que initc7 toma son para el canal midi, el número de controlador y el valor inicial. El valor inicial se define dentro del rango 0-1, por lo tanto un valor de 1 ajustará este controlador a su valor máximo (valor midi 127), y un valor de 0.5 lo ajustará a su valor intermedio (valor midi 64), y así en.

Additionally this example uses the cpsmidi opcode to scan midi pitch (basically converting midi note numbers to cycles-per-second) and the ampmidi opcode to scan and rescale key velocity.

Adicionalmente, este ejemplo usa el código de operación cpsmidi para escanear el pitch midi (básicamente convirtiendo los números de notas midi a ciclos por segundo) y el opcode ampmidi para escanear y reescalar la velocidad de la clave.

  EXAMPLE 07C03_cpsmidi_ampmidi.csd

<CsoundSynthesizer>

<CsOptions>
-Ma -odac
; activate all midi inputs and real-time audio output
</CsOptions>

<CsInstruments>
; Example by Iain McCurdy

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

giSine ftgen 0,0,2^12,10,1 ; a sine wave
initc7 1,1,1               ; initialize CC 1 on chan. 1 to its max level

  instr 1
iCps cpsmidi               ; read in midi pitch in cycles-per-second
iAmp ampmidi 1             ; read in key velocity. Rescale to be from 0 to 1
kVol ctrl7   1,1,0,1       ; read in CC 1, chan 1. Rescale to be from 0 to 1
aSig poscil  iAmp*kVol, iCps, giSine ; an audio oscillator
     out     aSig          ; send audio to output
  endin

</CsInstruments>

<CsScore>
f 0 3600
e
</CsScore>

<CsoundSynthesizer>

You will maybe hear that this instrument produces 'clicks' as notes begin and end. To find out how to prevent this see the section on envelopes with release sensing in the chapter Sound Modification: Envelopes.

Tal vez se entere que este instrumento produce clics como las notas comienzan y terminan. Para saber cómo evitar esto, consulte la sección sobre sobres con detección de liberación en el capítulo Modificación de sonido: sobres.

Smoothing 7-bit Quantisation in MIDI Controllers

Suavizar la cuantificación de 7 bits en controladores MIDI

 

A problem we encounter with 7 bit midi controllers is the poor resolution that they offer us. 7 bit means that we have 2 to the power of 7 possible values; therefore 128 possible values, which is rather inadequate for defining, for example, the frequency of an oscillator over a number of octaves, the cutoff frequency of a filter or a quickly moving volume control. We soon become aware of the parameter that is being changed moving in steps - so not really a 'continuous' controller. We may also experience clicking artefacts, sometimes called 'zipper noise', as the value changes. The extent of this will depend upon the parameter being controlled. There are some things we can do to address this problem. We can filter the controller signal within Csound so that the sudden changes that occur between steps along the controller's travel are smoothed using additional interpolating values - we must be careful not to smooth excessively otherwise the response of the controller will become sluggish. Any k-rate compatible lowpass filter can be used for this task but the portk opcode is particularly useful as it allows us to define the amount of smoothing as a time taken to glide to half the required value rather than having to specify a cutoff frequency. Additionally this 'half time' value can be varied at k-rate which provides an advantage availed of in the following example.

Un problema que nos encontramos con los controladores MIDI de 7 bits es la pobre resolución que nos ofrecen. 7 bits significa que tenemos 2 a la potencia de 7 valores posibles; Por lo tanto 128 valores posibles, lo cual es bastante inadecuado para definir, por ejemplo, la frecuencia de un oscilador sobre varias octavas, la frecuencia de corte de un filtro o un control de volumen que se mueve rápidamente. Pronto nos damos cuenta del parámetro que se está cambiando moviendo en pasos - por lo que no realmente un controlador continuo. También podemos experimentar hacer clic en artefactos, a veces llamado ruido de cremallera, como el valor cambia. El alcance de esto dependerá del parámetro que se esté controlando. Hay algunas cosas que podemos hacer para solucionar este problema. Podemos filtrar la señal del controlador dentro de Csound para que los cambios repentinos que se producen entre los pasos a lo largo del recorrido de los controladores se alisan usando valores de interpolación adicionales - debemos tener cuidado de no suavizar excesivamente de lo contrario la respuesta del controlador se volverá lenta. Cualquier filtro de paso bajo compatible con k-rate puede ser utilizado para esta tarea, pero el código de operación de portk es particularmente útil ya que nos permite definir la cantidad de suavizado como el tiempo necesario para deslizarse a la mitad del valor requerido en lugar de tener que especificar una frecuencia de corte. Adicionalmente, este valor de tiempo medio se puede variar a la velocidad k que proporciona una ventaja aprovechada en el ejemplo siguiente.

 

This example takes the simple synthesizer of the previous example as its starting point. The volume control, which is controlled by midi controller 1 on channel 1, is passed through a 'portk' filter. The 'half time' for 'portk' ramps quickly up to its required value of 0.01 through the use of a linseg statement in the previous line. This ensures that when a new note begins the volume control immediately jumps to its required value rather than gliding up from zero as would otherwise be affected by the 'portk' filter. Try this example with the 'portk' half time defined as a constant to hear the difference. To further smooth the volume control, it is converted to an a-rate variable through the use of the interp opcode which, as well as performing this conversion, interpolates values in the gaps between k-cycles.

Este ejemplo toma el sintetizador simple del ejemplo anterior como su punto de partida. El control de volumen, que es controlado por el controlador midi 1 en el canal 1, se pasa a través de un filtro portk. El tiempo medio para portk rampas rápidamente hasta su valor requerido de 0,01 a través del uso de una declaración linseg en la línea anterior. Esto asegura que cuando una nueva nota comienza el control de volumen salta inmediatamente a su valor requerido en lugar de deslizarse desde cero, ya que de lo contrario serían afectados por el filtro de portk. Pruebe este ejemplo con el medio tiempo definido como una constante para escuchar la diferencia. Para suavizar aún más el control de volumen, se convierte en una variable a-rate mediante el uso del código interp que, además de realizar esta conversión, interpola valores en los espacios entre ciclos k.

  EXAMPLE 07C04_smoothing.csd

<CsoundSynthesizer>
<CsOptions>
-Ma -odac
</CsOptions>
<CsInstruments>
;Example by Iain McCurdy

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

giSine   ftgen    0,0,2^12,10,1
         initc7   1,1,1          ; initialize CC 1 to its max. level

  instr 1
iCps      cpsmidi                ; read in midi pitch in cycles-per-second
iAmp      ampmidi 1              ; read in note velocity - re-range 0 to 1
kVol      ctrl7   1,1,0,1        ; read in CC 1, chan. 1. Re-range from 0 to 1
kPortTime linseg  0,0.001,0.01   ; create a value that quickly ramps up to 0.01
kVol      portk   kVol,kPortTime ; create a filtered version of kVol
aVol      interp  kVol           ; create an a-rate version of kVol
aSig      poscil  iAmp*aVol,iCps,giSine
          out     aSig
  endin

</CsInstruments>
<CsScore>
f 0 300
e
</CsScore>
<CsoundSynthesizer>

All of the techniques introduced in this section are combined in the final example which includes a 2-semitone pitch bend and tone control which is controlled by aftertouch. For tone generation this example uses the gbuzz opcode.

Todas las técnicas introducidas en esta sección se combinan en el ejemplo final que incluye una curva de tono de 2 semitonos y un control de tono que está controlado por un toque posterior. Para la generación de tonos, este ejemplo utiliza el opcode gbuzz.

  EXAMPLE 07C05_MidiControlComplex.csd

<CsoundSynthesizer>

<CsOptions>
-Ma -odac
</CsOptions>

<CsInstruments>
;Example by Iain McCurdy

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

giCos   ftgen    0,0,2^12,11,1 ; a cosine wave
         initc7   1,1,1        ; initialize controller to its maximum level

  instr 1
iNum      notnum                   ; read in midi note number
iAmp      ampmidi 0.1              ; read in note velocity - range 0 to 0.2
kVol      ctrl7   1,1,0,1          ; read in CC 1, chan. 1. Re-range from 0 to 1
kPortTime linseg  0,0.001,0.01     ; create a value that quickly ramps up to 0.01
kVol      portk   kVol, kPortTime  ; create filtered version of kVol
aVol      interp  kVol             ; create an a-rate version of kVol.
iRange    =       2                ; pitch bend range in semitones
iMin      =       0                ; equilibrium position
kPchBnd	  pchbend iMin, 2*iRange   ; pitch bend in semitones (range -2 to 2)
kPchBnd   portk   kPchBnd,kPortTime; create a filtered version of kPchBnd
aEnv      linsegr 0,0.005,1,0.1,0  ; amplitude envelope with release stage
kMul      aftouch 0.4,0.85         ; read in aftertouch
kMul      portk   kMul,kPortTime   ; create a filtered version of kMul
; create an audio signal using the 'gbuzz' additive synthesis opcode
aSig      gbuzz   iAmp*aVol*aEnv,cpsmidinn(iNum+kPchBnd),70,0,kMul,giCos
          out     aSig             ; audio to output
  endin

</CsInstruments>

<CsScore>
f 0 300
e
</CsScore>

<CsoundSynthesizer>

RECORDING CONTROLLER DATA GRABACIÓN DE LOS DATOS DEL CONTROLADOR

Data performed on a controller or controllers can be recorded into GEN tables or arrays so that a real-time interaction with a Csound instrument can be replayed at a later time. This can be preferable to recording the audio output, as this will allow the controller data to be modified. The simplest approach is to simply store each controller value every k-cycle into sequential locations in a function table but this is rather wasteful as controllers will frequently remain unchanged from k-cycle to k-cycle.

Los datos realizados en un controlador o controladores se pueden grabar en tablas GEN o arrays para que una interacción en tiempo real con un instrumento Csound pueda ser reproducida en un momento posterior. Esto puede ser preferible a la grabación de la salida de audio, ya que esto permitirá modificar los datos del controlador. El enfoque más simple es simplemente almacenar cada valor del controlador cada ciclo k en ubicaciones secuenciales en una tabla de funciones, pero esto es bastante inútil, ya que los controladores permanecerán frecuentemente sin cambios desde el ciclo k hasta el ciclo k.

A more efficient approach is to store values only when they change and to time stamp those events to that they can be replayed later on in the right order and at the right speed. In this case data will be written to a function table in pairs: time-stamp followed by a value for each new event ('event' refers to when a controller changes). This method does not store durations of each event, merely when they happen, therefore it will not record how long the final event lasts until recording stopped. This may or may not be critical depending on how the recorded controller data is used later on but in order to get around this, the following example stores the duration of the complete recording at index location 0 so that we can derive the duration of the last event. Additionally the first event stored at index location 1 is simply a value: the initial value of the controller (the time stamp for this would always be zero anyway). Thereafter events are stored as time-stamped pairs of data: index 2=time stamp, index 3=associated value and so on.

Un enfoque más eficiente es almacenar valores sólo cuando cambian y sellar estos eventos a tiempo para que puedan ser reproducidos más tarde en el orden correcto ya la velocidad correcta. En este caso, los datos se escribirán en una tabla de funciones en pares: sello de tiempo seguido de un valor para cada nuevo evento (el evento se refiere a cuándo cambia un controlador). Este método no almacena las duraciones de cada evento, simplemente cuando ocurren, por lo tanto no registrará cuánto dura el evento final hasta que se detiene la grabación. Esto puede o no ser crítico dependiendo de cómo se utilizan los datos de controlador registrados más tarde, pero con el fin de evitar esto, el siguiente ejemplo almacena la duración de la grabación completa en la posición de índice 0 para que podamos derivar la duración de la última evento. Además, el primer evento almacenado en la posición de índice 1 es simplemente un valor: el valor inicial del controlador (la marca de tiempo para esto siempre sería cero de todos modos). A partir de entonces, los eventos se almacenan como pares de datos con fecha y hora: índice 2 = marca de tiempo, índice 3 = valor asociado y así sucesivamente.

To use the following example, activate 'Record', move the slider around and then deactivate 'Record'. This gesture can now be replayed using the 'Play' button. As well as moving the GUI slider, a tone is produced, the pitch of which is controlled by the slider.

Para usar el siguiente ejemplo, active Registro, mueva el control deslizante y luego desactive Registro. Este gesto se puede reproducir ahora con el botón Reproducir. Además de mover el control deslizante GUI, se produce un tono, cuyo tono es controlado por el control deslizante.

Recorded data in the GEN table can also be backed up onto the hard drive using ftsave and recalled in a later session using ftload. Note that ftsave also has the capability of storing multiple function tables in a single file.

Los datos registrados en la tabla GEN también se pueden hacer copias de seguridad en el disco duro utilizando ftsave y se recuperarán en una sesión posterior utilizando ftload. Tenga en cuenta que ftsave también tiene la capacidad de almacenar múltiples tablas de funciones en un solo archivo.

EXAMPLE 07C06_RecordingController.csd

<CsoundSynthesizer>

<CsOptions>
-odac -dm0
</CsOptions>

<CsInstruments>

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

FLpanel "Record Gesture",500,90,0,0
gkRecord,gihRecord FLbutton "Rec/Stop",1,0,22,100,25,  5, 5,-1
gkPlay,gihPlay  FLbutton "Play",    1,0,22,100,25,110, 5,-1
gksave,ihsave  FLbutton "Save to HD", 1,0,21,100,25,290,5,0,4,0,0
gkload,ihload  FLbutton "Load from HD", 1,0,21,100,25,395,5,0,5,0,0
gkval, gihval  FLslider "Control", 0,1, 0,23, -1,490,25, 5,35
FLpanel_end
FLrun

gidata ftgen 1,0,1048576,-2,0 ; Table for controller data.

opcode RecordController,0,Ki
 kval,ifn        xin
 i_      ftgen   1,0,ftlen(ifn),-2,0             ; erase table
 tableiw i(kval),1,ifn           ; write initial value at index 1.
         ;(Index 0 will be used be storing the complete gesture duration.)
 kndx    init    2         ; Initialise index
 kTime   timeinsts         ; time since this instrument started in seconds
; Write a data event only when the input value changes
if changed(kval)==1 && kndx<=(ftlen(ifn)-2) && kTime>0 then
; Write timestamp to table location defined by current index.
  tablew kTime, kndx, ifn
; Write slider value to table location defined by current index.
  tablew kval, kndx + 1, ifn
; Increment index 2 steps (one for time, one for value).
  kndx   =       kndx + 2
 endif
; sense note release
 krel    release
; if we are in the final k-cycle before the note ends
 if(krel==1) then
; write total gesture duration into the table at index 0
  tablew kTime,0,ifn
 endif
endop

opcode PlaybackController,k,i
 ifn     xin
 ; read first value
; initial controller value read from index 1
 ival    table   1,ifn
; initial value for k-rate output
 kval    init    ival
; Initialise index to first non-zero timestamp
 kndx    init    2
; time in seconds since this note started
 kTime   timeinsts
; first non-zero timestamp
 iTimeStamp      tablei  2,ifn
; initialise k-variable for first non-zero timestamp
 kTimeStamp      init    iTimeStamp
; if we have reached the timestamp value...
 if kTime>=kTimeStamp && kTimeStamp>0 then
; ...Read value from table defined by current index.
  kval   table   kndx+1,ifn
  kTimeStamp     table   kndx+2,ifn              ; Read next timestamp
; Increment index. (Always 2 steps: timestamp and value.)
  kndx   limit   kndx+2, 0, ftlen(ifn)-2
 endif
         xout    kval
endop

; cleaner way to start instruments than using FLbutton built-in mechanism
instr   1
; trigger when button value goes from off to on
 kOnTrig trigger gkRecord,0.5,0
; start instrument with a held note when trigger received
 schedkwhen      kOnTrig,0,0,2,0,-1
; trigger when button value goes from off to on
 kOnTrig trigger gkPlay,0.5,0
; start instrument with a held note when trigger received
 schedkwhen      kOnTrig,0,0,3,0,-1
endin

instr   2       ; Record gesture
 if gkRecord==0 then            ; If record button is deactivated...
  turnoff                       ; ...turn this instrument off.
 endif
; call UDO
         RecordController        gkval,gidata
; Generate a sound.
 kporttime       linseg  0,0.001,0.02
 kval    portk   gkval,kporttime
 asig    poscil  0.2,cpsoct((kval*2)+7)
         out     asig

endin

instr   3       ; Playback recorded gesture
 if gkPlay==0 then                 ; if play button is deactivated...
  turnoff                          ; ...turn this instrument off.
 endif
 kval    PlaybackController      gidata
; send initial value to controller
         FLsetVal_i      i(kval),gihval
; Send values to slider when needed.
         FLsetVal        changed(kval),kval,gihval
 ; Generate a sound.
 kporttime       linseg  0,0.001,0.02
 kval    portk   gkval,kporttime
 asig    poscil  0.2,cpsoct((kval*2)+7)
         out     asig
 ; stop note when end of table reached
 kTime   timeinsts              ; time in seconds since this note began
; read complete gesture duration from index zero
 iRecTime        tablei  0,gidata
; if we have reach complete duration of gesture...
 if kTime>=iRecTime then
; deactivate play button (which will in turn, turn off this note.)
  FLsetVal       1,0,gihPlay
 endif
endin

instr   4       ; save table
 ftsave "ControllerData.txt", 0, gidata
endin


instr   5       ; load table
 ftload "ControllerData.txt", 0, gidata
endin

</CsInstruments>

<CsScore>
i 1 0 3600
</CsScore>

</CsoundSynthesizer>

 

 

 

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

You should refresh this page.