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
|
# Importing CsoundAC automatically creates a global 'csound' object.
import csnd6
import wx
# Csound MUST run in its own thread.
import threading
import traceback
# Create a panel to hold widgets that will control a Csound performance.
class ControlPanel(wx.Panel):
# Override the base class constructor.
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
# Create a button to send a note to Csound.
self.ID_BUTTON1 = 10
self.button1 = wx.Button(self, self.ID_BUTTON1, "Send Note", (20, 20))
# Bind the button to its event handler.
wx.EVT_BUTTON(self, self.ID_BUTTON1, self.OnClickButton1)
# Create a slider to change the pitch of the note.
self.ID_SLIDER1 = 20
self.slider1 = wx.Slider(self, self.ID_SLIDER1, 63, 0, 127, (20, 50), (200,50),
wx.SL_HORIZONTAL | wx.SL_LABELS)
self.slider1.SetTickFreq(5, 1)
# Bind the slider to its event handler.
wx.EVT_SLIDER(self, self.ID_SLIDER1, self.OnSlider1Move)
# Set up a 'close' event handler to cleanly shut down Csound.
wx.EVT_CLOSE(parent, self.OnClose)
# Default pitch.
self.pitch = 60
# Create an instance of CppSound.
self.csound = csnd6.CppSound()
# Create the Csound thread and start it.
self.csoundThread = threading.Thread(None, self.csoundThreadRoutine)
self.csoundThread.start()
# Initialize Csound and start performing, in a separate thread.
# Csound will play notes sent in from wxWindows.
def csoundThreadRoutine(self):
# Embed an orchestra in this script.
self.csound.setOrchestra('''
sr=44100
ksmps=128
nchnls=2
instr 1
; print p1, p2, p3, p4, p5
; Slider sends note with MIDI key number.
; Convert it to octaves.
ioctave = p4 / 12.0 + 3.0
print ioctave
; Convert octave to frequency.
ihertz = cpsoct(ioctave)
p3 = p3 + 0.05
a1 oscili ampdb(p5), ihertz, 1
kenv linseg 0, 0.05, 1, p3, 0
a1 = kenv * a1
outs a1,a1
endin
''')
# And a score.
self.csound.setScore('''
f1 0 8192 10 1
f0 600
e
''')
# Real-time audio output.
# It is not necessary to enable line events.
self.csound.setCommand('''csound -h -m128 -d -odac -B512 -b400 temp.orc temp.sco''')
# Export the orc and sco.
self.csound.exportForPerformance()
# Start the performance.
self.csound.compile()
# Perform in blocks of ksmps
# (Csound will yield implicitly to wxWindows).
self.performanceThread = csnd6.CsoundPerformanceThread(self.csound)
self.performanceThread.Play()
# Handle the button click -- send a note to Csound
# with the pitch set by the slider.
def OnClickButton1(self, event):
print "You pressed button 1"
# Send a line event.
self.performanceThread.InputMessage("i 1 0 8 %i 70" % self.pitch)
# Handle the slider movement -- change the pitch.
def OnSlider1Move(self, event):
print "You moved the slider to %d" % event.GetInt()
self.pitch = event.GetInt()
# Handle the window close event -- stop performance and
# wait for Csound to exit, then destroy main window.
def OnClose(self, event):
try:
print "You closed the window."
self.performanceThread.Stop()
self.performanceThread.Join()
self.csoundThread.join()
print 'Csound thread has finished.'
self.GetParent().Destroy()
except:
print traceback.print_exc()
try:
# Create a wx application.
application = wx.PySimpleApp()
# Create a frame to hold the control panel.
frame = wx.Frame(None, -1, "Csound Controller")
# Create the control panel as a child of the frame.
controlPanel = ControlPanel(frame)
# Display the frame.
frame.Show(True)
# Run the application.
application.MainLoop()
print 'Done...'
except:
traceback.print_exc()
|