csound~ | Install | Troubleshooting

csound~ Manual

This is the manual for csound~ v1.0.4.
Manuals for earlier versions are contained within their respective archive files.

What is csound~?

Arguments for csound~

Inlets & Outlets

Csound Flags

Csound Score Events

MIDI

Recording & Playing Events

Where to Put Your MaxMSP Patch

Tips

Table of csound~ Messages



 What is csound~? csound~ is a MaxMSP external that runs Csound5. It facilitates communication of audio, control, and MIDI data to and from Csound. Each csound~ object runs one instance of Csound, and you can have multiple csound~'s running at the same time.

The most common way csound~ is used is by creating a GUI in Max that "links" up to a Csound orchestra. Likely applications include an effects processor, synthesizer, orchestra player/renderer, etc... .  

csound~ accepts audio data, MIDI data, control data, and Csound events.  This data can be accessed from inside your Csound orchestra.  csound~ also outputs various forms of data from Csound.  This includes audio data, control data, and MIDI data.  

Arguments for csound~

0 int argument(s): 2 signal inlets/outlets.
1 int argument(s): # of signal inlets/outlets.
2 int argument(s): # signal inlets and # of signal outlets respectively.
"noscale": If present, don't scale audio from [-1, 1] to Csound's 0dB level.

Example:
[csound~ noscale 1 4] : No scaling, 1 signal inlet, 4 signal outlets.

Adding the "noscale" flag means that audio data is not scaled between csound~ and Csound. By default, audio data passed to Csound is multiplied by Csound's 0dB level, and audio data received from Csound is divided by Csound's 0dB level. The "noscale" flag allows this feature to be bypassed.  This is useful if you're already treating 1.0 as your 0dB level in your Csound orchestra, or you're using audio data for parameter manipulation in Csound.

Inlets & Outlets The # of inlets always equals the # of signal inlets. The first inlet is special in that it accepts messages, integers (MIDI bytes) as well as an audio signal. See the table below for a complete list of recognized messages.

The rightmost outlet sends a bang when the score is finished, or when the csound performance is stopped prematurely by the user with the "stop" message.

The second from right outlet sends a bang when a csd/orc is successfully compiled. This bang is useful if you need to initialize Csound MIDI control opcodes with data stored in your Max patch.

The third from right outlet sends MIDI bytes received from Csound. To enable MIDI output from this outlet, you must add the flag "-Q0" to the "csound" message.

The fourth from right outlet sends two element messages. The first element is a symbol and the second is a floating point value. The outvalue/chnset opcodes in a csd/orc file will output values via this outlet. Outvalue processing must be enabled for this feature to work (see "output"). An outvalue/chnset opcode will only output messages when there is at least one active instance of the containing instrument. Outvalue pairs are output every 50ms, by default. To output pairs as soon as possible, send the message "overdrive 1" to csound~.

All other outlets are signal outlets.

In order to access audio signals from MSP inside Csound, use the inch opcode. Audio sent to the leftmost inlet corresponds to channel 1. To send audio to csound~'s outlets, I recommend using the outch opcode. Audio sent out channel 1 will be received in the leftmost outlet.

By default, audio data is scaled between csound~ and Csound. In MaxMSP, 0dB == 1.0. In Csound, 0dB == 32768.0 (unless the user has changed the 0dB level with the 0dbfs opcode). To bypass scaling, add the "noscale" flag to csound~'s argument list.

When using chnset, you must declare all output channels in the orchestra header using the chn_k opcode.

Csound Flags In most situations, you won't need to add any flags to your "csound" message. Since csound~ handles the communication of data, flags such as [-i, -o, -M, -L] are not needed.

If you're wondering what flags to add to the 
"csound" message, my short answer is: none.  Just start with something like:

     csound hello.csd

and you should be fine (as long as your csd/orc/sco files are in the same directory as your MaxMSP patch). For more detailed information, see the 
"csound" message description.
Csound Score Events csound~ accepts score events using the "event" message. Using this feature, you can send almost any type of score event in realtime.

When csound~ is running in non-realtime mode (i.e. when rendering to a file), "event" messages are ignored.

MIDI csound~ accepts integers in its leftmost inlet as part of a MIDI byte stream. An alternative is to use the "midi" message. When using this message, make sure each message contains a complete MIDI event. For example, a NoteOn event needs exactly 3 integers (e.g. "midi 144 64 127"). csound~ is able to process these types of MIDI data: NoteOn, NoteOff, PitchBend, Aftertouch, ControlChange, ProgramChange, and ChannelAftertouch. csound~ will ignore Sysex data.

Remember to send initializing MIDI control values AFTER the csound orchestra has been compiled. When an orchestra has been compiled, a "bang" is sent out the second from right outlet. Use this "bang" to trigger your UI elements (faders, knobs, etc...) so that your MIDI opcodes (in your orchestra) are properly initialized. Otherwise, you may hear nothing, something weird, or something very LOUD!!

Recording & Playing Events You can record MIDI data, "control" messages, and "event" messages, play them back, and save a recorded sequence to a file.

Start recording with the "recordstart" message and stop with "recordstop".  To play/stop a recording, use the "playstart" and "playstop" messages.  To save/load a recorded sequence, use the "read" and "write" messages.  For detailed information on related messages, consult the table of csound messages below.

This feature was originally added to make the creation of high-quality non-realtime rendering of realtime performances easier. The idea was to capture a performance using low-quality instruments that don't tax the cpu, then render that performance in non-realtime using high-quality/cpu-intensive instruments. As such, there aren't many extra features... but it works.

Here are some miscellaneous facts:

  • The maximum recording time is 60 minutes.

  • The timing resolution of recorded events is approximately 1ms.  

  • The recorded data is saved in binary format, not text (this may change in the future).

  • If you start a non-realtime rendering (e.g. by adding "-oSomeFileName.aif" to your"csound" message) and csound~ has a recorded sequence in memory, that sequence will be played back along with the rendering.

  • Where to Put Your MaxMSP Patch Where you put your patch may affect csound~'s ability to find your csd/orc/sco files. If your patch is within the Max search path, csound~ may not be able to find your csd/orc/sco file(s). Here are some example "csound" messages:

         csound hello.csd

    In this example, "hello.csd" must be in the same directory as your patch. If your patch is inside Max's search path, Max will search within the search path and open the first file called "hello.csd" that it finds (take care not to have multiple csd's with the same name in the search path).

         csound /Users/george/CsoundStuff/hello.csd

    In this example, an absolute pathname is used to specify the location of your CSD file. This will always work no matter where your patch is located. By the way, on MacOSX, external drives are rooted in the /Volumes folder.

         csound version3/hello.csd

    In this example, a relative pathname is being used. This will only work when your patch is outside Max's search path.

    If you're still confused, or you don't know what the Max search path is, then here's my suggestion:

         1) Create a directory in your home directory and put your patch in it.

         2) Place your csd/orc/sco file(s) in the same directory.

         3) Make your "csound" message look like this:

            "csound hello.csd" or "csound hello.orc hello.sco".

    These steps should work for most users.

    Tips

    Immediately after creating a new patch, there's no way to determine which folder contains that patch. After you add a [csound~] external to the new patch, save it, then re-open it. That way, [csound~] will know which folder contains the patch. This is important if you're using relative paths to specify your csd/orc/sco files.


    On Windows, csound~ works with Max style paths. The default Max path style is very similar to the Windows path style. The only difference is the type of slash. Max uses forward slashes (/) and Windows uses back slashes (\). Since csound~ and Csound5 both work with forward slashes, you can make things easier on yourself by sticking with forward slashes.

    On MacOSX, csound~ works with Unix style paths, not Max style paths. A typical Max style path:

       MyFireWireHD:/samples/achtung

    and its Unix equivalent:

       /Volumes/MyFireWireHD/samples/achtung

    As of v1.0.4, a Universal Binary external called dp.pathconvert.mxo is included in the csound~ package. It will help to convert paths between the two styles.


    If you're concerned about performance (perhaps in a live situation), then disable csound message output by passing "message 0" to csound~, or by adding the flag "-m0" to your
    "csound" message. This will prevent Csound from printing to the Max window. The same goes for outvalue and chnset processing, which can be disabled with "output 0". invalue and chnget processing can be disabled with "input 0". Alternatively, you could comment out these types of opcodes in your orchestra.


    If you make changes to a csd/ord/sco file, but the name and location haven't changed, then simply sending "start", "bang", or "reset" will recompile the file and re-start the performance; you don't have to re-send the "csound" message.


    Never put csound~.mxo or csound~.mxe in the same directory as your MaxMSP patch.


    For greater timing accuracy of MIDI, "event" messages, and "control" messages to/from csound~:

        Lower your orchestra ksmps (i.e. increase kr).

        Decrease the MSP signal vector size (Options -> DSP Status...).

        Enable "Max Scheduler In Overdrive" in the Options menu. 

        Enable "Scheduler In Audio Interrupt" in the DSP Status window (Options -> DSP Status...). 

        Send the message "overdrive 1" to csound~.

    To minimize timing latency, decrease the I/O vector size in MaxMSP (Options -> DSP Status...). As is often the case, there is no best combination of settings for all contingencies. To find the best settings for a particular situation, set things up for maximum timing accuracy and minimum latency, then scale back if the audio is breaking up.


    If you have a polyphonic Csound instrument that uses k-rate data from invalue or chnget, you can reduce redundancy by using global variables and creating an always-on instrument to contain the invalue/chnget opcodes. This new instrument should have a smaller instrument # than your polyphonic instrument. Set things up so that the invalue/chnget opcodes write to global variables and change your polyphonic instrument to access those variables. For example:

          ; always-on instrument
        instr 1
            gkfrq chnget "frq"
            gkfilterQ chnget "Q"
        endin

        ; polyphonic instrument
        instr 2
            ifrq cpsmidi
            a1 vco 1, ifrq, 1
            aout svfilt a1, gkfrq, gkfilterQ
            outs aout, aout
        endin
       


    The "event" message allows you to load/replace Csound f-tables in realtime. However, Csound may crash when you are replacing a table that is being accessed by an instrument.

    One crash-free solution is to use the "loadsamp" message with a positive table argument.

    Another solution is to make sure there aren't any active instruments using that table. If you have an instrument that's activated by MIDI, then flush all MIDI notes and wait until all active instances are inactive. If your instrument is score activated, then use the turnoff or turnoff2 opcodes to deactivate active instances (or just wait until their durations expire).

    Another way to prevent crashes due to replacement of f-tables is to use conditionals to bypass the offending opcode(s). Here is an example where the offending opcode is bypassed when "bypass 1" is sent to csound~:

       ; always-on instrument
        instr 1
            gkbypass chnget "bypass"
        endin

        ; polyphonic instrument
        instr 2
            ifrq cpsmidi
            if gkbypass == 1 kgoto silent_out 
                aout oscil 1, ifrq, 1 ; uses f-table # 1
                kgoto continue:
            silent_out:
                aout = 0
            continue:

            outs aout, aout
        endin
     

    In my experience, I've found that crashes due this problem are infrequent. You could do 100 replacements and not have a crash, or you may crash on the first try. If you hate crashes (who doesn't?) or you're going to do replacements live, then do some extra work to prevent them.


    Table of csound~ Messages:

    Message Description
    bypass Enable/disable audio bypass. A non-zero argument enables and zero disables.

    When bypass mode is enabled, audio arriving at [csound~]'s inlets will be copied to their respective outlets. If there is an active Csound performance, it will not be performed while in bypass mode, thus saving CPU cycles.

    control
    c
    Sends k-rate values to Csound using invalue and chnget processing. Here are some examples:

        control gain .1

        c filterQ .8

        c atk 1.4

    To access this value in your orc/csd, use the invalue or chnget opcode like this:

       kgain invalue "gain"

       kQ chnget "filterQ"

       iatk chnget "atk"

    Invalue processing (see "input" message description) must be enabled in order for "control" messages to send values to their respective invalue or chnget opcodes.

    Use of chnget is preferred over invalue. chnget is a little faster than invalue and it runs at i-rate as well as k-rate (invalue only runs at k-rate).

    csound Loads the command line that will be passed to Csound when the "start" or "bang" message is received.

       csound hello.csd

    In this example, hello.csd should be in the same directory as the patch. By default, whenever a patch is opened, csound~ will save the path to the directory that contains it. This directory will be the current directory. When "start" is received, Csound will look for hello.csd relative to the current directory.

    You can change the current directory for a given instance of csound~ using the "path" message. Each instance of csound~ keeps track of its own current directory.

    Here's a MacOSX example. Let's say your patch is located at /Users/george/patches/ and your csd file is located at /Users/george/patches/csd_files/. In this case, your "csound" message should look like:

       csound csd_files/hello.csd

    You can add Csound flags to the message.  For example:

        csound -m0 hello.csd

    will disable Csound message output to the Max window.  

    Never use these flags: -+rtmidi, -M, -L

    When using csound~ in realtime (i.e. not rendering to an audio file), don't use these flags: -o, -i

    To enable non-realtime rendering, add -oSomeFileName.aif to the "csound" message. In non-realtime mode, rendering is done in a seperate thread. This means that audio will not be output from csound~'s outlets. Rendering will be done regardless of whether DSP is active or not. MIDI data, "control" messages, and "event" messages will be ignored by csound~. To render with a MIDI file, use the -F flag (and -T if appropriate).

    If csound~ has a recorded sequence loaded when non-realtime rendering begins, that sequence will playback from the beginning and will "keep time" with the rendering process. This will allow users to render recorded sequences in non-realtime mode. This is useful if the user wants to produce a higher quality rendering with, for example: higher samplerate and/or krate, increased polyphony, better (but more cpu hungry) filters, etc... .

    If neither -d or -g is present in the "csound" message, then csound~ will add -g so that ASCII representations of f-tables will appear in the Max window.

    event
    e
    Pass score line events to Csound during a realtime performance. Here are some examples:

        event i3 0 3.33 440

    Creates a new instance of instr 3 to be played immediately for 3.33 seconds with a 4'th argument set to 440.

        e f74 1 0 8192 10 1

    Loads a sine wave into table # 74.

        e a 0 0 60

    Advances the score time by 60 seconds.

        e i3 0 3.33 220, e i3 0 3.33 440, e i3 0 3.33 880

    A comma delimited list of events packed into one message.

    input Enable/disable invalue and chnget processing (enabled by default). A non-zero argument enables and zero disables.
    loadsamp Load an audio file into a table. Three arguments: table #, channel, filename, offset time (optional), size time (optional)

    arg #1: If the table argument references a non-existent table, it will be created. If the table argument is positive and the table exists, then it won't be replaced. This is useful when you want to replace table data on the fly without causing a crash. If the table is too small for the requested file, then samples will be read until full. If the table argument is negative and the table exists but is too small for the file you want to load, then it will be replaced. Replacing tables during a performance is NOT SAFE! See the "Tips" section above for some crash-free solutions.

    arg #2: The channel argument determines which channel of audio data you want to read in. For stereo files, 1 is left, 2 is right. To read in all channels as interleaved data, use 0.

    arg #3: The filename argument must be a Unix or Windows style path (depending on platform). If it's a relative path, it will be relative to the directory containing the patch.

    arg #4 (optional, default = 0): Read offset time in seconds. If negative, time is in sample frames.

    arg #5 (optional, default = 0): Amount of time to read in seconds. 0 means read in all data or as much data a possible. If negative, time is in sample frames.

    Examples:

        loadsamp 1 2 "/Users/Georg/samples/fun.aif"

    If table # 1 exists, then read in channel 2 of fun.aif until the table is full (the table is not replaced). If table # 1 does not exist, then create it and read in all channel 2 data.

        loadsamp -3 0 "/Users/Georg/samples/fun.aif"

    If table # 3 does not exist or it's too small, create/replace it. Then read in all channels of fun.aif as interleaved data.

    Note: When using loadsamp, some of the table opcodes will not operate as expected. Some of the affected opcodes:

       nsamp, ftchnls, ftlptim, ftsr

    To minimize frustration, always load a similar type of sample to the one you're replacing. In other words, if a table contains a single channel of data at 44100 sr, then only load samples with similar characteristics in that table.

    message
    printout
    Enable/disable Csound message posting to the Max window (enabled by default). A non-zero argument enables and zero disables.

    An alternative to disabling message posting is to add the "-m0" flag to the "csound" message. You will still see the results of Csound initialization and compilation, but Csound events won't be posted.

    midi
    m
    Send a complete MIDI message to Csound. For example, to send a note-on to Csound do something like:

       midi 144 64 127

    An alternative to the "midi" message is to send a MIDI byte stream to the first inlet of csound~ . Do not connect more than one MIDI byte stream to csound~. If you're working with multiple byte streams, use the Max objects midiparse and midiformat to merge them.

    output Enable/disable outvalue and chnset processing (enabled by default). A non-zero argument enables and zero disables.

    When enabled, messages generated by outvalue and chnset will be sent out the fourth from right outlet.

    If a message is identical to a previous message, there will be no output. For example, if Csound outputs the message "frequency 224.89" multiple times, only the first time produces output from csound~. Only when the value changes (e.g. "frequency 440.01") will a message starting with "frequency" be output again.

    When using chnset, remember to declare the output channels in your orchestra header with the chn_k opcode. For example:

       chn_k "frq", 2

       instr 1
       ...
          chnset kFrq, "frq"
       endin

    overdrive Enable/disable outvalue and chnset processing in overdrive mode.  A non-zero argument enables overdrive mode and zero disables it.

    When overdrive is disabled, messages generated by outvalue and chnset are output at 50ms intervals. Use this mode when you're debugging. If you need better timing accuracy, enable overdrive with the message "overdrive 1". When overdrive is enabled, value pairs are output as soon as possible.

    path Set the current directory for this instance of csound~. "path" only accepts an absolute pathname argument in Unix or Windows style.
    playstart This message will start playback of recorded MIDI data, "control" messages, and "event" messages.
    playstop This message will stop playback of recorded MIDI data, "control" messages, and "event" messages.
    read This message is used to load a csound~ recorded sequence.  It has one argument: the pathname of a file.  There is no requirement for the file extension.
    readbuf The "readbuf" message will copy audio data from a [buffer~] to a Csound table.

    arg #1: Csound table number to write to. A negative number forces the table to be replaced with a table whose size equals the amount of data requested in arg #5. A positive number will not replace an exisiting table, but will create one if it doesn't exist.

    arg #2: Channel to read. 0 means read all channels. If > 0, then read from that channel into the Csound table (treating the table as a single channel table).

    arg #3: The name of the [buffer~] to read from.

    arg #4 (optional, default = 0): Read offset time (from beginning of buffer~). If positive, specifies time in seconds. If negative, specifies time in sample frames.

    arg #5 (optional, default = 0): Amount of audio data to read. 0 means read in all data or as much data as possible. If positive, specifies time in seconds. If negative, specifies time in sample frames.

    recordstart This message will start the recording of MIDI data, "control" messages, and "event" messages.  Previously recorded data will be delete before recording starts.

    When "recordstart" is received by csound~, it will automatically generate MIDI control events and 
    "control" messages to reflect the last known state of all such data.  This will allow the user to start recording without having to send initializing MIDI and "control" data afterwards.  
    recordstop This message will stop the recording of MIDI data, "control" messages, and "event" messages.  To playback the recorded data, send the message "playstart".

    If there are any hanging MIDI notes when recording stops, MIDI NoteOff's will be added to cancel them.

    Events are moved in time within the recorded sequence so that the "empty space" at the beginning of the recording is removed. This will allow playback of recorded events to start immediately upon receiving the "playstart" message.
    reset Stop the current performance (if it's still running), recompile the orc/csd, then restart the performance.
    rewind Set the score offset to 0 seconds. Score playback will resume from that time.
    rsidx Read the table value at a specified index. Two integer arguments: table number, index.

    Example:

        rsidx 3 128

    If table # 3 exists and the value at index 128 is 0.42481, then this message will be sent out the fourth from right outlet:

        rsidx 0.42481
    sfdir Set the Csound variables SFDIR, SSDIR, and SADIR. Accepts one argument: an absolute pathname to a directory. It has been provided for compatiblity with Ingalls' csound~ patches.
    start
    bang
    Compile the csd/orc file specified in the "csound" message (which should have been received before "start"). If the compilation is successful, then performance will start once DSP processing is started. If DSP processing is already active, then the csound performance will start immediately.

    When rendering to a file, DSP processing need not be active.

    New in v1.0.4:
    Upon successfull compilation, if DSP is not active, then one k-cycle will be automatically processed. This will force all initializations (including events with a start time of zero) to take place. For example, all tables that were scheduled to be loaded at time zero will be loaded. During this initial k-cycle, audio input will be filled with zeros, and audio output will be ignored.

    stop Stop the csound performance and send a bang out the rightmost outlet.
    tempo Set the relative playback speed of recorded events. Accepts one float argument.

    "tempo 1.0" means playback at original speed. "tempo" messages are not recorded.

    write This message will save a recorded sequence to a binary file. It has one argument: the pathname of a file to save to. There is no requirement for the file extension.
    writebuf The "writebuf" message will copy audio data from a Csound table to a [buffer~].

    arg #1: Csound table number to read from.

    arg #2: Target [buffer~] channel. If = 0, copy all channels (with the assumption that the Csound table has the same number of channels as [buffer~]). If > 0, treat the Csound table as a single-channel table.

    arg #3: arg #3: The name of the target [buffer~].

    arg #4 (optional, default = 0): Read offset time in seconds. If negative, time is in sample frames.

    arg #5 (optional, default = 0): Amount of time to read in seconds. 0 means read in all data or as much data a possible. If negative, time is in sample frames.

    wsidx Set the value at a specific index in a given table. Three arguments: table # (integer), index (integer), value (float)

    Example:

        wsidx 5 17 .2515

    If table # 5 exists and index 17 is within bounds, then the value at that index will be set to .2515.