code: def update():
      if audio.data["values"] is None:
          return
  
      signal, spectrum, bins = audio.data["values"]
  
      # seems to be a problem with Array property, using List for now
      waterfall_renderer.latest = spectrum.tolist()
      waterfall_plot.y_range.end = freq.value * 0.001
  
      # the if-elses below are small optimization: avoid computing and sending
      # all the x-values, if the length has not changed
  
      if len(signal) == len(signal_source.data["y"]):
          signal_source.data["y"] = signal * gain.value
      else:
          t = np.linspace(0, TIMESLICE, len(signal))
          signal_source.data = dict(t=t, y=signal * gain.value)
  
      if len(spectrum) == len(spectrum_source.data["y"]):
          spectrum_source.data["y"] = spectrum
      else:
          f = np.linspace(0, MAX_FREQ_KHZ, len(spectrum))
          spectrum_source.data = dict(f=f, y=spectrum)
      spectrum_plot.x_range.end = freq.value * 0.001
  
      alphas = []
      for x in bins:
          a = np.zeros_like(eq_range)
          N = int(ceil(x))
          a[:N] = 1 - eq_range[:N] * 0.05
          alphas.append(a)
      eq_source.data["alpha"] = np.hstack(alphas)
  
file_path: bokeh/examples/server/app/spectrogram/main.py
imports: from math import ceil
  from os.path import dirname, join
  import numpy
  from bokeh.io import curdoc
  from bokeh.layouts import column, grid, row
  from bokeh.models import ColumnDataSource, Div, Slider
  from bokeh.plotting import figure
  from .None import audio
  from .audio import MAX_FREQ, NUM_BINS, TIMESLICE
  from .waterfall import WaterfallRenderer
label_desc: Use image node_id 1 for calling a global function with example usage: update() without return types