To use icsound create an icsound instance:
In [1]:
%pylab inline
In [2]:
import icsound
cs = icsound.icsound()
Then start the engine:
In [3]:
cs.start_engine()
You can set the properties of the Csound engine with parameters to the start_engine() function.
In [4]:
help(cs.start_engine)
The engine runs in a separate thread, so it doesn't block execution of python.
In [5]:
cs.start_engine()
Use the %%csound magic command to directly type csound language code in the cell and send it to the current engine.
In [6]:
%%csound
gkinstr init 1
In [7]:
%%csound
print i(gkinstr)
So where did it print?
In [8]:
cs.print_log()
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.
You can create csound f-tables directly from python lists or numpy arrays:
In [9]:
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 [10]:
cs.plot_table(1)
cs.plot_table(2, reuse=True)
grid()
You can get the function table values from the csound instance:
In [11]:
cs.get_table_data(1)
Out[11]:
In [12]:
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 [13]:
cs.get_table_data(2)[100: 105]
Out[13]:
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 [14]:
randsig = random.random((320, 720))
i = 0
for i,row in enumerate(randsig):
cs.fill_table(50 + i, row)
print i, '..',
In [15]:
cs.plot_table(104)
You can send instruments to the running csound engine with the %%csound magic. Any syntax errors will be displayed inline.
In [16]:
%%csound
instr 1
asig asds
In [17]:
%%csound
instr 1
asig oscil 0.5, 440
outs asig, asig
In [18]:
%%csound
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 [21]:
cs.set_channel("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 [22]:
cs.get_channel("val")
Out[22]:
You can record the realtime output from csound: (This requires Csound 6.04 - unrealeased as of this writing...)
In [23]:
cs.start_record("out.wav")
In [24]:
cs.send_score("i 1 0 1")
import time
time.sleep(1)
In [25]:
cs.stop_record()
In [26]:
!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 [ ]:
cs_client = icsound.icsound()
cs_client.start_client()
In [ ]:
cs.clear_log()
Now send notes and instruments from the client:
In [ ]:
cs_client.send_score("i 1 0 1")
cs_client.send_code("print i(gkinstr)")
And show the log in the server:
In [ ]:
cs.print_log()
In [ ]:
cs.stop_engine()
In [ ]:
cs
In [ ]:
cs.stop_engine()
Reading Earthquake data through a web API:
In [27]:
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 urllib2
f = urllib2.urlopen(prefix + SCNL_parameters + times + output)
timeseries = f.read()
In [28]:
data = 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[28]:
In [29]:
cs.start_engine()
cs.fill_table(1, values)
Instrument to play back the earthquake data stored in a table:
In [30]:
%%csound
instr 1
idur = p3
itable = p4
asig poscil 1/8000, 1/p3, p4
outs asig, asig
endin
Listen:
In [32]:
cs.send_score('i 1 0 3 1')
Slower:
In [33]:
cs.send_score('i 1 0 7 1')
In [34]:
cs.send_score('i 1 0 1 1')
Get financial data through a web API:
In [35]:
import xml.etree.ElementTree as ET
import urllib2
from datetime import datetime
symbols = 'MSFT', 'GOOG'
data = {}
for symbol in symbols:
url = 'http://chartapi.finance.yahoo.com/instrument/1.0/' + \
symbol + '/chartdata;type=quote;range=1y/xml'
f = urllib2.urlopen(url)
root = ET.fromstring(f.read())
dates = []
values = []
for v in root[2].findall('p'):
dateval = v.attrib['ref']
date = datetime(year=int(dateval[0:4]), month=int(dateval[4:6]), day=int(dateval[6:8]))
dates.append(date)
entryvalues = []
for num in v:
entryvalues.append(float(num.text))
values.append(entryvalues)
data[symbol] = [dates, array(values)]
In [36]:
cs.fill_table(1,data['GOOG'][1][:,1] - min(data['GOOG'][1][:,1]) )
cs.fill_table(2,data['MSFT'][1][:,1] - min(data['MSFT'][1][:,1]) )
In [37]:
cs.plot_table(1)
title('GOOG')
Out[37]:
In [38]:
cs.plot_table(2)
title('MSFT')
Out[38]:
In [39]:
%%csound
gisine ftgen 0, 0, 4096, 10, 1
instr 5
amoddepth poscil 1/2, 1/p3, 2
acarfreq poscil 3, 1/p3, 1
acmratio = amoddepth*10
aphs phasor 220 + acarfreq
aphsmod oscili amoddepth/2, acarfreq*( acmratio)
asig table3 aphs + aphsmod, gisine, 1, 0, 1
aenv linen 0.2, 0.01, p3, 0.01
outs asig*aenv, asig*aenv
endin
In [40]:
cs.send_score('i 5 0 20')
In [ ]:
cs.send_score('i -5 0 20')
In [41]:
%%csound
gisine ftgen 0, 0, 4096, 10, 1
instr 7
kratiofactor chnget "factor"
amoddepth poscil 1/2, 1/p3, 2
acarfreq poscil 3, 1/p3, 1
acmratio = amoddepth*kratiofactor
aphs phasor 220 + acarfreq
aphsmod oscili amoddepth/2, acarfreq*( acmratio)
asig table3 aphs + aphsmod, gisine, 1, 0, 1
aenv linen 0.2, 0.01, p3, 0.01
outs asig*aenv, asig*aenv
endin
In [42]:
cs.send_score('i 7 0 40')
In [45]:
cs.set_channel("factor", 0.1)
In [46]:
cs.plot_table(1)
cs.plot_table(2)
Another engine:
In [ ]:
ics = icsound.icsound()
In [ ]:
ics.start_engine(buffersize=64)
In [ ]:
ics.list_interfaces()
In [ ]:
%%csound
instr 1
asig oscil 0.5, 440
outs asig, asig
endin
In [ ]:
ics.send_score("i 1 0 0.5")
In [ ]:
ics.stop_engine()
In [ ]:
del ics