text: #!/usr/bin/env python
  """
  This plot displays the audio spectrum from the microphone.
  
  Based on updating_plot.py
  """
  
  # Major library imports
  import pyaudio
  from numpy import zeros, linspace, short, fromstring, hstack, transpose
  from scipy import fft
  
  # Enthought library imports
  from chaco.default_colormaps import jet
  from traits.api import HasTraits, Any
  
  # Chaco imports
  from chaco.api import Plot, ArrayPlotData, OverlayPlotContainer
  from chaco.tools.api import MoveTool, PanTool, ZoomTool
  
  NUM_SAMPLES = 1024
  SAMPLING_RATE = 11025
  SPECTROGRAM_LENGTH = 100
  
  
  def create_plot_component(obj):
      # Setup the spectrum plot
      frequencies = linspace(0., float(SAMPLING_RATE)/2, num=NUM_SAMPLES/2)
      obj.spectrum_data = ArrayPlotData(frequency=frequencies)
      empty_amplitude = zeros(NUM_SAMPLES/2)
      obj.spectrum_data.set_data('amplitude', empty_amplitude)
  
      obj.spectrum_plot = Plot(obj.spectrum_data)
      obj.spectrum_plot.plot(("frequency", "amplitude"), name="Spectrum",
                             color="red")
      obj.spectrum_plot.padding = 50
      obj.spectrum_plot.title = "Spectrum"
      spec_range = obj.spectrum_plot.plots.values()[0][0].value_mapper.range
      spec_range.low = 0.0
      spec_range.high = 5.0
      obj.spectrum_plot.index_axis.title = 'Frequency (hz)'
      obj.spectrum_plot.value_axis.title = 'Amplitude'
  
      # Time Series plot
      times = linspace(0., float(NUM_SAMPLES)/SAMPLING_RATE, num=NUM_SAMPLES)
      obj.time_data = ArrayPlotData(time=times)
      empty_amplitude = zeros(NUM_SAMPLES)
      obj.time_data.set_data('amplitude', empty_amplitude)
  
      obj.time_plot = Plot(obj.time_data)
      obj.time_plot.plot(("time", "amplitude"), name="Time", color="blue")
      obj.time_plot.padding = 50
      obj.time_plot.title = "Time"
      obj.time_plot.index_axis.title = 'Time (seconds)'
      obj.time_plot.value_axis.title = 'Amplitude'
      time_range = obj.time_plot.plots.values()[0][0].value_mapper.range
      time_range.low = -0.2
      time_range.high = 0.2
  
      # Spectrogram plot
      spectrogram_data = zeros(( NUM_SAMPLES/2, SPECTROGRAM_LENGTH))
      obj.spectrogram_plotdata = ArrayPlotData()
      obj.spectrogram_plotdata.set_data('imagedata', spectrogram_data)
      spectrogram_plot = Plot(obj.spectrogram_plotdata)
      spectrogram_time = linspace(
          0.0, float(SPECTROGRAM_LENGTH*NUM_SAMPLES)/float(SAMPLING_RATE),
          num=SPECTROGRAM_LENGTH)
      spectrogram_freq = linspace(0.0, float(SAMPLING_RATE/2), num=NUM_SAMPLES/2)
      xbounds = (spectrogram_time[0], spectrogram_time[-1])
      ybounds = (spectrogram_freq[0], spectrogram_freq[-1])
      spectrogram_plot.img_plot('imagedata',
                                name='Spectrogram',
                                xbounds=xbounds,
                                ybounds=ybounds,
                                colormap=jet,
                                )
      range_obj = spectrogram_plot.plots['Spectrogram'][0].value_mapper.range
      range_obj.high = 5
      range_obj.low = 0.0
      spectrogram_plot.title = 'Spectrogram'
      obj.spectrogram_plot = spectrogram_plot
  
      return obj.spectrum_plot, obj.time_plot, obj.spectrogram_plot
  
  _stream = None
  def get_audio_data():
      global _stream
      if _stream is None:
          # The audio stream is opened the first time this function gets called.
          # The stream is always closed (if it was opened) in a try finally
          # block at the end of this file,
          pa = pyaudio.PyAudio()
          _stream = pa.open(format=pyaudio.paInt16, channels=1,
                            rate=SAMPLING_RATE,
                            input=True, frames_per_buffer=NUM_SAMPLES)
  
      audio_data  = fromstring(_stream.read(NUM_SAMPLES), dtype=short)
      normalized_data = audio_data / 32768.0
      return (abs(fft(normalized_data))[:NUM_SAMPLES/2], normalized_data)
  
  class TimerController(HasTraits):
      interactor = Any()
      timer_id = Any()
  
      def on_timer(self, vtk_obj=None, eventname=""):
          try:
              spectrum, time = get_audio_data()
          except IOError:
              return
          self.spectrum_data.set_data('amplitude', spectrum)
          self.time_data.set_data('amplitude', time)
          spectrogram_data = self.spectrogram_plotdata.get_data('imagedata')
          spectrogram_data = hstack((spectrogram_data[:,1:],
                                     transpose([spectrum])))
  
          self.spectrogram_plotdata.set_data('imagedata', spectrogram_data)
          self.spectrum_plot.request_redraw()
          return
  
  def main():
      from tvtk.api import tvtk
      from mayavi import mlab
      from enable.vtk_backend.vtk_window import EnableVTKWindow
      f = mlab.figure(size=(900,850))
      m = mlab.test_mesh()
      scene = mlab.gcf().scene
      render_window = scene.render_window
      renderer = scene.renderer
      rwi = scene.interactor
  
      # Create the plot
      timer_controller = TimerController()
      plots = create_plot_component(timer_controller)
      specplot, timeplot, spectrogram = plots
  
      for i, p in enumerate(plots):
          p.set(resizable = "", bounds = [200,200], outer_x = 0,
                  bgcolor = "transparent",
                  )
          p.outer_y = i*250
          p.tools.append(MoveTool(p, drag_button="right"))
          p.tools.append(PanTool(p))
          p.tools.append(ZoomTool(p))
  
      spectrogram.tools[-1].set(tool_mode="range", axis="value")
      spectrogram.tools[-2].set(constrain=True, constrain_direction="y")
  
      container = OverlayPlotContainer(bgcolor = "transparent",
                      fit_window = True)
      container.add(*plots)
      container.timer_callback = timer_controller.on_timer
  
      window = EnableVTKWindow(rwi, renderer,
              component = container,
              istyle_class = tvtk.InteractorStyleTrackballCamera,
              bgcolor = "transparent",
              event_passthrough = True,
              )
  
      mlab.show()
  
  if __name__ == "__main__":
      main()
  
  