Using icsound

By: Andres Cabrera mantaraya36@gmail.com

Starting the Csound engine

To use icsound create an icsound instance:


In [1]:
import icsound
cs = icsound.icsound()

Then start the engine:


In [2]:
cs.start_engine()


Csound server started. Listening to port 12894

You can set the properties of the Csound engine with parameters to the start_engine() function.


In [3]:
help(cs.start_engine)


Help on method start_engine in module icsound:

start_engine(self, sr=44100, ksmps=64, nchnls=2, zerodbfs=1.0, dacout='dac', adcin=None, port=12894) method of icsound.icsound instance
    Start the csound engine on a separate thread

The engine runs in a separate thread, so it doesn't block execution of python.


In [4]:
cs.start_engine()


icsound: Csound already running

Use the %%csound magic command to directly type csound language code in the cell and send it to the current engine.


In [5]:
%%csound
gkinstr init 1

In [6]:
%%csound
print i(gkinstr)

So where did it print?


In [7]:
cs.print_log()


rtaudio: ALSA module enabled
rtmidi: ALSA Raw MIDI module enabled
--Csound version 6.03.2 (double samples) Jun 15 2014
graphics suppressed, ascii substituted
0dBFS level = 1.0
UDP server started on port 12894 
orch now loaded
audio buffered in 256 sample-frame blocks
ALSA output: total buffer size: 1024, period size: 256 
writing 512 sample blks of 64-bit floats to dac 
SECTION 1:
instr 0:  #i0 = 1.000

By default, messages from Csound are not shown, but they are stored in an internal buffer. You can view them with the print_log() function. If the log is getting too long and cinfusing, use the clear_log() function.

Function tables

You can create csound f-tables directly from python lists or numpy arrays:


In [8]:
cs.fill_table(1, [4,5,7,0,8,7,9])
cs.fill_table(2, array([8,7,9, 1, 1, 1]))

Tables can be plotted in the usual matplotlib way, but icsound provides a plot_table function which styles the graphs.


In [9]:
cs.plot_table(1)
cs.plot_table(2, reuse=True)
grid()


You can get the function table values from the csound instance:


In [10]:
cs.get_table_data(1)


Out[10]:
array([ 4.,  5.,  7.,  0.,  8.,  7.], dtype=float32)

In [11]:
cs.make_table(2, 1024, 10, 1)
cs.make_table(3, 1024, -10, 0.5, 1)
cs.plot_table(2)
cs.plot_table(3, reuse=True)
#ylim((-1.1,1.1))



In [12]:
cs.get_table_data(2)[100: 105]


Out[12]:
array([ 0.57580817,  0.58081394,  0.58579785,  0.59075969,  0.59569931], dtype=float32)

If ctypes is available in your system, icsound will use it to significantly speed up data transfer to and from Csound f-tables. The following will create 320 tables with 720 points each:


In [13]:
randsig = random.random((320, 720))
i = 0
for i,row in enumerate(randsig):
    cs.fill_table(50 + i, row)
    print i, '..',


0 .. 1 .. 2 .. 3 .. 4 .. 5 .. 6 .. 7 .. 8 .. 9 .. 10 .. 11 .. 12 .. 13 .. 14 .. 15 .. 16 .. 17 .. 18 .. 19 .. 20 .. 21 .. 22 .. 23 .. 24 .. 25 .. 26 .. 27 .. 28 .. 29 .. 30 .. 31 .. 32 .. 33 .. 34 .. 35 .. 36 .. 37 .. 38 .. 39 .. 40 .. 41 .. 42 .. 43 .. 44 .. 45 .. 46 .. 47 .. 48 .. 49 .. 50 .. 51 .. 52 .. 53 .. 54 .. 55 .. 56 .. 57 .. 58 .. 59 .. 60 .. 61 .. 62 .. 63 .. 64 .. 65 .. 66 .. 67 .. 68 .. 69 .. 70 .. 71 .. 72 .. 73 .. 74 .. 75 .. 76 .. 77 .. 78 .. 79 .. 80 .. 81 .. 82 .. 83 .. 84 .. 85 .. 86 .. 87 .. 88 .. 89 .. 90 .. 91 .. 92 .. 93 .. 94 .. 95 .. 96 .. 97 .. 98 .. 99 .. 100 .. 101 .. 102 .. 103 .. 104 .. 105 .. 106 .. 107 .. 108 .. 109 .. 110 .. 111 .. 112 .. 113 .. 114 .. 115 .. 116 .. 117 .. 118 .. 119 .. 120 .. 121 .. 122 .. 123 .. 124 .. 125 .. 126 .. 127 .. 128 .. 129 .. 130 .. 131 .. 132 .. 133 .. 134 .. 135 .. 136 .. 137 .. 138 .. 139 .. 140 .. 141 .. 142 .. 143 .. 144 .. 145 .. 146 .. 147 .. 148 .. 149 .. 150 .. 151 .. 152 .. 153 .. 154 .. 155 .. 156 .. 157 .. 158 .. 159 .. 160 .. 161 .. 162 .. 163 .. 164 .. 165 .. 166 .. 167 .. 168 .. 169 .. 170 .. 171 .. 172 .. 173 .. 174 .. 175 .. 176 .. 177 .. 178 .. 179 .. 180 .. 181 .. 182 .. 183 .. 184 .. 185 .. 186 .. 187 .. 188 .. 189 .. 190 .. 191 .. 192 .. 193 .. 194 .. 195 .. 196 .. 197 .. 198 .. 199 .. 200 .. 201 .. 202 .. 203 .. 204 .. 205 .. 206 .. 207 .. 208 .. 209 .. 210 .. 211 .. 212 .. 213 .. 214 .. 215 .. 216 .. 217 .. 218 .. 219 .. 220 .. 221 .. 222 .. 223 .. 224 .. 225 .. 226 .. 227 .. 228 .. 229 .. 230 .. 231 .. 232 .. 233 .. 234 .. 235 .. 236 .. 237 .. 238 .. 239 .. 240 .. 241 .. 242 .. 243 .. 244 .. 245 .. 246 .. 247 .. 248 .. 249 .. 250 .. 251 .. 252 .. 253 .. 254 .. 255 .. 256 .. 257 .. 258 .. 259 .. 260 .. 261 .. 262 .. 263 .. 264 .. 265 .. 266 .. 267 .. 268 .. 269 .. 270 .. 271 .. 272 .. 273 .. 274 .. 275 .. 276 .. 277 .. 278 .. 279 .. 280 .. 281 .. 282 .. 283 .. 284 .. 285 .. 286 .. 287 .. 288 .. 289 .. 290 .. 291 .. 292 .. 293 .. 294 .. 295 .. 296 .. 297 .. 298 .. 299 .. 300 .. 301 .. 302 .. 303 .. 304 .. 305 .. 306 .. 307 .. 308 .. 309 .. 310 .. 311 .. 312 .. 313 .. 314 .. 315 .. 316 .. 317 .. 318 .. 319 ..

In [14]:
cs.plot_table(104)


Sending instruments

You can send instruments to the running csound engine with the %%csound magic. Any syntax errors will be displayed inline.


In [15]:
%%csound
instr 1
asig asds


error: syntax error, unexpected T_IDENT  (token "asds") line 120:
>>>asig asds <<<
Unexpected untyped word asig when expecting a variable
Parsing failed due to invalid input!
Stopping on parser failure


In [16]:
%%csound
instr 1
asig oscil 0.5, 440
outs asig, asig


error: syntax error, unexpected $end  (token "") line 8696292:
>>> <<<
Parsing failed due to invalid input!
Stopping on parser failure


In [17]:
%%csound
instr 1
asig oscil 0.5, 440
outs asig, asig
endin

Channels

Csound channels can be used to send values to Csound. They can affect running instances of instruments by using the invalue/chnget opcodes:


In [18]:
cs.set_channel("val", 10)

You can also read the channels from Csound. These channels can be set from icsound or within instruments with the outvalue/chnset opcodes:


In [19]:
cs.get_channel("val")


Out[19]:
10.0

Recording the output

You can record the realtime output from csound: (This requires Csound 6.04 - unrealeased as of this writing...)


In [25]:
cs.start_record("out.wav")

In [26]:
cs.send_score("i 1 0 1")
import time
time.sleep(1)

In [27]:
cs.stop_record()

In [28]:
!aplay out.wav


Playing WAVE 'out.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

Remote engines

You can also interact with engines through UDP. Note that not all operations are available, notably reading f-tables, but you can send instruments and note events to the remote engine.


In [31]:
cs_client = icsound.icsound()
cs_client.start_client()

In [32]:
cs.clear_log()

Now send notes and instruments from the client:


In [33]:
cs_client.send_score("i 1 0 1")
cs_client.send_code("print i(gkinstr)")

And show the log in the server:


In [34]:
cs.print_log()


  rtevent:	   T 74.034 TT 74.034 M:  0.50000  0.50000
instr 0:  #i2 = 1.000

Stopping the engine


In [ ]:
cs.stop_engine()

In [ ]:
cs

In [ ]:
cs.stop_engine()

In [ ]:

Other tests

Another engine:


In [9]:
ics = icsound.icsound()

In [10]:
ics.start_engine(buffersize=64)


Csound server started.

In [11]:
ics.list_interfaces()


4 interfaces available:

In [12]:
%%csound

instr 1
asig oscil 0.5, 440
outs asig, asig
endin

In [13]:
ics.send_score("i 1 0 0.5")

In [ ]:
ics.stop_engine()

In [8]:
del ics

In [ ]: