csoundmagics includes an ICsound class which is adapted from André Cabrera's icsound module. ICsound is bound to the %%csound and %csound magics command.
This notebook is an adaptation of André's icsound test notebook.
To use ICsound create an ICsound instance:
In [1]:
%pylab inline
In [2]:
%load_ext csoundmagics
Creating an ICsound object automatically starts the engine:
In [3]:
cs = ICsound(port=12894)
You can set the properties of the Csound engine with parameters to the startEngine() function.
In [4]:
help(cs.startEngine)
The engine runs in a separate thread, so it doesn't block execution of python.
In [5]:
cs.startEngine()
Use the %%csound magic command to directly type csound language code in the cell and send it to the engine. The number after the magic command is optional; it references the slot where the engine is running. If omitted, slot#1 is assumed.
In [6]:
%%csound 1
gkinstr init 1
In [7]:
%%csound
print i(gkinstr)
So where did it print?
In [8]:
cs.printLog()
By default, messages from Csound are not shown, but they are stored in an internal buffer. You can view them with the printLog() function. If the log is getting too long and confusing, use the clearLog() function.
You can create csound f-tables directly from python lists or numpy arrays:
In [9]:
cs.fillTable(1, array([8, 7, 9, 1, 1, 1]))
cs.fillTable(2, [4, 5, 7, 0, 8, 7, 9, 6])
Tables can be plotted in the usual matplotlib way, but ICsound provides a plotTable function which styles the graphs.
In [10]:
cs.plotTable(1)
cs.plotTable(2, reuse=True)
grid()
You can get the function table values from the csound instance:
In [11]:
cs.table(2)
Out[11]:
In [12]:
cs.makeTable(2, 1024, 10, 1)
cs.makeTable(3, 1024, -10, 0.5, 1)
cs.plotTable(2)
cs.plotTable(3, reuse=True)
#ylim((-1.1,1.1))
In [13]:
cs.table(2)[100: 105]
Out[13]:
The following will create 320 tables with 720 points each:
In [14]:
randsig = random.random((320, 720))
i = 0
for i, row in enumerate(randsig):
cs.fillTable(50 + i, row)
print(i, '..', end=' ')
In [15]:
cs.plotTable(104)
You can send instruments to a running csound engine with the %%csound magic. Any syntax errors will be displayed inline.
In [16]:
%%csound 1
instr 1
asig asds
In [17]:
%%csound 1
instr 1
asig oscil 0.5, 440
outs asig, asig
In [18]:
%%csound 1
instr 1
asig oscil 0.5, 440
outs asig, asig
endin
Csound channels can be used to send values to Csound. They can affect running instances of instruments by using the invalue/chnget opcodes:
In [19]:
cs.setChannel("val", 20)
You can also read the channels from Csound. These channels can be set from ICsound or within instruments with the outvalue/chnset opcodes:
In [20]:
cs.channel("val")
Out[20]:
You can record the realtime output from csound:
In [21]:
cs.startRecord("out.wav")
In [22]:
cs.sendScore("i 1 0 1")
import time
time.sleep(1)
In [23]:
cs.stopRecord()
In [24]:
!aplay out.wav
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 [25]:
cs_client = ICsound()
cs_client.startClient()
In [26]:
cs.clearLog()
Now send notes and instruments from the client:
In [27]:
cs_client.sendScore("i 1 0 1")
cs_client.sendCode("print i(gkinstr)")
And show the log in the server:
In [28]:
cs.printLog()
In [29]:
cs.stopEngine()
In [30]:
cs
Out[30]:
If we don't need cs_client anymore, we can delete its slot with the %csound line magic (note the single % sign and the negative slot#). The python instance cs_client can then be deleted:
In [31]:
%csound -2
del cs_client
Reading Earthquake data through a web API:
In [32]:
prefix = 'http://service.iris.edu/irisws/timeseries/1/query?'
SCNL_parameters = 'net=IU&sta=ANMO&loc=00&cha=BHZ&'
times = 'starttime=2005-01-01T00:00:00&endtime=2005-01-02T00:00:00&'
output = 'output=ascii'
import urllib
f = urllib.request.urlopen(prefix + SCNL_parameters + times + output)
timeseries = f.read()
In [33]:
import ctcsound
data = ctcsound.pstring(timeseries).split('\n')
dates = []
values = []
for line in data[1:-1]:
date, val = line.split()
dates.append(date)
values.append(float(val))
plot(values)
Out[33]:
In [34]:
cs.startEngine()
cs.fillTable(1, values)
Instrument to play back the earthquake data stored in a table:
In [35]:
%%csound 1
instr 1
idur = p3
itable = p4
asig poscil 1/8000, 1/p3, p4
outs asig, asig
endin
Listen:
In [36]:
cs.sendScore('i 1 0 3 1')
Slower:
In [37]:
cs.sendScore('i 1 0 7 1')
Quicker:
In [38]:
cs.sendScore('i 1 0 1 1')
Another engine:
In [39]:
ics = ICsound(bufferSize=64)
In [40]:
ics.listInterfaces()
In [41]:
%%csound 2
instr 1
asig oscil 0.5, 440
outs asig, asig
endin
In [42]:
ics.sendScore("i 1 0 0.5")
In [43]:
%csound -2
In [44]:
del ics
In [45]:
cs.stopEngine()