What Is an Opcode?

An opcode is a pre-compiled chunk of computer code that does something. For a list (a long list) of opcodes, from a to zkwm, open the frames version of the manual in your web browser and scroll down the left column. The Reference section of this column includes a complete list. (Even the word “opcode” is an opcode.)

Every opcode has zero or more inputs, and zero or more outputs. In most (though not all) cases, an opcode is placed on a line of code by itself, with its outputs to the left and its inputs to the right, like this:


  kr1, kr2 readk2 ifilname, iformat, iprd

This is the prototype of the readk2 opcode. (For details on what readk2 does, consult the manual. For an explanation of how to read a prototype in the manual, see below.) At the left end of the line are two output variables, separated by a comma. Next is the name of the opcode. To the right are the inputs, again separated by commas. This layout is standard: output(s), then the opcode, then input(s). (A mere handful of opcodes have an output on the right side, among the inputs.)

The arguments to an opcode are always in a fixed order. You can learn this order by consulting the manual. If you’re using the CsoundQt interface, you’ll see the prototype for an opcode displayed along the bottom of the main window whenever your cursor is on a line that contains an opcode. The abbreviations in this prototype, such as xamp, will often give you all the information you need about the correct order of the inputs.

At first glance, such a layout may seem backward—at least to folks who read printed languages, such as English, that are displayed from left to right. Shouldn’t the outputs be on the right? But in fact it’s normal in computer programming to put the result of an operation on the left side. This method is also convenient: Most opcodes have only a single output, while the list of inputs may be long and may contain optional items that can be omitted. When you want to check the name of the variable that you’re using as the output, your eye will find it more easily when it’s always at the left end of the line.

The technical term for an opcode’s inputs and outputs is arguments. (Some people would say that only the inputs are arguments.) In this book I’ll often use “inputs” and “outputs” rather than “arguments,” because most musicians are more familiar with using the input and output jacks on hardware modules. If you think of each opcode as being like an electronic hardware module, such as you’ll find on a classic analog synthesizer, you won’t be far off the mark. You can plug signals (in the form of numbers, variable names such as ipan and kamp, or in some cases other types of data, such as text strings) into the inputs, which are normally written on the right side of the opcode. The opcode will chew on your inputs and produce one or more signals at its output “jacks,” which are almost always found to the left of the opcode. You can then plug these signals into another opcode as if it were a hardware module, using the variable names (such as kr1 and kr2 in the readk2 example shown above) as “patch cords.”

How to Read Prototypes in the Manual

To learn the precise meanings of the input(s) and the sort of data that will appear at the output(s) for a given opcode, you’ll need to consult the manual. It’s important to understand that the symbols used in the prototype are placeholders. That is, you can use whatever variable names you prefer for the inputs and outputs. All that matters is that you use a value of the correct type (i-, k-, a-, S-, and so on, as explained in Chapter 6).

Reading the prototype will tell you a few things. Any input or output whose name begins with i-will be sent to or received from the opcode during the initialization pass, before the instrument starts playing. (For more on the initialization pass, see the section “i- versus k- versus a-” in Chapter 6.) Any input or output whose name begins with k- will be sent to or received from the opcode on every control pass while the instrument is active. Any input or output whose name begins with a- will contain an audio signal. If the prototype shows an input whose name begins with x-, it can accept an a-, k-, or i-rate variable.

Many opcodes expect to receive the number of a function table as an input. This is the case, for instance, with the oscil opcode (see below). In the manual, the opcode prototype will generally show a function table number as ifn. Function tables are identified by integers, so this input could either be a numerical constant (such as 3) or an i-rate variable (such as iSine).

Reading the Initialization section of the manual page will tell you what type of table data the opcode expects to receive.

In general, a k-type input to an opcode will accept an i-time value or a numerical constant. For instance, given the prototype for oscil:


  ares oscil xamp, xcps, ifn [, iphs]

you could set the amplitude and frequency to constant values like this:


  aoutput oscil 1, 440, 1, 0.5

In effect, by entering a number you’re using a k-rate value that never changes. This oscillator’s output amplitude will be 1 continuously throughout each note, and its frequency will be 440 Hz. It will generate its output signal using the data in function table 1 as a source for the waveshape, and will begin its first cycle halfway through the table, because the start phase (iphs) has been set to 0.5.

Other types of conversions require special handling. If you want to send an audio signal (an a-rate variable) to an input that accepts only k-rate values, you’ll need to downsample the audio signal to k-rate. This operation may produce audio artifacts, but there are times when it’s useful. You might even want the artifacts! As you might guess, the downsampling operation is handled by the downsamp opcode.

Looking back at the prototype for oscil, you’ll see an item in square brackets to the right of ifn. Items that appear within square brackets in opcode prototypes are optional arguments. That is, they’re inputs for which the opcode has a preset default value. If you don’t supply a value for this input, the opcode will use its default. Square brackets are also used in prototypes for opcodes that may have multiple outputs, such as xin:


  xinarg1 [, xinarg2] ... [, xinargN] xin

In this case, the xin opcode will always have one output (shown as xinarg1). It may have additional outputs, and the exact number of outputs is unknown. Because the number is not known, the prototype includes three dots, and the final optional output has a name that ends with “N” to indicate that some unknown number belongs there. This is a prototype, however, so numbers need not be used in your code. Here are three quick examples, all of which would match the xin prototype:


  asig xin
  idataA, idataB xin
  asig1, asig2, kenv, idelayL, idelayR xin

Some opcodes have several optional input arguments. Here’s a good example:


  ares dripwater kamp, idettack [, inum] [, idamp] [, imaxshake] [, ifreq] 
[, ifreq1] [, ifreq2]

The dripwater opcode requires only two inputs, kamp and idettack. The other inputs are optional. However, if you want to specify, for instance, your own value for ifreq with this opcode, you also have to specify inum, idamp, and imaxshake. Otherwise, Csound won’t know how to interpret your code. If you give dripwater three inputs—for kamp, idettack, and one more—Csound will assume your third input is a value for inum, not for ifreq, because inum is the first optional input.

This is not a problem; it’s just something to be aware of. The manual will almost always tell you what the defaults are for any optional inputs. Just enter the defaults for any inputs that you don’t care about, enter your own value for the one you do care about, and ignore any optional inputs that fall after the one you’re giving your own value to. This will give you the desired result.


image

Note The backslash character at the end of the first line in the dripwater prototype, shown here, creates a “soft line break.” This is a way of breaking up long lines of code into shorter lines that will be easier to see in your editing window; it’s used throughout this book to break up long lines of code. The backslash is not required when using this (or any) opcode: You can string your code out into really long lines if you want to.

Note, however, that the backslash character cannot currently be used in CsoundQt. It can be used in your code only when you’re running Csound from the command line.


A few opcodes use a different syntax. Here is the prototype for the urd opcode:


  kout = urd(ktableNum)

This opcode uses a syntax similar to what in other programming languages would be a function call. The output value is followed by an equals sign (in fact, this is the assignment operator), and the input argument to the opcode is in parentheses.

Now that you know how to read prototypes, we’re ready to start talking about specific opcodes.

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

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