show_spectrum.gd 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. extends Node2D
  2. const VU_COUNT = 16
  3. const FREQ_MAX = 11050.0
  4. const WIDTH = 800
  5. const HEIGHT = 250
  6. const HEIGHT_SCALE = 8.0
  7. const MIN_DB = 60
  8. const ANIMATION_SPEED = 0.1
  9. var spectrum
  10. var min_values = []
  11. var max_values = []
  12. func _draw():
  13. var w = WIDTH / VU_COUNT
  14. for i in range(VU_COUNT):
  15. var min_height = min_values[i]
  16. var max_height = max_values[i]
  17. var height = lerp(min_height, max_height, ANIMATION_SPEED)
  18. draw_rect(
  19. Rect2(w * i, HEIGHT - height, w - 2, height),
  20. Color.from_hsv(float(VU_COUNT * 0.6 + i * 0.5) / VU_COUNT, 0.5, 0.6)
  21. )
  22. draw_line(
  23. Vector2(w * i, HEIGHT - height),
  24. Vector2(w * i + w - 2, HEIGHT - height),
  25. Color.from_hsv(float(VU_COUNT * 0.6 + i * 0.5) / VU_COUNT, 0.5, 1.0),
  26. 2.0,
  27. true
  28. )
  29. # Draw a reflection of the bars with lower opacity.
  30. draw_rect(
  31. Rect2(w * i, HEIGHT, w - 2, height),
  32. Color.from_hsv(float(VU_COUNT * 0.6 + i * 0.5) / VU_COUNT, 0.5, 0.6) * Color(1, 1, 1, 0.125)
  33. )
  34. draw_line(
  35. Vector2(w * i, HEIGHT + height),
  36. Vector2(w * i + w - 2, HEIGHT + height),
  37. Color.from_hsv(float(VU_COUNT * 0.6 + i * 0.5) / VU_COUNT, 0.5, 1.0) * Color(1, 1, 1, 0.125),
  38. 2.0,
  39. true
  40. )
  41. func _process(_delta):
  42. var data = []
  43. var prev_hz = 0
  44. for i in range(1, VU_COUNT + 1):
  45. var hz = i * FREQ_MAX / VU_COUNT
  46. var magnitude = spectrum.get_magnitude_for_frequency_range(prev_hz, hz).length()
  47. var energy = clampf((MIN_DB + linear_to_db(magnitude)) / MIN_DB, 0, 1)
  48. var height = energy * HEIGHT * HEIGHT_SCALE
  49. data.append(height)
  50. prev_hz = hz
  51. for i in range(VU_COUNT):
  52. if data[i] > max_values[i]:
  53. max_values[i] = data[i]
  54. else:
  55. max_values[i] = lerp(max_values[i], data[i], ANIMATION_SPEED)
  56. if data[i] <= 0.0:
  57. min_values[i] = lerp(min_values[i], 0.0, ANIMATION_SPEED)
  58. # Sound plays back continuously, so the graph needs to be updated every frame.
  59. queue_redraw()
  60. func _ready():
  61. spectrum = AudioServer.get_bus_effect_instance(0, 0)
  62. min_values.resize(VU_COUNT)
  63. max_values.resize(VU_COUNT)
  64. min_values.fill(0.0)
  65. max_values.fill(0.0)