Sampler in ChucK
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

241 lines
7.9KB

  1. from libs.simpleosc import *
  2. import wx
  3. class OSCSlider(wx.Panel):
  4. ''' A GUI slider '''
  5. def __init__(self, parent, label, min_value=0, max_value=1, default_value=0, align=True):
  6. ''' Constructor '''
  7. wx.Panel.__init__(self, parent)
  8. sizer=wx.BoxSizer(wx.HORIZONTAL)
  9. label=wx.StaticText(self, label=label, size=(100,15) if align else None)
  10. sizer.Add(label, 0, wx.RIGHT, 10)
  11. self.slider=wx.Slider(self, value=default_value*100, minValue=min_value*100, maxValue=max_value*100)
  12. sizer.Add(self.slider, 1, wx.EXPAND)
  13. self.SetSizerAndFit(sizer)
  14. self.Bind=self.slider.Bind
  15. self.GetValue=self.slider.GetValue
  16. class CommsPanel(wx.Panel):
  17. """ OSC comms """
  18. def __init__(self, parent):
  19. wx.Panel.__init__(self, parent)
  20. sizer = wx.BoxSizer(wx.HORIZONTAL)
  21. label = wx.StaticText(self, label="Sync:")
  22. font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  23. sizer.Add(label, 0, wx.TOP|wx.BOTTOM|wx.RIGHT|wx.EXPAND, 5)
  24. self.master = wx.ToggleButton(self, 1, "Master/Minion")
  25. sizer.Add(self.master, 0, wx.ALL, 3)
  26. self.ip=wx.TextCtrl(self, value="127.0.0.1")
  27. sizer.Add(self.ip, 0, wx.ALL, 3)
  28. self.port=wx.TextCtrl(self, value="9000")
  29. sizer.Add(self.port, 0, wx.ALL, 3)
  30. self.SetSizerAndFit(sizer)
  31. class InputPanel(wx.Panel):
  32. ''' Handle the ADC input settings '''
  33. def __init__(self, parent):
  34. ''' Constructor '''
  35. wx.Panel.__init__(self, parent)
  36. sizer = wx.BoxSizer(wx.HORIZONTAL)
  37. label = wx.StaticText(self, label="Line in:")
  38. font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  39. sizer.Add(label, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5)
  40. self.gain = OSCSlider(self, "Gain", default_value=.5, align=False)
  41. sizer.Add(self.gain, 1, wx.ALL, 5)
  42. self.thru = OSCSlider(self, "Thru", default_value=.5, align=False)
  43. sizer.Add(self.thru, 1, wx.ALL, 5)
  44. self.mute = wx.ToggleButton(self, 1, "Mute")
  45. #self.mute.SetValue(1)
  46. sizer.Add(self.mute, 0)
  47. self.SetSizerAndFit(sizer)
  48. self.gain.Bind(wx.EVT_SCROLL, self.update)
  49. self.thru.Bind(wx.EVT_SCROLL, self.update)
  50. self.mute.Bind(wx.EVT_TOGGLEBUTTON, self.update)
  51. self.update()
  52. def update(self, evt=None):
  53. """ Send OSC messages """
  54. gain=self.gain.slider.GetValue()/100.
  55. thru=self.thru.slider.GetValue()/100.
  56. if self.mute.GetValue(): gain, thru = 0.,0.
  57. try:
  58. sendOSCMsg("/input", [gain, thru])
  59. except OSCClientError:
  60. pass
  61. class DelayPanel(wx.Panel):
  62. ''' Handle the ADC input settings '''
  63. def __init__(self, parent):
  64. ''' Constructor '''
  65. wx.Panel.__init__(self, parent)
  66. sizer = wx.BoxSizer(wx.VERTICAL)
  67. label = wx.StaticText(self, label="Delay lines:")
  68. font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  69. sizer.Add(label, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5)
  70. self.delayTime=OSCSlider(self, "Delay time (s)", default_value=1, max_value=10)
  71. sizer.Add(self.delayTime, 0, wx.EXPAND|wx.ALL, 5)
  72. self.feedback=OSCSlider(self, "Feedback", default_value=.99)
  73. sizer.Add(self.feedback, 0, wx.EXPAND|wx.ALL, 5)
  74. self.metronome=wx.ToggleButton(self, 0, "Metronome")
  75. sizer.Add(self.metronome, 0, wx.EXPAND|wx.ALL, 5)
  76. self.SetSizerAndFit(sizer)
  77. self.delayTime.Bind(wx.EVT_SCROLL, self.update)
  78. self.feedback.Bind(wx.EVT_SCROLL, self.update)
  79. self.update(None)
  80. def update(self, evt):
  81. """ Send OSC messages """
  82. a=self.delayTime.slider.GetValue()/100.
  83. b=self.feedback.slider.GetValue()/100.
  84. try:
  85. sendOSCMsg("/delay", [a, b])
  86. except OSCClientError:
  87. pass
  88. class Channel(wx.Panel):
  89. """ A single channel """
  90. def __init__(self, parent, index):
  91. self.index=index
  92. wx.Panel.__init__(self, parent)
  93. sizer = wx.BoxSizer(wx.VERTICAL)
  94. label = wx.StaticText(self, label="CH%d" % self.index)
  95. font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
  96. sizer.Add(label, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5)
  97. self.gain = OSCSlider(self, "Gain", default_value=1, max_value=1.3, align=False)
  98. sizer.Add(self.gain, 0, wx.ALL|wx.EXPAND, 3)
  99. self.record = wx.ToggleButton(self, 1, "Arm")
  100. sizer.Add(self.record, 0, wx.ALL|wx.EXPAND if index==0 else wx.ALL|wx.EXPAND, 3)
  101. self.mute = wx.ToggleButton(self, 1, "Mute")
  102. sizer.Add(self.mute, 0, wx.ALL|wx.EXPAND, 3)
  103. self.clear = wx.Button(self, 1, "Clear")
  104. sizer.Add(self.clear, 0, wx.ALL|wx.EXPAND, 3)
  105. self.SetSizerAndFit(sizer)
  106. self.gain.Bind(wx.EVT_SCROLL, self.update)
  107. self.mute.Bind(wx.EVT_TOGGLEBUTTON, self.update)
  108. self.update()
  109. def update(self, evt=None):
  110. gain=self.gain.GetValue()/100.
  111. if self.mute.GetValue(): gain=0.0;
  112. try:
  113. sendOSCMsg("/channel", [self.index, gain])
  114. except OSCClientError:
  115. pass
  116. class Mixer(wx.Panel):
  117. ''' All the channels '''
  118. def __init__(self, parent):
  119. ''' Constructor '''
  120. wx.Panel.__init__(self, parent)
  121. sizer = wx.BoxSizer(wx.HORIZONTAL)
  122. self.channels=[]
  123. for i in range(4):
  124. c=Channel(self, index=i)
  125. c.record.Bind(wx.EVT_TOGGLEBUTTON, self.switch_record)
  126. c.record.index=i
  127. c.clear.Bind(wx.EVT_BUTTON, self.clear_channel)
  128. c.clear.index=i
  129. self.channels.append(c)
  130. sizer.Add(c, 1, wx.EXPAND)
  131. self.SetSizerAndFit(sizer)
  132. def switch_record(self, evt):
  133. """ Send OSC message to switch recording channel """
  134. index = evt.GetEventObject().index
  135. value = evt.GetEventObject().GetValue()
  136. for i, c in enumerate(self.channels):
  137. c.record.SetValue(0)
  138. self.channels[index].record.SetValue(value)
  139. if value:
  140. sendOSCMsg("/arm", [index])
  141. print "Record on channel %d" % index
  142. else:
  143. sendOSCMsg("/arm", [-1])
  144. print "Stop recording on all channels"
  145. def clear_channel(self, evt):
  146. """ Send OSC message to clear a channel """
  147. index = evt.GetEventObject().index
  148. print "Clear channel %d" % index
  149. class MainGUI(wx.Frame):
  150. """ A simple GUI to talk to Chuck """
  151. def __init__(self):
  152. """ Constructor """
  153. # Build the interface
  154. self.app = wx.App(False)
  155. self.build()
  156. self.app.MainLoop()
  157. def build(self):
  158. """ Builds the various pieces of the GUI """
  159. wx.Frame.__init__(self, None, title="DELAY LORD")
  160. self.Bind(wx.EVT_CLOSE, self.quit)
  161. # The main sizer
  162. self.mainsizer = wx.BoxSizer(wx.VERTICAL)
  163. self.commsPanel = CommsPanel(self)
  164. self.mainsizer.Add(self.commsPanel, 0, wx.EXPAND|wx.ALL, 5)
  165. line=wx.StaticLine(self); self.mainsizer.Add(line, 0, wx.EXPAND|wx.ALL, 1)
  166. self.inputPanel = InputPanel(self)
  167. self.mainsizer.Add(self.inputPanel, 0, wx.EXPAND|wx.ALL, 5)
  168. line=wx.StaticLine(self); self.mainsizer.Add(line, 0, wx.EXPAND|wx.ALL, 1)
  169. self.delayPanel = DelayPanel(self)
  170. self.mainsizer.Add(self.delayPanel, 0, wx.EXPAND|wx.ALL, 5)
  171. line=wx.StaticLine(self); self.mainsizer.Add(line, 0, wx.EXPAND|wx.ALL, 1)
  172. self.mixer = Mixer(self)
  173. self.mainsizer.Add(self.mixer, 1, wx.EXPAND|wx.ALL, 5)
  174. # Put things together
  175. self.SetSizerAndFit(self.mainsizer)
  176. self.Show()
  177. def populate_left_panel(self):
  178. """ Populate the left panel """
  179. # Status boxes
  180. def quit(self, *args):
  181. """ Close down gracefully, and then destroy the window """
  182. self.Destroy()
  183. if __name__ == "__main__":
  184. initOSCClient(ip="127.0.0.1", port=9000)
  185. g=MainGUI()
  186. closeOSC()