Creating Score Events during Performance

The list of events in a Csound score is pretty much set in stone at the time the score is compiled. During the compilation process, the events are sorted, looping sections are spelled out as linear lists of events, and so forth, and then the score is played. For some types of musical compositions, this is perfectly appropriate. But there are other situations in which we might want to insert new events during performance. One way of doing this is with real-time MIDI input, as discussed in Chapter 10. Another method is to use the Live Events feature in CsoundQt, as explained in Chapter 5. Yet a third method is to create new score events from within the orchestra.

Three families of opcodes are available with which to accomplish this: schedule, scoreline, and event. To some extent, which one you use is a matter of taste; they’ll all do the job. However, scoreline is a bit different in that it accepts a new score event in the form of text. This can make it a good choice when used in conjunction with embedded Python code, as you can assemble strings in a Python routine and return them to Csound so as to generate notes with them. The use of Python within Csound is discussed in Chapter 10.

Ordinarily, the event-generating opcodes will be used by a master sequencing or loop-generating instrument. They will be used to generate new events by a different instrument, which will produce the actual sounds. With the usual amount of care, however, they can be used recursively, as the next example illustrates.


image

Note In some versions of The Canonical Csound Reference Manual, due to block-copying of text, reference is made on a few manual pages to trigger arguments that will cause a score-scheduling event to fire, even though no such argument can be used with that particular opcode.


schedule and schedwhen

schedule is an i-time opcode. Its arguments exactly parallel the p-fields of a score statement: instrument number (or name as a double-quoted string), starting time (in relation to the moment when schedule is invoked), duration, p4, p5, and so on.

In the example below, schedule is being used recursively to call another instance of the same instrument:


  giSine ftgen 0, 0, 8192, 10, 1

  instr 1
  idur = p3
  iamp = p4
  ifrq = p5
  icount = p6

  if icount > 0 then
    schedule 1, 0, idur, iamp * 0.65, ifrq * 1.35, icount - 1
  endif

  kamp linseg 0, 0.01, iamp, idur - 0.11, iamp, 0.1, 0
  asig oscil kamp, ifrq, giSine
  outs asig, asig
  endin

  </CsInstruments>
  <CsScore>

  i1 0 2 0.3 200 4

This example produces a four-note chord. Each note is higher and quieter than the note before it. The value of icount is decremented before being passed to schedule, and when icount reaches zero, no more notes are generated.

Though the presence of a k-rate trigger argument would seem to imply otherwise, schedwhen behaves somewhat like an i-time opcode. In fact, it runs during k-rate passes, but a given instance of it runs only once—the first time its trigger is non-zero. You can use it several times within a single score event by setting up an if/elseif switching block, like this:


  instr 1
  kcount init 0
  ktrig metro 3
  if ktrig == 1 then
    kcount = kcount + 1
  endif

  kdur line 0.1, p3, 0.5

  if kcount == 1 then
    schedwhen 1, 2, 0, kdur, 0.3, 200
  elseif kcount == 2 then
    schedwhen 1, 2, 0, kdur, 0.3, 300
  elseif kcount == 3 then
    schedwhen 1, 2, 0, kdur, 0.3, 400
  elseif kcount == 4 then
    schedwhen 1, 2, 0, kdur, 0.3, 500
  elseif kcount == 5 then
    schedwhen 1, 2, 0, kdur, 0.3, 600
  elseif kcount == 6 then
    schedwhen 1, 2, 0, kdur, 0.3, 700
  endif

  endin

This code will fire six notes in succession, and the duration of each successive note will be longer because kdur is ramping upward. But the values sent to the new event’s p-fields by the schedule family of opcodes must always be i-time. To use varying k-rate values in p-fields, you’ll need to use the event opcode. schedkwhen can generate a cloud of notes, but again, they will all have the same p-field values, because the p-field arguments are i-time values.

schedkwhen adds a few features: It can be triggered more than once, and it will limit the maximum number of simultaneous events that it will produce, as well as the minimum time between events.

scoreline

Instead of firing new score events with numerical values for the p-fields, scoreline accepts a text string as its first argument (and a trigger as its second). This has two advantages. First, the text can contain multiple lines. Second, you can assemble the text on the fly. Here’s an example of the first technique:


  instr 1
  Strudel = {{i2 0 0.5 0.5 200
  i2 1.. 300
  i2 2.. 400 }}

  ktrig init 1
  scoreline Strudel, ktrig
  ktrig = 0

  endin

This instrument plays three notes, one second apart. The double curly braces are used around the text because it has multiple lines. Note that the carry symbol (.) can be used in the string sent to scoreline, but some other shortcuts, such as +, can’t be. ktrig is set to 0 after being used, so the three score lines will play only once. As the manual notes, if the actual score comes to an end while some of the events queued up by scoreline are still waiting, playback will stop. An e-statement with a p-field to control the score’s ending time may come in handy as a way of preventing this. Note, also, that scoreline takes no notice of the current tempo in the score. It always interprets p2 and p3 in seconds.

To put varying values into a string, we can use sprintfk. The resulting string can then be passed to scoreline. Here is an example in which a stream of notes (played by instrument 2, not shown) gets shorter in duration, closer together, and higher in pitch:


  instr 1
  ktempo line 3, p3, 7
  ktrig metro ktempo
  kpitch line 100, p3, 600
  kdur line 0.5, p3, 0.15
  Strudel sprintfk “i2 0 %f 0.3 %f”, kdur, kpitch
  scoreline Strudel, ktrig
  endin

The call to sprintf uses formatting strings to put the current (floating-point) values of kdur and kpitch into the string, which happens to be called Strudel. The string is then passed to scoreline, which fires a new event each time the value of ktrig is 1. ktrig comes from the metro opcode, which is increasing in tempo during the course of the instrument 1 event.

event

In some ways event is the most flexible opcode for generating score events from within the orchestra. This is because the p-fields for the newly generated event can be filled with k-rate values. The syntax of event_i is identical, but because it runs at i-time, only i-time variables can be used as arguments. Here is a simple example that uses event in conjunction with metro; metro produces a regular series of pulses, each of which causes a new call to event.


  instr 1
  ktrig metro 4
  kdur line 0.3, p3, 0.03
  kamp expseg 0.5, p3, 0.05
  kfreq expseg 200, p3, 600
  if ktrig != 0 then
    event “i”, 2, 0, kdur, kamp, kfreq
  endif
  endin

The first argument to event is normally “i”, the score character that defines the event. However, ”f” is also legal here; you can create a new f-table on the fly using event or change the data in an f-table that already exists. The second argument is the instrument number. The third argument is the start time with reference to the moment when event is called; this is generally zero, but needn’t be. The fourth argument has the same meaning as the third p-field in a score event: It sets the duration of the note. The meanings of the remaining arguments are p-fields and depend on the nature of the instrument being triggered.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.137.75