OSC

Open Sound Control (OSC) is a powerful, open-ended communications protocol for sending data from one piece of music software or hardware to another. Two programs can be linked using OSC even if they’re running on different computers. It could be argued that OSC requires a bit more expertise to set up than a MIDI communications system—or it could be argued that OSC is actually easier to use than MIDI, because you’re not limited to MIDI’s fixed set of message types and control value ranges. With OSC, you can define messages in whatever way you need, so once you learn the syntax, the path to musical satisfaction will be smoother.

Although it has been in existence for more than a decade, OSC remains poorly supported by the major hardware manufacturers. It has made some inroads in the software world, however. Renoise, Apple Logic Audio, Csound, Pd, SuperCollider, Native Instruments Reaktor, and some Linux programs work with OSC.

Andres Cabrera has uploaded an excellent five-minute video to YouTube (www.youtube.com/watch?v=JX1C3TqP_9Y&list=PL3EE3219702D17FD3&index=12&feature=plpp) showing how to use OSC for communications between Csound and Pd. The setup is entirely different from running Csound as an object within Pd, a topic that will be covered later in this chapter. The musical results might or might not be similar; that’s up to you. Pd is used in the video, and we’ll use it here, entirely as a matter of convenience. It’s readily available and arguably easier for a newcomer to work with than SuperCollider.


image

Caution The Pd objects sendOSC and dumpOSC, which are used in the tutorial video, are now deprecated. They may work for you, but I’m told that they’re not free of bugs. In the discussion in this section, we’ll use Pd’s newer udpsend and udpreceive objects. The Pd objects that work with them, such as packOSC and unpackOSC, are distributed with Pd-Extended 0.42.5, which is the latest version at this writing, but they are not loaded automatically when Pd starts. To load them, you must create an object box whose text reads import mrpeach, as shown in Figure 10.3. Oddly enough, this object doesn’t even need to be connected to a bang or loadbang to do its job; however, you may need to save your patch, close it, and reopen it in order for the import command to take effect.


To begin experimenting with OSC, launch Pd and create the patch shown in Figure 10.3. The horizontal slider should be given a range from 0 to 1.0. This slider will be used to send amplitude data to Csound, so an upper limit of 1.0 is a good idea, assuming you’re running Csound with 0dbfs=1. The range of the vertical slider, which will control oscillator frequency, is less crucial; a range from 100 to 400 might be good.

Figure 10.3 A simple patch in Pd with which to try out the OSC features of Csound. The objects on the left side will transmit OSC values to Csound; the objects on the right will receive from Csound.

image

In Csound, create the following .csd file:


  sr = 44100
  ksmps = 4
  nchnls = 2
  0dbfs = 1

  giSine ftgen 0, 0, 8192, 10, 1
  giOSC OSCinit 9999

  instr 1; receive from OSC
  kamp init 0
  kfreq init 200
  ktrig1 OSClisten giOSC, “/amp”, “f”, kamp
  ktrig2 OSClisten giOSC, “/freq”, “f”, kfreq
  asig foscil kamp, kfreq, 1, 1, 1, giSine
  outs asig, asig
  endin

  instr 2; send to OSC
  kosc oscil 100, 0.2, giSine
  OSCsend kosc, “localhost”, 9998, “/wave”, “f”, kosc
  endin

  </CsInstruments>
  <CsScore>
  i1 0 60

In order for Csound to transmit to OSC, you need to put a call to the OSCinit opcode in your orchestra header, as shown. The argument to this opcode is arbitrary, but it should be a number higher than 1024, as the lower-numbered ports are reserved. Your computer’s operating system is probably using some of them, though most will remain unused. 9999 is a good choice. OSCinit is not needed if Csound is not receiving from OSC but only sending to OSC using OSCsend.

Looking at instrument 1, you’ll see two calls to OSClisten. The first will receive amplitude values from Pd using the /amp destination, and the second will receive frequency values using the /freq destination. These same items are used in the Pd patch; you can think of them as named channels if you like.

OSClisten is a rare example of a Csound opcode whose output is on the right, among the arguments. It also has an output on the left, in the usual position; the latter will have a value of 1 when OSClisten has just received data and a value of 0 otherwise. In this example we’re not using this output. We’re only using the outputs kamp (in the first line) and kfreq (in the second). These variables have to be declared before they can be used; hence the uses of init in the preceding two lines.

The rest of the code for instrument 1 is straightforward. If you’ve been reading Csound Power! attentively, you should have no trouble understanding it.

Start this file by clicking CsoundQt’s Run button. (The first time you do this, your computer’s operating system may ask you whether you would like to allow the communication. This is a security feature. Just click OK.) You won’t hear anything, because kamp has been initialized to zero. Bring up the Pd window, hit Ctrl+E if necessary to take it out of edit mode, and click the connect localhost 9999 message. This will make the OSC connection active. Then click on the send/amp 0.1 or send /amp 0.5 message box. This message will be sent to the packOSC object, and thence to udpsend. You should now hear the sound of the Csound instrument. You can adjust its volume with the horizontal slider and its pitch with the vertical slider, which also send messages.

When you click Pd’s disconnect message box, the communications port will be closed, but Csound’s output will continue. You can shut it off in the normal way, by clicking the Stop button.

Let’s look at the syntax for OSClisten in more detail. Here is the prototype:


  kans OSClisten ihandle, idest, itype [, xdata1, xdata2, ...]

The left-side output (kans) has already been explained. We’ve set ihandle using the handle returned by the call to OSCinit, which is giOSC. (The name is arbitrary, but it should be a global init-time value.) The argument corresponding to idest is a string: ”/amp” or ”/freq”. This string is, again, arbitrary—we can put whatever we like here, beginning with a slash character—but it must correspond to the message being transmitted by the other device.

The argument to itype is, again, a string. This tells the OSC port what type of data we expect to receive. As the Csound manual explains, “The string can contain the characters ’cdfhis’, which stand [respectively] for character, double, float, 64-bit integer, 32-bit integer, and string. All types other than ’s’ require a k-rate variable, while ’s’ requires a string variable.” In the example above, we’re expecting to receive a floating-point number from Pd, so we use “f”. Finally, we tell OSClisten what variable to put the data in (kamp or kfreq, as the case may be).

To try sending OSC messages from Csound, replace the call to instrument 1 in the score with a call to instrument 2 and then click the Run button. When you look at the Pd window, you should see the number object on the right side scrolling up and down from −100 to 100 as the output of the control-rate oscillator in instrument 2 is sent over OSC.

Instrument 2 uses OSCsend. Here is the prototype:


  OSCsend kwhen, ihost, iport, idestination, itype [, kdata1, kdata2,...]

The first argument, kwhen, triggers the sending of a new OSC message each time it changes. In the example above, we want each change in the output of the oscillator to be sent, so we use kosc for this argument as well as for the data argument.

Assuming that both Csound and Pd are running on the same computer, ihost should be set to “localhost”. The port argument is 9998, corresponding to the argument to Pd’s dumpOSC object. The value for idestination is ”/wave”, which matches the argument to Pd’s OSCroute object. As with the use of OSClisten, explained earlier, the argument itype is ”f” because we’re planning to send a single floating-point number. The number itself, in this case kosc, is the final argument.

Sending and Receiving Longer Messages

As you might already have inferred from looking at the prototypes of OSClisten and OSC-send, an OSC message can contain more than one data value. To see this functionality in action, edit your Pd patch as shown in Figure 10.4. The new patch sends values using the /data identifier and receives them using the /mods identifier. To see the received values, you’ll need to keep Pd’s console window open.

Figure 10.4 A Pd patch that can send and receive OSC messages, each message containing two floating-point numbers. The message boxes in the upper center send two data values each, and the sliders can be used to change one data value at a time. The two print boxes send the values received over OSC to Pd’s console window.

image

The revised Csound instruments look like this:


  instr 1; receive multiply from OSC
  kamp init 0
  kfreq init 200
  ktrig1 OSClisten giOSC, “/data”, “ff”, kamp, kfreq
  asig foscil kamp, kfreq, 1, 1, 1, giSine
  outs asig, asig
  endin
  instr 2; send multiply to OSC
  kosc oscil 100, 0.2, giSine
  ksig line 0, p3, 1
  OSCsend kosc, “localhost”, 9998, “/mods”, “ff”, kosc, ksig
  endin

The itype arguments to OSClisten and OSCsend now say “ff”, because we’re sending and receiving messages with two floating-point numbers in each message.

Data Buffering

In a thread on the Csound mailing list, Lou Cohen pointed out that OSC messages can potentially arrive faster than Csound can process them. This is especially likely if you’re using a high value of ksmps in order to prevent CPU overload in live performance. If several messages are in the input buffer, strange things can happen.


image

Note You may want to do the same kind of input processing with MIDI messages, because they’re buffered in the same way. However, MIDI messages being sent from MIDI hardware are limited to a lower bandwidth than OSC, so the likelihood of losing messages is lower.


Here is a UDO that Lou reports using to filter the OSC input so that a Csound instrument only has to deal with one message per k-period. This opcode discards everything but the last message of some specified type in the input buffer.


  opcode getosc, k,Sk; reads OSC message, emptying input buffer
  Smsg, kvalue xin
  kcount = 0
  getmore:
    kk OSClisten giport, Smsg, “f”, kvalue
    if (kk>0) then
       kcount = kcount + 1
       kgoto getmore
    endif
  xout kvalue
  endop

Here, according to Lou, is a typical call to this UDO:


  gkpitchval getosc “/wii/1/accel/pry/0”, gkpitchval

Connecting Two Computers Using OSC

I haven’t yet tried this, but I’m told it should be fairly easy to set up. A router (wireless or wired) is a good choice for setting up a local network. You’ll also need to know the IP address of each computer. In Windows, you can get this information by running the program ipconfig from the Command Prompt. From the Mac OS Terminal, you can run ifconfig, which will display the same information. You would then use the IP address of the receiving machine in place of “localhost” in the call to OSCsend.

Connecting two computers over the Internet using OSC should also be possible, but the latency will inevitably be somewhat higher and also somewhat unpredictable. In order to do this, you’ll also need to configure your router properly and deal with your computer’s firewall.

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

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