Sampler in ChucK
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

main.py 12KB

10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
10 år sedan
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. from libs.simpleosc import *
  2. import wx
  3. #TODO: standardize methods for adding/removing arrays of widgets
  4. #TODO: fix the *100 / /100 stuff
  5. def sendOSCSafe(channel, data):
  6. try:
  7. sendOSCMsg(channel, data)
  8. except OSCClientError:
  9. print "OSC comms error"
  10. class OSCSlider(wx.Panel):
  11. ''' A GUI slider '''
  12. def __init__(self, parent, label, min_value=0, max_value=1, default_value=0, align=True):
  13. ''' Constructor '''
  14. wx.Panel.__init__(self, parent)
  15. sizer=wx.BoxSizer(wx.HORIZONTAL)
  16. label=wx.StaticText(self, label=label, size=(100,15) if align else None)
  17. sizer.Add(label, 0, wx.RIGHT, 10)
  18. self.slider=wx.Slider(self, value=default_value*100, minValue=min_value*100, maxValue=max_value*100)
  19. sizer.Add(self.slider, 1, wx.EXPAND)
  20. self.SetSizerAndFit(sizer)
  21. self.Bind=self.slider.Bind
  22. self.GetValue=self.slider.GetValue
  23. class CommsPanel(wx.Panel):
  24. """ OSC comms """
  25. def __init__(self, parent):
  26. wx.Panel.__init__(self, parent)
  27. sizer = wx.BoxSizer(wx.HORIZONTAL)
  28. label = wx.StaticText(self, label="Sync:")
  29. font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  30. sizer.Add(label, 0, wx.TOP|wx.BOTTOM|wx.RIGHT|wx.EXPAND, 5)
  31. choices=["Master", "Minion"]
  32. self.master= wx.ComboBox(self, choices=choices, style=wx.CB_READONLY, size=(25,25))
  33. sizer.Add(self.master, 1, wx.ALL, 3)
  34. self.master.SetValue(choices[0])
  35. self.ip=wx.TextCtrl(self, value="127.0.0.1")
  36. sizer.Add(self.ip, 0, wx.ALL, 3)
  37. self.port=wx.TextCtrl(self, value="9000")
  38. sizer.Add(self.port, 0, wx.ALL, 3)
  39. self.SetSizerAndFit(sizer)
  40. class InputPanel(wx.Panel):
  41. ''' Handle the ADC input settings '''
  42. def __init__(self, parent):
  43. ''' Constructor '''
  44. wx.Panel.__init__(self, parent)
  45. sizer = wx.BoxSizer(wx.HORIZONTAL)
  46. label = wx.StaticText(self, label="Input:")
  47. font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  48. sizer.Add(label, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5)
  49. self.gain = OSCSlider(self, "Gain", default_value=.5, align=False)
  50. sizer.Add(self.gain, 1, wx.ALL, 5)
  51. self.thru = OSCSlider(self, "Thru", default_value=.5, align=False)
  52. sizer.Add(self.thru, 1, wx.ALL, 5)
  53. self.mute = wx.ToggleButton(self, 0, "Mute")
  54. #self.mute.SetValue(1)
  55. sizer.Add(self.mute, 0)
  56. self.SetSizerAndFit(sizer)
  57. self.gain.Bind(wx.EVT_SCROLL, self.update)
  58. self.thru.Bind(wx.EVT_SCROLL, self.update)
  59. self.mute.Bind(wx.EVT_TOGGLEBUTTON, self.update)
  60. self.update()
  61. def update(self, evt=None):
  62. """ Send OSC messages """
  63. gain=self.gain.slider.GetValue()/100.
  64. thru=self.thru.slider.GetValue()/100.
  65. if self.mute.GetValue(): gain, thru = 0.,0.
  66. sendOSCSafe("/input", [gain, thru])
  67. class DelayPanel(wx.Panel):
  68. ''' Handle the ADC input settings '''
  69. def __init__(self, parent):
  70. ''' Constructor '''
  71. wx.Panel.__init__(self, parent)
  72. sizer = wx.BoxSizer(wx.HORIZONTAL)
  73. label = wx.StaticText(self, label="Loop:")
  74. font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  75. sizer.Add(label, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5)
  76. self.delayTime=OSCSlider(self, "Time", default_value=1, max_value=10, align=False)
  77. sizer.Add(self.delayTime, 1, wx.ALL, 5)
  78. self.feedback=OSCSlider(self, "Hold", default_value=.99, align=False)
  79. sizer.Add(self.feedback, 1, wx.ALL, 5)
  80. self.metronome=wx.ToggleButton(self, 0, "Metronome")
  81. sizer.Add(self.metronome, 0)
  82. self.SetSizerAndFit(sizer)
  83. self.delayTime.Bind(wx.EVT_SCROLL, self.update)
  84. self.feedback.Bind(wx.EVT_SCROLL, self.update)
  85. self.metronome.Bind(wx.EVT_TOGGLEBUTTON, self.switchMetronome)
  86. self.update(None)
  87. def update(self, evt):
  88. """ Send OSC messages """
  89. a=self.delayTime.slider.GetValue()/100.
  90. b=self.feedback.slider.GetValue()/100.
  91. sendOSCSafe("/delay", [a, b])
  92. def switchMetronome(self, evt):
  93. """ Send OSC messages """
  94. sendOSCSafe("/metronome", [int(self.metronome.GetValue())])
  95. class ButtonArray(wx.Panel):
  96. ''' Handle the ADC input settings '''
  97. def __init__(self, parent, index):
  98. wx.Panel.__init__(self, parent)
  99. w=40
  100. sizer = wx.BoxSizer(wx.HORIZONTAL)
  101. self.record = wx.ToggleButton(self, 0, "Arm", size=(w,25))
  102. sizer.Add(self.record, 1, wx.ALL, 0)
  103. self.mute = wx.ToggleButton(self, 0, "Mute", size=(w,25))
  104. sizer.Add(self.mute, 1, wx.ALL, 0)
  105. self.clear = wx.Button(self, 0, "Clear", size=(w,25))
  106. sizer.Add(self.clear, 1, wx.ALL, 0)
  107. self.buttons=(self.record, self.mute, self.clear)
  108. self.SetSizerAndFit(sizer)
  109. class Channel(wx.Panel):
  110. """ A single channel """
  111. def __init__(self, parent, index):
  112. self.index=index
  113. wx.Panel.__init__(self, parent)
  114. sizer = wx.BoxSizer(wx.VERTICAL)
  115. #label = wx.StaticText(self, label="CH%d" % self.index)
  116. #font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  117. #sizer.Add(label, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5)
  118. self.gain = OSCSlider(self, "Gain", default_value=1, max_value=1.3, align=False)
  119. sizer.Add(self.gain, 0, wx.ALL|wx.EXPAND, 3)
  120. self.pan = OSCSlider(self, "Pan", default_value=0, min_value=-1, max_value=1, align=False)
  121. sizer.Add(self.pan, 0, wx.ALL|wx.EXPAND, 3)
  122. self.fxsend = OSCSlider(self, "Dry/Wet", default_value=0, min_value=0, max_value=1, align=False)
  123. sizer.Add(self.fxsend, 0, wx.ALL|wx.EXPAND, 3)
  124. self.buttons=ButtonArray(self, index)
  125. self.record, self.mute, self.clear = self.buttons.buttons
  126. sizer.Add(self.buttons, 0, wx.ALL|wx.EXPAND, 3)
  127. choices=["1 bar", "2 bars", "4 bars", "Dephase", "1/2 rate"]
  128. self.speed= wx.ComboBox(self, choices=choices, style=wx.CB_READONLY, size=(25,25))
  129. self.speed.SetValue("1 bar")
  130. sizer.Add(self.speed, 0, wx.ALL|wx.EXPAND, 3)
  131. self.SetSizerAndFit(sizer)
  132. self.gain.Bind(wx.EVT_SCROLL, self.update)
  133. self.pan.Bind(wx.EVT_SCROLL, self.update)
  134. self.fxsend.Bind(wx.EVT_SCROLL, self.update)
  135. self.mute.Bind(wx.EVT_TOGGLEBUTTON, self.update)
  136. self.update()
  137. def update(self, evt=None):
  138. gain=self.gain.GetValue()/100.
  139. pan=self.pan.GetValue()/100.
  140. fxsend=self.fxsend.GetValue()/100.
  141. if self.mute.GetValue(): gain=0.0;
  142. sendOSCSafe("/channel", [self.index, gain, pan, fxsend])
  143. class Mixer(wx.Panel):
  144. ''' All the channels '''
  145. def __init__(self, parent):
  146. ''' Constructor '''
  147. wx.Panel.__init__(self, parent)
  148. sizer = wx.BoxSizer(wx.HORIZONTAL)
  149. self.channels=[]
  150. for i in range(4):
  151. c=Channel(self, index=i)
  152. c.record.Bind(wx.EVT_TOGGLEBUTTON, self.switch_record)
  153. c.record.index=i
  154. c.clear.Bind(wx.EVT_BUTTON, self.clear_channel)
  155. c.clear.index=i
  156. self.channels.append(c)
  157. sizer.Add(c, 1, wx.EXPAND)
  158. self.SetSizerAndFit(sizer)
  159. def switch_record(self, evt):
  160. """ Send OSC message to switch recording channel """
  161. index = evt.GetEventObject().index
  162. value = evt.GetEventObject().GetValue()
  163. for i, c in enumerate(self.channels):
  164. c.record.SetValue(0)
  165. self.channels[index].record.SetValue(value)
  166. sendOSCSafe("/arm", [index if value else -1])
  167. def clear_channel(self, evt):
  168. """ Send OSC message to clear a channel """
  169. index = evt.GetEventObject().index
  170. sendOSCSafe("/clear", [index])
  171. class FXPanel(wx.Panel):
  172. ''' Effects chain '''
  173. def __init__(self, parent):
  174. ''' Constructor '''
  175. wx.Panel.__init__(self, parent)
  176. sizer = wx.BoxSizer(wx.HORIZONTAL)
  177. label = wx.StaticText(self, label="FX:")
  178. font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  179. sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.BOTTOM|wx.RIGHT, 5)
  180. #choices=["Low pass filter", "High pass filter", "Reverb"]
  181. #self.fxtype= wx.ComboBox(self, choices=choices, style=wx.CB_READONLY, size=(25,25))
  182. #sizer.Add(self.fxtype, 1, wx.ALL|wx.EXPAND, 5)
  183. #self.fxtype.SetValue(choices[0])
  184. self.lpf=OSCSlider(self, "Lowpass", default_value=.5, align=False)
  185. sizer.Add(self.lpf, 2, wx.EXPAND|wx.ALL, 5)
  186. self.lpf.Bind(wx.EVT_SCROLL, self.update)
  187. self.reverb=OSCSlider(self, "Reverb", default_value=.5, align=False)
  188. sizer.Add(self.reverb, 2, wx.EXPAND|wx.ALL, 5)
  189. self.reverb.Bind(wx.EVT_SCROLL, self.update)
  190. self.SetSizerAndFit(sizer)
  191. self.update(None)
  192. def update(self, evt):
  193. a=self.lpf.slider.GetValue()/100.
  194. b=self.reverb.slider.GetValue()/100.
  195. sendOSCSafe("/fx", [a,b])
  196. class OutputPanel(wx.Panel):
  197. ''' Handle the ADC input settings '''
  198. def __init__(self, parent):
  199. ''' Constructor '''
  200. wx.Panel.__init__(self, parent)
  201. sizer = wx.BoxSizer(wx.HORIZONTAL)
  202. label = wx.StaticText(self, label="Output:")
  203. font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  204. sizer.Add(label, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5)
  205. self.level=OSCSlider(self, "Level", default_value=.8, align=False)
  206. sizer.Add(self.level, 2, wx.EXPAND|wx.ALL, 5)
  207. self.level.Bind(wx.EVT_SCROLL, self.update)
  208. #self.gauge = wx.Gauge(self, size=(40,10))
  209. #sizer.Add(self.gauge, 1, wx.EXPAND|wx.ALL, 5)
  210. self.SetSizerAndFit(sizer)
  211. def update(self, evt):
  212. a=self.level.slider.GetValue()/100.
  213. sendOSCSafe("/master", [a])
  214. class MainGUI(wx.Frame):
  215. """ A simple GUI to talk to Chuck """
  216. def __init__(self):
  217. """ Constructor """
  218. # Build the interface
  219. self.app = wx.App(False)
  220. self.build()
  221. def run(self): self.app.MainLoop()
  222. def update_vu(self, a,b,c,d):
  223. level=int(1000000*c[0])
  224. self.output.gauge.SetValue(level)
  225. def build(self):
  226. """ Builds the various pieces of the GUI """
  227. wx.Frame.__init__(self, None, title="DELAY LORD")
  228. self.Bind(wx.EVT_CLOSE, self.quit)
  229. # The main sizer
  230. self.mainsizer = wx.BoxSizer(wx.VERTICAL)
  231. self.commsPanel = CommsPanel(self)
  232. self.mainsizer.Add(self.commsPanel, 0, wx.EXPAND|wx.ALL, 5)
  233. line=wx.StaticLine(self); self.mainsizer.Add(line, 0, wx.EXPAND|wx.ALL, 1)
  234. self.inputPanel = InputPanel(self)
  235. self.mainsizer.Add(self.inputPanel, 0, wx.EXPAND|wx.ALL, 5)
  236. line=wx.StaticLine(self); self.mainsizer.Add(line, 0, wx.EXPAND|wx.ALL, 1)
  237. self.delayPanel = DelayPanel(self)
  238. self.mainsizer.Add(self.delayPanel, 0, wx.EXPAND|wx.ALL, 5)
  239. line=wx.StaticLine(self); self.mainsizer.Add(line, 0, wx.EXPAND|wx.ALL, 1)
  240. self.mixer = Mixer(self)
  241. self.mainsizer.Add(self.mixer, 0, wx.EXPAND|wx.ALL, 5)
  242. line=wx.StaticLine(self); self.mainsizer.Add(line, 0, wx.EXPAND|wx.ALL, 1)
  243. self.fx = FXPanel(self)
  244. self.mainsizer.Add(self.fx, 0, wx.EXPAND|wx.ALL, 5)
  245. line=wx.StaticLine(self); self.mainsizer.Add(line, 0, wx.EXPAND|wx.ALL, 1)
  246. self.output = OutputPanel(self)
  247. self.mainsizer.Add(self.output, 0, wx.EXPAND|wx.ALL, 5)
  248. # Put things together
  249. self.SetSizerAndFit(self.mainsizer)
  250. self.Show()
  251. def populate_left_panel(self):
  252. """ Populate the left panel """
  253. # Status boxes
  254. def quit(self, *args):
  255. """ Close down gracefully, and then destroy the window """
  256. self.Destroy()
  257. if __name__ == "__main__":
  258. initOSCClient(ip="127.0.0.1", port=9000)
  259. g=MainGUI()
  260. #initOSCServer(ip="127.0.0.1", port=6649, mode=0)
  261. #setOSCHandler("/vu", g.update_vu)
  262. g.run()
  263. closeOSC()